diff options
147 files changed, 1779 insertions, 1088 deletions
diff --git a/Help/command/cmake_command.rst b/Help/command/cmake_command.rst index 9281647..08b7832 100644 --- a/Help/command/cmake_command.rst +++ b/Help/command/cmake_command.rst @@ -9,6 +9,7 @@ Synopsis .. parsed-literal:: cmake_command(`INVOKE`_ <command> [<args>...]) + cmake_command(`EVAL`_ CODE <code>...) Introduction ^^^^^^^^^^^^ @@ -16,8 +17,10 @@ Introduction This command will call meta-operations on built-in CMake commands or those created via the :command:`macro` or :command:`function` commands. -Invoking -^^^^^^^^ +``cmake_command`` does not introduce a new variable or policy scope. + +Invoking Commands +^^^^^^^^^^^^^^^^^ .. _INVOKE: @@ -38,3 +41,50 @@ is equivalent to .. code-block:: cmake message(STATUS "Hello World!") + +Evaluating Code +^^^^^^^^^^^^^^^ + +.. _EVAL: + +.. code-block:: cmake + + cmake_command(EVAL CODE <code>...) + +Evaluates the ``<code>...`` as CMake code. + +For example, the code: + +.. code-block:: cmake + + set(A TRUE) + set(B TRUE) + set(C TRUE) + set(condition "(A AND B) OR C") + + cmake_command(EVAL CODE " + if (${condition}) + message(STATUS TRUE) + else() + message(STATUS FALSE) + endif()" + ) + +is equivalent to + +.. code-block:: cmake + + set(A TRUE) + set(B TRUE) + set(C TRUE) + set(condition "(A AND B) OR C") + + file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/eval.cmake " + if (${condition}) + message(STATUS TRUE) + else() + message(STATUS FALSE) + endif()" + ) + + include(${CMAKE_CURRENT_BINARY_DIR}/eval.cmake) diff --git a/Help/generator/Ninja Multi-Config.rst b/Help/generator/Ninja Multi-Config.rst index 11c59f2..1f68535 100644 --- a/Help/generator/Ninja Multi-Config.rst +++ b/Help/generator/Ninja Multi-Config.rst @@ -12,9 +12,10 @@ multiple configurations at once with :variable:`CMAKE_CONFIGURATION_TYPES` instead of only one configuration with :variable:`CMAKE_BUILD_TYPE`. One ``build-<Config>.ninja`` file will be generated for each of these configurations (with ``<Config>`` being the configuration name.) These files -are intended to be run with ``ninja -f build-<Config>.ninja``. No -``build.ninja`` file is generated by default (see below for how to generate -it.) +are intended to be run with ``ninja -f build-<Config>.ninja``. A +``build.ninja`` file is also generated, using the configuration from either +:variable:`CMAKE_DEFAULT_BUILD_TYPE` or the first item from +:variable:`CMAKE_CONFIGURATION_TYPES`. ``cmake --build . --config <Config>`` will always use ``build-<Config>.ninja`` to build. If no ``--config`` argument is specified, ``cmake --build .`` will @@ -35,7 +36,7 @@ The ``Ninja Multi-Config`` generator recognizes the following variables: Specifies the total set of configurations to build. See the variable's documentation for more information. -:variable:`CMAKE_NMC_CROSS_CONFIGS` +:variable:`CMAKE_CROSS_CONFIGS` Specifies a :ref:`semicolon-separated list <CMake Language Lists>` of configurations available from all ``build-<Config>.ninja`` files. This variable activates cross-config mode. @@ -49,36 +50,36 @@ The ``Ninja Multi-Config`` generator recognizes the following variables: The value of this variable must be a subset of :variable:`CMAKE_CONFIGURATION_TYPES`. -:variable:`CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG` +:variable:`CMAKE_DEFAULT_BUILD_TYPE` Specifies the configuration to use by default in a ``build.ninja`` file. If - this variable is specified, a ``build.ninja`` file is generated which uses - build rules from ``build-<Config>.ninja`` by default. All custom commands are - executed with this configuration. If the variable is not specified, no - ``build.ninja`` file is generated. + this variable is specified, ``build.ninja`` uses build rules from + ``build-<Config>.ninja`` by default. All custom commands are executed with + this configuration. If the variable is not specified, the first item from + :variable:`CMAKE_CONFIGURATION_TYPES` is used instead. The value of this variable must be one of the items from :variable:`CMAKE_CONFIGURATION_TYPES`. -:variable:`CMAKE_NMC_DEFAULT_CONFIGS` +:variable:`CMAKE_DEFAULT_CONFIGS` Specifies a :ref:`semicolon-separated list <CMake Language Lists>` of configurations to build for a target in ``build.ninja`` if no ``:<Config>`` suffix is specified. If it is set to ``all``, all - configurations from :variable:`CMAKE_NMC_CROSS_CONFIGS` are used. If + configurations from :variable:`CMAKE_CROSS_CONFIGS` are used. If it is not specified, it defaults to - :variable:`CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG`. + :variable:`CMAKE_DEFAULT_BUILD_TYPE`. For example, if you set - :variable:`CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG` to ``Release``, but - set :variable:`CMAKE_NMC_DEFAULT_CONFIGS` to ``Debug`` or ``all``, + :variable:`CMAKE_DEFAULT_BUILD_TYPE` to ``Release``, but + set :variable:`CMAKE_DEFAULT_CONFIGS` to ``Debug`` or ``all``, all ``<target>`` aliases in ``build.ninja`` will resolve to ``<target>:Debug`` or ``<target>:all``, but custom commands will still use the ``Release`` configuration. The value of this variable must be a subset of - :variable:`CMAKE_NMC_CROSS_CONFIGS` or be the same as - :variable:`CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG`. It must not be - specified if :variable:`CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG` or - :variable:`CMAKE_NMC_CROSS_CONFIGS` is not used. + :variable:`CMAKE_CROSS_CONFIGS` or be the same as + :variable:`CMAKE_DEFAULT_BUILD_TYPE`. It must not be + specified if :variable:`CMAKE_DEFAULT_BUILD_TYPE` or + :variable:`CMAKE_CROSS_CONFIGS` is not used. Consider the following example: @@ -104,8 +105,8 @@ This would build the ``Debug`` configuration of ``generator``, which would be used to generate ``generated.c``, which would be used to build the ``Debug`` configuration of ``generated``. -But if :variable:`CMAKE_NMC_CROSS_CONFIGS` is set to ``all``, and you -run the following instead: +But if :variable:`CMAKE_CROSS_CONFIGS` is set to ``all``, and you run the +following instead: .. code-block:: shell diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 1023a66..a639b5d 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -372,11 +372,14 @@ Variables that Control the Build /variable/CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY /variable/CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY_CONFIG /variable/CMAKE_CONFIG_POSTFIX + /variable/CMAKE_CROSS_CONFIGS /variable/CMAKE_CTEST_ARGUMENTS /variable/CMAKE_CUDA_SEPARABLE_COMPILATION /variable/CMAKE_CUDA_RESOLVE_DEVICE_SYMBOLS /variable/CMAKE_CUDA_RUNTIME_LIBRARY /variable/CMAKE_DEBUG_POSTFIX + /variable/CMAKE_DEFAULT_BUILD_TYPE + /variable/CMAKE_DEFAULT_CONFIGS /variable/CMAKE_DISABLE_PRECOMPILE_HEADERS /variable/CMAKE_ENABLE_EXPORTS /variable/CMAKE_EXE_LINKER_FLAGS @@ -428,9 +431,6 @@ Variables that Control the Build /variable/CMAKE_MODULE_LINKER_FLAGS_INIT /variable/CMAKE_MSVCIDE_RUN_PATH /variable/CMAKE_MSVC_RUNTIME_LIBRARY - /variable/CMAKE_NMC_CROSS_CONFIGS - /variable/CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG - /variable/CMAKE_NMC_DEFAULT_CONFIGS /variable/CMAKE_NINJA_OUTPUT_PATH_PREFIX /variable/CMAKE_NO_BUILTIN_CHRPATH /variable/CMAKE_NO_SYSTEM_FROM_IMPORTED diff --git a/Help/release/3.17.rst b/Help/release/3.17.rst index 30e6cc3..23dec84 100644 --- a/Help/release/3.17.rst +++ b/Help/release/3.17.rst @@ -179,7 +179,9 @@ Modules * The :module:`FindPython3` and :module:`FindPython` modules gained, respectively, variable ``Python3_SOABI`` and ``Python_SOABI`` giving - the standard extension suffix for modules. + the standard extension suffix for modules. Moreover, commands + ``Python3_add_library`` and ``Python_add_library`` gained the option + ``WITH_SOABI`` to prefix the library suffix with the value of ``SOABI``. * The :module:`FindLibXml2` module now provides an imported target for the ``xmllint`` executable diff --git a/Help/release/dev/cmake_command-command.rst b/Help/release/dev/cmake_command-command.rst index ebe75b1..6200ae2 100644 --- a/Help/release/dev/cmake_command-command.rst +++ b/Help/release/dev/cmake_command-command.rst @@ -3,4 +3,4 @@ cmake_command * The :command:`cmake_command()` command was added for meta-operations on scripted or built-in commands, starting with a mode to ``INVOKE`` other - commands. + commands, and ``EVAL CODE`` to inplace evaluate a CMake script. diff --git a/Help/variable/CMAKE_NMC_CROSS_CONFIGS.rst b/Help/variable/CMAKE_CROSS_CONFIGS.rst index 6eb6494..c850af2 100644 --- a/Help/variable/CMAKE_NMC_CROSS_CONFIGS.rst +++ b/Help/variable/CMAKE_CROSS_CONFIGS.rst @@ -1,5 +1,5 @@ -CMAKE_NMC_CROSS_CONFIGS -------------------------------- +CMAKE_CROSS_CONFIGS +------------------- Specifies a :ref:`semicolon-separated list <CMake Language Lists>` of configurations available from all ``build-<Config>.ninja`` files in the diff --git a/Help/variable/CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG.rst b/Help/variable/CMAKE_DEFAULT_BUILD_TYPE.rst index c0eab56..62ee0d2 100644 --- a/Help/variable/CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG.rst +++ b/Help/variable/CMAKE_DEFAULT_BUILD_TYPE.rst @@ -1,5 +1,5 @@ -CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG -------------------------------------------- +CMAKE_DEFAULT_BUILD_TYPE +------------------------ Specifies the configuration to use by default in a ``build.ninja`` file in the :generator:`Ninja Multi-Config` generator. See the generator's documentation diff --git a/Help/variable/CMAKE_NMC_DEFAULT_CONFIGS.rst b/Help/variable/CMAKE_DEFAULT_CONFIGS.rst index e2bb017..86d8a5a 100644 --- a/Help/variable/CMAKE_NMC_DEFAULT_CONFIGS.rst +++ b/Help/variable/CMAKE_DEFAULT_CONFIGS.rst @@ -1,5 +1,5 @@ -CMAKE_NMC_DEFAULT_CONFIGS ---------------------------------- +CMAKE_DEFAULT_CONFIGS +--------------------- Specifies a :ref:`semicolon-separated list <CMake Language Lists>` of configurations to build for a target in ``build.ninja`` if no ``:<Config>`` suffix is specified in diff --git a/Modules/CMakeGenericSystem.cmake b/Modules/CMakeGenericSystem.cmake index 7efe5c4..f539b46 100644 --- a/Modules/CMakeGenericSystem.cmake +++ b/Modules/CMakeGenericSystem.cmake @@ -27,7 +27,7 @@ set(CMAKE_FIND_LIBRARY_SUFFIXES ".so" ".a") set(CMAKE_AUTOGEN_ORIGIN_DEPENDS ON) set(CMAKE_AUTOMOC_COMPILER_PREDEFINES ON) set(CMAKE_AUTOMOC_PATH_PREFIX ON) -set(CMAKE_AUTOMOC_MACRO_NAMES "Q_OBJECT" "Q_GADGET" "Q_NAMESPACE") +set(CMAKE_AUTOMOC_MACRO_NAMES "Q_OBJECT" "Q_GADGET" "Q_NAMESPACE" "Q_NAMESPACE_EXPORT") # basically all general purpose OSs support shared libs set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS TRUE) diff --git a/Modules/CheckFortranSourceCompiles.cmake b/Modules/CheckFortranSourceCompiles.cmake index f0fde8d..3354bfb 100644 --- a/Modules/CheckFortranSourceCompiles.cmake +++ b/Modules/CheckFortranSourceCompiles.cmake @@ -103,8 +103,6 @@ macro(CHECK_Fortran_SOURCE_COMPILES SOURCE VAR) if(NOT _SRC_EXT) set(_SRC_EXT F) endif() - set(MACRO_CHECK_FUNCTION_DEFINITIONS - "-D${VAR} ${CMAKE_REQUIRED_FLAGS}") if(CMAKE_REQUIRED_LINK_OPTIONS) set(CHECK_Fortran_SOURCE_COMPILES_ADD_LINK_OPTIONS LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS}) @@ -132,10 +130,10 @@ macro(CHECK_Fortran_SOURCE_COMPILES SOURCE VAR) try_compile(${VAR} ${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.${_SRC_EXT} - COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} + COMPILE_DEFINITIONS -D${VAR} ${CMAKE_REQUIRED_DEFINITIONS} ${CHECK_Fortran_SOURCE_COMPILES_ADD_LINK_OPTIONS} ${CHECK_Fortran_SOURCE_COMPILES_ADD_LIBRARIES} - CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS} + CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${CMAKE_REQUIRED_FLAGS} "${CHECK_Fortran_SOURCE_COMPILES_ADD_INCLUDES}" OUTPUT_VARIABLE OUTPUT) diff --git a/Modules/CheckFortranSourceRuns.cmake b/Modules/CheckFortranSourceRuns.cmake index a3e5d5d..f858b84 100644 --- a/Modules/CheckFortranSourceRuns.cmake +++ b/Modules/CheckFortranSourceRuns.cmake @@ -98,8 +98,6 @@ macro(CHECK_Fortran_SOURCE_RUNS SOURCE VAR) if(NOT _SRC_EXT) set(_SRC_EXT F90) endif() - set(MACRO_CHECK_FUNCTION_DEFINITIONS - "-D${VAR} ${CMAKE_REQUIRED_FLAGS}") if(CMAKE_REQUIRED_LINK_OPTIONS) set(CHECK_Fortran_SOURCE_COMPILES_ADD_LINK_OPTIONS LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS}) @@ -127,10 +125,10 @@ macro(CHECK_Fortran_SOURCE_RUNS SOURCE VAR) try_run(${VAR}_EXITCODE ${VAR}_COMPILED ${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.${_SRC_EXT} - COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} + COMPILE_DEFINITIONS -D${VAR} ${CMAKE_REQUIRED_DEFINITIONS} ${CHECK_Fortran_SOURCE_COMPILES_ADD_LINK_OPTIONS} ${CHECK_Fortran_SOURCE_COMPILES_ADD_LIBRARIES} - CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS} + CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${CMAKE_REQUIRED_FLAGS} -DCMAKE_SKIP_RPATH:BOOL=${CMAKE_SKIP_RPATH} "${CHECK_Fortran_SOURCE_COMPILES_ADD_INCLUDES}" COMPILE_OUTPUT_VARIABLE OUTPUT diff --git a/Modules/CheckTypeSize.c.in b/Modules/CheckTypeSize.c.in index 82035a3..fb93073 100644 --- a/Modules/CheckTypeSize.c.in +++ b/Modules/CheckTypeSize.c.in @@ -5,10 +5,14 @@ # 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','_','_' #elif defined(__ppc64__) # define KEY '_','_','p','p','c','6','4','_','_' +#elif defined(__PPC__) +# define KEY '_','_','P','P','C','_','_' +#elif defined(__ppc__) +# define KEY '_','_','p','p','c','_','_' #elif defined(__aarch64__) # define KEY '_','_','a','a','r','c','h','6','4','_','_' #elif defined(__ARM_ARCH_7A__) diff --git a/Modules/Compiler/XL-Fortran.cmake b/Modules/Compiler/XL-Fortran.cmake index 1683dff..e01ec8e 100644 --- a/Modules/Compiler/XL-Fortran.cmake +++ b/Modules/Compiler/XL-Fortran.cmake @@ -8,6 +8,7 @@ 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_MODDIR_INCLUDE_FLAG "-I") # -qmoddir= does not affect search path set(CMAKE_Fortran_DEFINE_FLAG "-WF,-D") diff --git a/Modules/FindPython.cmake b/Modules/FindPython.cmake index be272e1..9dfa222 100644 --- a/Modules/FindPython.cmake +++ b/Modules/FindPython.cmake @@ -297,9 +297,13 @@ This module defines the command ``Python_add_library`` (when when library type is ``MODULE``, to target ``Python::Module`` and takes care of Python module naming rules:: - Python_add_library (my_module MODULE src1.cpp) + Python_add_library (<name> [STATIC | SHARED | MODULE [WITH_SOABI]] + <source1> [<source2> ...]) -If library type is not specified, ``MODULE`` is assumed. +If the library type is not specified, ``MODULE`` is assumed. + +For ``MODULE`` library type, if option ``WITH_SOABI`` is specified, the +module suffix will include the ``Python_SOABI`` value, if any. #]=======================================================================] diff --git a/Modules/FindPython/Support.cmake b/Modules/FindPython/Support.cmake index 0f52008..bf55bf5 100644 --- a/Modules/FindPython/Support.cmake +++ b/Modules/FindPython/Support.cmake @@ -2514,15 +2514,21 @@ if(_${_PYTHON_PREFIX}_CMAKE_ROLE STREQUAL "PROJECT") # function (__${_PYTHON_PREFIX}_ADD_LIBRARY prefix name) cmake_parse_arguments (PARSE_ARGV 2 PYTHON_ADD_LIBRARY - "STATIC;SHARED;MODULE" "" "") + "STATIC;SHARED;MODULE;WITH_SOABI" "" "") - unset (type) - if (NOT (PYTHON_ADD_LIBRARY_STATIC - OR PYTHON_ADD_LIBRARY_SHARED - OR PYTHON_ADD_LIBRARY_MODULE)) + if (prefix STREQUAL "Python2" AND PYTHON_ADD_LIBRARY_WITH_SOABI) + message (AUTHOR_WARNING "FindPython2: Option `WITH_SOABI` is not supported for Python2 and will be ignored.") + unset (PYTHON_ADD_LIBRARY_WITH_SOABI) + endif() + + if (PYTHON_ADD_LIBRARY_STATIC) + set (type STATIC) + elseif (PYTHON_ADD_LIBRARY_SHARED) + set (type SHARED) + else() set (type MODULE) endif() - add_library (${name} ${type} ${ARGN}) + add_library (${name} ${type} ${PYTHON_ADD_LIBRARY_UNPARSED_ARGUMENTS}) get_property (type TARGET ${name} PROPERTY TYPE) @@ -2533,7 +2539,18 @@ if(_${_PYTHON_PREFIX}_CMAKE_ROLE STREQUAL "PROJECT") if(CMAKE_SYSTEM_NAME STREQUAL "Windows") set_property (TARGET ${name} PROPERTY SUFFIX ".pyd") endif() + + if (PYTHON_ADD_LIBRARY_WITH_SOABI AND ${prefix}_SOABI) + get_property (suffix TARGET ${name} PROPERTY SUFFIX) + if (NOT suffix) + set (suffix "${CMAKE_SHARED_MODULE_SUFFIX}") + endif() + set_property (TARGET ${name} PROPERTY SUFFIX ".${${prefix}_SOABI}${suffix}") + endif() else() + if (PYTHON_ADD_LIBRARY_WITH_SOABI) + message (AUTHOR_WARNING "Find${prefix}: Option `WITH_SOABI` is only supported for `MODULE` library type.") + endif() target_link_libraries (${name} PRIVATE ${prefix}::Python) endif() endfunction() diff --git a/Modules/FindPython2.cmake b/Modules/FindPython2.cmake index 9d4eda2..af8ad39 100644 --- a/Modules/FindPython2.cmake +++ b/Modules/FindPython2.cmake @@ -240,13 +240,14 @@ setting the following variables: Commands ^^^^^^^^ -This module defines the command ``Python_add_library`` (when +This module defines the command ``Python2_add_library`` (when :prop_gbl:`CMAKE_ROLE` is ``PROJECT``), which has the same semantics as :command:`add_library` and adds a dependency to target ``Python2::Python`` or, when library type is ``MODULE``, to target ``Python2::Module`` and takes care of Python module naming rules:: - Python2_add_library (my_module MODULE src1.cpp) + Python2_add_library (<name> [STATIC | SHARED | MODULE] + <source1> [<source2> ...]) If library type is not specified, ``MODULE`` is assumed. #]=======================================================================] diff --git a/Modules/FindPython3.cmake b/Modules/FindPython3.cmake index 00c354e..66f4f75 100644 --- a/Modules/FindPython3.cmake +++ b/Modules/FindPython3.cmake @@ -288,15 +288,19 @@ setting the following variables: Commands ^^^^^^^^ -This module defines the command ``Python_add_library`` (when +This module defines the command ``Python3_add_library`` (when :prop_gbl:`CMAKE_ROLE` is ``PROJECT``), which has the same semantics as :command:`add_library` and adds a dependency to target ``Python3::Python`` or, when library type is ``MODULE``, to target ``Python3::Module`` and takes care of Python module naming rules:: - Python3_add_library (my_module MODULE src1.cpp) + Python3_add_library (<name> [STATIC | SHARED | MODULE [WITH_SOABI]] + <source1> [<source2> ...]) -If library type is not specified, ``MODULE`` is assumed. +If the library type is not specified, ``MODULE`` is assumed. + +For ``MODULE`` library type, if option ``WITH_SOABI`` is specified, the +module suffix will include the ``Python3_SOABI`` value, if any. #]=======================================================================] diff --git a/Modules/FortranCInterface/CMakeLists.txt b/Modules/FortranCInterface/CMakeLists.txt index 381080b..13e4498 100644 --- a/Modules/FortranCInterface/CMakeLists.txt +++ b/Modules/FortranCInterface/CMakeLists.txt @@ -101,3 +101,7 @@ set_property(TARGET symbols PROPERTY POSITION_INDEPENDENT_CODE 1) # Require symbols through Fortran. add_executable(FortranCInterface main.F call_sub.f ${call_mod}) target_link_libraries(FortranCInterface PUBLIC symbols) + +file(GENERATE OUTPUT exe-$<CONFIG>.cmake CONTENT [[ +set(FortranCInterface_EXE "$<TARGET_FILE:FortranCInterface>") +]]) diff --git a/Modules/FortranCInterface/Detect.cmake b/Modules/FortranCInterface/Detect.cmake index 33de6c6..c75067b 100644 --- a/Modules/FortranCInterface/Detect.cmake +++ b/Modules/FortranCInterface/Detect.cmake @@ -43,17 +43,11 @@ set(FortranCInterface_COMPILED ${FortranCInterface_COMPILED}) unset(FortranCInterface_COMPILED CACHE) # Locate the sample project executable. +set(FortranCInterface_EXE) if(FortranCInterface_COMPILED) - find_program(FortranCInterface_EXE - NAMES FortranCInterface${CMAKE_EXECUTABLE_SUFFIX} - PATHS ${FortranCInterface_BINARY_DIR} ${FortranCInterface_BINARY_DIR}/Release - NO_DEFAULT_PATH - ) - set(FortranCInterface_EXE ${FortranCInterface_EXE}) - unset(FortranCInterface_EXE CACHE) + include(${FortranCInterface_BINARY_DIR}/exe-Release.cmake OPTIONAL) 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") diff --git a/Modules/Platform/Windows-Clang.cmake b/Modules/Platform/Windows-Clang.cmake index dc8dd6f..87ddfcd 100644 --- a/Modules/Platform/Windows-Clang.cmake +++ b/Modules/Platform/Windows-Clang.cmake @@ -141,7 +141,7 @@ if("x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC" set(CMAKE_RC_PREPROCESSOR CMAKE_CXX_COMPILER) endif() if(DEFINED CMAKE_RC_PREPROCESSOR) - set(CMAKE_RC_COMPILE_OBJECT "${CMAKE_COMMAND} -E cmake_llvm_rc <OBJECT>.pp <${CMAKE_RC_PREPROCESSOR}> <DEFINES> -DRC_INVOKED <INCLUDES> <FLAGS> -clang:-MD -clang:-MF -clang:<SOURCE>.d -E <SOURCE> -- <CMAKE_RC_COMPILER> <FLAGS> /fo <OBJECT> <OBJECT>.pp") + set(CMAKE_RC_COMPILE_OBJECT "${CMAKE_COMMAND} -E cmake_llvm_rc <OBJECT>.pp <${CMAKE_RC_PREPROCESSOR}> <DEFINES> -DRC_INVOKED <INCLUDES> <FLAGS> -clang:-MD -clang:-MF -clang:<SOURCE>.d -E <SOURCE> -- <CMAKE_RC_COMPILER> <DEFINES> /fo <OBJECT> <OBJECT>.pp") if(CMAKE_GENERATOR STREQUAL "Ninja") set(CMAKE_NINJA_CMCLDEPS_RC 0) set(CMAKE_NINJA_DEP_TYPE_RC gcc) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 0372c78..3ab354c 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,7 +1,7 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 17) -set(CMake_VERSION_PATCH 20200228) +set(CMake_VERSION_PATCH 20200304) #set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0) diff --git a/Source/LexerParser/cmListFileLexer.c b/Source/LexerParser/cmListFileLexer.c index 15dcda0..ec7424c 100644 --- a/Source/LexerParser/cmListFileLexer.c +++ b/Source/LexerParser/cmListFileLexer.c @@ -2787,7 +2787,7 @@ int cmListFileLexer_SetString(cmListFileLexer* lexer, const char* text) /*--------------------------------------------------------------------------*/ cmListFileLexer_Token* cmListFileLexer_Scan(cmListFileLexer* lexer) { - if (!lexer->file) { + if (!lexer->file && !lexer->string_buffer) { return 0; } if (cmListFileLexer_yylex(lexer->scanner, lexer)) { @@ -2801,21 +2801,13 @@ cmListFileLexer_Token* cmListFileLexer_Scan(cmListFileLexer* lexer) /*--------------------------------------------------------------------------*/ long cmListFileLexer_GetCurrentLine(cmListFileLexer* lexer) { - if (lexer->file) { - return lexer->line; - } else { - return 0; - } + return lexer->line; } /*--------------------------------------------------------------------------*/ long cmListFileLexer_GetCurrentColumn(cmListFileLexer* lexer) { - if (lexer->file) { - return lexer->column; - } else { - return 0; - } + return lexer->column; } /*--------------------------------------------------------------------------*/ diff --git a/Source/LexerParser/cmListFileLexer.in.l b/Source/LexerParser/cmListFileLexer.in.l index fdf14d2..94cf8a5 100644 --- a/Source/LexerParser/cmListFileLexer.in.l +++ b/Source/LexerParser/cmListFileLexer.in.l @@ -500,7 +500,7 @@ int cmListFileLexer_SetString(cmListFileLexer* lexer, const char* text) /*--------------------------------------------------------------------------*/ cmListFileLexer_Token* cmListFileLexer_Scan(cmListFileLexer* lexer) { - if (!lexer->file) { + if (!lexer->file && !lexer->string_buffer) { return 0; } if (cmListFileLexer_yylex(lexer->scanner, lexer)) { @@ -514,21 +514,13 @@ cmListFileLexer_Token* cmListFileLexer_Scan(cmListFileLexer* lexer) /*--------------------------------------------------------------------------*/ long cmListFileLexer_GetCurrentLine(cmListFileLexer* lexer) { - if (lexer->file) { - return lexer->line; - } else { - return 0; - } + return lexer->line; } /*--------------------------------------------------------------------------*/ long cmListFileLexer_GetCurrentColumn(cmListFileLexer* lexer) { - if (lexer->file) { - return lexer->column; - } else { - return 0; - } + return lexer->column; } /*--------------------------------------------------------------------------*/ diff --git a/Source/cmCMakeCommand.cxx b/Source/cmCMakeCommand.cxx index 5699086..c11a003 100644 --- a/Source/cmCMakeCommand.cxx +++ b/Source/cmCMakeCommand.cxx @@ -2,11 +2,14 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCMakeCommand.h" +#include <algorithm> #include <cstddef> #include "cmExecutionStatus.h" #include "cmListFileCache.h" #include "cmMakefile.h" +#include "cmRange.h" +#include "cmStringAlgorithms.h" bool cmCMakeCommand(std::vector<std::string> const& args, cmExecutionStatus& status) @@ -19,6 +22,8 @@ bool cmCMakeCommand(std::vector<std::string> const& args, cmMakefile& makefile = status.GetMakefile(); cmListFileContext context = makefile.GetExecutionContext(); + bool result = false; + if (args[0] == "INVOKE") { if (args.size() == 1) { status.SetError("called with incorrect number of arguments"); @@ -39,9 +44,25 @@ bool cmCMakeCommand(std::vector<std::string> const& args, func.Arguments.emplace_back(lfarg); } - return makefile.ExecuteCommand(func, status); + result = makefile.ExecuteCommand(func, status); + } else if (args[0] == "EVAL") { + if (args.size() < 2) { + status.SetError("called with incorrect number of arguments"); + return false; + } + + auto code_iter = std::find(args.begin(), args.end(), "CODE"); + if (code_iter == args.end()) { + status.SetError("called without CODE argument"); + return false; + } + + const std::string code = cmJoin(cmMakeRange(++code_iter, args.end()), " "); + result = makefile.ReadListFileAsString( + code, cmStrCat(context.FilePath, ":", context.Line, ":EVAL")); + } else { + status.SetError("called with unknown meta-operation"); } - status.SetError("called with unknown meta-operation"); - return false; + return result; } diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx index b5c7e96..f6c1e47 100644 --- a/Source/cmCPluginAPI.cxx +++ b/Source/cmCPluginAPI.cxx @@ -488,24 +488,8 @@ struct cmCPluginAPISourceFile // 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: - using derived = std::map<cmSourceFile*, cmCPluginAPISourceFile*>; - using iterator = derived::iterator; - using value_type = derived::value_type; - cmCPluginAPISourceFileMap() = default; - ~cmCPluginAPISourceFileMap() - { - for (auto const& i : *this) { - delete i.second; - } - } - cmCPluginAPISourceFileMap(const cmCPluginAPISourceFileMap&) = delete; - cmCPluginAPISourceFileMap& operator=(const cmCPluginAPISourceFileMap&) = - delete; -}; +using cmCPluginAPISourceFileMap = + std::map<cmSourceFile*, std::unique_ptr<cmCPluginAPISourceFile>>; cmCPluginAPISourceFileMap cmCPluginAPISourceFiles; void* CCONV cmCreateSourceFile(void) @@ -536,7 +520,7 @@ void CCONV* cmGetSource(void* arg, const char* name) auto i = cmCPluginAPISourceFiles.find(rsf); if (i == cmCPluginAPISourceFiles.end()) { // Create a proxy source file object for this source. - cmCPluginAPISourceFile* sf = new cmCPluginAPISourceFile; + auto sf = cm::make_unique<cmCPluginAPISourceFile>(); sf->RealSourceFile = rsf; sf->FullPath = rsf->ResolveFullPath(); sf->SourceName = @@ -545,10 +529,9 @@ void CCONV* cmGetSource(void* arg, const char* name) cmSystemTools::GetFilenameLastExtension(sf->FullPath); // Store the proxy in the map so it can be re-used and deleted later. - cmCPluginAPISourceFileMap::value_type entry(rsf, sf); - i = cmCPluginAPISourceFiles.insert(entry).first; + i = cmCPluginAPISourceFiles.emplace(rsf, std::move(sf)).first; } - return i->second; + return i->second.get(); } return nullptr; } @@ -569,15 +552,16 @@ void* CCONV cmAddSource(void* arg, void* arg2) } // Create the proxy for the real source file. - cmCPluginAPISourceFile* sf = new cmCPluginAPISourceFile; + auto sf = cm::make_unique<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 sf; + auto value = sf.get(); + cmCPluginAPISourceFiles[rsf] = std::move(sf); + return value; } const char* CCONV cmSourceFileGetSourceName(void* arg) diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index 04f75bd..fb100b1 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -16,6 +16,9 @@ #include <utility> #include <vector> +#include <cm/memory> +#include <cmext/algorithm> + #include "cmsys/Base64.h" #include "cmsys/Directory.hxx" #include "cmsys/FStream.hxx" @@ -32,9 +35,6 @@ # include <unistd.h> // IWYU pragma: keep #endif -#include <cm/memory> -#include <cmext/algorithm> - #include "cmCTestBuildAndTestHandler.h" #include "cmCTestBuildHandler.h" #include "cmCTestConfigureHandler.h" @@ -201,7 +201,7 @@ struct cmCTest::Private int SubmitIndex = 0; - cmGeneratedFileStream* OutputLogFile = nullptr; + std::unique_ptr<cmGeneratedFileStream> OutputLogFile; int OutputLogFileLastTag = -1; bool OutputTestOutputOnTestFailure = false; @@ -362,10 +362,7 @@ cmCTest::cmCTest() cmSystemTools::EnableVSConsoleOutput(); } -cmCTest::~cmCTest() -{ - delete this->Impl->OutputLogFile; -} +cmCTest::~cmCTest() = default; int cmCTest::GetParallelLevel() const { @@ -3086,12 +3083,10 @@ bool cmCTest::RunCommand(std::vector<std::string> const& args, void cmCTest::SetOutputLogFileName(const char* name) { - if (this->Impl->OutputLogFile) { - delete this->Impl->OutputLogFile; - this->Impl->OutputLogFile = nullptr; - } if (name) { - this->Impl->OutputLogFile = new cmGeneratedFileStream(name); + this->Impl->OutputLogFile = cm::make_unique<cmGeneratedFileStream>(name); + } else { + this->Impl->OutputLogFile.reset(); } } diff --git a/Source/cmCommandArgumentParserHelper.cxx b/Source/cmCommandArgumentParserHelper.cxx index 613ae06..379836a 100644 --- a/Source/cmCommandArgumentParserHelper.cxx +++ b/Source/cmCommandArgumentParserHelper.cxx @@ -5,6 +5,9 @@ #include <cstring> #include <iostream> #include <sstream> +#include <utility> + +#include <cm/memory> #include "cmCommandArgumentLexer.h" #include "cmMakefile.h" @@ -40,10 +43,10 @@ const char* cmCommandArgumentParserHelper::AddString(const std::string& str) if (str.empty()) { return ""; } - char* stVal = new char[str.size() + 1]; - strcpy(stVal, str.c_str()); - this->Variables.push_back(stVal); - return stVal; + auto stVal = cm::make_unique<char[]>(str.size() + 1); + strcpy(stVal.get(), str.c_str()); + this->Variables.push_back(std::move(stVal)); + return this->Variables.back().get(); } const char* cmCommandArgumentParserHelper::ExpandSpecialVariable( @@ -136,11 +139,11 @@ const char* cmCommandArgumentParserHelper::CombineUnions(const char* in1, 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; + auto out = cm::make_unique<char[]>(len); + strcpy(out.get(), in1); + strcat(out.get(), in2); + this->Variables.push_back(std::move(out)); + return this->Variables.back().get(); } void cmCommandArgumentParserHelper::AllocateParserType( @@ -153,11 +156,11 @@ void cmCommandArgumentParserHelper::AllocateParserType( if (len == 0) { return; } - char* out = new char[len + 1]; - memcpy(out, str, len); - out[len] = 0; - pt->str = out; - this->Variables.push_back(out); + auto out = cm::make_unique<char[]>(len + 1); + memcpy(out.get(), str, len); + out.get()[len] = 0; + pt->str = out.get(); + this->Variables.push_back(std::move(out)); } bool cmCommandArgumentParserHelper::HandleEscapeSymbol( @@ -235,10 +238,7 @@ int cmCommandArgumentParserHelper::ParseString(const char* str, int verb) void cmCommandArgumentParserHelper::CleanupParser() { - for (char* var : this->Variables) { - delete[] var; - } - this->Variables.erase(this->Variables.begin(), this->Variables.end()); + this->Variables.clear(); } int cmCommandArgumentParserHelper::LexInput(char* buf, int maxlen) diff --git a/Source/cmCommandArgumentParserHelper.h b/Source/cmCommandArgumentParserHelper.h index 25e6892..b46edcb 100644 --- a/Source/cmCommandArgumentParserHelper.h +++ b/Source/cmCommandArgumentParserHelper.h @@ -5,6 +5,7 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include <memory> #include <string> #include <vector> @@ -69,7 +70,7 @@ private: void CleanupParser(); void SetError(std::string const& msg); - std::vector<char*> Variables; + std::vector<std::unique_ptr<char[]>> Variables; const cmMakefile* Makefile; std::string Result; std::string ErrorString; diff --git a/Source/cmDependsJavaParserHelper.cxx b/Source/cmDependsJavaParserHelper.cxx index 516bbbf..fc1bbdd 100644 --- a/Source/cmDependsJavaParserHelper.cxx +++ b/Source/cmDependsJavaParserHelper.cxx @@ -8,6 +8,7 @@ #include <iostream> #include <utility> +#include <cm/memory> #include <cm/string_view> #include "cmsys/FStream.hxx" @@ -169,10 +170,11 @@ void cmDependsJavaParserHelper::AllocateParserType( return; } this->UnionsAvailable++; - pt->str = new char[len + 1]; + auto up = cm::make_unique<char[]>(len + 1); + pt->str = up.get(); strncpy(pt->str, str, len); pt->str[len] = 0; - this->Allocates.push_back(pt->str); + this->Allocates.push_back(std::move(up)); } void cmDependsJavaParserHelper::StartClass(const char* cls) @@ -275,10 +277,7 @@ int cmDependsJavaParserHelper::ParseString(const char* str, int verb) void cmDependsJavaParserHelper::CleanupParser() { - for (char* allocate : this->Allocates) { - delete[] allocate; - } - this->Allocates.erase(this->Allocates.begin(), this->Allocates.end()); + this->Allocates.clear(); } int cmDependsJavaParserHelper::LexInput(char* buf, int maxlen) diff --git a/Source/cmDependsJavaParserHelper.h b/Source/cmDependsJavaParserHelper.h index a673b5b..c545ee2 100644 --- a/Source/cmDependsJavaParserHelper.h +++ b/Source/cmDependsJavaParserHelper.h @@ -5,6 +5,7 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include <memory> #include <string> #include <vector> @@ -81,7 +82,7 @@ private: int CurrentDepth; int Verbose; - std::vector<char*> Allocates; + std::vector<std::unique_ptr<char[]>> Allocates; void PrintClasses(); diff --git a/Source/cmDynamicLoader.cxx b/Source/cmDynamicLoader.cxx index 0b72a94..a3731c1 100644 --- a/Source/cmDynamicLoader.cxx +++ b/Source/cmDynamicLoader.cxx @@ -6,6 +6,7 @@ #include <string> #include <utility> +namespace { class cmDynamicLoaderCache { public: @@ -15,14 +16,15 @@ public: cmsys::DynamicLoader::LibraryHandle& /*p*/); bool FlushCache(const char* path); void FlushCache(); - static cmDynamicLoaderCache* GetInstance(); + static cmDynamicLoaderCache& GetInstance(); private: std::map<std::string, cmsys::DynamicLoader::LibraryHandle> CacheMap; - static cmDynamicLoaderCache* Instance; + static cmDynamicLoaderCache Instance; }; -cmDynamicLoaderCache* cmDynamicLoaderCache::Instance = nullptr; +cmDynamicLoaderCache cmDynamicLoaderCache::Instance; +} cmDynamicLoaderCache::~cmDynamicLoaderCache() = default; @@ -64,15 +66,11 @@ void cmDynamicLoaderCache::FlushCache() for (auto const& it : this->CacheMap) { cmsys::DynamicLoader::CloseLibrary(it.second); } - delete cmDynamicLoaderCache::Instance; - cmDynamicLoaderCache::Instance = nullptr; + this->CacheMap.clear(); } -cmDynamicLoaderCache* cmDynamicLoaderCache::GetInstance() +cmDynamicLoaderCache& cmDynamicLoaderCache::GetInstance() { - if (!cmDynamicLoaderCache::Instance) { - cmDynamicLoaderCache::Instance = new cmDynamicLoaderCache; - } return cmDynamicLoaderCache::Instance; } @@ -80,15 +78,15 @@ cmsys::DynamicLoader::LibraryHandle cmDynamicLoader::OpenLibrary( const char* libname) { cmsys::DynamicLoader::LibraryHandle lh; - if (cmDynamicLoaderCache::GetInstance()->GetCacheFile(libname, lh)) { + if (cmDynamicLoaderCache::GetInstance().GetCacheFile(libname, lh)) { return lh; } lh = cmsys::DynamicLoader::OpenLibrary(libname); - cmDynamicLoaderCache::GetInstance()->CacheFile(libname, lh); + cmDynamicLoaderCache::GetInstance().CacheFile(libname, lh); return lh; } void cmDynamicLoader::FlushCache() { - cmDynamicLoaderCache::GetInstance()->FlushCache(); + cmDynamicLoaderCache::GetInstance().FlushCache(); } diff --git a/Source/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx index ac48287..0546186 100644 --- a/Source/cmForEachCommand.cxx +++ b/Source/cmForEachCommand.cxx @@ -12,6 +12,8 @@ #include <cstdlib> #include <iterator> #include <map> +#include <sstream> +#include <stdexcept> #include <utility> #include <cm/memory> @@ -354,6 +356,21 @@ bool HandleInMode(std::vector<std::string> const& args, return true; } +bool TryParseInteger(cmExecutionStatus& status, const std::string& str, int& i) +{ + try { + i = std::stoi(str); + } catch (std::invalid_argument&) { + std::ostringstream e; + e << "Invalid integer: '" << str << "'"; + status.SetError(e.str()); + cmSystemTools::SetFatalErrorOccured(); + return false; + } + + return true; +} + } // anonymous namespace bool cmForEachCommand(std::vector<std::string> const& args, @@ -376,16 +393,28 @@ bool cmForEachCommand(std::vector<std::string> const& args, int stop = 0; int step = 0; if (args.size() == 3) { - stop = std::stoi(args[2]); + if (!TryParseInteger(status, args[2], stop)) { + return false; + } } if (args.size() == 4) { - start = std::stoi(args[2]); - stop = std::stoi(args[3]); + if (!TryParseInteger(status, args[2], start)) { + return false; + } + if (!TryParseInteger(status, args[3], stop)) { + return false; + } } if (args.size() == 5) { - start = std::stoi(args[2]); - stop = std::stoi(args[3]); - step = std::stoi(args[4]); + if (!TryParseInteger(status, args[2], start)) { + return false; + } + if (!TryParseInteger(status, args[3], stop)) { + return false; + } + if (!TryParseInteger(status, args[4], step)) { + return false; + } } if (step == 0) { if (start > stop) { @@ -399,6 +428,7 @@ bool cmForEachCommand(std::vector<std::string> const& args, status.SetError( cmStrCat("called with incorrect range specification: start ", start, ", stop ", stop, ", step ", step)); + cmSystemTools::SetFatalErrorOccured(); return false; } diff --git a/Source/cmGeneratedFileStream.cxx b/Source/cmGeneratedFileStream.cxx index 2af04b6..f76e205 100644 --- a/Source/cmGeneratedFileStream.cxx +++ b/Source/cmGeneratedFileStream.cxx @@ -180,6 +180,7 @@ int cmGeneratedFileStreamBase::CompressFile(std::string const& oldname, } FILE* ifs = cmsys::SystemTools::Fopen(oldname, "r"); if (!ifs) { + gzclose(gf); return 0; } size_t res; diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index ff6ad9d..0404715 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -1361,8 +1361,43 @@ void cmGlobalGenerator::ComputeBuildFileGenerators() } } +bool cmGlobalGenerator::UnsupportedVariableIsDefined(const std::string& name, + bool supported) const +{ + if (!supported && this->Makefiles.front()->GetDefinition(name)) { + std::ostringstream e; + /* clang-format off */ + e << + "Generator\n" + " " << this->GetName() << "\n" + "does not support variable\n" + " " << name << "\n" + "but it has been specified." + ; + /* clang-format on */ + this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e.str()); + return true; + } + + return false; +} + bool cmGlobalGenerator::Compute() { + // Make sure unsupported variables are not used. + if (this->UnsupportedVariableIsDefined("CMAKE_DEFAULT_BUILD_TYPE", + this->SupportsDefaultBuildType())) { + return false; + } + if (this->UnsupportedVariableIsDefined("CMAKE_CROSS_CONFIGS", + this->SupportsCrossConfigs())) { + return false; + } + if (this->UnsupportedVariableIsDefined("CMAKE_DEFAULT_CONFIGS", + this->SupportsDefaultConfigs())) { + return false; + } + // Some generators track files replaced during the Generate. // Start with an empty vector: this->FilesReplacedDuringGenerate.clear(); diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 0e7e03d..ba997b2 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -455,6 +455,10 @@ public: /** Generate an <output>.rule file path for a given command output. */ virtual std::string GenerateRuleFile(std::string const& output) const; + virtual bool SupportsDefaultBuildType() const { return false; } + virtual bool SupportsCrossConfigs() const { return false; } + virtual bool SupportsDefaultConfigs() const { return false; } + static std::string EscapeJSON(const std::string& s); void ProcessEvaluationFiles(); @@ -674,6 +678,9 @@ private: virtual const char* GetBuildIgnoreErrorsFlag() const { return nullptr; } + bool UnsupportedVariableIsDefined(const std::string& name, + bool supported) const; + // Cache directory content and target files to be built. struct DirectoryContent { diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 12a5167..e59664b 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -2490,8 +2490,7 @@ bool cmGlobalNinjaMultiGenerator::OpenBuildFileStreams() return false; } *this->DefaultFileStream - << "# This file is a convenience file generated by\n" - << "# CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG.\n\n" + << "# Build using rules for '" << this->DefaultFileConfig << "'.\n\n" << "include " << GetNinjaImplFilename(this->DefaultFileConfig) << "\n\n"; } @@ -2603,14 +2602,14 @@ void cmGlobalNinjaMultiGenerator::GetQtAutoGenConfigs( bool cmGlobalNinjaMultiGenerator::InspectConfigTypeVariables() { + this->GetCMakeInstance()->MarkCliAsUsed("CMAKE_DEFAULT_BUILD_TYPE"); + this->GetCMakeInstance()->MarkCliAsUsed("CMAKE_CROSS_CONFIGS"); + this->GetCMakeInstance()->MarkCliAsUsed("CMAKE_DEFAULT_CONFIGS"); return this->ReadCacheEntriesForBuild(*this->Makefiles.front()->GetState()); } std::string cmGlobalNinjaMultiGenerator::GetDefaultBuildConfig() const { - if (this->DefaultFileConfig.empty()) { - return "Debug"; - } return ""; } @@ -2626,12 +2625,14 @@ bool cmGlobalNinjaMultiGenerator::ReadCacheEntriesForBuild( std::set<std::string> configs(configsVec.cbegin(), configsVec.cend()); this->DefaultFileConfig = - state.GetSafeCacheEntryValue("CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG"); - if (!this->DefaultFileConfig.empty() && - !configs.count(this->DefaultFileConfig)) { + state.GetSafeCacheEntryValue("CMAKE_DEFAULT_BUILD_TYPE"); + if (this->DefaultFileConfig.empty()) { + this->DefaultFileConfig = configsVec.front(); + } + if (!configs.count(this->DefaultFileConfig)) { std::ostringstream msg; msg << "The configuration specified by " - << "CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG (" << this->DefaultFileConfig + << "CMAKE_DEFAULT_BUILD_TYPE (" << this->DefaultFileConfig << ") is not present in CMAKE_CONFIGURATION_TYPES"; this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, msg.str()); @@ -2639,12 +2640,12 @@ bool cmGlobalNinjaMultiGenerator::ReadCacheEntriesForBuild( } std::vector<std::string> crossConfigsVec; - cmExpandList(state.GetSafeCacheEntryValue("CMAKE_NMC_CROSS_CONFIGS"), + cmExpandList(state.GetSafeCacheEntryValue("CMAKE_CROSS_CONFIGS"), crossConfigsVec); auto crossConfigs = ListSubsetWithAll(configs, configs, crossConfigsVec); if (!crossConfigs) { std::ostringstream msg; - msg << "CMAKE_NMC_CROSS_CONFIGS is not a subset of " + msg << "CMAKE_CROSS_CONFIGS is not a subset of " << "CMAKE_CONFIGURATION_TYPES"; this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, msg.str()); @@ -2653,7 +2654,7 @@ bool cmGlobalNinjaMultiGenerator::ReadCacheEntriesForBuild( this->CrossConfigs = *crossConfigs; auto defaultConfigsString = - state.GetSafeCacheEntryValue("CMAKE_NMC_DEFAULT_CONFIGS"); + state.GetSafeCacheEntryValue("CMAKE_DEFAULT_CONFIGS"); if (defaultConfigsString.empty()) { defaultConfigsString = this->DefaultFileConfig; } @@ -2661,9 +2662,8 @@ bool cmGlobalNinjaMultiGenerator::ReadCacheEntriesForBuild( defaultConfigsString != this->DefaultFileConfig && (this->DefaultFileConfig.empty() || this->CrossConfigs.empty())) { std::ostringstream msg; - msg << "CMAKE_NMC_DEFAULT_CONFIGS cannot be used without " - << "CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG or " - << "CMAKE_NMC_CROSS_CONFIGS"; + msg << "CMAKE_DEFAULT_CONFIGS cannot be used without " + << "CMAKE_DEFAULT_BUILD_TYPE or CMAKE_CROSS_CONFIGS"; this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, msg.str()); return false; @@ -2677,8 +2677,7 @@ bool cmGlobalNinjaMultiGenerator::ReadCacheEntriesForBuild( this->CrossConfigs, defaultConfigsVec); if (!defaultConfigs) { std::ostringstream msg; - msg << "CMAKE_NMC_DEFAULT_CONFIGS is not a subset of " - << "CMAKE_NMC_CROSS_CONFIGS"; + msg << "CMAKE_DEFAULT_CONFIGS is not a subset of CMAKE_CROSS_CONFIGS"; this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, msg.str()); return false; diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index 3db8356..5668dd1 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -640,6 +640,10 @@ public: bool ReadCacheEntriesForBuild(const cmState& state) override; + bool SupportsDefaultBuildType() const override { return true; } + bool SupportsCrossConfigs() const override { return true; } + bool SupportsDefaultConfigs() const override { return true; } + protected: bool OpenBuildFileStreams() override; void CloseBuildFileStreams() override; diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index d123830..7daca74 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -41,7 +41,6 @@ cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3(cmake* cm) #else this->UseLinkScript = true; #endif - this->CommandDatabase = nullptr; this->IncludeDirective = "include"; this->DefineWindowsNULL = false; @@ -49,6 +48,8 @@ cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3(cmake* cm) this->UnixCD = true; } +cmGlobalUnixMakefileGenerator3::~cmGlobalUnixMakefileGenerator3() = default; + void cmGlobalUnixMakefileGenerator3::EnableLanguage( std::vector<std::string> const& languages, cmMakefile* mf, bool optional) { @@ -157,10 +158,9 @@ void cmGlobalUnixMakefileGenerator3::Generate() this->WriteMainMakefile2(); this->WriteMainCMakefile(); - if (this->CommandDatabase != nullptr) { + if (this->CommandDatabase) { *this->CommandDatabase << std::endl << "]"; - delete this->CommandDatabase; - this->CommandDatabase = nullptr; + this->CommandDatabase.reset(); } } @@ -168,11 +168,12 @@ void cmGlobalUnixMakefileGenerator3::AddCXXCompileCommand( const std::string& sourceFile, const std::string& workingDirectory, const std::string& compileCommand) { - if (this->CommandDatabase == nullptr) { + if (!this->CommandDatabase) { std::string commandDatabaseName = this->GetCMakeInstance()->GetHomeOutputDirectory() + "/compile_commands.json"; - this->CommandDatabase = new cmGeneratedFileStream(commandDatabaseName); + this->CommandDatabase = + cm::make_unique<cmGeneratedFileStream>(commandDatabaseName); *this->CommandDatabase << "[" << std::endl; } else { *this->CommandDatabase << "," << std::endl; diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h index 340a7ef..19b2b85 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.h +++ b/Source/cmGlobalUnixMakefileGenerator3.h @@ -68,6 +68,13 @@ public: new cmGlobalGeneratorSimpleFactory<cmGlobalUnixMakefileGenerator3>()); } + ~cmGlobalUnixMakefileGenerator3() override; + + cmGlobalUnixMakefileGenerator3(const cmGlobalUnixMakefileGenerator3&) = + delete; + cmGlobalUnixMakefileGenerator3& operator=( + const cmGlobalUnixMakefileGenerator3&) = delete; + //! Get the name for the generator. std::string GetName() const override { @@ -232,7 +239,7 @@ protected: std::set<cmGeneratorTarget const*>& emitted); size_t CountProgressMarksInAll(const cmLocalGenerator& lg); - cmGeneratedFileStream* CommandDatabase; + std::unique_ptr<cmGeneratedFileStream> CommandDatabase; private: const char* GetBuildIgnoreErrorsFlag() const override { return "-i"; } diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx index 2c53a28..6e3508c 100644 --- a/Source/cmInstallExportGenerator.cxx +++ b/Source/cmInstallExportGenerator.cxx @@ -7,6 +7,8 @@ #include <sstream> #include <utility> +#include <cm/memory> + #ifndef CMAKE_BOOTSTRAP # include "cmExportInstallAndroidMKGenerator.h" #endif @@ -33,18 +35,15 @@ cmInstallExportGenerator::cmInstallExportGenerator( { if (android) { #ifndef CMAKE_BOOTSTRAP - this->EFGen = new cmExportInstallAndroidMKGenerator(this); + this->EFGen = cm::make_unique<cmExportInstallAndroidMKGenerator>(this); #endif } else { - this->EFGen = new cmExportInstallFileGenerator(this); + this->EFGen = cm::make_unique<cmExportInstallFileGenerator>(this); } exportSet->AddInstallation(this); } -cmInstallExportGenerator::~cmInstallExportGenerator() -{ - delete this->EFGen; -} +cmInstallExportGenerator::~cmInstallExportGenerator() = default; bool cmInstallExportGenerator::Compute(cmLocalGenerator* lg) { diff --git a/Source/cmInstallExportGenerator.h b/Source/cmInstallExportGenerator.h index cf28b35..43dd00d 100644 --- a/Source/cmInstallExportGenerator.h +++ b/Source/cmInstallExportGenerator.h @@ -7,6 +7,7 @@ #include <cstddef> #include <iosfwd> +#include <memory> #include <string> #include <vector> @@ -30,8 +31,12 @@ public: bool exclude_from_all, std::string filename, std::string name_space, bool exportOld, bool android); + cmInstallExportGenerator(const cmInstallExportGenerator&) = delete; ~cmInstallExportGenerator() override; + cmInstallExportGenerator& operator=(const cmInstallExportGenerator&) = + delete; + cmExportSet* GetExportSet() { return this->ExportSet; } bool Compute(cmLocalGenerator* lg) override; @@ -61,7 +66,7 @@ protected: std::string TempDir; std::string MainImportFile; - cmExportInstallFileGenerator* EFGen; + std::unique_ptr<cmExportInstallFileGenerator> EFGen; }; #endif diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx index 47679c9..7ebb02f 100644 --- a/Source/cmListFileCache.cxx +++ b/Source/cmListFileCache.cxx @@ -26,13 +26,15 @@ cmCommandContext::cmCommandName& cmCommandContext::cmCommandName::operator=( struct cmListFileParser { cmListFileParser(cmListFile* lf, cmListFileBacktrace lfbt, - cmMessenger* messenger, const char* filename); + cmMessenger* messenger); ~cmListFileParser(); cmListFileParser(const cmListFileParser&) = delete; cmListFileParser& operator=(const cmListFileParser&) = delete; void IssueFileOpenError(std::string const& text) const; void IssueError(std::string const& text) const; - bool ParseFile(); + bool ParseFile(const char* filename); + bool ParseString(const char* str, const char* virtual_filename); + bool Parse(); bool ParseFunction(const char* name, long line); bool AddArgument(cmListFileLexer_Token* token, cmListFileArgument::Delimiter delim); @@ -51,12 +53,11 @@ struct cmListFileParser }; cmListFileParser::cmListFileParser(cmListFile* lf, cmListFileBacktrace lfbt, - cmMessenger* messenger, - const char* filename) + cmMessenger* messenger) : ListFile(lf) , Backtrace(std::move(lfbt)) , Messenger(messenger) - , FileName(filename) + , FileName(nullptr) , Lexer(cmListFileLexer_New()) { } @@ -83,8 +84,10 @@ void cmListFileParser::IssueError(const std::string& text) const cmSystemTools::SetFatalErrorOccured(); } -bool cmListFileParser::ParseFile() +bool cmListFileParser::ParseFile(const char* filename) { + this->FileName = filename; + // Open the file. cmListFileLexer_BOM bom; if (!cmListFileLexer_SetFileName(this->Lexer, this->FileName, &bom)) { @@ -107,6 +110,24 @@ bool cmListFileParser::ParseFile() return false; } + return Parse(); +} + +bool cmListFileParser::ParseString(const char* str, + const char* virtual_filename) +{ + this->FileName = virtual_filename; + + if (!cmListFileLexer_SetString(this->Lexer, str)) { + this->IssueFileOpenError("cmListFileCache: cannot allocate buffer."); + return false; + } + + return Parse(); +} + +bool cmListFileParser::Parse() +{ // Use a simple recursive-descent parser to process the token // stream. bool haveNewline = true; @@ -155,8 +176,22 @@ bool cmListFile::ParseFile(const char* filename, cmMessenger* messenger, bool parseError = false; { - cmListFileParser parser(this, lfbt, messenger, filename); - parseError = !parser.ParseFile(); + cmListFileParser parser(this, lfbt, messenger); + parseError = !parser.ParseFile(filename); + } + + return !parseError; +} + +bool cmListFile::ParseString(const char* str, const char* virtual_filename, + cmMessenger* messenger, + const cmListFileBacktrace& lfbt) +{ + bool parseError = false; + + { + cmListFileParser parser(this, lfbt, messenger); + parseError = !parser.ParseString(str, virtual_filename); } return !parseError; diff --git a/Source/cmListFileCache.h b/Source/cmListFileCache.h index 9cae827..89902ff 100644 --- a/Source/cmListFileCache.h +++ b/Source/cmListFileCache.h @@ -184,6 +184,9 @@ struct cmListFile bool ParseFile(const char* path, cmMessenger* messenger, cmListFileBacktrace const& lfbt); + bool ParseString(const char* str, const char* virtual_filename, + cmMessenger* messenger, cmListFileBacktrace const& lfbt); + std::vector<cmListFileFunction> Functions; }; diff --git a/Source/cmLocalCommonGenerator.cxx b/Source/cmLocalCommonGenerator.cxx index 025ef7e..278ec8b 100644 --- a/Source/cmLocalCommonGenerator.cxx +++ b/Source/cmLocalCommonGenerator.cxx @@ -50,6 +50,15 @@ std::string cmLocalCommonGenerator::GetTargetFortranFlags( this->Makefile->GetRequiredDefinition("CMAKE_Fortran_MODDIR_FLAG"), mod_dir); this->AppendFlags(flags, modflag); + // Some compilers do not search their own module output directory + // for using other modules. Add an include directory explicitly + // for consistency with compilers that do search it. + std::string incflag = + this->Makefile->GetSafeDefinition("CMAKE_Fortran_MODDIR_INCLUDE_FLAG"); + if (!incflag.empty()) { + incflag = cmStrCat(incflag, mod_dir); + this->AppendFlags(flags, incflag); + } } // If there is a separate module path flag then duplicate the diff --git a/Source/cmMachO.cxx b/Source/cmMachO.cxx index 6cbed36..53112e0 100644 --- a/Source/cmMachO.cxx +++ b/Source/cmMachO.cxx @@ -79,14 +79,14 @@ public: // A load_command and its associated data struct RawLoadCommand { - uint32_t type(const cmMachOHeaderAndLoadCommands* m) const + uint32_t type(const cmMachOHeaderAndLoadCommands& m) const { if (this->LoadCommand.size() < sizeof(load_command)) { return 0; } const load_command* cmd = reinterpret_cast<const load_command*>(&this->LoadCommand[0]); - return m->swap(cmd->cmd); + return m.swap(cmd->cmd); } std::vector<char> LoadCommand; }; @@ -186,8 +186,11 @@ class cmMachOInternal { public: cmMachOInternal(const char* fname); + cmMachOInternal(const cmMachOInternal&) = delete; ~cmMachOInternal(); + cmMachOInternal& operator=(const cmMachOInternal&) = delete; + // read a Mach-O file bool read_mach_o(uint32_t file_offset); @@ -202,7 +205,7 @@ public: std::string ErrorMessage; // the list of Mach-O's - std::vector<cmMachOHeaderAndLoadCommands*> MachOList; + std::vector<std::unique_ptr<cmMachOHeaderAndLoadCommands>> MachOList; }; cmMachOInternal::cmMachOInternal(const char* fname) @@ -260,12 +263,7 @@ cmMachOInternal::cmMachOInternal(const char* fname) } } -cmMachOInternal::~cmMachOInternal() -{ - for (auto& i : this->MachOList) { - delete i; - } -} +cmMachOInternal::~cmMachOInternal() = default; bool cmMachOInternal::read_mach_o(uint32_t file_offset) { @@ -280,25 +278,25 @@ bool cmMachOInternal::read_mach_o(uint32_t file_offset) return false; } - cmMachOHeaderAndLoadCommands* f = nullptr; + std::unique_ptr<cmMachOHeaderAndLoadCommands> f; if (magic == MH_CIGAM || magic == MH_MAGIC) { bool swap = false; if (magic == MH_CIGAM) { swap = true; } - f = new cmMachOHeaderAndLoadCommandsImpl<mach_header>(swap); + f = cm::make_unique<cmMachOHeaderAndLoadCommandsImpl<mach_header>>(swap); } else if (magic == MH_CIGAM_64 || magic == MH_MAGIC_64) { bool swap = false; if (magic == MH_CIGAM_64) { swap = true; } - f = new cmMachOHeaderAndLoadCommandsImpl<mach_header_64>(swap); + f = + cm::make_unique<cmMachOHeaderAndLoadCommandsImpl<mach_header_64>>(swap); } if (f && f->read_mach_o(this->Fin)) { - this->MachOList.push_back(f); + this->MachOList.push_back(std::move(f)); } else { - delete f; this->ErrorMessage = "Failed to read Mach-O header."; return false; } @@ -333,11 +331,12 @@ bool cmMachO::GetInstallName(std::string& install_name) } // grab the first Mach-O and get the install name from that one - cmMachOHeaderAndLoadCommands* macho = this->Internal->MachOList[0]; + std::unique_ptr<cmMachOHeaderAndLoadCommands>& macho = + this->Internal->MachOList[0]; for (size_t i = 0; i < macho->load_commands().size(); i++) { const cmMachOHeaderAndLoadCommands::RawLoadCommand& cmd = macho->load_commands()[i]; - uint32_t lc_cmd = cmd.type(macho); + uint32_t lc_cmd = cmd.type(*macho); if (lc_cmd == LC_ID_DYLIB || lc_cmd == LC_LOAD_WEAK_DYLIB || lc_cmd == LC_LOAD_DYLIB) { if (sizeof(dylib_command) < cmd.LoadCommand.size()) { diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index ed627f8..94d99b7 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -684,6 +684,27 @@ bool cmMakefile::ReadListFile(const std::string& filename) return true; } +bool cmMakefile::ReadListFileAsString(const std::string& content, + const std::string& virtualFileName) +{ + std::string filenametoread = cmSystemTools::CollapseFullPath( + virtualFileName, this->GetCurrentSourceDirectory()); + + ListFileScope scope(this, filenametoread); + + cmListFile listFile; + if (!listFile.ParseString(content.c_str(), virtualFileName.c_str(), + this->GetMessenger(), this->Backtrace)) { + return false; + } + + this->ReadListFile(listFile, filenametoread); + if (cmSystemTools::GetFatalErrorOccured()) { + scope.Quiet(); + } + return true; +} + void cmMakefile::ReadListFile(cmListFile const& listFile, std::string const& filenametoread) { diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index f1a68c2..9c6dca6 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -117,6 +117,9 @@ public: bool ReadListFile(const std::string& filename); + bool ReadListFileAsString(const std::string& content, + const std::string& virtualFileName); + bool ReadDependentFile(const std::string& filename, bool noPolicyScope = true); diff --git a/Source/cmServer.cxx b/Source/cmServer.cxx index 3b2e5f3..434fb68 100644 --- a/Source/cmServer.cxx +++ b/Source/cmServer.cxx @@ -59,16 +59,12 @@ cmServer::cmServer(cmConnection* conn, bool supportExperimental) , SupportExperimental(supportExperimental) { // Register supported protocols: - this->RegisterProtocol(new cmServerProtocol1); + this->RegisterProtocol(cm::make_unique<cmServerProtocol1>()); } cmServer::~cmServer() { Close(); - - for (cmServerProtocol* p : this->SupportedProtocols) { - delete p; - } } void cmServer::ProcessRequest(cmConnection* connection, @@ -117,22 +113,22 @@ void cmServer::ProcessRequest(cmConnection* connection, } } -void cmServer::RegisterProtocol(cmServerProtocol* protocol) +void cmServer::RegisterProtocol(std::unique_ptr<cmServerProtocol> protocol) { if (protocol->IsExperimental() && !this->SupportExperimental) { - delete protocol; + protocol.reset(); return; } auto version = protocol->ProtocolVersion(); assert(version.first >= 0); assert(version.second >= 0); - auto it = std::find_if(this->SupportedProtocols.begin(), - this->SupportedProtocols.end(), - [version](cmServerProtocol* p) { - return p->ProtocolVersion() == version; - }); + auto it = std::find_if( + this->SupportedProtocols.begin(), this->SupportedProtocols.end(), + [version](const std::unique_ptr<cmServerProtocol>& p) { + return p->ProtocolVersion() == version; + }); if (it == this->SupportedProtocols.end()) { - this->SupportedProtocols.push_back(protocol); + this->SupportedProtocols.push_back(std::move(protocol)); } } @@ -297,19 +293,20 @@ void cmServer::WriteJsonObject(cmConnection* connection, } cmServerProtocol* cmServer::FindMatchingProtocol( - const std::vector<cmServerProtocol*>& protocols, int major, int minor) + const std::vector<std::unique_ptr<cmServerProtocol>>& protocols, int major, + int minor) { cmServerProtocol* bestMatch = nullptr; - for (auto protocol : protocols) { + for (const auto& protocol : protocols) { auto version = protocol->ProtocolVersion(); if (major != version.first) { continue; } if (minor == version.second) { - return protocol; + return protocol.get(); } if (!bestMatch || bestMatch->ProtocolVersion().second < version.second) { - bestMatch = protocol; + bestMatch = protocol.get(); } } return minor < 0 ? bestMatch : nullptr; diff --git a/Source/cmServer.h b/Source/cmServer.h index 3d7027b..ec40738 100644 --- a/Source/cmServer.h +++ b/Source/cmServer.h @@ -103,7 +103,7 @@ public: cmFileMonitor* FileMonitor() const; private: - void RegisterProtocol(cmServerProtocol* protocol); + void RegisterProtocol(std::unique_ptr<cmServerProtocol> protocol); // Callbacks from cmServerConnection: @@ -149,12 +149,13 @@ private: const DebugInfo* debug) const; static cmServerProtocol* FindMatchingProtocol( - const std::vector<cmServerProtocol*>& protocols, int major, int minor); + const std::vector<std::unique_ptr<cmServerProtocol>>& protocols, int major, + int minor); const bool SupportExperimental; cmServerProtocol* Protocol = nullptr; - std::vector<cmServerProtocol*> SupportedProtocols; + std::vector<std::unique_ptr<cmServerProtocol>> SupportedProtocols; friend class cmServerProtocol; friend class cmServerRequest; diff --git a/Source/cmSourceGroup.cxx b/Source/cmSourceGroup.cxx index 8c3ec9f..155068cb 100644 --- a/Source/cmSourceGroup.cxx +++ b/Source/cmSourceGroup.cxx @@ -4,6 +4,8 @@ #include <utility> +#include <cm/memory> + #include "cmStringAlgorithms.h" class cmSourceGroupInternals @@ -16,7 +18,7 @@ cmSourceGroup::cmSourceGroup(std::string name, const char* regex, const char* parentName) : Name(std::move(name)) { - this->Internal = new cmSourceGroupInternals; + this->Internal = cm::make_unique<cmSourceGroupInternals>(); this->SetGroupRegex(regex); if (parentName) { this->FullName = cmStrCat(parentName, '\\'); @@ -24,10 +26,7 @@ cmSourceGroup::cmSourceGroup(std::string name, const char* regex, this->FullName += this->Name; } -cmSourceGroup::~cmSourceGroup() -{ - delete this->Internal; -} +cmSourceGroup::~cmSourceGroup() = default; cmSourceGroup::cmSourceGroup(cmSourceGroup const& r) { @@ -36,7 +35,7 @@ cmSourceGroup::cmSourceGroup(cmSourceGroup const& r) this->GroupRegex = r.GroupRegex; this->GroupFiles = r.GroupFiles; this->SourceFiles = r.SourceFiles; - this->Internal = new cmSourceGroupInternals(*r.Internal); + this->Internal = cm::make_unique<cmSourceGroupInternals>(*r.Internal); } cmSourceGroup& cmSourceGroup::operator=(cmSourceGroup const& r) diff --git a/Source/cmSourceGroup.h b/Source/cmSourceGroup.h index 581dc5d..623cded 100644 --- a/Source/cmSourceGroup.h +++ b/Source/cmSourceGroup.h @@ -5,6 +5,7 @@ #include "cmConfigure.h" // IWYU pragma: keep +#include <memory> #include <set> #include <string> #include <vector> @@ -122,7 +123,7 @@ private: */ std::vector<const cmSourceFile*> SourceFiles; - cmSourceGroupInternals* Internal; + std::unique_ptr<cmSourceGroupInternals> Internal; }; #endif diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 9127c50..d8cd705 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -25,6 +25,9 @@ #endif #if !defined(CMAKE_BOOTSTRAP) +# if defined(_WIN32) +# include <cm/memory> +# endif # include "cmCryptoHash.h" #endif @@ -908,7 +911,6 @@ std::string cmSystemTools::ComputeCertificateThumbprint( std::string thumbprint; #if !defined(CMAKE_BOOTSTRAP) && defined(_WIN32) - BYTE* certData = NULL; CRYPT_INTEGER_BLOB cryptBlob; HCERTSTORE certStore = NULL; PCCERT_CONTEXT certContext = NULL; @@ -920,12 +922,12 @@ std::string cmSystemTools::ComputeCertificateThumbprint( if (certFile != INVALID_HANDLE_VALUE && certFile != NULL) { DWORD fileSize = GetFileSize(certFile, NULL); if (fileSize != INVALID_FILE_SIZE) { - certData = new BYTE[fileSize]; + auto certData = cm::make_unique<BYTE[]>(fileSize); if (certData != NULL) { DWORD dwRead = 0; - if (ReadFile(certFile, certData, fileSize, &dwRead, NULL)) { + if (ReadFile(certFile, certData.get(), fileSize, &dwRead, NULL)) { cryptBlob.cbData = fileSize; - cryptBlob.pbData = certData; + cryptBlob.pbData = certData.get(); // Verify that this is a valid cert if (PFXIsPFXBlob(&cryptBlob)) { @@ -961,7 +963,6 @@ std::string cmSystemTools::ComputeCertificateThumbprint( } } } - delete[] certData; } } CloseHandle(certFile); diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 8da113e..121ff6e 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -981,17 +981,11 @@ void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup(Elem& e0) // If the resource was NOT added using a relative path (which should // be the default), we have to provide a link here if (!useRelativePath) { - std::string link; - if (obj.find(srcDir) == 0) { - link = obj.substr(srcDir.length() + 1); - } else if (obj.find(binDir) == 0) { - link = obj.substr(binDir.length() + 1); - } else { + std::string link = this->GetCSharpSourceLink(oi); + if (link.empty()) { link = cmsys::SystemTools::GetFilenameName(obj); } - if (!link.empty()) { - e2.Element("Link", link); - } + e2.Element("Link", link); } // Determine if this is a generated resource from a .Designer.cs file std::string designerResource = @@ -1054,25 +1048,6 @@ void cmVisualStudio10TargetGenerator::WriteXamlFilesGroup(Elem& e0) Elem e2(e1, xamlType); this->WriteSource(e2, oi); e2.SetHasElements(); - if (this->ProjectType == csproj && !this->InSourceBuild) { - // add <Link> tag to written XAML source if necessary - const std::string& srcDir = - this->Makefile->GetCurrentSourceDirectory(); - const std::string& binDir = - this->Makefile->GetCurrentBinaryDirectory(); - std::string link; - if (obj.find(srcDir) == 0) { - link = obj.substr(srcDir.length() + 1); - } else if (obj.find(binDir) == 0) { - link = obj.substr(binDir.length() + 1); - } else { - link = cmsys::SystemTools::GetFilenameName(obj); - } - if (!link.empty()) { - ConvertToWindowsSlash(link); - e2.Element("Link", link); - } - } e2.Element("SubType", "Designer"); } } @@ -1442,13 +1417,8 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule( } else { Elem e1(e0, "ItemGroup"); Elem e2(e1, "None"); - std::string link; - this->GetCSharpSourceLink(source, link); this->WriteSource(e2, source); e2.SetHasElements(); - if (!link.empty()) { - e2.Element("Link", link); - } } for (std::string const& c : this->Configurations) { cmCustomCommandGenerator ccg(command, c, lg); @@ -1805,30 +1775,8 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1, std::string copyToOutDir; std::string includeInVsix; std::string ext = cmSystemTools::LowerCase(sf->GetExtension()); - if (this->ProjectType == csproj) { - // EVERY extra source file must have a <Link>, otherwise it might not - // be visible in Visual Studio at all. The path relative to current - // source- or binary-dir is used within the link, if the file is - // in none of these paths, it is added with the plain filename without - // any path. This means the file will show up at root-level of the csproj - // (where CMakeLists.txt etc. are). - if (!this->InSourceBuild) { - toolHasSettings = true; - std::string fullFileName = sf->GetFullPath(); - std::string srcDir = this->Makefile->GetCurrentSourceDirectory(); - std::string binDir = this->Makefile->GetCurrentBinaryDirectory(); - if (fullFileName.find(binDir) != std::string::npos) { - sourceLink.clear(); - } else if (fullFileName.find(srcDir) != std::string::npos) { - sourceLink = fullFileName.substr(srcDir.length() + 1); - } else { - // fallback: add plain filename without any path - sourceLink = cmsys::SystemTools::GetFilenameName(fullFileName); - } - if (!sourceLink.empty()) { - ConvertToWindowsSlash(sourceLink); - } - } + if (this->ProjectType == csproj && !this->InSourceBuild) { + toolHasSettings = true; } if (ext == "hlsl") { tool = "FXCompile"; @@ -2047,9 +1995,6 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1, if (!settingsLastGenOutput.empty()) { e2.Element("LastGenOutput", settingsLastGenOutput); } - if (!sourceLink.empty()) { - e2.Element("Link", sourceLink); - } if (!subType.empty()) { e2.Element("SubType", subType); } @@ -2102,6 +2047,20 @@ void cmVisualStudio10TargetGenerator::WriteSource(Elem& e2, ConvertToWindowsSlash(sourceFile); e2.Attribute("Include", sourceFile); + if (this->ProjectType == csproj && !this->InSourceBuild) { + // For out of source projects we have to provide a link (if not specified + // via property) for every source file (besides .cs files) otherwise they + // will not be visible in VS at all. + // First we check if the file is in a source group, then we check if the + // file path is relative to current source- or binary-dir, otherwise it is + // added with the plain filename without any path. This means the file will + // show up at root-level of the csproj (where CMakeLists.txt etc. are). + std::string link = this->GetCSharpSourceLink(sf); + if (link.empty()) + link = cmsys::SystemTools::GetFilenameName(sf->GetFullPath()); + e2.Element("Link", link); + } + ToolSource toolSource = { sf, forceRelative }; this->Tools[e2.Tag].push_back(toolSource); } @@ -2461,12 +2420,6 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags( std::string f = source->GetFullPath(); using CsPropMap = std::map<std::string, std::string>; CsPropMap sourceFileTags; - // set <Link> tag if necessary - std::string link; - this->GetCSharpSourceLink(source, link); - if (!link.empty()) { - sourceFileTags["Link"] = link; - } this->GetCSharpSourceProperties(&sf, sourceFileTags); // write source file specific tags if (!sourceFileTags.empty()) { @@ -4869,24 +4822,34 @@ void cmVisualStudio10TargetGenerator::WriteCSharpSourceProperties( } } -void cmVisualStudio10TargetGenerator::GetCSharpSourceLink( - cmSourceFile const* sf, std::string& link) +std::string cmVisualStudio10TargetGenerator::GetCSharpSourceLink( + cmSourceFile const* source) { - std::string const& sourceFilePath = sf->GetFullPath(); - std::string const& binaryDir = LocalGenerator->GetCurrentBinaryDirectory(); - - if (!cmSystemTools::IsSubDirectory(sourceFilePath, binaryDir)) { - const std::string& stripFromPath = - this->Makefile->GetCurrentSourceDirectory(); - if (sourceFilePath.find(stripFromPath) == 0) { - if (const char* l = sf->GetProperty("VS_CSHARP_Link")) { - link = l; - } else { - link = sourceFilePath.substr(stripFromPath.length() + 1); - } - ConvertToWindowsSlash(link); - } - } + // For out of source files, we first check if a matching source group + // for this file exists, otherwise we check if the path relative to current + // source- or binary-dir is used within the link and return that + std::string link; + std::string const& fullFileName = source->GetFullPath(); + std::string const& srcDir = this->Makefile->GetCurrentSourceDirectory(); + std::string const& binDir = this->Makefile->GetCurrentBinaryDirectory(); + // unfortunately we have to copy the source groups, because + // FindSourceGroup uses a regex which is modifying the group + std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups(); + cmSourceGroup* sourceGroup = + this->Makefile->FindSourceGroup(fullFileName, sourceGroups); + if (sourceGroup && !sourceGroup->GetFullName().empty()) { + link = sourceGroup->GetFullName() + "/" + + cmsys::SystemTools::GetFilenameName(fullFileName); + } else if (fullFileName.find(srcDir) == 0) { + link = fullFileName.substr(srcDir.length() + 1); + } else if (fullFileName.find(binDir) == 0) { + link = fullFileName.substr(binDir.length() + 1); + } else if (const char* l = source->GetProperty("VS_CSHARP_Link")) { + link = l; + } + + ConvertToWindowsSlash(link); + return link; } std::string cmVisualStudio10TargetGenerator::GetCMakeFilePath( diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h index 30027c9..4977c1a 100644 --- a/Source/cmVisualStudio10TargetGenerator.h +++ b/Source/cmVisualStudio10TargetGenerator.h @@ -183,7 +183,7 @@ private: std::map<std::string, std::string>& tags); void WriteCSharpSourceProperties( Elem& e2, const std::map<std::string, std::string>& tags); - void GetCSharpSourceLink(cmSourceFile const* sf, std::string& link); + std::string GetCSharpSourceLink(cmSourceFile const* source); private: friend class cmVS10GeneratorOptions; diff --git a/Tests/CSharpOnly/CMakeLists.txt b/Tests/CSharpOnly/CMakeLists.txt index 82049c7..42cbe2e 100644 --- a/Tests/CSharpOnly/CMakeLists.txt +++ b/Tests/CSharpOnly/CMakeLists.txt @@ -2,7 +2,9 @@ project (CSharpOnly CSharp) # C# does not make any difference between STATIC and SHARED libs -add_library(lib1 STATIC lib1.cs) +add_library(lib1 STATIC lib1.cs nested/lib1.cs) +#without the source group this test will fail to compile +source_group(nested FILES nested/lib1.cs) add_library(lib2 SHARED lib2.cs) add_executable(CSharpOnly csharponly.cs) diff --git a/Tests/CSharpOnly/csharponly.cs b/Tests/CSharpOnly/csharponly.cs index ad4641a..3890c82 100644 --- a/Tests/CSharpOnly/csharponly.cs +++ b/Tests/CSharpOnly/csharponly.cs @@ -5,10 +5,8 @@ namespace CSharpOnly public static void Main(string[] args) { int val = Lib1.getResult(); - Lib2 l = new Lib2(); - val = l.myVal; - + val = val + l.myVal + nested.Lib1.getResult(); return; } } diff --git a/Tests/CSharpOnly/nested/lib1.cs b/Tests/CSharpOnly/nested/lib1.cs new file mode 100644 index 0000000..c2fde4b --- /dev/null +++ b/Tests/CSharpOnly/nested/lib1.cs @@ -0,0 +1,13 @@ +namespace CSharpOnly +{ + namespace nested + { + public class Lib1 + { + public static int getResult() + { + return 23; + } + } + } +} diff --git a/Tests/FindPython/SOABI/CMakeLists.txt b/Tests/FindPython/SOABI/CMakeLists.txt index aea2baf..4a6aea3 100644 --- a/Tests/FindPython/SOABI/CMakeLists.txt +++ b/Tests/FindPython/SOABI/CMakeLists.txt @@ -10,3 +10,13 @@ endif() if(NOT DEFINED Python3_SOABI) message(FATAL_ERROR "Python3_SOABI for ${CMake_TEST_FindPython_COMPONENT} not found") endif() + +if (Python3_Development_FOUND AND Python3_SOABI) + Python3_add_library (spam3 MODULE WITH_SOABI ../spam.c) + target_compile_definitions (spam3 PRIVATE PYTHON3) + + get_property (suffix TARGET spam3 PROPERTY SUFFIX) + if (NOT suffix MATCHES "^.${Python3_SOABI}") + message(FATAL_ERROR "Module suffix do not include Python3_SOABI") + endif() +endif() diff --git a/Tests/FortranModules/CMakeLists.txt b/Tests/FortranModules/CMakeLists.txt index d056b43..b7a6f68 100644 --- a/Tests/FortranModules/CMakeLists.txt +++ b/Tests/FortranModules/CMakeLists.txt @@ -21,7 +21,7 @@ end module parent submodule ( parent ) child contains module procedure id - f = x + id = x end procedure id end submodule child program main diff --git a/Tests/FortranOnly/CMakeLists.txt b/Tests/FortranOnly/CMakeLists.txt index d945375..4327c2f 100644 --- a/Tests/FortranOnly/CMakeLists.txt +++ b/Tests/FortranOnly/CMakeLists.txt @@ -51,40 +51,36 @@ add_custom_target(checksayhello ALL ) add_dependencies(checksayhello sayhello) -# Exclude this test on IBM XL for now because the check strangely -# fails with 'ld: 0706-029 Use a number with the -H flag'. -if(NOT CMAKE_Fortran_COMPILER_ID STREQUAL XL) - set(err_log ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log) - file(REMOVE "${err_log}") - include(CheckFortranSourceCompiles) - unset(HAVE_PRINT CACHE) - CHECK_Fortran_SOURCE_COMPILES([[ +set(err_log ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log) +file(REMOVE "${err_log}") +include(CheckFortranSourceCompiles) +unset(HAVE_PRINT CACHE) +CHECK_Fortran_SOURCE_COMPILES([[ PROGRAM TEST_HAVE_PRINT PRINT *, 'Hello' END ]] HAVE_PRINT) - if(NOT HAVE_PRINT) - if(EXISTS "${err_log}") - file(READ "${err_log}" err) - endif() - string(REPLACE "\n" "\n " err " ${err}") - message(SEND_ERROR "CHECK_Fortran_SOURCE_COMPILES for HAVE_PRINT failed:\n" - "${err}") +if(NOT HAVE_PRINT) + if(EXISTS "${err_log}") + file(READ "${err_log}" err) endif() + string(REPLACE "\n" "\n " err " ${err}") + message(SEND_ERROR "CHECK_Fortran_SOURCE_COMPILES for HAVE_PRINT failed:\n" + "${err}") +endif() - unset(Fortran_BOGUS_FLAG CACHE) - include(CheckFortranCompilerFlag) - CHECK_Fortran_COMPILER_FLAG(-_this_is_not_a_flag_ Fortran_BOGUS_FLAG) - if (Fortran_BOGUS_FLAG) - message(SEND_ERROR "CHECK_Fortran_COMPILER_FLAG() succeeded, but should have failed") - endif() +unset(Fortran_BOGUS_FLAG CACHE) +include(CheckFortranCompilerFlag) +CHECK_Fortran_COMPILER_FLAG(-_this_is_not_a_flag_ Fortran_BOGUS_FLAG) +if (Fortran_BOGUS_FLAG) + message(SEND_ERROR "CHECK_Fortran_COMPILER_FLAG() succeeded, but should have failed") +endif() - unset(Fortran_RUN_FLAG CACHE) - include(CheckFortranSourceRuns) - check_fortran_source_runs("program a; end program" Fortran_RUN_FLAG SRC_EXT F90) - if(NOT Fortran_RUN_FLAG) - message(SEND_ERROR "CHECK_Fortran_SOURCE_RUNS() failed") - endif() +unset(Fortran_RUN_FLAG CACHE) +include(CheckFortranSourceRuns) +check_fortran_source_runs("program a; end program" Fortran_RUN_FLAG SRC_EXT F90) +if(NOT Fortran_RUN_FLAG) + message(SEND_ERROR "CHECK_Fortran_SOURCE_RUNS() failed") endif() # Test generation of preprocessed sources. diff --git a/Tests/Preprocess/preprocess.c b/Tests/Preprocess/preprocess.c index 958c77e..b3117da 100644 --- a/Tests/Preprocess/preprocess.c +++ b/Tests/Preprocess/preprocess.c @@ -15,21 +15,21 @@ int check_defines_C(void) result = 0; } if (strcmp(TARGET_STRING, STRING_VALUE) != 0) { - fprintf(stderr, "TARGET_STRING has wrong value in C [%s]\n", - TARGET_STRING); + fprintf(stderr, "TARGET_STRING has wrong value in C [%s] vs [%s]\n", + TARGET_STRING, STRING_VALUE); 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)); + fprintf(stderr, "FILE_EXPR did not work in C [%s] vs [%s]\n", + TO_STRING(FILE_EXPR), TO_STRING(EXPR)); result = 0; } if ((TARGET_EXPR) != (EXPR)) { - fprintf(stderr, "TARGET_EXPR did not work in C [%s]\n", - TO_STRING(FILE_EXPR)); + fprintf(stderr, "TARGET_EXPR did not work in C [%s] vs [%s]\n", + TO_STRING(TARGET_EXPR), TO_STRING(EXPR)); result = 0; } } diff --git a/Tests/Preprocess/preprocess.cxx b/Tests/Preprocess/preprocess.cxx index 34a69c6..f2fffef 100644 --- a/Tests/Preprocess/preprocess.cxx +++ b/Tests/Preprocess/preprocess.cxx @@ -12,25 +12,26 @@ 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); + fprintf(stderr, "FILE_STRING has wrong value in CXX [%s] vs [%s]\n", + FILE_STRING, STRING_VALUE); result = 0; } if (strcmp(TARGET_STRING, STRING_VALUE) != 0) { - fprintf(stderr, "TARGET_STRING has wrong value in CXX [%s]\n", - TARGET_STRING); + fprintf(stderr, "TARGET_STRING has wrong value in CXX [%s] vs [%s]\n", + TARGET_STRING, STRING_VALUE); 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)); + fprintf(stderr, "FILE_EXPR did not work in CXX [%s] vs [%s]\n", + TO_STRING(FILE_EXPR), TO_STRING(EXPR)); result = 0; } if ((TARGET_EXPR) != (EXPR)) { - fprintf(stderr, "TARGET_EXPR did not work in CXX [%s]\n", - TO_STRING(FILE_EXPR)); + fprintf(stderr, "TARGET_EXPR did not work in CXX [%s] vs [%s]\n", + TO_STRING(TARGET_EXPR), TO_STRING(EXPR)); result = 0; } } diff --git a/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsNoDefaultFile-result.txt b/Tests/RunCMake/Configure/NoCMAKE_CROSS_CONFIGS-result.txt index d00491f..d00491f 100644 --- a/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsNoDefaultFile-result.txt +++ b/Tests/RunCMake/Configure/NoCMAKE_CROSS_CONFIGS-result.txt diff --git a/Tests/RunCMake/Configure/NoCMAKE_CROSS_CONFIGS-stderr.txt b/Tests/RunCMake/Configure/NoCMAKE_CROSS_CONFIGS-stderr.txt new file mode 100644 index 0000000..a5d149d --- /dev/null +++ b/Tests/RunCMake/Configure/NoCMAKE_CROSS_CONFIGS-stderr.txt @@ -0,0 +1,11 @@ +^CMake Error: + Generator + + [^ +]* + + does not support variable + + CMAKE_CROSS_CONFIGS + + but it has been specified. diff --git a/Tests/RunCMake/Configure/NoCMAKE_CROSS_CONFIGS.cmake b/Tests/RunCMake/Configure/NoCMAKE_CROSS_CONFIGS.cmake new file mode 100644 index 0000000..75d0c47 --- /dev/null +++ b/Tests/RunCMake/Configure/NoCMAKE_CROSS_CONFIGS.cmake @@ -0,0 +1 @@ +set(CMAKE_CROSS_CONFIGS "") diff --git a/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_BUILD_TYPE-result.txt b/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_BUILD_TYPE-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_BUILD_TYPE-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_BUILD_TYPE-stderr.txt b/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_BUILD_TYPE-stderr.txt new file mode 100644 index 0000000..8aa3ed3 --- /dev/null +++ b/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_BUILD_TYPE-stderr.txt @@ -0,0 +1,11 @@ +^CMake Error: + Generator + + [^ +]* + + does not support variable + + CMAKE_DEFAULT_BUILD_TYPE + + but it has been specified. diff --git a/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_BUILD_TYPE.cmake b/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_BUILD_TYPE.cmake new file mode 100644 index 0000000..64c7feb --- /dev/null +++ b/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_BUILD_TYPE.cmake @@ -0,0 +1 @@ +set(CMAKE_DEFAULT_BUILD_TYPE "") diff --git a/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_CONFIGS-result.txt b/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_CONFIGS-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_CONFIGS-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_CONFIGS-stderr.txt b/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_CONFIGS-stderr.txt new file mode 100644 index 0000000..040bf4d --- /dev/null +++ b/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_CONFIGS-stderr.txt @@ -0,0 +1,11 @@ +^CMake Error: + Generator + + [^ +]* + + does not support variable + + CMAKE_DEFAULT_CONFIGS + + but it has been specified. diff --git a/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_CONFIGS.cmake b/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_CONFIGS.cmake new file mode 100644 index 0000000..5b65172 --- /dev/null +++ b/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_CONFIGS.cmake @@ -0,0 +1 @@ +set(CMAKE_DEFAULT_CONFIGS "") diff --git a/Tests/RunCMake/Configure/RunCMakeTest.cmake b/Tests/RunCMake/Configure/RunCMakeTest.cmake index 76d843c..9fd4499 100644 --- a/Tests/RunCMake/Configure/RunCMakeTest.cmake +++ b/Tests/RunCMake/Configure/RunCMakeTest.cmake @@ -50,3 +50,9 @@ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}") run_cmake(RemoveCache) file(REMOVE "${RunCMake_TEST_BINARY_DIR}/CMakeCache.txt") run_cmake(RemoveCache) + +if(NOT RunCMake_GENERATOR MATCHES "^Ninja Multi-Config$") + run_cmake(NoCMAKE_CROSS_CONFIGS) + run_cmake(NoCMAKE_DEFAULT_BUILD_TYPE) + run_cmake(NoCMAKE_DEFAULT_CONFIGS) +endif() diff --git a/Tests/RunCMake/NinjaMultiConfig/InvalidCrossConfigs-stderr.txt b/Tests/RunCMake/NinjaMultiConfig/InvalidCrossConfigs-stderr.txt index 6e165e8..76c5ecf 100644 --- a/Tests/RunCMake/NinjaMultiConfig/InvalidCrossConfigs-stderr.txt +++ b/Tests/RunCMake/NinjaMultiConfig/InvalidCrossConfigs-stderr.txt @@ -1,5 +1,5 @@ ^CMake Error: - CMAKE_NMC_CROSS_CONFIGS is not a subset of CMAKE_CONFIGURATION_TYPES + CMAKE_CROSS_CONFIGS is not a subset of CMAKE_CONFIGURATION_TYPES CMake Generate step failed\. Build files cannot be regenerated correctly\.$ diff --git a/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultBuildFileConfig-stderr.txt b/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultBuildFileConfig-stderr.txt index 114a8a3..5aa9038 100644 --- a/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultBuildFileConfig-stderr.txt +++ b/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultBuildFileConfig-stderr.txt @@ -1,6 +1,6 @@ ^CMake Error: - The configuration specified by CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG - \(RelWithDebInfo\) is not present in CMAKE_CONFIGURATION_TYPES + The configuration specified by CMAKE_DEFAULT_BUILD_TYPE \(RelWithDebInfo\) is + not present in CMAKE_CONFIGURATION_TYPES CMake Generate step failed\. Build files cannot be regenerated correctly\.$ diff --git a/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsCross-stderr.txt b/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsCross-stderr.txt index 8d52189..6c2df86 100644 --- a/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsCross-stderr.txt +++ b/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsCross-stderr.txt @@ -1,5 +1,5 @@ ^CMake Error: - CMAKE_NMC_DEFAULT_CONFIGS is not a subset of CMAKE_NMC_CROSS_CONFIGS + CMAKE_DEFAULT_CONFIGS is not a subset of CMAKE_CROSS_CONFIGS CMake Generate step failed\. Build files cannot be regenerated correctly\.$ diff --git a/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsNoCross-stderr.txt b/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsNoCross-stderr.txt index f9cb56d..5d090a0 100644 --- a/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsNoCross-stderr.txt +++ b/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsNoCross-stderr.txt @@ -1,6 +1,6 @@ ^CMake Error: - CMAKE_NMC_DEFAULT_CONFIGS cannot be used without - CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG or CMAKE_NMC_CROSS_CONFIGS + CMAKE_DEFAULT_CONFIGS cannot be used without CMAKE_DEFAULT_BUILD_TYPE or + CMAKE_CROSS_CONFIGS CMake Generate step failed\. Build files cannot be regenerated correctly\.$ diff --git a/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsNoDefaultFile-stderr.txt b/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsNoDefaultFile-stderr.txt deleted file mode 100644 index f9cb56d..0000000 --- a/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsNoDefaultFile-stderr.txt +++ /dev/null @@ -1,6 +0,0 @@ -^CMake Error: - CMAKE_NMC_DEFAULT_CONFIGS cannot be used without - CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG or CMAKE_NMC_CROSS_CONFIGS - - -CMake Generate step failed\. Build files cannot be regenerated correctly\.$ diff --git a/Tests/RunCMake/NinjaMultiConfig/NoUnusedVariables.cmake b/Tests/RunCMake/NinjaMultiConfig/NoUnusedVariables.cmake new file mode 100644 index 0000000..bb7b160 --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/NoUnusedVariables.cmake @@ -0,0 +1 @@ +# Intentionally empty diff --git a/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake b/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake index a608e9e..6472f46 100644 --- a/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake +++ b/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake @@ -78,10 +78,10 @@ endfunction() ############################################################################### -set(RunCMake_TEST_NO_CLEAN 1) - set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Simple-build) -set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release\\;MinSizeRel\\;RelWithDebInfo;-DCMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG=RelWithDebInfo;-DCMAKE_NMC_CROSS_CONFIGS=all") +# IMPORTANT: Setting RelWithDebInfo as the first item in CMAKE_CONFIGURATION_TYPES +# generates a build.ninja file with that configuration +set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=RelWithDebInfo\\;Debug\\;Release\\;MinSizeRel;-DCMAKE_CROSS_CONFIGS=all") run_cmake_configure(Simple) unset(RunCMake_TEST_OPTIONS) include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake) @@ -113,7 +113,7 @@ run_ninja(Simple default-build-file-clean-minsizerel build.ninja clean:MinSizeRe run_ninja(Simple default-build-file-all build.ninja all) set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/SimpleDefaultBuildAlias-build) -set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release\\;MinSizeRel\\;RelWithDebInfo;-DCMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG=Release;-DCMAKE_NMC_DEFAULT_CONFIGS=all;-DCMAKE_NMC_CROSS_CONFIGS=all") +set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release\\;MinSizeRel\\;RelWithDebInfo;-DCMAKE_DEFAULT_BUILD_TYPE=Release;-DCMAKE_DEFAULT_CONFIGS=all;-DCMAKE_CROSS_CONFIGS=all") run_cmake_configure(SimpleDefaultBuildAlias) unset(RunCMake_TEST_OPTIONS) include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake) @@ -122,7 +122,7 @@ run_ninja(SimpleDefaultBuildAlias all build.ninja all) run_ninja(SimpleDefaultBuildAlias clean build.ninja clean) set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/SimpleDefaultBuildAliasList-build) -set(RunCMake_TEST_OPTIONS "-DCMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG=Release;-DCMAKE_NMC_DEFAULT_CONFIGS=Debug\\;Release;-DCMAKE_NMC_CROSS_CONFIGS=all") +set(RunCMake_TEST_OPTIONS "-DCMAKE_DEFAULT_BUILD_TYPE=Release;-DCMAKE_DEFAULT_CONFIGS=Debug\\;Release;-DCMAKE_CROSS_CONFIGS=all") run_cmake_configure(SimpleDefaultBuildAliasList) unset(RunCMake_TEST_OPTIONS) include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake) @@ -133,7 +133,7 @@ run_ninja(SimpleDefaultBuildAliasList all-relwithdebinfo build.ninja all:RelWith run_ninja(SimpleDefaultBuildAliasList clean-configs build.ninja clean) set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/SimpleDefaultBuildAliasListCross-build) -set(RunCMake_TEST_OPTIONS "-DCMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG=RelWithDebInfo;-DCMAKE_NMC_DEFAULT_CONFIGS=all;-DCMAKE_NMC_CROSS_CONFIGS=Debug\\;Release") +set(RunCMake_TEST_OPTIONS "-DCMAKE_DEFAULT_BUILD_TYPE=RelWithDebInfo;-DCMAKE_DEFAULT_CONFIGS=all;-DCMAKE_CROSS_CONFIGS=Debug\\;Release") run_cmake_configure(SimpleDefaultBuildAliasListCross) unset(RunCMake_TEST_OPTIONS) include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake) @@ -141,27 +141,23 @@ run_ninja(SimpleDefaultBuildAliasListCross target-configs build.ninja simpleexe) unset(RunCMake_TEST_BINARY_DIR) -set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release;-DCMAKE_NMC_CROSS_CONFIGS=Debug\\;Release\\;RelWithDebInfo") +set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release;-DCMAKE_CROSS_CONFIGS=Debug\\;Release\\;RelWithDebInfo") run_cmake(InvalidCrossConfigs) unset(RunCMake_TEST_OPTIONS) -set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release;-DCMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG=RelWithDebInfo") +set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release;-DCMAKE_DEFAULT_BUILD_TYPE=RelWithDebInfo") run_cmake(InvalidDefaultBuildFileConfig) unset(RunCMake_TEST_OPTIONS) -set(RunCMake_TEST_OPTIONS "-DCMAKE_NMC_CROSS_CONFIGS=Debug\\;Release;-DCMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG=Release;-DCMAKE_NMC_DEFAULT_CONFIGS=Debug\\;Release\\;RelWithDebInfo") +set(RunCMake_TEST_OPTIONS "-DCMAKE_CROSS_CONFIGS=Debug\\;Release;-DCMAKE_DEFAULT_BUILD_TYPE=Release;-DCMAKE_DEFAULT_CONFIGS=Debug\\;Release\\;RelWithDebInfo") run_cmake(InvalidDefaultConfigsCross) unset(RunCMake_TEST_OPTIONS) -set(RunCMake_TEST_OPTIONS "-DCMAKE_NMC_CROSS_CONFIGS=Debug\\;Release;-DCMAKE_NMC_DEFAULT_CONFIGS=all") -run_cmake(InvalidDefaultConfigsNoDefaultFile) -unset(RunCMake_TEST_OPTIONS) - -set(RunCMake_TEST_OPTIONS "-DCMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG=Release;-DCMAKE_NMC_DEFAULT_CONFIGS=all") +set(RunCMake_TEST_OPTIONS "-DCMAKE_DEFAULT_BUILD_TYPE=Release;-DCMAKE_DEFAULT_CONFIGS=all") run_cmake(InvalidDefaultConfigsNoCross) unset(RunCMake_TEST_OPTIONS) -set(RunCMake_TEST_OPTIONS "-DCMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG=Release") +set(RunCMake_TEST_OPTIONS "-DCMAKE_DEFAULT_BUILD_TYPE=Release") run_cmake(DefaultBuildFileConfig) unset(RunCMake_TEST_OPTIONS) @@ -178,7 +174,7 @@ run_ninja(SimpleNoCross all-all build-Debug.ninja all:all) run_cmake_build(SimpleNoCross all-clean Debug clean:all) set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/SimpleCrossConfigs-build) -set(RunCMake_TEST_OPTIONS "-DCMAKE_NMC_CROSS_CONFIGS=Debug\\;Release") +set(RunCMake_TEST_OPTIONS "-DCMAKE_CROSS_CONFIGS=Debug\\;Release") run_cmake_configure(SimpleCrossConfigs) include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake) run_ninja(SimpleCrossConfigs release-in-release-graph build-Release.ninja simpleexe) @@ -192,21 +188,22 @@ run_cmake_build(SimpleCrossConfigs all-all-in-release-graph Release all:all) run_cmake_build(SimpleCrossConfigs all-relwithdebinfo-in-release-graph Release all:RelWithDebInfo) set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Framework-build) -set(RunCMake_TEST_OPTIONS "-DCMAKE_NMC_CROSS_CONFIGS=all") +set(RunCMake_TEST_OPTIONS "-DCMAKE_CROSS_CONFIGS=all") run_cmake_configure(Framework) unset(RunCMake_TEST_OPTIONS) include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake) run_cmake_build(Framework framework Debug all) set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/FrameworkDependencyAutogen-build) -set(RunCMake_TEST_OPTIONS "-DCMAKE_NMC_CROSS_CONFIGS=all") +set(RunCMake_TEST_OPTIONS "-DCMAKE_CROSS_CONFIGS=all") run_cmake_configure(FrameworkDependencyAutogen) unset(RunCMake_TEST_OPTIONS) include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake) run_cmake_build(FrameworkDependencyAutogen framework Release test2:Debug) +set(RunCMake_TEST_NO_CLEAN 1) set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CustomCommandGenerator-build) -set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release\\;MinSizeRel\\;RelWithDebInfo;-DCMAKE_NMC_CROSS_CONFIGS=all") +set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release\\;MinSizeRel\\;RelWithDebInfo;-DCMAKE_CROSS_CONFIGS=all") run_cmake_configure(CustomCommandGenerator) unset(RunCMake_TEST_OPTIONS) include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake) @@ -221,9 +218,10 @@ run_cmake_command(CustomCommandGenerator-debug-in-release-graph-generated "${TAR run_ninja(CustomCommandGenerator debug-in-release-graph-clean build-Debug.ninja clean:Debug) run_ninja(CustomCommandGenerator release-in-debug-graph build-Debug.ninja generated:Release) run_cmake_command(CustomCommandGenerator-release-in-debug-graph-generated "${TARGET_FILE_generated_Release}") +unset(RunCMake_TEST_NO_CLEAN) set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CustomCommandsAndTargets-build) -set(RunCMake_TEST_OPTIONS "-DCMAKE_NMC_CROSS_CONFIGS=all") +set(RunCMake_TEST_OPTIONS "-DCMAKE_CROSS_CONFIGS=all") run_cmake_configure(CustomCommandsAndTargets) unset(RunCMake_TEST_OPTIONS) include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake) @@ -243,7 +241,7 @@ unset(RunCMake_TEST_BINARY_DIR) run_cmake(CustomCommandDepfile) set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/PostfixAndLocation-build) -set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release;-DCMAKE_NMC_CROSS_CONFIGS=all") +set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release;-DCMAKE_CROSS_CONFIGS=all") run_cmake_configure(PostfixAndLocation) unset(RunCMake_TEST_OPTIONS) include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake) @@ -258,14 +256,14 @@ run_ninja(Clean release-notall build-Release.ninja exenotall) run_cmake_build(Clean release-clean Release clean) set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/AdditionalCleanFiles-build) -set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release\\;MinSizeRel\\;RelWithDebInfo;-DCMAKE_NMC_CROSS_CONFIGS=all") +set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release\\;MinSizeRel\\;RelWithDebInfo;-DCMAKE_CROSS_CONFIGS=all") run_cmake_configure(AdditionalCleanFiles) unset(RunCMake_TEST_OPTIONS) run_cmake_build(AdditionalCleanFiles release-clean Release clean) run_ninja(AdditionalCleanFiles all-clean build-Debug.ninja clean:all) set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Install-build) -set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX=${RunCMake_TEST_BINARY_DIR}/install;-DCMAKE_NMC_CROSS_CONFIGS=all") +set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX=${RunCMake_TEST_BINARY_DIR}/install;-DCMAKE_CROSS_CONFIGS=all") run_cmake_configure(Install) unset(RunCMake_TEST_OPTIONS) include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake) @@ -277,6 +275,16 @@ run_ninja(Install debug-in-release-graph-install build-Release.ninja install:Deb #run_cmake_configure(AutoMocExecutable) #run_cmake_build(AutoMocExecutable debug-in-release-graph Release exe) +# Need to test this manually because run_cmake() adds --no-warn-unused-cli +set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/NoUnusedVariables-build) +run_cmake_command(NoUnusedVariables ${CMAKE_COMMAND} ${CMAKE_CURRENT_LIST_DIR} + -G "Ninja Multi-Config" + "-DRunCMake_TEST=NoUnusedVariables" + "-DCMAKE_CROSS_CONFIGS=all" + "-DCMAKE_DEFAULT_BUILD_TYPE=Debug" + "-DCMAKE_DEFAULT_CONFIGS=all" + ) + if(CMake_TEST_CUDA) set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CudaSimple-build) run_cmake_configure(CudaSimple) @@ -287,7 +295,7 @@ endif() if(CMake_TEST_Qt5) set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Qt5-build) - set(RunCMake_TEST_OPTIONS "-DCMAKE_NMC_CROSS_CONFIGS=all") + set(RunCMake_TEST_OPTIONS "-DCMAKE_CROSS_CONFIGS=all") run_cmake_configure(Qt5) unset(RunCMake_TEST_OPTIONS) include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake) diff --git a/Tests/RunCMake/Syntax/CommandEOF-stderr.txt b/Tests/RunCMake/Syntax/CommandEOF-stderr.txt index 31cbc08..b9f8fd1 100644 --- a/Tests/RunCMake/Syntax/CommandEOF-stderr.txt +++ b/Tests/RunCMake/Syntax/CommandEOF-stderr.txt @@ -1,4 +1,4 @@ -^CMake Error in CommandEOF.cmake: +^CMake Error at CommandEOF.cmake:1: Unexpected end of file. Parse error. Function missing opening "\(". diff --git a/Tests/RunCMake/VS10Project/CSharpSourceGroup/foo.cs b/Tests/RunCMake/VS10Project/CSharpSourceGroup/foo.cs new file mode 100644 index 0000000..3695dc9 --- /dev/null +++ b/Tests/RunCMake/VS10Project/CSharpSourceGroup/foo.cs @@ -0,0 +1,3 @@ +void foo() +{ +} diff --git a/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsNoDefaultFile.cmake b/Tests/RunCMake/VS10Project/CSharpSourceGroup/images/empty.bmp index e69de29..e69de29 100644 --- a/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsNoDefaultFile.cmake +++ b/Tests/RunCMake/VS10Project/CSharpSourceGroup/images/empty.bmp diff --git a/Tests/RunCMake/VS10Project/CSharpSourceGroup/nested/baz.cs b/Tests/RunCMake/VS10Project/CSharpSourceGroup/nested/baz.cs new file mode 100644 index 0000000..d5d334a --- /dev/null +++ b/Tests/RunCMake/VS10Project/CSharpSourceGroup/nested/baz.cs @@ -0,0 +1,3 @@ +void baz() +{ +} diff --git a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake index ff31a74..3ca7cc0 100644 --- a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake +++ b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake @@ -3,12 +3,12 @@ cmake_policy(SET CMP0057 NEW) include(RunCMake) cmake_policy(SET CMP0054 NEW) +run_cmake(VsCsharpSourceGroup) run_cmake(VsCSharpCompilerOpts) run_cmake(ExplicitCMakeLists) run_cmake(RuntimeLibrary) run_cmake(SourceGroupCMakeLists) run_cmake(SourceGroupTreeCMakeLists) - run_cmake(VsConfigurationType) run_cmake(VsTargetsFileReferences) run_cmake(VsCustomProps) diff --git a/Tests/RunCMake/VS10Project/VsCsharpSourceGroup-check.cmake b/Tests/RunCMake/VS10Project/VsCsharpSourceGroup-check.cmake new file mode 100644 index 0000000..3b5c70f --- /dev/null +++ b/Tests/RunCMake/VS10Project/VsCsharpSourceGroup-check.cmake @@ -0,0 +1,22 @@ +set(csProjFile "${RunCMake_TEST_BINARY_DIR}/VsCsharpSourceGroup.csproj") +if(NOT EXISTS "${csProjFile}") + set(RunCMake_TEST_FAILED "Project file ${csProjFile} does not exist.") + return() +endif() + +file(STRINGS "${csProjFile}" lines) + +include(${RunCMake_TEST_SOURCE_DIR}/VsCsharpSourceGroupHelpers.cmake) + +set(SOURCE_GROUPS_TO_FIND + "CSharpSourceGroup" + "CSharpSourceGroup/nested" + "Images" +) + +foreach(GROUP_NAME IN LISTS ${SOURCE_GROUPS_TO_FIND}) + find_source_group("${lines}" ${GROUP_NAME}) + if(NOT ${SOURCE_GROUP_FOUND}) + return() + endif() +endforeach() diff --git a/Tests/RunCMake/VS10Project/VsCsharpSourceGroup.cmake b/Tests/RunCMake/VS10Project/VsCsharpSourceGroup.cmake new file mode 100644 index 0000000..024993c --- /dev/null +++ b/Tests/RunCMake/VS10Project/VsCsharpSourceGroup.cmake @@ -0,0 +1,16 @@ +enable_language(CSharp) +set(CMAKE_CONFIGURATION_TYPES Debug) + +set(SRC_FILES + ${CMAKE_CURRENT_SOURCE_DIR}/CSharpSourceGroup/foo.cs + ${CMAKE_CURRENT_SOURCE_DIR}/CSharpSourceGroup/nested/baz.cs +) + +set(IMAGE_FILES + ${CMAKE_CURRENT_SOURCE_DIR}/CSharpSourceGroup/Images/empty.bmp +) + +add_library(VsCsharpSourceGroup SHARED ${SRC_FILES} ${IMAGE_FILES}) +source_group("CSharpSourceGroup" FILES ${CMAKE_CURRENT_SOURCE_DIR}/CSharpSourceGroup/foo.cs) +source_group("CSharpSourceGroup/nested" FILES ${CMAKE_CURRENT_SOURCE_DIR}/CSharpSourceGroup/nested/baz.cs) +source_group("Images" FILES ${IMAGE_FILES}) diff --git a/Tests/RunCMake/VS10Project/VsCsharpSourceGroupHelpers.cmake b/Tests/RunCMake/VS10Project/VsCsharpSourceGroupHelpers.cmake new file mode 100644 index 0000000..bfa9a67 --- /dev/null +++ b/Tests/RunCMake/VS10Project/VsCsharpSourceGroupHelpers.cmake @@ -0,0 +1,15 @@ +function(find_source_group LINES NAME) + set(foundSourceGroupLink 0) + foreach(line IN LISTS LINES) + if(line MATCHES "<Link>${NAME}</Link>") + set(foundSourceGroupLink 1) + endif() + endforeach() + + if(NOT foundSourceGroupLink) + set(RunCMake_TEST_FAILED "Source group link for ${NAME} not found." PARENT_SCOPE) + set(SOURCE_GROUP_FOUND 0 PARENT_SCOPE) + return() + endif() + set(SOURCE_GROUP_FOUND 1 PARENT_SCOPE) +endfunction() diff --git a/Tests/RunCMake/cmake_command/RunCMakeTest.cmake b/Tests/RunCMake/cmake_command/RunCMakeTest.cmake index d338cd8..2b6e7a2 100644 --- a/Tests/RunCMake/cmake_command/RunCMakeTest.cmake +++ b/Tests/RunCMake/cmake_command/RunCMakeTest.cmake @@ -6,3 +6,8 @@ run_cmake(cmake_command_invoke_message) run_cmake(cmake_command_invoke_message_fatal_error) run_cmake(cmake_command_invoke_no_parameters) run_cmake(cmake_command_invoke_unknown_function) +run_cmake(cmake_command_eval_message) +run_cmake(cmake_command_eval_message_fatal_error) +run_cmake(cmake_command_eval_no_code) +run_cmake(cmake_command_eval_no_parameters) +run_cmake(cmake_command_eval_variable_outside_message) diff --git a/Tests/RunCMake/cmake_command/cmake_command_eval_message-stderr.txt b/Tests/RunCMake/cmake_command/cmake_command_eval_message-stderr.txt new file mode 100644 index 0000000..cfc8694 --- /dev/null +++ b/Tests/RunCMake/cmake_command/cmake_command_eval_message-stderr.txt @@ -0,0 +1 @@ +WORKS! diff --git a/Tests/RunCMake/cmake_command/cmake_command_eval_message.cmake b/Tests/RunCMake/cmake_command/cmake_command_eval_message.cmake new file mode 100644 index 0000000..9ef5e25 --- /dev/null +++ b/Tests/RunCMake/cmake_command/cmake_command_eval_message.cmake @@ -0,0 +1 @@ +cmake_command(EVAL CODE message(WORKS!)) diff --git a/Tests/RunCMake/cmake_command/cmake_command_eval_message_fatal_error-result.txt b/Tests/RunCMake/cmake_command/cmake_command_eval_message_fatal_error-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/cmake_command/cmake_command_eval_message_fatal_error-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/cmake_command/cmake_command_eval_message_fatal_error-stderr.txt b/Tests/RunCMake/cmake_command/cmake_command_eval_message_fatal_error-stderr.txt new file mode 100644 index 0000000..6a8a124 --- /dev/null +++ b/Tests/RunCMake/cmake_command/cmake_command_eval_message_fatal_error-stderr.txt @@ -0,0 +1,5 @@ +CMake Error at cmake_command_eval_message_fatal_error.cmake:1:EVAL:2 \(message\): + error! +Call Stack \(most recent call first\): + cmake_command_eval_message_fatal_error.cmake:1 \(cmake_command\) + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/cmake_command/cmake_command_eval_message_fatal_error.cmake b/Tests/RunCMake/cmake_command/cmake_command_eval_message_fatal_error.cmake new file mode 100644 index 0000000..22913de --- /dev/null +++ b/Tests/RunCMake/cmake_command/cmake_command_eval_message_fatal_error.cmake @@ -0,0 +1,5 @@ +cmake_command(EVAL CODE +" + message(FATAL_ERROR error!) +" +) diff --git a/Tests/RunCMake/cmake_command/cmake_command_eval_no_code-result.txt b/Tests/RunCMake/cmake_command/cmake_command_eval_no_code-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/cmake_command/cmake_command_eval_no_code-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/cmake_command/cmake_command_eval_no_code-stderr.txt b/Tests/RunCMake/cmake_command/cmake_command_eval_no_code-stderr.txt new file mode 100644 index 0000000..ee53312 --- /dev/null +++ b/Tests/RunCMake/cmake_command/cmake_command_eval_no_code-stderr.txt @@ -0,0 +1,2 @@ +CMake Error at cmake_command_eval_no_code.cmake:1 \(cmake_command\): + cmake_command called without CODE argument diff --git a/Tests/RunCMake/cmake_command/cmake_command_eval_no_code.cmake b/Tests/RunCMake/cmake_command/cmake_command_eval_no_code.cmake new file mode 100644 index 0000000..22e1667 --- /dev/null +++ b/Tests/RunCMake/cmake_command/cmake_command_eval_no_code.cmake @@ -0,0 +1 @@ +cmake_command(EVAL message "too many parameters") diff --git a/Tests/RunCMake/cmake_command/cmake_command_eval_no_parameters-result.txt b/Tests/RunCMake/cmake_command/cmake_command_eval_no_parameters-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/cmake_command/cmake_command_eval_no_parameters-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/cmake_command/cmake_command_eval_no_parameters-stderr.txt b/Tests/RunCMake/cmake_command/cmake_command_eval_no_parameters-stderr.txt new file mode 100644 index 0000000..e9fc317 --- /dev/null +++ b/Tests/RunCMake/cmake_command/cmake_command_eval_no_parameters-stderr.txt @@ -0,0 +1,2 @@ +CMake Error at cmake_command_eval_no_parameters.cmake:1 \(cmake_command\): + cmake_command called with incorrect number of arguments diff --git a/Tests/RunCMake/cmake_command/cmake_command_eval_no_parameters.cmake b/Tests/RunCMake/cmake_command/cmake_command_eval_no_parameters.cmake new file mode 100644 index 0000000..a5ba2c7 --- /dev/null +++ b/Tests/RunCMake/cmake_command/cmake_command_eval_no_parameters.cmake @@ -0,0 +1 @@ +cmake_command(EVAL) diff --git a/Tests/RunCMake/cmake_command/cmake_command_eval_variable_outside_message-stderr.txt b/Tests/RunCMake/cmake_command/cmake_command_eval_variable_outside_message-stderr.txt new file mode 100644 index 0000000..cfc8694 --- /dev/null +++ b/Tests/RunCMake/cmake_command/cmake_command_eval_variable_outside_message-stderr.txt @@ -0,0 +1 @@ +WORKS! diff --git a/Tests/RunCMake/cmake_command/cmake_command_eval_variable_outside_message.cmake b/Tests/RunCMake/cmake_command/cmake_command_eval_variable_outside_message.cmake new file mode 100644 index 0000000..b7a06a5 --- /dev/null +++ b/Tests/RunCMake/cmake_command/cmake_command_eval_variable_outside_message.cmake @@ -0,0 +1,2 @@ +cmake_command(EVAL CODE "set(phrase \"WORKS!\")") +message(${phrase}) diff --git a/Tests/RunCMake/foreach/RunCMakeTest.cmake b/Tests/RunCMake/foreach/RunCMakeTest.cmake index 8f50203..22a0a75 100644 --- a/Tests/RunCMake/foreach/RunCMakeTest.cmake +++ b/Tests/RunCMake/foreach/RunCMakeTest.cmake @@ -12,3 +12,10 @@ run_cmake(foreach-ZIP_LISTS-with-LISTS-mix-test) run_cmake(foreach-ZIP_LISTS-multiple-iter-vars-test) run_cmake(foreach-ZIP_LISTS-iter-vars-mismatch-test-1) run_cmake(foreach-ZIP_LISTS-iter-vars-mismatch-test-2) +run_cmake(foreach-RANGE-non-int-test-1) +run_cmake(foreach-RANGE-non-int-test-2-1) +run_cmake(foreach-RANGE-non-int-test-2-2) +run_cmake(foreach-RANGE-non-int-test-3-1) +run_cmake(foreach-RANGE-non-int-test-3-2) +run_cmake(foreach-RANGE-non-int-test-3-3) +run_cmake(foreach-RANGE-invalid-test) diff --git a/Tests/RunCMake/foreach/foreach-RANGE-invalid-test-result.txt b/Tests/RunCMake/foreach/foreach-RANGE-invalid-test-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-RANGE-invalid-test-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/foreach/foreach-RANGE-invalid-test-stderr.txt b/Tests/RunCMake/foreach/foreach-RANGE-invalid-test-stderr.txt new file mode 100644 index 0000000..66efdc1 --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-RANGE-invalid-test-stderr.txt @@ -0,0 +1,4 @@ +^CMake Error at foreach-RANGE-invalid-test\.cmake:[0-9]+ \(foreach\): + foreach called with incorrect range specification: start 2, stop 1, step 1 +Call Stack \(most recent call first\): + CMakeLists\.txt:3 \(include\)$ diff --git a/Tests/RunCMake/foreach/foreach-RANGE-invalid-test.cmake b/Tests/RunCMake/foreach/foreach-RANGE-invalid-test.cmake new file mode 100644 index 0000000..2f8eaba --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-RANGE-invalid-test.cmake @@ -0,0 +1,2 @@ +foreach(a RANGE 2 1 1) +endforeach() diff --git a/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-1-result.txt b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-1-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-1-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-1-stderr.txt b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-1-stderr.txt new file mode 100644 index 0000000..78355dc --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-1-stderr.txt @@ -0,0 +1,4 @@ +^CMake Error at foreach-RANGE-non-int-test-1\.cmake:[0-9]+ \(foreach\): + foreach Invalid integer: 'b' +Call Stack \(most recent call first\): + CMakeLists\.txt:3 \(include\)$ diff --git a/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-1.cmake b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-1.cmake new file mode 100644 index 0000000..452fbdf --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-1.cmake @@ -0,0 +1,2 @@ +foreach(a RANGE b) +endforeach() diff --git a/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-1-result.txt b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-1-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-1-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-1-stderr.txt b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-1-stderr.txt new file mode 100644 index 0000000..787ffc1 --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-1-stderr.txt @@ -0,0 +1,4 @@ +^CMake Error at foreach-RANGE-non-int-test-2-1\.cmake:[0-9]+ \(foreach\): + foreach Invalid integer: 'b' +Call Stack \(most recent call first\): + CMakeLists\.txt:3 \(include\)$ diff --git a/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-1.cmake b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-1.cmake new file mode 100644 index 0000000..885c805 --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-1.cmake @@ -0,0 +1,2 @@ +foreach(a RANGE b 1) +endforeach() diff --git a/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-2-result.txt b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-2-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-2-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-2-stderr.txt b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-2-stderr.txt new file mode 100644 index 0000000..70cc73f --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-2-stderr.txt @@ -0,0 +1,4 @@ +^CMake Error at foreach-RANGE-non-int-test-2-2\.cmake:[0-9]+ \(foreach\): + foreach Invalid integer: 'b' +Call Stack \(most recent call first\): + CMakeLists\.txt:3 \(include\)$ diff --git a/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-2.cmake b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-2.cmake new file mode 100644 index 0000000..d52aeb9 --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-2.cmake @@ -0,0 +1,2 @@ +foreach(a RANGE 1 b) +endforeach() diff --git a/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-1-result.txt b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-1-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-1-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-1-stderr.txt b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-1-stderr.txt new file mode 100644 index 0000000..5803fe8 --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-1-stderr.txt @@ -0,0 +1,4 @@ +^CMake Error at foreach-RANGE-non-int-test-3-1\.cmake:[0-9]+ \(foreach\): + foreach Invalid integer: 'b' +Call Stack \(most recent call first\): + CMakeLists\.txt:3 \(include\)$ diff --git a/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-1.cmake b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-1.cmake new file mode 100644 index 0000000..33a488d --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-1.cmake @@ -0,0 +1,2 @@ +foreach(a RANGE b 1 1) +endforeach() diff --git a/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-2-result.txt b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-2-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-2-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-2-stderr.txt b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-2-stderr.txt new file mode 100644 index 0000000..189c60d --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-2-stderr.txt @@ -0,0 +1,4 @@ +^CMake Error at foreach-RANGE-non-int-test-3-2\.cmake:[0-9]+ \(foreach\): + foreach Invalid integer: 'b' +Call Stack \(most recent call first\): + CMakeLists\.txt:3 \(include\)$ diff --git a/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-2.cmake b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-2.cmake new file mode 100644 index 0000000..ff119d3 --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-2.cmake @@ -0,0 +1,2 @@ +foreach(a RANGE 1 b 1) +endforeach() diff --git a/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-3-result.txt b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-3-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-3-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-3-stderr.txt b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-3-stderr.txt new file mode 100644 index 0000000..ee9e62c --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-3-stderr.txt @@ -0,0 +1,4 @@ +^CMake Error at foreach-RANGE-non-int-test-3-3\.cmake:[0-9]+ \(foreach\): + foreach Invalid integer: 'b' +Call Stack \(most recent call first\): + CMakeLists\.txt:3 \(include\)$ diff --git a/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-3.cmake b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-3.cmake new file mode 100644 index 0000000..fdebdf0 --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-3.cmake @@ -0,0 +1,2 @@ +foreach(a RANGE 1 1 b) +endforeach() diff --git a/Utilities/Scripts/update-librhash.bash b/Utilities/Scripts/update-librhash.bash index 009ce32..ea7e655 100755 --- a/Utilities/Scripts/update-librhash.bash +++ b/Utilities/Scripts/update-librhash.bash @@ -8,11 +8,10 @@ readonly name="librhash" readonly ownership="librhash upstream <kwrobot@kitware.com>" readonly subtree="Utilities/cmlibrhash" readonly repo="https://github.com/rhash/rhash.git" -readonly tag="master" +readonly tag="v1.3.9" readonly shortlog=false readonly paths=" COPYING - README librhash/algorithms.c librhash/algorithms.h librhash/byte_order.c diff --git a/Utilities/cmlibrhash/CMakeLists.txt b/Utilities/cmlibrhash/CMakeLists.txt index 6067b7d..1b025fc 100644 --- a/Utilities/cmlibrhash/CMakeLists.txt +++ b/Utilities/cmlibrhash/CMakeLists.txt @@ -37,4 +37,4 @@ include_directories( add_library(cmlibrhash ${librhash_sources}) -install(FILES COPYING README DESTINATION ${CMAKE_DOC_DIR}/cmlibrhash) +install(FILES COPYING DESTINATION ${CMAKE_DOC_DIR}/cmlibrhash) diff --git a/Utilities/cmlibrhash/COPYING b/Utilities/cmlibrhash/COPYING index bf65ee1..be7d4a9 100644 --- a/Utilities/cmlibrhash/COPYING +++ b/Utilities/cmlibrhash/COPYING @@ -1,15 +1,15 @@ - RHash License + BSD Zero Clause License -Copyright (c) 2005-2014 Aleksey Kravchenko <rhash.admin@gmail.com> +Copyright (c) 2005, Aleksey Kravchenko <rhash.admin@gmail.com> -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. +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. -The Software 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. Use this program at your own risk! +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. diff --git a/Utilities/cmlibrhash/README b/Utilities/cmlibrhash/README deleted file mode 100644 index 4ea492f..0000000 --- a/Utilities/cmlibrhash/README +++ /dev/null @@ -1,7 +0,0 @@ - === Notes on RHash License === - -The RHash program and LibRHash library are distributed under RHash License, -see the COPYING file for details. In particular, the program, the library -and source code can be used free of charge under the MIT, BSD, GPL, -commercial or freeware license without additional restrictions. In the case -the OSI-approved license is required the MIT license should be used. diff --git a/Utilities/cmlibrhash/librhash/algorithms.c b/Utilities/cmlibrhash/librhash/algorithms.c index fc01690..cdd4053 100644 --- a/Utilities/cmlibrhash/librhash/algorithms.c +++ b/Utilities/cmlibrhash/librhash/algorithms.c @@ -1,17 +1,17 @@ /* algorithms.c - the algorithms supported by the rhash library * - * Copyright: 2011-2012 Aleksey Kravchenko <rhash.admin@gmail.com> + * Copyright (c) 2011, Aleksey Kravchenko <rhash.admin@gmail.com> * - * 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. + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted. * - * 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. Use this program at your own risk! + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. */ #include <stdio.h> @@ -27,7 +27,8 @@ #include "crc32.h" #include "ed2k.h" #include "edonr.h" -#include "gost.h" +#include "gost12.h" +#include "gost94.h" #include "has160.h" #include "md4.h" #endif @@ -54,18 +55,13 @@ #else # define NEED_OPENSSL_INIT 0 #endif /* USE_OPENSSL */ -#ifdef GENERATE_GOST_LOOKUP_TABLE -# define NEED_GOST_INIT (RHASH_GOST | RHASH_GOST_CRYPTOPRO) +#ifdef GENERATE_GOST94_LOOKUP_TABLE +# define NEED_GOST94_INIT (RHASH_GOST94 | RHASH_GOST94_CRYPTOPRO) #else -# define NEED_GOST_INIT 0 -#endif /* GENERATE_GOST_LOOKUP_TABLE */ -#ifdef GENERATE_CRC32_TABLE -# define NEED_CRC32_INIT RHASH_CRC32 -#else -# define NEED_CRC32_INIT 0 -#endif /* GENERATE_CRC32_TABLE */ +# define NEED_GOST94_INIT 0 +#endif /* GENERATE_GOST94_LOOKUP_TABLE */ -#define RHASH_NEED_INIT_ALG (NEED_CRC32_INIT | NEED_GOST_INIT | NEED_OPENSSL_INIT) +#define RHASH_NEED_INIT_ALG (NEED_GOST94_INIT | NEED_OPENSSL_INIT) unsigned rhash_uninitialized_algorithms = RHASH_NEED_INIT_ALG; rhash_hash_info* rhash_info_table = rhash_hash_info_default; @@ -75,10 +71,14 @@ int rhash_info_size = RHASH_HASH_COUNT; static void rhash_crc32_init(uint32_t* crc32); static void rhash_crc32_update(uint32_t* crc32, const unsigned char* msg, size_t size); static void rhash_crc32_final(uint32_t* crc32, unsigned char* result); +static void rhash_crc32c_init(uint32_t* crc32); +static void rhash_crc32c_update(uint32_t* crc32, const unsigned char* msg, size_t size); +static void rhash_crc32c_final(uint32_t* crc32, unsigned char* result); #endif #if 0 -rhash_info info_crc32 = { RHASH_CRC32, F_BE32, 4, "CRC32", "crc32" }; +rhash_info info_crc32 = { RHASH_CRC32, F_BE32, 4, "CRC32", "crc32" }; +rhash_info info_crc32c = { RHASH_CRC32C, F_BE32, 4, "CRC32C", "crc32c" }; rhash_info info_md4 = { RHASH_MD4, F_LE32, 16, "MD4", "md4" }; #endif rhash_info info_md5 = { RHASH_MD5, F_LE32, 16, "MD5", "md5" }; @@ -91,8 +91,10 @@ rhash_info info_ed2k = { RHASH_ED2K, F_LE32, 16, "ED2K", "ed2k" }; rhash_info info_aich = { RHASH_AICH, F_BS32, 20, "AICH", "aich" }; rhash_info info_whirlpool = { RHASH_WHIRLPOOL, F_BE64, 64, "WHIRLPOOL", "whirlpool" }; rhash_info info_rmd160 = { RHASH_RIPEMD160, F_LE32, 20, "RIPEMD-160", "ripemd160" }; -rhash_info info_gost = { RHASH_GOST, F_LE32, 32, "GOST", "gost" }; -rhash_info info_gostpro = { RHASH_GOST_CRYPTOPRO, F_LE32, 32, "GOST-CRYPTOPRO", "gost-cryptopro" }; +rhash_info info_gost12_256 = { RHASH_GOST12_256, F_LE64, 32, "GOST12-256", "gost12-256" }; +rhash_info info_gost12_512 = { RHASH_GOST12_512, F_LE64, 64, "GOST12-512", "gost12-512" }; +rhash_info info_gost94 = { RHASH_GOST94, F_LE32, 32, "GOST94", "gost94" }; +rhash_info info_gost94pro = { RHASH_GOST94_CRYPTOPRO, F_LE32, 32, "GOST94-CRYPTOPRO", "gost94-cryptopro" }; rhash_info info_has160 = { RHASH_HAS160, F_LE32, 20, "HAS-160", "has160" }; rhash_info info_snf128 = { RHASH_SNEFRU128, F_BE32, 16, "SNEFRU-128", "snefru128" }; rhash_info info_snf256 = { RHASH_SNEFRU256, F_BE32, 32, "SNEFRU-256", "snefru256" }; @@ -117,9 +119,10 @@ rhash_info info_sha3_512 = { RHASH_SHA3_512, F_LE64, 64, "SHA3-512", "sha3-512" #define upd(name) ((pupdate_t)(name##_update)) #define fin(name) ((pfinal_t)(name##_final)) #define iuf(name) ini(name), upd(name), fin(name) +#define iuf2(name1, name2) ini(name1), upd(name2), fin(name2) #define diuf(name) dgshft(name), ini(name), upd(name), fin(name) -/* information about all hashes */ +/* information about all supported hash functions */ rhash_hash_info rhash_hash_info_default[RHASH_HASH_COUNT] = { #if 0 @@ -135,28 +138,35 @@ rhash_hash_info rhash_hash_info_default[RHASH_HASH_COUNT] = { &info_aich, sizeof(aich_ctx), dgshft2(aich, sha1_context.hash), iuf(rhash_aich), (pcleanup_t)rhash_aich_cleanup }, /* 160 bit */ { &info_whirlpool, sizeof(whirlpool_ctx), dgshft(whirlpool), iuf(rhash_whirlpool), 0 }, /* 512 bit */ { &info_rmd160, sizeof(ripemd160_ctx), dgshft(ripemd160), iuf(rhash_ripemd160), 0 }, /* 160 bit */ - { &info_gost, sizeof(gost_ctx), dgshft(gost), iuf(rhash_gost), 0 }, /* 256 bit */ - { &info_gostpro, sizeof(gost_ctx), dgshft(gost), ini(rhash_gost_cryptopro), upd(rhash_gost), fin(rhash_gost), 0 }, /* 256 bit */ + { &info_gost94, sizeof(gost94_ctx), dgshft(gost94), iuf(rhash_gost94), 0 }, /* 256 bit */ + { &info_gost94pro, sizeof(gost94_ctx), dgshft(gost94), iuf2(rhash_gost94_cryptopro, rhash_gost94), 0 }, /* 256 bit */ { &info_has160, sizeof(has160_ctx), dgshft(has160), iuf(rhash_has160), 0 }, /* 160 bit */ - { &info_snf128, sizeof(snefru_ctx), dgshft(snefru), ini(rhash_snefru128), upd(rhash_snefru), fin(rhash_snefru), 0 }, /* 128 bit */ - { &info_snf256, sizeof(snefru_ctx), dgshft(snefru), ini(rhash_snefru256), upd(rhash_snefru), fin(rhash_snefru), 0 }, /* 256 bit */ + { &info_gost12_256, sizeof(gost12_ctx), dgshft2(gost12, h) + 32, iuf2(rhash_gost12_256, rhash_gost12), 0 }, /* 256 bit */ + { &info_gost12_512, sizeof(gost12_ctx), dgshft2(gost12, h), iuf2(rhash_gost12_512, rhash_gost12), 0 }, /* 512 bit */ #endif - { &info_sha224, sizeof(sha256_ctx), dgshft(sha256), ini(rhash_sha224), upd(rhash_sha256), fin(rhash_sha256), 0 }, /* 224 bit */ + { &info_sha224, sizeof(sha256_ctx), dgshft(sha256), iuf2(rhash_sha224, rhash_sha256), 0 }, /* 224 bit */ { &info_sha256, sizeof(sha256_ctx), dgshft(sha256), iuf(rhash_sha256), 0 }, /* 256 bit */ - { &info_sha384, sizeof(sha512_ctx), dgshft(sha512), ini(rhash_sha384), upd(rhash_sha512), fin(rhash_sha512), 0 }, /* 384 bit */ + { &info_sha384, sizeof(sha512_ctx), dgshft(sha512), iuf2(rhash_sha384, rhash_sha512), 0 }, /* 384 bit */ { &info_sha512, sizeof(sha512_ctx), dgshft(sha512), iuf(rhash_sha512), 0 }, /* 512 bit */ #if 0 - { &info_edr256, sizeof(edonr_ctx), dgshft2(edonr, u.data256.hash) + 32, iuf(rhash_edonr256), 0 }, /* 256 bit */ - { &info_edr512, sizeof(edonr_ctx), dgshft2(edonr, u.data512.hash) + 64, iuf(rhash_edonr512), 0 }, /* 512 bit */ + { &info_edr256, sizeof(edonr_ctx), dgshft2(edonr, u.data256.hash) + 32, iuf(rhash_edonr256), 0 }, /* 256 bit */ + { &info_edr512, sizeof(edonr_ctx), dgshft2(edonr, u.data512.hash) + 64, iuf(rhash_edonr512), 0 }, /* 512 bit */ +#endif + { &info_sha3_224, sizeof(sha3_ctx), dgshft(sha3), iuf2(rhash_sha3_224, rhash_sha3), 0 }, /* 224 bit */ + { &info_sha3_256, sizeof(sha3_ctx), dgshft(sha3), iuf2(rhash_sha3_256, rhash_sha3), 0 }, /* 256 bit */ + { &info_sha3_384, sizeof(sha3_ctx), dgshft(sha3), iuf2(rhash_sha3_384, rhash_sha3), 0 }, /* 384 bit */ + { &info_sha3_512, sizeof(sha3_ctx), dgshft(sha3), iuf2(rhash_sha3_512, rhash_sha3), 0 }, /* 512 bit */ +#if 0 + { &info_crc32c, sizeof(uint32_t), 0, iuf(rhash_crc32c), 0 }, /* 32 bit */ + { &info_snf128, sizeof(snefru_ctx), dgshft(snefru), iuf2(rhash_snefru128, rhash_snefru), 0 }, /* 128 bit */ + { &info_snf256, sizeof(snefru_ctx), dgshft(snefru), iuf2(rhash_snefru256, rhash_snefru), 0 }, /* 256 bit */ #endif - { &info_sha3_224, sizeof(sha3_ctx), dgshft(sha3), ini(rhash_sha3_224), upd(rhash_sha3), fin(rhash_sha3), 0 }, /* 224 bit */ - { &info_sha3_256, sizeof(sha3_ctx), dgshft(sha3), ini(rhash_sha3_256), upd(rhash_sha3), fin(rhash_sha3), 0 }, /* 256 bit */ - { &info_sha3_384, sizeof(sha3_ctx), dgshft(sha3), ini(rhash_sha3_384), upd(rhash_sha3), fin(rhash_sha3), 0 }, /* 384 bit */ - { &info_sha3_512, sizeof(sha3_ctx), dgshft(sha3), ini(rhash_sha3_512), upd(rhash_sha3), fin(rhash_sha3), 0 }, /* 512 bit */ }; /** * Initialize requested algorithms. + * + * @param mask ids of hash sums to initialize */ void rhash_init_algorithms(unsigned mask) { @@ -165,15 +175,26 @@ void rhash_init_algorithms(unsigned mask) /* verify that RHASH_HASH_COUNT is the index of the major bit of RHASH_ALL_HASHES */ assert(1 == (RHASH_ALL_HASHES >> (RHASH_HASH_COUNT - 1))); -#ifdef GENERATE_CRC32_TABLE - rhash_crc32_init_table(); -#endif -#ifdef GENERATE_GOST_LOOKUP_TABLE - rhash_gost_init_table(); +#ifdef GENERATE_GOST94_LOOKUP_TABLE + rhash_gost94_init_table(); #endif rhash_uninitialized_algorithms = 0; } +/** + * Returns information about a hash function by its hash_id. + * + * @param hash_id the id of hash algorithm + * @return pointer to the rhash_info structure containing the information + */ +const rhash_info* rhash_info_by_id(unsigned hash_id) +{ + hash_id &= RHASH_ALL_HASHES; + /* check that one and only one bit is set */ + if (!hash_id || (hash_id & (hash_id - 1)) != 0) return NULL; + return rhash_info_table[rhash_ctz(hash_id)].info; +} + #if 0 /* CRC32 helper functions */ @@ -217,4 +238,45 @@ static void rhash_crc32_final(uint32_t* crc32, unsigned char* result) result[2] = (unsigned char)(*crc32 >> 8), result[3] = (unsigned char)(*crc32); #endif } + +/** + * Initialize crc32c hash. + * + * @param crc32c pointer to the hash to initialize + */ +static void rhash_crc32c_init(uint32_t* crc32c) +{ + *crc32c = 0; /* note: context size is sizeof(uint32_t) */ +} + +/** + * Calculate message CRC32C hash. + * Can be called repeatedly with chunks of the message to be hashed. + * + * @param crc32c pointer to the hash + * @param msg message chunk + * @param size length of the message chunk + */ +static void rhash_crc32c_update(uint32_t* crc32c, const unsigned char* msg, size_t size) +{ + *crc32c = rhash_get_crc32c(*crc32c, msg, size); +} + +/** + * Store calculated hash into the given array. + * + * @param crc32c pointer to the current hash value + * @param result calculated hash in binary form + */ +static void rhash_crc32c_final(uint32_t* crc32c, unsigned char* result) +{ +#if defined(CPU_IA32) || defined(CPU_X64) + /* intel CPUs support assigment with non 32-bit aligned pointers */ + *(unsigned*)result = be2me_32(*crc32c); +#else + /* correct saving BigEndian integer on all archs */ + result[0] = (unsigned char)(*crc32c >> 24), result[1] = (unsigned char)(*crc32c >> 16); + result[2] = (unsigned char)(*crc32c >> 8), result[3] = (unsigned char)(*crc32c); +#endif +} #endif diff --git a/Utilities/cmlibrhash/librhash/algorithms.h b/Utilities/cmlibrhash/librhash/algorithms.h index 4db2517..01dda88 100644 --- a/Utilities/cmlibrhash/librhash/algorithms.h +++ b/Utilities/cmlibrhash/librhash/algorithms.h @@ -2,9 +2,9 @@ #ifndef RHASH_ALGORITHMS_H #define RHASH_ALGORITHMS_H -#include <stddef.h> /* for ptrdiff_t */ #include "rhash.h" #include "byte_order.h" +#include <stddef.h> #ifdef __cplusplus extern "C" { @@ -15,8 +15,40 @@ extern "C" { # define RHASH_API #endif +/** + * Bit flag: default hash output format is base32. + */ +#define RHASH_INFO_BASE32 1 + +/** + * Information about a hash function. + */ +typedef struct rhash_info +{ + /** + * Hash function indentifier. + */ + unsigned hash_id; + /** + * Flags bit-mask, including RHASH_INFO_BASE32 bit. + */ + unsigned flags; + /** + The size of of the raw message digest in bytes. + */ + size_t digest_size; + /** + * The hash function name. + */ + const char* name; + /** + * The corresponding paramenter name in a magnet link. + */ + const char* magnet_name; +} rhash_info; + typedef void (*pinit_t)(void*); -typedef void (*pupdate_t)(void *ctx, const void* msg, size_t size); +typedef void (*pupdate_t)(void* ctx, const void* msg, size_t size); typedef void (*pfinal_t)(void*, unsigned char*); typedef void (*pcleanup_t)(void*); @@ -25,7 +57,7 @@ typedef void (*pcleanup_t)(void*); */ typedef struct rhash_hash_info { - rhash_info *info; + rhash_info* info; size_t context_size; ptrdiff_t digest_diff; pinit_t init; @@ -40,7 +72,7 @@ typedef struct rhash_hash_info typedef struct rhash_vector_item { struct rhash_hash_info* hash_info; - void *context; + void* context; } rhash_vector_item; /** @@ -52,8 +84,9 @@ typedef struct rhash_context_ext unsigned hash_vector_size; /* number of contained hash sums */ unsigned flags; unsigned state; - void *callback, *callback_data; - void *bt_ctx; + void* callback; + void* callback_data; + void* bt_ctx; rhash_vector_item vector[1]; /* contexts of contained hash sums */ } rhash_context_ext; @@ -63,6 +96,7 @@ extern int rhash_info_size; extern unsigned rhash_uninitialized_algorithms; extern rhash_info info_crc32; +extern rhash_info info_crc32c; extern rhash_info info_md4; extern rhash_info info_md5; extern rhash_info info_sha1; @@ -95,7 +129,7 @@ extern rhash_info info_edr512; #define F_SWAP64 4 /* define endianness flags */ -#ifndef CPU_BIG_ENDIAN +#if IS_LITTLE_ENDIAN #define F_LE32 0 #define F_LE64 0 #define F_BE32 F_SWAP32 @@ -108,6 +142,7 @@ extern rhash_info info_edr512; #endif void rhash_init_algorithms(unsigned mask); +const rhash_info* rhash_info_by_id(unsigned hash_id); /* get hash sum info by hash id */ #if defined(OPENSSL_RUNTIME) && !defined(USE_OPENSSL) # define USE_OPENSSL diff --git a/Utilities/cmlibrhash/librhash/byte_order.c b/Utilities/cmlibrhash/librhash/byte_order.c index 8ce6fc8..de2c583 100644 --- a/Utilities/cmlibrhash/librhash/byte_order.c +++ b/Utilities/cmlibrhash/librhash/byte_order.c @@ -1,21 +1,21 @@ /* byte_order.c - byte order related platform dependent routines, * - * Copyright: 2008-2012 Aleksey Kravchenko <rhash.admin@gmail.com> + * Copyright (c) 2008, Aleksey Kravchenko <rhash.admin@gmail.com> * - * 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. + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted. * - * 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. Use this program at your own risk! + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. */ #include "byte_order.h" -#if !(__GNUC__ >= 4 || (__GNUC__ ==3 && __GNUC_MINOR__ >= 4)) /* if !GCC or GCC < 4.3 */ +#ifndef rhash_ctz # if _MSC_VER >= 1300 && (_M_IX86 || _M_AMD64 || _M_IA64) /* if MSVC++ >= 2002 on x86/x64 */ # include <intrin.h> @@ -59,7 +59,7 @@ unsigned rhash_ctz(unsigned x) return (unsigned)bit_pos[((uint32_t)((x & -x) * 0x077CB531U)) >> 27]; } # endif /* _MSC_VER >= 1300... */ -#endif /* !(GCC >= 4.3) */ +#endif /* rhash_ctz */ /** * Copy a memory block with simultaneous exchanging byte order. @@ -79,10 +79,12 @@ void rhash_swap_copy_str_to_u32(void* to, int index, const void* from, size_t le const uint32_t* src = (const uint32_t*)from; const uint32_t* end = (const uint32_t*)((const char*)src + length); uint32_t* dst = (uint32_t*)((char*)to + index); - while (src < end) *(dst++) = bswap_32( *(src++) ); + for (; src < end; dst++, src++) + *dst = bswap_32(*src); } else { const char* src = (const char*)from; - for (length += index; (size_t)index < length; index++) ((char*)to)[index ^ 3] = *(src++); + for (length += index; (size_t)index < length; index++) + ((char*)to)[index ^ 3] = *(src++); } } @@ -141,10 +143,31 @@ void rhash_swap_copy_u64_to_str(void* to, const void* from, size_t length) * @param arr the array to process * @param length array length */ -void rhash_u32_mem_swap(unsigned *arr, int length) +void rhash_u32_mem_swap(unsigned* arr, int length) { unsigned* end = arr + length; for (; arr < end; arr++) { *arr = bswap_32(*arr); } } + +#ifdef HAS_INTEL_CPUID +#include <cpuid.h> + +static uint64_t get_cpuid_features(void) +{ + uint32_t tmp, edx, ecx; + if (__get_cpuid(1, &tmp, &tmp, &ecx, &edx)) + return ((((uint64_t)ecx) << 32) ^ edx); + return 0; +} + +int has_cpu_feature(unsigned feature_bit) +{ + static uint64_t features; + const uint64_t feature = ((uint64_t)1) << feature_bit; + if (!features) + features = (get_cpuid_features() | 1); + return !!(features & feature); +} +#endif diff --git a/Utilities/cmlibrhash/librhash/byte_order.h b/Utilities/cmlibrhash/librhash/byte_order.h index d34a020..a58174b 100644 --- a/Utilities/cmlibrhash/librhash/byte_order.h +++ b/Utilities/cmlibrhash/librhash/byte_order.h @@ -4,6 +4,19 @@ #include "ustd.h" #include <stdlib.h> +#if 0 +#if defined(__GLIBC__) +# include <endian.h> +#endif +#endif + +#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__) +# include <sys/types.h> +#elif defined (__NetBSD__) || defined(__OpenBSD__) +# include <sys/param.h> +#endif + + #ifdef __cplusplus extern "C" { #endif @@ -26,8 +39,6 @@ extern "C" { # endif #endif - -/* detect CPU endianness */ #include <cm_kwiml.h> #if KWIML_ABI_ENDIAN_ID == KWIML_ABI_ENDIAN_ID_LITTLE # define CPU_LITTLE_ENDIAN @@ -37,8 +48,53 @@ extern "C" { # define CPU_BIG_ENDIAN # define IS_BIG_ENDIAN 1 # define IS_LITTLE_ENDIAN 0 +#endif + +#if 0 +#define RHASH_BYTE_ORDER_LE 1234 +#define RHASH_BYTE_ORDER_BE 4321 + +#if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && __BYTE_ORDER == __LITTLE_ENDIAN) || \ + (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) +# define RHASH_BYTE_ORDER RHASH_BYTE_ORDER_LE +#elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && __BYTE_ORDER == __BIG_ENDIAN) || \ + (defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) +# define RHASH_BYTE_ORDER RHASH_BYTE_ORDER_BE +#elif defined(_BYTE_ORDER) +# if defined(_LITTLE_ENDIAN) && (_BYTE_ORDER == _LITTLE_ENDIAN) +# define RHASH_BYTE_ORDER RHASH_BYTE_ORDER_LE +# elif defined(_BIG_ENDIAN) && (_BYTE_ORDER == _BIG_ENDIAN) +# define RHASH_BYTE_ORDER RHASH_BYTE_ORDER_BE +# endif +#elif defined(__sun) && defined(_LITTLE_ENDIAN) +# define RHASH_BYTE_ORDER RHASH_BYTE_ORDER_LE +#elif defined(__sun) && defined(_BIG_ENDIAN) +# define RHASH_BYTE_ORDER RHASH_BYTE_ORDER_BE +#endif + +/* try detecting endianness by CPU */ +#ifdef RHASH_BYTE_ORDER +#elif defined(CPU_IA32) || defined(CPU_X64) || defined(__ia64) || defined(__ia64__) || \ + defined(__alpha__) || defined(_M_ALPHA) || defined(vax) || defined(MIPSEL) || \ + defined(_ARM_) || defined(__arm__) +# define RHASH_BYTE_ORDER RHASH_BYTE_ORDER_LE +#elif defined(__sparc) || defined(__sparc__) || defined(sparc) || \ + defined(_ARCH_PPC) || defined(_ARCH_PPC64) || defined(_POWER) || \ + defined(__POWERPC__) || defined(POWERPC) || defined(__powerpc) || \ + defined(__powerpc__) || defined(__powerpc64__) || defined(__ppc__) || \ + defined(__hpux) || defined(_MIPSEB) || defined(mc68000) || \ + defined(__s390__) || defined(__s390x__) || defined(sel) +# define RHASH_BYTE_ORDER RHASH_BYTE_ORDER_BE #else -# error "Can't detect CPU architechture" +# error "Can't detect CPU architechture" +#endif + +#define IS_BIG_ENDIAN (RHASH_BYTE_ORDER == RHASH_BYTE_ORDER_BE) +#define IS_LITTLE_ENDIAN (RHASH_BYTE_ORDER == RHASH_BYTE_ORDER_LE) +#endif + +#ifndef __has_builtin +# define __has_builtin(x) 0 #endif #define IS_ALIGNED_32(p) (0 == (3 & ((const char*)(p) - (const char*)0))) @@ -56,11 +112,23 @@ extern "C" { #if defined(_MSC_VER) || defined(__BORLANDC__) #define I64(x) x##ui64 #else -#define I64(x) x##LL +#define I64(x) x##ULL #endif -/* convert a hash flag to index */ -#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) /* GCC < 3.4 */ +#if defined(_MSC_VER) +#define RHASH_INLINE __inline +#elif defined(__GNUC__) && !defined(__STRICT_ANSI__) +#define RHASH_INLINE inline +#elif defined(__GNUC__) +#define RHASH_INLINE __inline__ +#else +#define RHASH_INLINE +#endif + +/* define rhash_ctz - count traling zero bits */ +#if (defined(__GNUC__) && __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) || \ + (defined(__clang__) && __has_builtin(__builtin_ctz)) +/* GCC >= 3.4 or clang */ # define rhash_ctz(x) __builtin_ctz(x) #else unsigned rhash_ctz(unsigned); /* define as function */ @@ -69,42 +137,31 @@ unsigned rhash_ctz(unsigned); /* define as function */ void rhash_swap_copy_str_to_u32(void* to, int index, const void* from, size_t length); void rhash_swap_copy_str_to_u64(void* to, int index, const void* from, size_t length); void rhash_swap_copy_u64_to_str(void* to, const void* from, size_t length); -void rhash_u32_mem_swap(unsigned *p, int length_in_u32); +void rhash_u32_mem_swap(unsigned* p, int length_in_u32); -#ifndef __has_builtin -# define __has_builtin(x) 0 -#endif - -/* define bswap_32 */ -#if defined(__GNUC__) && defined(CPU_IA32) && !defined(__i386__) -/* for intel x86 CPU */ -static inline uint32_t bswap_32(uint32_t x) { - __asm("bswap\t%0" : "=r" (x) : "0" (x)); - return x; -} -#elif defined(__GNUC__) && (__GNUC__ >= 4) && (__GNUC__ > 4 || __GNUC_MINOR__ >= 3) -/* for GCC >= 4.3 */ -# define bswap_32(x) __builtin_bswap32(x) -#elif defined(__clang__) && __has_builtin(__builtin_bswap32) +/* bswap definitions */ +#if (defined(__GNUC__) && (__GNUC__ >= 4) && (__GNUC__ > 4 || __GNUC_MINOR__ >= 3)) || \ + (defined(__clang__) && __has_builtin(__builtin_bswap32) && __has_builtin(__builtin_bswap64)) +/* GCC >= 4.3 or clang */ # define bswap_32(x) __builtin_bswap32(x) +# define bswap_64(x) __builtin_bswap64(x) #elif (_MSC_VER > 1300) && (defined(CPU_IA32) || defined(CPU_X64)) /* MS VC */ # define bswap_32(x) _byteswap_ulong((unsigned long)x) +# define bswap_64(x) _byteswap_uint64((__int64)x) #else -/* general bswap_32 definition */ -static uint32_t bswap_32(uint32_t x) { - x = ((x << 8) & 0xFF00FF00) | ((x >> 8) & 0x00FF00FF); +/* fallback to generic bswap definition */ +static RHASH_INLINE uint32_t bswap_32(uint32_t x) +{ +# if defined(__GNUC__) && defined(CPU_IA32) && !defined(__i386__) && !defined(RHASH_NO_ASM) + __asm("bswap\t%0" : "=r" (x) : "0" (x)); /* gcc x86 version */ + return x; +# else + x = ((x << 8) & 0xFF00FF00u) | ((x >> 8) & 0x00FF00FFu); return (x >> 16) | (x << 16); +# endif } -#endif /* bswap_32 */ - -#if defined(__GNUC__) && (__GNUC__ >= 4) && (__GNUC__ > 4 || __GNUC_MINOR__ >= 3) -# define bswap_64(x) __builtin_bswap64(x) -#elif defined(__clang__) && __has_builtin(__builtin_bswap64) -# define bswap_64(x) __builtin_bswap64(x) -#elif (_MSC_VER > 1300) && (defined(CPU_IA32) || defined(CPU_X64)) /* MS VC */ -# define bswap_64(x) _byteswap_uint64((__int64)x) -#else -static uint64_t bswap_64(uint64_t x) { +static RHASH_INLINE uint64_t bswap_64(uint64_t x) +{ union { uint64_t ll; uint32_t l[2]; @@ -114,9 +171,9 @@ static uint64_t bswap_64(uint64_t x) { r.l[1] = bswap_32(w.l[0]); return r.ll; } -#endif +#endif /* bswap definitions */ -#ifdef CPU_BIG_ENDIAN +#if IS_BIG_ENDIAN # define be2me_32(x) (x) # define be2me_64(x) (x) # define le2me_32(x) bswap_32(x) @@ -129,7 +186,7 @@ static uint64_t bswap_64(uint64_t x) { # define me64_to_be_str(to, from, length) memcpy((to), (from), (length)) # define me64_to_le_str(to, from, length) rhash_swap_copy_u64_to_str((to), (from), (length)) -#else /* CPU_BIG_ENDIAN */ +#else /* IS_BIG_ENDIAN */ # define be2me_32(x) bswap_32(x) # define be2me_64(x) bswap_64(x) # define le2me_32(x) (x) @@ -141,7 +198,7 @@ static uint64_t bswap_64(uint64_t x) { # define le64_copy(to, index, from, length) memcpy((to) + (index), (from), (length)) # define me64_to_be_str(to, from, length) rhash_swap_copy_u64_to_str((to), (from), (length)) # define me64_to_le_str(to, from, length) memcpy((to), (from), (length)) -#endif /* CPU_BIG_ENDIAN */ +#endif /* IS_BIG_ENDIAN */ /* ROTL/ROTR macros rotate a 32/64-bit word left/right by n bits */ #define ROTL32(dword, n) ((dword) << (n) ^ ((dword) >> (32 - (n)))) @@ -149,6 +206,16 @@ static uint64_t bswap_64(uint64_t x) { #define ROTL64(qword, n) ((qword) << (n) ^ ((qword) >> (64 - (n)))) #define ROTR64(qword, n) ((qword) >> (n) ^ ((qword) << (64 - (n)))) +#define CPU_FEATURE_SSE4_2 (52) + +#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) \ + && (defined(CPU_X64) || defined(CPU_IA32)) +# define HAS_INTEL_CPUID +int has_cpu_feature(unsigned feature_bit); +#else +# define has_cpu_feature(x) (0) +#endif + #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ diff --git a/Utilities/cmlibrhash/librhash/hex.c b/Utilities/cmlibrhash/librhash/hex.c index c941149..f0bbf04 100644 --- a/Utilities/cmlibrhash/librhash/hex.c +++ b/Utilities/cmlibrhash/librhash/hex.c @@ -1,71 +1,57 @@ /* hex.c - conversion for hexadecimal and base32 strings. * - * Copyright: 2008-2012 Aleksey Kravchenko <rhash.admin@gmail.com> + * Copyright (c) 2008, Aleksey Kravchenko <rhash.admin@gmail.com> * - * 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. + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted. * - * 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. Use this program at your own risk! + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. */ -#include <string.h> -#include <ctype.h> #include "hex.h" - -/** -* Convert a byte to a hexadecimal number. The result, consisting of two -* hexadecimal digits is stored into a buffer. - * - * @param dest the buffer to receive two symbols of hex representation - * @param byte the byte to decode - * @param upper_case flag to print string in uppercase - * @return pointer to the chararcter just after the written number (dest + 2) - */ -char* rhash_print_hex_byte(char *dest, const unsigned char byte, int upper_case) -{ - const char add = (upper_case ? 'A' - 10 : 'a' - 10); - unsigned char c = (byte >> 4) & 15; - *dest++ = (c > 9 ? c + add : c + '0'); - c = byte & 15; - *dest++ = (c > 9 ? c + add : c + '0'); - return dest; -} +#include <assert.h> +#include <ctype.h> +#include <string.h> /** * Store hexadecimal representation of a binary string to given buffer. * - * @param dest the buffer to receive hexadecimal representation + * @param dst the buffer to receive hexadecimal representation * @param src binary string - * @param len string length + * @param length string length * @param upper_case flag to print string in uppercase */ -void rhash_byte_to_hex(char *dest, const unsigned char *src, unsigned len, int upper_case) +void rhash_byte_to_hex(char* dst, const unsigned char* src, size_t length, int upper_case) { - while (len-- > 0) { - dest = rhash_print_hex_byte(dest, *src++, upper_case); + const char hex_add = (upper_case ? 'A' - 10 : 'a' - 10); + for (; length > 0; src++, length--) { + const unsigned char hi = (*src >> 4) & 15; + const unsigned char lo = *src & 15; + *dst++ = (hi > 9 ? hi + hex_add : hi + '0'); + *dst++ = (lo > 9 ? lo + hex_add : lo + '0'); } - *dest = '\0'; + *dst = '\0'; } /** * Encode a binary string to base32. * - * @param dest the buffer to store result + * @param dst the buffer to store result * @param src binary string - * @param len string length + * @param length string length * @param upper_case flag to print string in uppercase */ -void rhash_byte_to_base32(char* dest, const unsigned char* src, unsigned len, int upper_case) +void rhash_byte_to_base32(char* dst, const unsigned char* src, size_t length, int upper_case) { const char a = (upper_case ? 'A' : 'a'); unsigned shift = 0; unsigned char word; - const unsigned char* e = src + len; + const unsigned char* e = src + length; while (src < e) { if (shift > 3) { word = (*src & (0xFF >> shift)); @@ -79,25 +65,25 @@ void rhash_byte_to_base32(char* dest, const unsigned char* src, unsigned len, in word = ( *src >> ( (8 - shift) & 7 ) ) & 0x1F; if (shift == 0) src++; } - *dest++ = ( word < 26 ? word + a : word + '2' - 26 ); + *dst++ = ( word < 26 ? word + a : word + '2' - 26 ); } - *dest = '\0'; + *dst = '\0'; } /** * Encode a binary string to base64. * Encoded output length is always a multiple of 4 bytes. * - * @param dest the buffer to store result + * @param dst the buffer to store result * @param src binary string - * @param len string length + * @param length string length */ -void rhash_byte_to_base64(char* dest, const unsigned char* src, unsigned len) +void rhash_byte_to_base64(char* dst, const unsigned char* src, size_t length) { static const char* tail = "0123456789+/"; unsigned shift = 0; unsigned char word; - const unsigned char* e = src + len; + const unsigned char* e = src + length; while (src < e) { if (shift > 2) { word = (*src & (0xFF >> shift)); @@ -111,45 +97,80 @@ void rhash_byte_to_base64(char* dest, const unsigned char* src, unsigned len) word = ( *src >> ( (8 - shift) & 7 ) ) & 0x3F; if (shift == 0) src++; } - *dest++ = ( word < 52 ? (word < 26 ? word + 'A' : word - 26 + 'a') : tail[word - 52]); + *dst++ = ( word < 52 ? (word < 26 ? word + 'A' : word - 26 + 'a') : tail[word - 52]); } if (shift > 0) { - *dest++ = '='; - if (shift == 4) *dest++ = '='; + *dst++ = '='; + if (shift == 4) *dst++ = '='; } - *dest = '\0'; + *dst = '\0'; } -/* unsafe characters are "<>{}[]%#/|\^~`@:;?=&+ */ -#define IS_GOOD_URL_CHAR(c) (isalnum((unsigned char)c) || strchr("$-_.!'(),", c)) +size_t rhash_base64_url_encoded_helper(char* dst, const unsigned char* src, size_t length, int url_encode, int upper_case) +{ +#define B64_CHUNK_SIZE 120 + char buffer[164]; + assert((BASE64_LENGTH(B64_CHUNK_SIZE) + 4) <= sizeof(buffer)); + assert((B64_CHUNK_SIZE % 6) == 0); + if (url_encode) { + size_t result_length = 0; + for (; length > 0; src += B64_CHUNK_SIZE) { + size_t chunk_size = (length < B64_CHUNK_SIZE ? length : B64_CHUNK_SIZE); + size_t encoded_length; + rhash_byte_to_base64(buffer, src, chunk_size); + encoded_length = rhash_urlencode(dst, buffer, BASE64_LENGTH(chunk_size), upper_case); + result_length += encoded_length; + dst += encoded_length; + length -= chunk_size; + } + return result_length; + } + rhash_byte_to_base64(dst, src, length); + return BASE64_LENGTH(length); +} + +/* RFC 3986: safe url characters are ascii alpha-numeric and "-._~", other characters should be percent-encoded */ +static unsigned url_safe_char_mask[4] = { 0, 0x03ff6000, 0x87fffffe, 0x47fffffe }; +#define IS_URL_GOOD_CHAR(c) ((unsigned)(c) < 128 && (url_safe_char_mask[c >> 5] & (1 << (c & 31)))) /** - * URL-encode a string. + * URL-encode specified binary string. * - * @param dst buffer to receive result or NULL to calculate - * the lengths of encoded string - * @param filename the file name + * @param dst (nullable) buffer to output encoded string to, + * NULL to just calculate the lengths of encoded string + * @param src binary string to encode + * @param size size of the binary string + * @param upper_case flag to output hex-codes in uppercase * @return the length of the result string */ -int rhash_urlencode(char *dst, const char *name) +size_t rhash_urlencode(char* dst, const char* src, size_t size, int upper_case) { - const char *start; + const char* start; + size_t i; if (!dst) { - int len; - for (len = 0; *name; name++) len += (IS_GOOD_URL_CHAR(*name) ? 1 : 3); - return len; - } - /* encode URL as specified by RFC 1738 */ - for (start = dst; *name; name++) { - if ( IS_GOOD_URL_CHAR(*name) ) { - *dst++ = *name; - } else { - *dst++ = '%'; - dst = rhash_print_hex_byte(dst, *name, 'A'); + size_t length = size; + for (i = 0; i < size; i++) + if (!IS_URL_GOOD_CHAR(src[i])) + length += 2; + return length; + } else { + const char hex_add = (upper_case ? 'A' - 10 : 'a' - 10); + start = dst; + /* percent-encode all but unreserved URL characters */ + for (i = 0; i < size; i++) { + if (IS_URL_GOOD_CHAR(src[i])) { + *dst++ = src[i]; + } else { + unsigned char hi = ((unsigned char)(src[i]) >> 4) & 0x0f; + unsigned char lo = (unsigned char)(src[i]) & 0x0f; + *dst++ = '%'; + *dst++ = (hi > 9 ? hi + hex_add : hi + '0'); + *dst++ = (lo > 9 ? lo + hex_add : lo + '0'); + } } + *dst = 0; } - *dst = 0; - return (int)(dst - start); + return dst - start; } /** @@ -160,10 +181,11 @@ int rhash_urlencode(char *dst, const char *name) * @param number the number to print * @return length of the printed number (without trailing '\0') */ -int rhash_sprintI64(char *dst, uint64_t number) +int rhash_sprintI64(char* dst, uint64_t number) { /* The biggest number has 20 digits: 2^64 = 18 446 744 073 709 551 616 */ - char buf[24], *p; + char buf[24]; + char* p; size_t length; if (dst == NULL) { diff --git a/Utilities/cmlibrhash/librhash/hex.h b/Utilities/cmlibrhash/librhash/hex.h index 2b365e2..6bea036 100644 --- a/Utilities/cmlibrhash/librhash/hex.h +++ b/Utilities/cmlibrhash/librhash/hex.h @@ -8,12 +8,13 @@ extern "C" { #endif -void rhash_byte_to_hex(char *dest, const unsigned char *src, unsigned len, int upper_case); -void rhash_byte_to_base32(char* dest, const unsigned char* src, unsigned len, int upper_case); -void rhash_byte_to_base64(char* dest, const unsigned char* src, unsigned len); -char* rhash_print_hex_byte(char *dest, const unsigned char byte, int upper_case); -int rhash_urlencode(char *dst, const char *name); -int rhash_sprintI64(char *dst, uint64_t number); +void rhash_byte_to_hex(char* dest, const unsigned char* src, size_t length, int upper_case); +void rhash_byte_to_base32(char* dest, const unsigned char* src, size_t length, int upper_case); +void rhash_byte_to_base64(char* dest, const unsigned char* src, size_t length); +char* rhash_print_hex_byte(char* dest, const unsigned char byte, int upper_case); +size_t rhash_urlencode(char* dst, const char* str, size_t size, int upper_case); +size_t rhash_base64_url_encoded_helper(char* dst, const unsigned char* src, size_t length, int url_encode, int upper_case); +int rhash_sprintI64(char* dst, uint64_t number); #define BASE32_LENGTH(bytes) (((bytes) * 8 + 4) / 5) #define BASE64_LENGTH(bytes) ((((bytes) + 2) / 3) * 4) diff --git a/Utilities/cmlibrhash/librhash/md5.c b/Utilities/cmlibrhash/librhash/md5.c index b20de45..9b76822 100644 --- a/Utilities/cmlibrhash/librhash/md5.c +++ b/Utilities/cmlibrhash/librhash/md5.c @@ -1,17 +1,17 @@ /* md5.c - an implementation of the MD5 algorithm, based on RFC 1321. * - * Copyright: 2007-2012 Aleksey Kravchenko <rhash.admin@gmail.com> + * Copyright (c) 2007, Aleksey Kravchenko <rhash.admin@gmail.com> * - * 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. + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted. * - * 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. Use this program at your own risk! + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. */ #include <string.h> @@ -23,7 +23,7 @@ * * @param ctx context to initialize */ -void rhash_md5_init(md5_ctx *ctx) +void rhash_md5_init(md5_ctx* ctx) { ctx->length = 0; @@ -162,7 +162,7 @@ static void rhash_md5_process_block(unsigned state[4], const unsigned* x) * @param msg message chunk * @param size length of the message chunk */ -void rhash_md5_update(md5_ctx *ctx, const unsigned char* msg, size_t size) +void rhash_md5_update(md5_ctx* ctx, const unsigned char* msg, size_t size) { unsigned index = (unsigned)ctx->length & 63; ctx->length += size; @@ -205,7 +205,7 @@ void rhash_md5_update(md5_ctx *ctx, const unsigned char* msg, size_t size) * @param ctx the algorithm context containing current hashing state * @param result calculated hash in binary form */ -void rhash_md5_final(md5_ctx *ctx, unsigned char* result) +void rhash_md5_final(md5_ctx* ctx, unsigned char* result) { unsigned index = ((unsigned)ctx->length & 63) >> 2; unsigned shift = ((unsigned)ctx->length & 3) * 8; diff --git a/Utilities/cmlibrhash/librhash/md5.h b/Utilities/cmlibrhash/librhash/md5.h index 1af6f13..12a6b52 100644 --- a/Utilities/cmlibrhash/librhash/md5.h +++ b/Utilities/cmlibrhash/librhash/md5.h @@ -20,9 +20,9 @@ typedef struct md5_ctx /* hash functions */ -void rhash_md5_init(md5_ctx *ctx); -void rhash_md5_update(md5_ctx *ctx, const unsigned char* msg, size_t size); -void rhash_md5_final(md5_ctx *ctx, unsigned char result[16]); +void rhash_md5_init(md5_ctx* ctx); +void rhash_md5_update(md5_ctx* ctx, const unsigned char* msg, size_t size); +void rhash_md5_final(md5_ctx* ctx, unsigned char result[16]); #ifdef __cplusplus } /* extern "C" */ diff --git a/Utilities/cmlibrhash/librhash/rhash.c b/Utilities/cmlibrhash/librhash/rhash.c index 34e1eb3..ce6ace4 100644 --- a/Utilities/cmlibrhash/librhash/rhash.c +++ b/Utilities/cmlibrhash/librhash/rhash.c @@ -1,42 +1,40 @@ /* rhash.c - implementation of LibRHash library calls * - * Copyright: 2008-2012 Aleksey Kravchenko <rhash.admin@gmail.com> + * Copyright (c) 2008, Aleksey Kravchenko <rhash.admin@gmail.com> * - * 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. + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted. * - * 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. Use this program at your own risk! + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. */ +/* modifier for Windows DLL */ +#if (defined(_WIN32) || defined(__CYGWIN__)) && defined(RHASH_EXPORTS) +# define RHASH_API __declspec(dllexport) +#endif + /* macros for large file support, must be defined before any include file */ #define _LARGEFILE64_SOURCE #define _FILE_OFFSET_BITS 64 #include "ustd.h" /* Need this first within CMake. */ -#include <string.h> /* memset() */ -#include <stdlib.h> /* free() */ -#include <stddef.h> /* ptrdiff_t */ -#include <stdio.h> -#include <assert.h> -#include <errno.h> - -/* modifier for Windows DLL */ -#if defined(_WIN32) && defined(RHASH_EXPORTS) -# define RHASH_API __declspec(dllexport) -#endif - -#include "byte_order.h" +#include "rhash.h" #include "algorithms.h" -#include "util.h" +#include "byte_order.h" #include "hex.h" -#include "rhash.h" /* RHash library interface */ +#include "util.h" +#include <assert.h> +#include <errno.h> +#include <stdlib.h> +#include <stddef.h> +#include <string.h> #define STATE_ACTIVE 0xb01dbabe #define STATE_STOPED 0xdeadbeef @@ -45,11 +43,8 @@ #define RCTX_FINALIZED 0x2 #define RCTX_FINALIZED_MASK (RCTX_AUTO_FINAL | RCTX_FINALIZED) #define RHPR_FORMAT (RHPR_RAW | RHPR_HEX | RHPR_BASE32 | RHPR_BASE64) -#define RHPR_MODIFIER (RHPR_UPPERCASE | RHPR_REVERSE) +#define RHPR_MODIFIER (RHPR_UPPERCASE | RHPR_URLENCODE | RHPR_REVERSE) -/** - * Initialize static data of rhash algorithms - */ void rhash_library_init(void) { rhash_init_algorithms(RHASH_ALL_HASHES); @@ -58,31 +53,18 @@ void rhash_library_init(void) #endif } -/** - * Returns the number of supported hash algorithms. - * - * @return the number of supported hash functions - */ int RHASH_API rhash_count(void) { return rhash_info_size; } -/* Lo-level rhash library functions */ +/* LOW-LEVEL LIBRHASH INTERFACE */ -/** - * Allocate and initialize RHash context for calculating hash(es). - * After initializing rhash_update()/rhash_final() functions should be used. - * Then the context must be freed by calling rhash_free(). - * - * @param hash_id union of bit flags, containing ids of hashes to calculate. - * @return initialized rhash context, NULL on error and errno is set - */ RHASH_API rhash rhash_init(unsigned hash_id) { unsigned tail_bit_index; /* index of hash_id trailing bit */ unsigned num = 0; /* number of hashes to compute */ - rhash_context_ext *rctx = NULL; /* allocated rhash context */ + rhash_context_ext* rctx = NULL; /* allocated rhash context */ size_t hash_size_sum = 0; /* size of hash contexts to store in rctx */ unsigned i, bit_index, id; @@ -123,7 +105,7 @@ RHASH_API rhash rhash_init(unsigned hash_id) } /* align the size of the rhash context common part */ - aligned_size = (offsetof(rhash_context_ext, vector[num]) + 7) & ~7; + aligned_size = ((offsetof(rhash_context_ext, vector) + sizeof(rhash_vector_item) * num) + 7) & ~7; assert(aligned_size >= sizeof(rhash_context_ext)); /* allocate rhash context with enough memory to store contexts of all used hashes */ @@ -170,11 +152,6 @@ RHASH_API rhash rhash_init(unsigned hash_id) return &rctx->rc; /* return allocated and initialized rhash context */ } -/** - * Free RHash context memory. - * - * @param ctx the context to free. - */ void rhash_free(rhash ctx) { rhash_context_ext* const ectx = (rhash_context_ext*)ctx; @@ -195,12 +172,6 @@ void rhash_free(rhash ctx) free(ectx); } -/** - * Re-initialize RHash context to reuse it. - * Useful to speed up processing of many small messages. - * - * @param ctx context to reinitialize - */ RHASH_API void rhash_reset(rhash ctx) { rhash_context_ext* const ectx = (rhash_context_ext*)ctx; @@ -223,15 +194,6 @@ RHASH_API void rhash_reset(rhash ctx) ectx->flags &= ~RCTX_FINALIZED; /* clear finalized state */ } -/** - * Calculate hashes of message. - * Can be called repeatedly with chunks of the message to be hashed. - * - * @param ctx the rhash context - * @param message message chunk - * @param length length of the message chunk - * @return 0 on success; On fail return -1 and set errno - */ RHASH_API int rhash_update(rhash ctx, const void* message, size_t length) { rhash_context_ext* const ectx = (rhash_context_ext*)ctx; @@ -251,13 +213,6 @@ RHASH_API int rhash_update(rhash ctx, const void* message, size_t length) return 0; /* no error processing at the moment */ } -/** - * Finalize hash calculation and optionally store the first hash. - * - * @param ctx the rhash context - * @param first_result optional buffer to store a calculated hash with the lowest available id - * @return 0 on success; On fail return -1 and set errno - */ RHASH_API int rhash_final(rhash ctx, unsigned char* first_result) { unsigned i = 0; @@ -295,7 +250,7 @@ static void rhash_put_digest(rhash ctx, unsigned hash_id, unsigned char* result) { rhash_context_ext* const ectx = (rhash_context_ext*)ctx; unsigned i; - rhash_vector_item *item; + rhash_vector_item* item; struct rhash_hash_info* info; unsigned char* digest; @@ -332,34 +287,14 @@ static void rhash_put_digest(rhash ctx, unsigned hash_id, unsigned char* result) } } -/** - * Set the callback function to be called from the - * rhash_file() and rhash_file_update() functions - * on processing every file block. The file block - * size is set internally by rhash and now is 8 KiB. - * - * @param ctx rhash context - * @param callback pointer to the callback function - * @param callback_data pointer to data passed to the callback - */ RHASH_API void rhash_set_callback(rhash ctx, rhash_callback_t callback, void* callback_data) { - ((rhash_context_ext*)ctx)->callback = callback; + ((rhash_context_ext*)ctx)->callback = (void*)callback; ((rhash_context_ext*)ctx)->callback_data = callback_data; } +/* HIGH-LEVEL LIBRHASH INTERFACE */ -/* hi-level message hashing interface */ - -/** - * Compute a hash of the given message. - * - * @param hash_id id of hash sum to compute - * @param message the message to process - * @param length message length - * @param result buffer to receive binary hash string - * @return 0 on success, -1 on error - */ RHASH_API int rhash_msg(unsigned hash_id, const void* message, size_t length, unsigned char* result) { rhash ctx; @@ -372,22 +307,12 @@ RHASH_API int rhash_msg(unsigned hash_id, const void* message, size_t length, un return 0; } -/** - * Hash a file or stream. Multiple hashes can be computed. - * First, inintialize ctx parameter with rhash_init() before calling - * rhash_file_update(). Then use rhash_final() and rhash_print() - * to retrive hash values. Finaly call rhash_free() on ctx - * to free allocated memory or call rhash_reset() to reuse ctx. - * - * @param ctx rhash context - * @param fd descriptor of the file to hash - * @return 0 on success, -1 on error and errno is set - */ RHASH_API int rhash_file_update(rhash ctx, FILE* fd) { rhash_context_ext* const ectx = (rhash_context_ext*)ctx; const size_t block_size = 8192; - unsigned char *buffer, *pmem; + unsigned char* buffer; + unsigned char* pmem; size_t length = 0, align8; int res = 0; if (ectx->state != STATE_ACTIVE) return 0; /* do nothing if canceled */ @@ -425,14 +350,6 @@ RHASH_API int rhash_file_update(rhash ctx, FILE* fd) return res; } -/** - * Compute a single hash for given file. - * - * @param hash_id id of hash sum to compute - * @param filepath path to the file to hash - * @param result buffer to receive hash value with the lowest requested id - * @return 0 on success, -1 on error and errno is set - */ RHASH_API int rhash_file(unsigned hash_id, const char* filepath, unsigned char* result) { FILE* fd; @@ -447,7 +364,10 @@ RHASH_API int rhash_file(unsigned hash_id, const char* filepath, unsigned char* if ((fd = fopen(filepath, "rb")) == NULL) return -1; - if ((ctx = rhash_init(hash_id)) == NULL) return -1; + if ((ctx = rhash_init(hash_id)) == NULL) { + fclose(fd); + return -1; + } res = rhash_file_update(ctx, fd); /* hash the file */ fclose(fd); @@ -460,14 +380,6 @@ RHASH_API int rhash_file(unsigned hash_id, const char* filepath, unsigned char* #ifdef _WIN32 /* windows only function */ #include <share.h> -/** - * Compute a single hash for given file. - * - * @param hash_id id of hash sum to compute - * @param filepath path to the file to hash - * @param result buffer to receive hash value with the lowest requested id - * @return 0 on success, -1 on error, -1 on error and errno is set - */ RHASH_API int rhash_wfile(unsigned hash_id, const wchar_t* filepath, unsigned char* result) { FILE* fd; @@ -482,7 +394,10 @@ RHASH_API int rhash_wfile(unsigned hash_id, const wchar_t* filepath, unsigned ch if ((fd = _wfsopen(filepath, L"rb", _SH_DENYWR)) == NULL) return -1; - if ((ctx = rhash_init(hash_id)) == NULL) return -1; + if ((ctx = rhash_init(hash_id)) == NULL) { + fclose(fd); + return -1; + } res = rhash_file_update(ctx, fd); /* hash the file */ fclose(fd); @@ -495,28 +410,7 @@ RHASH_API int rhash_wfile(unsigned hash_id, const wchar_t* filepath, unsigned ch /* RHash information functions */ -/** - * Returns information about a hash function by its hash_id. - * - * @param hash_id the id of hash algorithm - * @return pointer to the rhash_info structure containing the information - */ -const rhash_info* rhash_info_by_id(unsigned hash_id) -{ - hash_id &= RHASH_ALL_HASHES; - /* check that only one bit is set */ - if (hash_id != (hash_id & -(int)hash_id)) return NULL; - /* note: alternative condition is (hash_id == 0 || (hash_id & (hash_id - 1)) != 0) */ - return rhash_info_table[rhash_ctz(hash_id)].info; -} - #if 0 -/** - * Detect default digest output format for given hash algorithm. - * - * @param hash_id the id of hash algorithm - * @return 1 for base32 format, 0 for hexadecimal - */ RHASH_API int rhash_is_base32(unsigned hash_id) { /* fast method is just to test a bit-mask */ @@ -524,12 +418,6 @@ RHASH_API int rhash_is_base32(unsigned hash_id) } #endif -/** - * Returns size of binary digest for given hash algorithm. - * - * @param hash_id the id of hash algorithm - * @return digest size in bytes - */ RHASH_API int rhash_get_digest_size(unsigned hash_id) { hash_id &= RHASH_ALL_HASHES; @@ -537,12 +425,6 @@ RHASH_API int rhash_get_digest_size(unsigned hash_id) return (int)rhash_info_table[rhash_ctz(hash_id)].info->digest_size; } -/** - * Returns length of digest hash string in default output format. - * - * @param hash_id the id of hash algorithm - * @return the length of hash string - */ RHASH_API int rhash_get_hash_length(unsigned hash_id) { const rhash_info* info = rhash_info_by_id(hash_id); @@ -550,26 +432,12 @@ RHASH_API int rhash_get_hash_length(unsigned hash_id) BASE32_LENGTH(info->digest_size) : info->digest_size * 2) : 0); } -/** - * Returns a name of given hash algorithm. - * - * @param hash_id the id of hash algorithm - * @return algorithm name - */ RHASH_API const char* rhash_get_name(unsigned hash_id) { const rhash_info* info = rhash_info_by_id(hash_id); return (info ? info->name : 0); } -/** - * Returns a name part of magnet urn of the given hash algorithm. - * Such magnet_name is used to generate a magnet link of the form - * urn:<magnet_name>=<hash_value>. - * - * @param hash_id the id of hash algorithm - * @return name - */ RHASH_API const char* rhash_get_magnet_name(unsigned hash_id) { const rhash_info* info = rhash_info_by_id(hash_id); @@ -599,7 +467,7 @@ static size_t rhash_get_magnet_url_size(const char* filepath, } if (filepath) { - size += 4 + rhash_urlencode(NULL, filepath); + size += 4 + rhash_urlencode(NULL, filepath, strlen(filepath), 0); } /* loop through hash values */ @@ -610,34 +478,20 @@ static size_t rhash_get_magnet_url_size(const char* filepath, size += (7 + 2) + strlen(name); size += rhash_print(NULL, context, bit, - (bit & (RHASH_SHA1 | RHASH_BTIH) ? RHPR_BASE32 : 0)); + (bit & RHASH_SHA1 ? RHPR_BASE32 : 0)); } return size; } -/** - * Print magnet link with given filepath and calculated hash sums into the - * output buffer. The hash_mask can limit which hash values will be printed. - * The function returns the size of the required buffer. - * If output is NULL the . - * - * @param output a string buffer to receive the magnet link or NULL - * @param filepath the file path to be printed or NULL - * @param context algorithms state - * @param hash_mask bit mask of the hash sums to add to the link - * @param flags can be combination of bits RHPR_UPPERCASE, RHPR_NO_MAGNET, - * RHPR_FILESIZE - * @return number of written characters, including terminating '\0' on success, 0 on fail - */ RHASH_API size_t rhash_print_magnet(char* output, const char* filepath, rhash context, unsigned hash_mask, int flags) { int i; const char* begin = output; - if (output == NULL) return rhash_get_magnet_url_size( - filepath, context, hash_mask, flags); + if (output == NULL) + return rhash_get_magnet_url_size(filepath, context, hash_mask, flags); /* RHPR_NO_MAGNET, RHPR_FILESIZE */ if ((flags & RHPR_NO_MAGNET) == 0) { @@ -652,13 +506,13 @@ RHASH_API size_t rhash_print_magnet(char* output, const char* filepath, *(output++) = '&'; } + flags &= RHPR_UPPERCASE; if (filepath) { strcpy(output, "dn="); output += 3; - output += rhash_urlencode(output, filepath); + output += rhash_urlencode(output, filepath, strlen(filepath), flags); *(output++) = '&'; } - flags &= RHPR_UPPERCASE; for (i = 0; i < 2; i++) { unsigned bit; @@ -679,7 +533,7 @@ RHASH_API size_t rhash_print_magnet(char* output, const char* filepath, output += strlen(name); *(output++) = ':'; output += rhash_print(output, context, bit, - (bit & (RHASH_SHA1 | RHASH_BTIH) ? flags | RHPR_BASE32 : flags)); + (bit & RHASH_SHA1 ? flags | RHPR_BASE32 : flags)); *(output++) = '&'; } } @@ -688,62 +542,39 @@ RHASH_API size_t rhash_print_magnet(char* output, const char* filepath, return (output - begin); } -/* hash sum output */ -/** - * Print a text presentation of a given hash sum to the specified buffer, - * - * @param output a buffer to print the hash to - * @param bytes a hash sum to print - * @param size a size of hash sum in bytes - * @param flags a bit-mask controlling how to format the hash sum, - * can be a mix of the flags: RHPR_RAW, RHPR_HEX, RHPR_BASE32, - * RHPR_BASE64, RHPR_UPPERCASE, RHPR_REVERSE - * @return the number of written characters - */ -size_t rhash_print_bytes(char* output, const unsigned char* bytes, - size_t size, int flags) +/* HASH SUM OUTPUT INTERFACE */ + +size_t rhash_print_bytes(char* output, const unsigned char* bytes, size_t size, int flags) { - size_t str_len; + size_t result_length; int upper_case = (flags & RHPR_UPPERCASE); int format = (flags & ~RHPR_MODIFIER); switch (format) { case RHPR_HEX: - str_len = size * 2; - rhash_byte_to_hex(output, bytes, (unsigned)size, upper_case); + result_length = size * 2; + rhash_byte_to_hex(output, bytes, size, upper_case); break; case RHPR_BASE32: - str_len = BASE32_LENGTH(size); - rhash_byte_to_base32(output, bytes, (unsigned)size, upper_case); + result_length = BASE32_LENGTH(size); + rhash_byte_to_base32(output, bytes, size, upper_case); break; case RHPR_BASE64: - str_len = BASE64_LENGTH(size); - rhash_byte_to_base64(output, bytes, (unsigned)size); + result_length = rhash_base64_url_encoded_helper(output, bytes, size, (flags & RHPR_URLENCODE), upper_case); break; default: - str_len = size; - memcpy(output, bytes, size); + if (flags & RHPR_URLENCODE) { + result_length = rhash_urlencode(output, (char*)bytes, size, upper_case); + } else { + memcpy(output, bytes, size); + result_length = size; + } break; } - return str_len; + return result_length; } -/** - * Print text presentation of a hash sum with given hash_id to the specified - * output buffer. If the hash_id is zero, then print the hash sum with - * the lowest id stored in the hash context. - * The function call fails if the context doesn't include a hash with the - * given hash_id. - * - * @param output a buffer to print the hash to - * @param context algorithms state - * @param hash_id id of the hash sum to print or 0 to print the first hash - * saved in the context. - * @param flags a bitmask controlling how to print the hash. Can contain flags - * RHPR_UPPERCASE, RHPR_HEX, RHPR_BASE32, RHPR_BASE64, etc. - * @return the number of written characters on success or 0 on fail - */ size_t RHASH_API rhash_print(char* output, rhash context, unsigned hash_id, int flags) { const rhash_info* info; @@ -764,15 +595,16 @@ size_t RHASH_API rhash_print(char* output, rhash context, unsigned hash_id, int } if (output == NULL) { + size_t multiplier = (flags & RHPR_URLENCODE ? 3 : 1); switch (flags & RHPR_FORMAT) { case RHPR_HEX: return (digest_size * 2); case RHPR_BASE32: return BASE32_LENGTH(digest_size); case RHPR_BASE64: - return BASE64_LENGTH(digest_size); + return BASE64_LENGTH(digest_size) * multiplier; default: - return digest_size; + return digest_size * multiplier; } } @@ -781,7 +613,8 @@ size_t RHASH_API rhash_print(char* output, rhash context, unsigned hash_id, int if ((flags & ~RHPR_UPPERCASE) == (RHPR_REVERSE | RHPR_HEX)) { /* reverse the digest */ - unsigned char *p = digest, *r = digest + digest_size - 1; + unsigned char* p = digest; + unsigned char* r = digest + digest_size - 1; char tmp; for (; p < r; p++, r--) { tmp = *p; @@ -793,7 +626,7 @@ size_t RHASH_API rhash_print(char* output, rhash context, unsigned hash_id, int return rhash_print_bytes(output, digest, digest_size, flags); } -#if defined(_WIN32) && defined(RHASH_EXPORTS) +#if (defined(_WIN32) || defined(__CYGWIN__)) && defined(RHASH_EXPORTS) #include <windows.h> BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID reserved); BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID reserved) @@ -814,17 +647,8 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID reserved) } #endif -#define PVOID2UPTR(p) ((rhash_uptr_t)((char*)p - 0)) +#define PVOID2UPTR(p) ((rhash_uptr_t)(((char*)(p)) + 0)) -/** - * Process a rhash message. - * - * @param msg_id message identifier - * @param dst message destination (can be NULL for generic messages) - * @param ldata data depending on message - * @param rdata data depending on message - * @return message-specific data - */ RHASH_API rhash_uptr_t rhash_transmit(unsigned msg_id, void* dst, rhash_uptr_t ldata, rhash_uptr_t rdata) { /* for messages working with rhash context */ @@ -865,6 +689,10 @@ RHASH_API rhash_uptr_t rhash_transmit(unsigned msg_id, void* dst, rhash_uptr_t l case RMSG_GET_OPENSSL_MASK: return rhash_openssl_hash_mask; #endif + case RMSG_GET_OPENSSL_SUPPORTED_MASK: + return rhash_get_openssl_supported_hash_mask(); + case RMSG_GET_OPENSSL_AVAILABLE_MASK: + return rhash_get_openssl_available_hash_mask(); default: return RHASH_ERROR; /* unknown message */ diff --git a/Utilities/cmlibrhash/librhash/rhash.h b/Utilities/cmlibrhash/librhash/rhash.h index cee0e25..c011762 100644 --- a/Utilities/cmlibrhash/librhash/rhash.h +++ b/Utilities/cmlibrhash/librhash/rhash.h @@ -9,7 +9,9 @@ extern "C" { #endif #ifndef RHASH_API -/* modifier for LibRHash functions */ +/** + * Modifier for LibRHash functions + */ # define RHASH_API #endif @@ -32,11 +34,11 @@ enum rhash_ids RHASH_AICH = 0x100, RHASH_WHIRLPOOL = 0x200, RHASH_RIPEMD160 = 0x400, - RHASH_GOST = 0x800, - RHASH_GOST_CRYPTOPRO = 0x1000, - RHASH_HAS160 = 0x2000, - RHASH_SNEFRU128 = 0x4000, - RHASH_SNEFRU256 = 0x8000, + RHASH_GOST94 = 0x800, + RHASH_GOST94_CRYPTOPRO = 0x1000, + RHASH_HAS160 = 0x2000, + RHASH_GOST12_256 = 0x4000, + RHASH_GOST12_512 = 0x8000, RHASH_SHA224 = 0x10000, RHASH_SHA256 = 0x20000, RHASH_SHA384 = 0x40000, @@ -47,18 +49,28 @@ enum rhash_ids RHASH_SHA3_256 = 0x0800000, RHASH_SHA3_384 = 0x1000000, RHASH_SHA3_512 = 0x2000000, + RHASH_CRC32C = 0x4000000, + RHASH_SNEFRU128 = 0x8000000, + RHASH_SNEFRU256 = 0x10000000, - /** The bit-mask containing all supported hashe functions */ - RHASH_ALL_HASHES = RHASH_CRC32 | RHASH_MD4 | RHASH_MD5 | RHASH_ED2K | RHASH_SHA1 | - RHASH_TIGER | RHASH_TTH | RHASH_GOST | RHASH_GOST_CRYPTOPRO | + /** + * The bit-mask containing all supported hashe functions. + */ + RHASH_ALL_HASHES = RHASH_CRC32 | RHASH_CRC32C | RHASH_MD4 | RHASH_MD5 | + RHASH_ED2K | RHASH_SHA1 |RHASH_TIGER | RHASH_TTH | + RHASH_GOST94 | RHASH_GOST94_CRYPTOPRO | RHASH_GOST12_256 | RHASH_GOST12_512 | RHASH_BTIH | RHASH_AICH | RHASH_WHIRLPOOL | RHASH_RIPEMD160 | RHASH_HAS160 | RHASH_SNEFRU128 | RHASH_SNEFRU256 | RHASH_SHA224 | RHASH_SHA256 | RHASH_SHA384 | RHASH_SHA512 | RHASH_SHA3_224 | RHASH_SHA3_256 | RHASH_SHA3_384 | RHASH_SHA3_512 | RHASH_EDONR256 | RHASH_EDONR512, - /** The number of supported hash functions */ - RHASH_HASH_COUNT = 26 + RHASH_GOST = RHASH_GOST94, /* deprecated constant name */ + RHASH_GOST_CRYPTOPRO = RHASH_GOST94_CRYPTOPRO, /* deprecated constant name */ + /** + * The number of supported hash functions. + */ + RHASH_HASH_COUNT = 29 #else RHASH_MD5 = 0x01, RHASH_SHA1 = 0x02, @@ -86,15 +98,17 @@ enum rhash_ids }; /** - * The rhash context structure contains contexts for several hash functions + * The rhash context structure contains contexts for several hash functions. */ typedef struct rhash_context { - /** The size of the hashed message */ + /** + * The size of the hashed message. + */ unsigned long long msg_size; /** - * The bit-mask containing identifiers of the hashes being calculated + * The bit-mask containing identifiers of the hashes being calculated. */ unsigned hash_id; } rhash_context; @@ -107,109 +121,285 @@ typedef struct rhash_context typedef struct rhash_context* rhash; #endif /* LIBRHASH_RHASH_CTX_DEFINED */ -/** type of a callback to be called periodically while hashing a file */ +/** + * Type of a callback to be called periodically while hashing a file. + */ typedef void (*rhash_callback_t)(void* data, unsigned long long offset); -RHASH_API void rhash_library_init(void); /* initialize static data */ +/** + * Initialize static data of rhash algorithms + */ +RHASH_API void rhash_library_init(void); -/* hi-level hashing functions */ + +/* HIGH-LEVEL LIBRHASH INTERFACE */ + +/** + * Compute a hash of the given message. + * + * @param hash_id id of hash sum to compute + * @param message the message to process + * @param length message length + * @param result buffer to receive binary hash string + * @return 0 on success, -1 on error + */ RHASH_API int rhash_msg(unsigned hash_id, const void* message, size_t length, unsigned char* result); + +/** + * Compute a single hash for given file. + * + * @param hash_id id of hash sum to compute + * @param filepath path to the file to hash + * @param result buffer to receive hash value with the lowest requested id + * @return 0 on success, -1 on error and errno is set + */ RHASH_API int rhash_file(unsigned hash_id, const char* filepath, unsigned char* result); -RHASH_API int rhash_file_update(rhash ctx, FILE* fd); -#ifdef _WIN32 /* windows only function */ +#ifdef _WIN32 +/** + * Compute a single hash for given file (Windows-specific function). + * + * @param hash_id id of hash sum to compute + * @param filepath path to the file to hash + * @param result buffer to receive hash value with the lowest requested id + * @return 0 on success, -1 on error, -1 on error and errno is set + */ RHASH_API int rhash_wfile(unsigned hash_id, const wchar_t* filepath, unsigned char* result); #endif -/* lo-level interface */ + +/* LOW-LEVEL LIBRHASH INTERFACE */ + +/** + * Allocate and initialize RHash context for calculating hash(es). + * After initializing rhash_update()/rhash_final() functions should be used. + * Then the context must be freed by calling rhash_free(). + * + * @param hash_id union of bit flags, containing ids of hashes to calculate. + * @return initialized rhash context, NULL on error and errno is set + */ RHASH_API rhash rhash_init(unsigned hash_id); -/*RHASH_API rhash rhash_init_by_ids(unsigned hash_ids[], unsigned count);*/ -RHASH_API int rhash_update(rhash ctx, const void* message, size_t length); -RHASH_API int rhash_final(rhash ctx, unsigned char* first_result); -RHASH_API void rhash_reset(rhash ctx); /* reinitialize the context */ + +/** + * Calculate hashes of message. + * Can be called repeatedly with chunks of the message to be hashed. + * + * @param ctx the rhash context + * @param message message chunk + * @param length length of the message chunk + * @return 0 on success; On fail return -1 and set errno + */ +RHASH_API int rhash_update(rhash ctx, const void* message, size_t length); + +/** + * Hash a file or stream. Multiple hashes can be computed. + * First, inintialize ctx parameter with rhash_init() before calling + * rhash_file_update(). Then use rhash_final() and rhash_print() + * to retrive hash values. Finaly call rhash_free() on ctx + * to free allocated memory or call rhash_reset() to reuse ctx. + * + * @param ctx rhash context + * @param fd descriptor of the file to hash + * @return 0 on success, -1 on error and errno is set + */ +RHASH_API int rhash_file_update(rhash ctx, FILE* fd); + +/** + * Finalize hash calculation and optionally store the first hash. + * + * @param ctx the rhash context + * @param first_result optional buffer to store a calculated hash with the lowest available id + * @return 0 on success; On fail return -1 and set errno + */ +RHASH_API int rhash_final(rhash ctx, unsigned char* first_result); + +/** + * Re-initialize RHash context to reuse it. + * Useful to speed up processing of many small messages. + * + * @param ctx context to reinitialize + */ +RHASH_API void rhash_reset(rhash ctx); + +/** + * Free RHash context memory. + * + * @param ctx the context to free. + */ RHASH_API void rhash_free(rhash ctx); -/* additional lo-level functions */ +/** + * Set the callback function to be called from the + * rhash_file() and rhash_file_update() functions + * on processing every file block. The file block + * size is set internally by rhash and now is 8 KiB. + * + * @param ctx rhash context + * @param callback pointer to the callback function + * @param callback_data pointer to data passed to the callback + */ RHASH_API void rhash_set_callback(rhash ctx, rhash_callback_t callback, void* callback_data); -/** bit-flag: default hash output format is base32 */ -#define RHASH_INFO_BASE32 1 + +/* INFORMATION FUNCTIONS */ /** - * Information about a hash function. + * Returns the number of supported hash algorithms. + * + * @return the number of supported hash functions */ -typedef struct rhash_info -{ - /** hash function indentifier */ - unsigned hash_id; - /** flags bit-mask, including RHASH_INFO_BASE32 bit */ - unsigned flags; - /** size of binary message digest in bytes */ - size_t digest_size; - const char* name; - const char* magnet_name; -} rhash_info; - -/* information functions */ RHASH_API int rhash_count(void); /* number of supported hashes */ + +/** + * Returns size of binary digest for given hash algorithm. + * + * @param hash_id the id of hash algorithm + * @return digest size in bytes + */ RHASH_API int rhash_get_digest_size(unsigned hash_id); /* size of binary message digest */ + +/** + * Returns length of digest hash string in default output format. + * + * @param hash_id the id of hash algorithm + * @return the length of hash string + */ RHASH_API int rhash_get_hash_length(unsigned hash_id); /* length of formatted hash string */ + +/** + * Detect default digest output format for given hash algorithm. + * + * @param hash_id the id of hash algorithm + * @return 1 for base32 format, 0 for hexadecimal + */ RHASH_API int rhash_is_base32(unsigned hash_id); /* default digest output format */ + +/** + * Returns a name of given hash algorithm. + * + * @param hash_id the id of hash algorithm + * @return algorithm name + */ RHASH_API const char* rhash_get_name(unsigned hash_id); /* get hash function name */ + +/** + * Returns a name part of magnet urn of the given hash algorithm. + * Such magnet_name is used to generate a magnet link of the form + * urn:<magnet_name>=<hash_value>. + * + * @param hash_id the id of hash algorithm + * @return name + */ RHASH_API const char* rhash_get_magnet_name(unsigned hash_id); /* get name part of magnet urn */ -/* note, that rhash_info_by_id() is not exported to a shared library or DLL */ -const rhash_info* rhash_info_by_id(unsigned hash_id); /* get hash sum info by hash id */ +/* HASH SUM OUTPUT INTERFACE */ #if 0 /** - * Flags for printing a hash sum + * Flags for printing a hash sum. */ enum rhash_print_sum_flags { - /** print in a default format */ + /* + * Print in a default format + */ RHPR_DEFAULT = 0x0, - /** output as binary message digest */ + /* + * Output as binary message digest + */ RHPR_RAW = 0x1, - /** print as a hexadecimal string */ + /* + * Print as a hexadecimal string + */ RHPR_HEX = 0x2, - /** print as a base32-encoded string */ + /* + * Print as a base32-encoded string + */ RHPR_BASE32 = 0x3, - /** print as a base64-encoded string */ + /* + * Print as a base64-encoded string + */ RHPR_BASE64 = 0x4, - - /** + /* * Print as an uppercase string. Can be used * for base32 or hexadecimal format only. */ RHPR_UPPERCASE = 0x8, - - /** + /* * Reverse hash bytes. Can be used for GOST hash. */ RHPR_REVERSE = 0x10, - - /** don't print 'magnet:?' prefix in rhash_print_magnet */ + /* + * Don't print 'magnet:?' prefix in rhash_print_magnet + */ RHPR_NO_MAGNET = 0x20, - /** print file size in rhash_print_magnet */ + /* + * Print file size in rhash_print_magnet + */ RHPR_FILESIZE = 0x40, + /* + * Print as URL-encoded string + */ + RHPR_URLENCODE = 0x80 }; #endif -/* output hash into the given buffer */ + +/** + * Print a text presentation of a given hash sum to the specified buffer. + * + * @param output a buffer to print the hash to + * @param bytes a hash sum to print + * @param size a size of hash sum in bytes + * @param flags a bit-mask controlling how to format the hash sum, + * can be a mix of the flags: RHPR_RAW, RHPR_HEX, RHPR_BASE32, + * RHPR_BASE64, RHPR_URLENCODE, RHPR_UPPERCASE, RHPR_REVERSE + * @return the number of written characters + */ RHASH_API size_t rhash_print_bytes(char* output, const unsigned char* bytes, size_t size, int flags); +/** + * Print text presentation of a hash sum with given hash_id to the specified + * output buffer. If the hash_id is zero, then print the hash sum with + * the lowest id stored in the hash context. + * The function call fails if the context doesn't include a hash with the + * given hash_id. + * + * @param output a buffer to print the hash to + * @param ctx algorithms state + * @param hash_id id of the hash sum to print or 0 to print the first hash + * saved in the context. + * @param flags a bitmask controlling how to print the hash. Can contain flags + * RHPR_UPPERCASE, RHPR_HEX, RHPR_BASE32, RHPR_BASE64, etc. + * @return the number of written characters on success or 0 on fail + */ RHASH_API size_t rhash_print(char* output, rhash ctx, unsigned hash_id, int flags); -/* output magnet URL into the given buffer */ +/** + * Print magnet link with given filepath and calculated hash sums into the + * output buffer. The hash_mask can limit which hash values will be printed. + * The function returns the size of the required buffer. + * If output is NULL the . + * + * @param output a string buffer to receive the magnet link or NULL + * @param filepath the file path to be printed or NULL + * @param context algorithms state + * @param hash_mask bit mask of the hash sums to add to the link + * @param flags can be combination of bits RHPR_UPPERCASE, RHPR_NO_MAGNET, + * RHPR_FILESIZE + * @return number of written characters, including terminating '\0' on success, 0 on fail + */ RHASH_API size_t rhash_print_magnet(char* output, const char* filepath, rhash context, unsigned hash_mask, int flags); -/* macros for message API */ -/** The type of an unsigned integer large enough to hold a pointer */ +/* MESSAGE API */ + +/** + * The type of an unsigned integer large enough to hold a pointer. + */ #if defined(UINTPTR_MAX) typedef uintptr_t rhash_uptr_t; #elif defined(_LP64) || defined(__LP64__) || defined(__x86_64) || \ @@ -219,14 +409,28 @@ typedef unsigned long long rhash_uptr_t; typedef unsigned long rhash_uptr_t; #endif -/** The value returned by rhash_transmit on error */ +/** + * The value returned by rhash_transmit on error. + */ #define RHASH_ERROR ((rhash_uptr_t)-1) -/** Convert a pointer to rhash_uptr_t */ +/** + * Convert a pointer to rhash_uptr_t. + */ #define RHASH_STR2UPTR(str) ((rhash_uptr_t)(char*)(str)) -/** Convert a rhash_uptr_t to a void* pointer */ -#define RHASH_UPTR2PVOID(u) ((void*)((char*)0 + (u))) +/** + * Convert a rhash_uptr_t to a void* pointer. + */ +#define RHASH_UPTR2PVOID(u) ((void*)((u) + 0)) -/* rhash API to set/get data via messages */ +/** + * Process a rhash message. + * + * @param msg_id message identifier + * @param dst message destination (can be NULL for generic messages) + * @param ldata data depending on message + * @param rdata data depending on message + * @return message-specific data + */ RHASH_API rhash_uptr_t rhash_transmit( unsigned msg_id, void* dst, rhash_uptr_t ldata, rhash_uptr_t rdata); @@ -239,22 +443,32 @@ RHASH_API rhash_uptr_t rhash_transmit( #define RMSG_SET_AUTOFINAL 5 #define RMSG_SET_OPENSSL_MASK 10 #define RMSG_GET_OPENSSL_MASK 11 +#define RMSG_GET_OPENSSL_SUPPORTED_MASK 12 +#define RMSG_GET_OPENSSL_AVAILABLE_MASK 13 -/* helper macros */ +/* HELPER MACROS */ -/** Get a pointer to context of the specified hash function */ +/** + * Get a pointer to context of the specified hash function. + */ #define rhash_get_context_ptr(ctx, hash_id) RHASH_UPTR2PVOID(rhash_transmit(RMSG_GET_CONTEXT, ctx, hash_id, 0)) -/** Cancel hash calculation of a file */ +/** + * Cancel hash calculation of a file. + */ #define rhash_cancel(ctx) rhash_transmit(RMSG_CANCEL, ctx, 0, 0) -/** Return non-zero if hash calculation was canceled, zero otherwise */ +/** + * Return non-zero if hash calculation was canceled, zero otherwise. + */ #define rhash_is_canceled(ctx) rhash_transmit(RMSG_IS_CANCELED, ctx, 0, 0) -/** Return non-zero if rhash_final was called for rhash_context */ +/** + * Return non-zero if rhash_final was called for rhash_context. + */ #define rhash_get_finalized(ctx) rhash_transmit(RMSG_GET_FINALIZED, ctx, 0, 0) /** * Turn on/off the auto-final flag for the given rhash_context. By default * auto-final is on, which means rhash_final is called automatically, if - * needed when a hash value is retrived by rhash_print call. + * needed when a hash value is retrieved by rhash_print call. */ #define rhash_set_autofinal(ctx, on) rhash_transmit(RMSG_SET_AUTOFINAL, ctx, on, 0) @@ -267,19 +481,36 @@ RHASH_API rhash_uptr_t rhash_transmit( #define rhash_set_openssl_mask(mask) rhash_transmit(RMSG_SET_OPENSSL_MASK, NULL, mask, 0) /** - * Return current bit-mask of hash algorithms selected to be calculated - * by OpenSSL library. + * Return current bit-mask of hash algorithms selected to be calculated by OpenSSL + * library. Return RHASH_ERROR if LibRHash is compiled without OpenSSL support. */ #define rhash_get_openssl_mask() rhash_transmit(RMSG_GET_OPENSSL_MASK, NULL, 0, 0) -/** The bit mask of hash algorithms implemented by OpenSSL */ -#if defined(USE_OPENSSL) || defined(OPENSSL_RUNTIME) -# define RHASH_OPENSSL_SUPPORTED_HASHES (RHASH_MD4 | RHASH_MD5 | \ - RHASH_SHA1 | RHASH_SHA224 | RHASH_SHA256 | RHASH_SHA384 | \ - RHASH_SHA512 | RHASH_RIPEMD160 | RHASH_WHIRLPOOL) -#else -# define RHASH_OPENSSL_SUPPORTED_HASHES 0 -#endif +/** + * Return the bit-mask of algorithms that can be provided by the OpenSSL plugin, + * if the library is compiled with OpenSSL support, 0 otherwise. This bit-mask is + * a constant value computed at compile-time. + */ +#define rhash_get_openssl_supported_mask() rhash_transmit(RMSG_GET_OPENSSL_SUPPORTED_MASK, NULL, 0, 0) + +/** + * Return the bit-mask of algorithms that are successfully loaded from + * OpenSSL library. If the library is not loaded or not supported by LibRHash, + * then return 0. + */ +#define rhash_get_openssl_available_mask() rhash_transmit(RMSG_GET_OPENSSL_AVAILABLE_MASK, NULL, 0, 0) + + +/** + * Return non-zero if LibRHash hash been compiled with OpenSSL support, + * and zero otherwise. + */ +#define rhash_is_openssl_supported() (rhash_get_openssl_mask() != RHASH_ERROR) + +/** + * Legacy macro. The bit mask of hash algorithms implemented by OpenSSL. + */ +# define RHASH_OPENSSL_SUPPORTED_HASHES (rhash_get_openssl_supported_mask()) #ifdef __cplusplus } /* extern "C" */ diff --git a/Utilities/cmlibrhash/librhash/sha1.c b/Utilities/cmlibrhash/librhash/sha1.c index f5a053b..b226925 100644 --- a/Utilities/cmlibrhash/librhash/sha1.c +++ b/Utilities/cmlibrhash/librhash/sha1.c @@ -1,18 +1,18 @@ /* sha1.c - an implementation of Secure Hash Algorithm 1 (SHA1) * based on RFC 3174. * - * Copyright: 2008-2012 Aleksey Kravchenko <rhash.admin@gmail.com> + * Copyright (c) 2008, Aleksey Kravchenko <rhash.admin@gmail.com> * - * 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. + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted. * - * 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. Use this program at your own risk! + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. */ #include <string.h> @@ -24,7 +24,7 @@ * * @param ctx context to initialize */ -void rhash_sha1_init(sha1_ctx *ctx) +void rhash_sha1_init(sha1_ctx* ctx) { ctx->length = 0; @@ -121,7 +121,7 @@ static void rhash_sha1_process_block(unsigned* hash, const unsigned* block) * @param msg message chunk * @param size length of the message chunk */ -void rhash_sha1_update(sha1_ctx *ctx, const unsigned char* msg, size_t size) +void rhash_sha1_update(sha1_ctx* ctx, const unsigned char* msg, size_t size) { unsigned index = (unsigned)ctx->length & 63; ctx->length += size; @@ -164,7 +164,7 @@ void rhash_sha1_update(sha1_ctx *ctx, const unsigned char* msg, size_t size) * @param ctx the algorithm context containing current hashing state * @param result calculated hash in binary form */ -void rhash_sha1_final(sha1_ctx *ctx, unsigned char* result) +void rhash_sha1_final(sha1_ctx* ctx, unsigned char* result) { unsigned index = (unsigned)ctx->length & 63; unsigned* msg32 = (unsigned*)ctx->message; diff --git a/Utilities/cmlibrhash/librhash/sha1.h b/Utilities/cmlibrhash/librhash/sha1.h index 74b2f94..7e99542 100644 --- a/Utilities/cmlibrhash/librhash/sha1.h +++ b/Utilities/cmlibrhash/librhash/sha1.h @@ -20,9 +20,9 @@ typedef struct sha1_ctx /* hash functions */ -void rhash_sha1_init(sha1_ctx *ctx); -void rhash_sha1_update(sha1_ctx *ctx, const unsigned char* msg, size_t size); -void rhash_sha1_final(sha1_ctx *ctx, unsigned char* result); +void rhash_sha1_init(sha1_ctx* ctx); +void rhash_sha1_update(sha1_ctx* ctx, const unsigned char* msg, size_t size); +void rhash_sha1_final(sha1_ctx* ctx, unsigned char* result); #ifdef __cplusplus } /* extern "C" */ diff --git a/Utilities/cmlibrhash/librhash/sha256.c b/Utilities/cmlibrhash/librhash/sha256.c index af5b0fe..21a69aa 100644 --- a/Utilities/cmlibrhash/librhash/sha256.c +++ b/Utilities/cmlibrhash/librhash/sha256.c @@ -1,18 +1,18 @@ /* sha256.c - an implementation of SHA-256/224 hash functions * based on FIPS 180-3 (Federal Information Processing Standart). * - * Copyright: 2010-2012 Aleksey Kravchenko <rhash.admin@gmail.com> + * Copyright (c) 2010, Aleksey Kravchenko <rhash.admin@gmail.com> * - * 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. + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted. * - * 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. Use this program at your own risk! + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. */ #include <string.h> @@ -65,7 +65,7 @@ static const unsigned rhash_k256[64] = { * * @param ctx context to initialize */ -void rhash_sha256_init(sha256_ctx *ctx) +void rhash_sha256_init(sha256_ctx* ctx) { /* Initial values. These words were obtained by taking the first 32 * bits of the fractional parts of the square roots of the first @@ -87,7 +87,7 @@ void rhash_sha256_init(sha256_ctx *ctx) * * @param ctx context to initialize */ -void rhash_sha224_init(struct sha256_ctx *ctx) +void rhash_sha224_init(struct sha256_ctx* ctx) { /* Initial values from FIPS 180-3. These words were obtained by taking * bits from 33th to 64th of the fractional parts of the square @@ -113,7 +113,7 @@ static void rhash_sha256_process_block(unsigned hash[8], unsigned block[16]) { unsigned A, B, C, D, E, F, G, H; unsigned W[16]; - const unsigned *k; + const unsigned* k; int i; A = hash[0], B = hash[1], C = hash[2], D = hash[3]; @@ -168,7 +168,7 @@ static void rhash_sha256_process_block(unsigned hash[8], unsigned block[16]) * @param msg message chunk * @param size length of the message chunk */ -void rhash_sha256_update(sha256_ctx *ctx, const unsigned char *msg, size_t size) +void rhash_sha256_update(sha256_ctx* ctx, const unsigned char* msg, size_t size) { size_t index = (size_t)ctx->length & 63; ctx->length += size; @@ -210,7 +210,7 @@ void rhash_sha256_update(sha256_ctx *ctx, const unsigned char *msg, size_t size) * @param ctx the algorithm context containing current hashing state * @param result calculated hash in binary form */ -void rhash_sha256_final(sha256_ctx *ctx, unsigned char* result) +void rhash_sha256_final(sha256_ctx* ctx, unsigned char* result) { size_t index = ((unsigned)ctx->length & 63) >> 2; unsigned shift = ((unsigned)ctx->length & 3) * 8; diff --git a/Utilities/cmlibrhash/librhash/sha256.h b/Utilities/cmlibrhash/librhash/sha256.h index f87ebaa..3625cfe 100644 --- a/Utilities/cmlibrhash/librhash/sha256.h +++ b/Utilities/cmlibrhash/librhash/sha256.h @@ -20,10 +20,10 @@ typedef struct sha256_ctx unsigned digest_length; /* length of the algorithm digest in bytes */ } sha256_ctx; -void rhash_sha224_init(sha256_ctx *ctx); -void rhash_sha256_init(sha256_ctx *ctx); -void rhash_sha256_update(sha256_ctx *ctx, const unsigned char* data, size_t length); -void rhash_sha256_final(sha256_ctx *ctx, unsigned char result[32]); +void rhash_sha224_init(sha256_ctx* ctx); +void rhash_sha256_init(sha256_ctx* ctx); +void rhash_sha256_update(sha256_ctx* ctx, const unsigned char* data, size_t length); +void rhash_sha256_final(sha256_ctx* ctx, unsigned char result[32]); #ifdef __cplusplus } /* extern "C" */ diff --git a/Utilities/cmlibrhash/librhash/sha3.c b/Utilities/cmlibrhash/librhash/sha3.c index e4a845f..bd2854f 100644 --- a/Utilities/cmlibrhash/librhash/sha3.c +++ b/Utilities/cmlibrhash/librhash/sha3.c @@ -3,18 +3,18 @@ * The Keccak SHA-3 submission. Submission to NIST (Round 3), 2011 * by Guido Bertoni, Joan Daemen, Michaƫl Peeters and Gilles Van Assche * - * Copyright: 2013 Aleksey Kravchenko <rhash.admin@gmail.com> + * Copyright (c) 2013, Aleksey Kravchenko <rhash.admin@gmail.com> * - * 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. + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted. * - * 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. Use this program at your own risk! + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. */ #include <assert.h> @@ -36,7 +36,7 @@ static uint64_t keccak_round_constants[NumberOfRounds] = { }; /* Initializing a sha3 context for given number of output bits */ -static void rhash_keccak_init(sha3_ctx *ctx, unsigned bits) +static void rhash_keccak_init(sha3_ctx* ctx, unsigned bits) { /* NB: The Keccak capacity parameter = bits * 2 */ unsigned rate = 1600 - bits * 2; @@ -51,7 +51,7 @@ static void rhash_keccak_init(sha3_ctx *ctx, unsigned bits) * * @param ctx context to initialize */ -void rhash_sha3_224_init(sha3_ctx *ctx) +void rhash_sha3_224_init(sha3_ctx* ctx) { rhash_keccak_init(ctx, 224); } @@ -61,7 +61,7 @@ void rhash_sha3_224_init(sha3_ctx *ctx) * * @param ctx context to initialize */ -void rhash_sha3_256_init(sha3_ctx *ctx) +void rhash_sha3_256_init(sha3_ctx* ctx) { rhash_keccak_init(ctx, 256); } @@ -71,7 +71,7 @@ void rhash_sha3_256_init(sha3_ctx *ctx) * * @param ctx context to initialize */ -void rhash_sha3_384_init(sha3_ctx *ctx) +void rhash_sha3_384_init(sha3_ctx* ctx) { rhash_keccak_init(ctx, 384); } @@ -81,37 +81,37 @@ void rhash_sha3_384_init(sha3_ctx *ctx) * * @param ctx context to initialize */ -void rhash_sha3_512_init(sha3_ctx *ctx) +void rhash_sha3_512_init(sha3_ctx* ctx) { rhash_keccak_init(ctx, 512); } +#define XORED_A(i) A[(i)] ^ A[(i) + 5] ^ A[(i) + 10] ^ A[(i) + 15] ^ A[(i) + 20] +#define THETA_STEP(i) \ + A[(i)] ^= D[(i)]; \ + A[(i) + 5] ^= D[(i)]; \ + A[(i) + 10] ^= D[(i)]; \ + A[(i) + 15] ^= D[(i)]; \ + A[(i) + 20] ^= D[(i)] \ + /* Keccak theta() transformation */ -static void keccak_theta(uint64_t *A) +static void keccak_theta(uint64_t* A) { - unsigned int x; - uint64_t C[5], D[5]; - - for (x = 0; x < 5; x++) { - C[x] = A[x] ^ A[x + 5] ^ A[x + 10] ^ A[x + 15] ^ A[x + 20]; - } - D[0] = ROTL64(C[1], 1) ^ C[4]; - D[1] = ROTL64(C[2], 1) ^ C[0]; - D[2] = ROTL64(C[3], 1) ^ C[1]; - D[3] = ROTL64(C[4], 1) ^ C[2]; - D[4] = ROTL64(C[0], 1) ^ C[3]; - - for (x = 0; x < 5; x++) { - A[x] ^= D[x]; - A[x + 5] ^= D[x]; - A[x + 10] ^= D[x]; - A[x + 15] ^= D[x]; - A[x + 20] ^= D[x]; - } + uint64_t D[5]; + D[0] = ROTL64(XORED_A(1), 1) ^ XORED_A(4); + D[1] = ROTL64(XORED_A(2), 1) ^ XORED_A(0); + D[2] = ROTL64(XORED_A(3), 1) ^ XORED_A(1); + D[3] = ROTL64(XORED_A(4), 1) ^ XORED_A(2); + D[4] = ROTL64(XORED_A(0), 1) ^ XORED_A(3); + THETA_STEP(0); + THETA_STEP(1); + THETA_STEP(2); + THETA_STEP(3); + THETA_STEP(4); } /* Keccak pi() transformation */ -static void keccak_pi(uint64_t *A) +static void keccak_pi(uint64_t* A) { uint64_t A1; A1 = A[1]; @@ -142,21 +142,27 @@ static void keccak_pi(uint64_t *A) /* note: A[ 0] is left as is */ } +#define CHI_STEP(i) \ + A0 = A[0 + (i)]; \ + A1 = A[1 + (i)]; \ + A[0 + (i)] ^= ~A1 & A[2 + (i)]; \ + A[1 + (i)] ^= ~A[2 + (i)] & A[3 + (i)]; \ + A[2 + (i)] ^= ~A[3 + (i)] & A[4 + (i)]; \ + A[3 + (i)] ^= ~A[4 + (i)] & A0; \ + A[4 + (i)] ^= ~A0 & A1 \ + /* Keccak chi() transformation */ -static void keccak_chi(uint64_t *A) +static void keccak_chi(uint64_t* A) { - int i; - for (i = 0; i < 25; i += 5) { - uint64_t A0 = A[0 + i], A1 = A[1 + i]; - A[0 + i] ^= ~A1 & A[2 + i]; - A[1 + i] ^= ~A[2 + i] & A[3 + i]; - A[2 + i] ^= ~A[3 + i] & A[4 + i]; - A[3 + i] ^= ~A[4 + i] & A0; - A[4 + i] ^= ~A0 & A1; - } + uint64_t A0, A1; + CHI_STEP(0); + CHI_STEP(5); + CHI_STEP(10); + CHI_STEP(15); + CHI_STEP(20); } -static void rhash_sha3_permutation(uint64_t *state) +static void rhash_sha3_permutation(uint64_t* state) { int round; for (round = 0; round < NumberOfRounds; round++) @@ -204,7 +210,7 @@ static void rhash_sha3_permutation(uint64_t *state) * @param block the message block to process * @param block_size the size of the processed block in bytes */ -static void rhash_sha3_process_block(uint64_t hash[25], const uint64_t *block, size_t block_size) +static void rhash_sha3_process_block(uint64_t hash[25], const uint64_t* block, size_t block_size) { /* expanded loop */ hash[ 0] ^= le2me_64(block[ 0]); @@ -260,7 +266,7 @@ static void rhash_sha3_process_block(uint64_t hash[25], const uint64_t *block, s * @param msg message chunk * @param size length of the message chunk */ -void rhash_sha3_update(sha3_ctx *ctx, const unsigned char *msg, size_t size) +void rhash_sha3_update(sha3_ctx* ctx, const unsigned char* msg, size_t size) { size_t index = (size_t)ctx->rest; size_t block_size = (size_t)ctx->block_size; @@ -305,7 +311,7 @@ void rhash_sha3_update(sha3_ctx *ctx, const unsigned char *msg, size_t size) * @param ctx the algorithm context containing current hashing state * @param result calculated hash in binary form */ -void rhash_sha3_final(sha3_ctx *ctx, unsigned char* result) +void rhash_sha3_final(sha3_ctx* ctx, unsigned char* result) { size_t digest_length = 100 - ctx->block_size / 2; const size_t block_size = ctx->block_size; @@ -333,7 +339,7 @@ void rhash_sha3_final(sha3_ctx *ctx, unsigned char* result) * @param ctx the algorithm context containing current hashing state * @param result calculated hash in binary form */ -void rhash_keccak_final(sha3_ctx *ctx, unsigned char* result) +void rhash_keccak_final(sha3_ctx* ctx, unsigned char* result) { size_t digest_length = 100 - ctx->block_size / 2; const size_t block_size = ctx->block_size; diff --git a/Utilities/cmlibrhash/librhash/sha3.h b/Utilities/cmlibrhash/librhash/sha3.h index 2831997..e00041d 100644 --- a/Utilities/cmlibrhash/librhash/sha3.h +++ b/Utilities/cmlibrhash/librhash/sha3.h @@ -31,12 +31,12 @@ typedef struct sha3_ctx /* methods for calculating the hash function */ -void rhash_sha3_224_init(sha3_ctx *ctx); -void rhash_sha3_256_init(sha3_ctx *ctx); -void rhash_sha3_384_init(sha3_ctx *ctx); -void rhash_sha3_512_init(sha3_ctx *ctx); -void rhash_sha3_update(sha3_ctx *ctx, const unsigned char* msg, size_t size); -void rhash_sha3_final(sha3_ctx *ctx, unsigned char* result); +void rhash_sha3_224_init(sha3_ctx* ctx); +void rhash_sha3_256_init(sha3_ctx* ctx); +void rhash_sha3_384_init(sha3_ctx* ctx); +void rhash_sha3_512_init(sha3_ctx* ctx); +void rhash_sha3_update(sha3_ctx* ctx, const unsigned char* msg, size_t size); +void rhash_sha3_final(sha3_ctx* ctx, unsigned char* result); #ifdef USE_KECCAK #define rhash_keccak_224_init rhash_sha3_224_init @@ -44,7 +44,7 @@ void rhash_sha3_final(sha3_ctx *ctx, unsigned char* result); #define rhash_keccak_384_init rhash_sha3_384_init #define rhash_keccak_512_init rhash_sha3_512_init #define rhash_keccak_update rhash_sha3_update -void rhash_keccak_final(sha3_ctx *ctx, unsigned char* result); +void rhash_keccak_final(sha3_ctx* ctx, unsigned char* result); #endif #ifdef __cplusplus diff --git a/Utilities/cmlibrhash/librhash/sha512.c b/Utilities/cmlibrhash/librhash/sha512.c index a3e681d..555e6ef 100644 --- a/Utilities/cmlibrhash/librhash/sha512.c +++ b/Utilities/cmlibrhash/librhash/sha512.c @@ -1,18 +1,18 @@ /* sha512.c - an implementation of SHA-384/512 hash functions * based on FIPS 180-3 (Federal Information Processing Standart). * - * Copyright: 2010-2012 Aleksey Kravchenko <rhash.admin@gmail.com> + * Copyright (c) 2010, Aleksey Kravchenko <rhash.admin@gmail.com> * - * 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. + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted. * - * 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. Use this program at your own risk! + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. */ #include <string.h> @@ -81,7 +81,7 @@ static const uint64_t rhash_k512[80] = { * * @param ctx context to initialize */ -void rhash_sha512_init(sha512_ctx *ctx) +void rhash_sha512_init(sha512_ctx* ctx) { /* Initial values. These words were obtained by taking the first 32 * bits of the fractional parts of the square roots of the first @@ -104,7 +104,7 @@ void rhash_sha512_init(sha512_ctx *ctx) * * @param ctx context to initialize */ -void rhash_sha384_init(struct sha512_ctx *ctx) +void rhash_sha384_init(struct sha512_ctx* ctx) { /* Initial values from FIPS 180-3. These words were obtained by taking * the first sixty-four bits of the fractional parts of the square @@ -131,7 +131,7 @@ static void rhash_sha512_process_block(uint64_t hash[8], uint64_t block[16]) { uint64_t A, B, C, D, E, F, G, H; uint64_t W[16]; - const uint64_t *k; + const uint64_t* k; int i; A = hash[0], B = hash[1], C = hash[2], D = hash[3]; @@ -186,7 +186,7 @@ static void rhash_sha512_process_block(uint64_t hash[8], uint64_t block[16]) * @param msg message chunk * @param size length of the message chunk */ -void rhash_sha512_update(sha512_ctx *ctx, const unsigned char *msg, size_t size) +void rhash_sha512_update(sha512_ctx* ctx, const unsigned char* msg, size_t size) { size_t index = (size_t)ctx->length & 127; ctx->length += size; @@ -228,7 +228,7 @@ void rhash_sha512_update(sha512_ctx *ctx, const unsigned char *msg, size_t size) * @param ctx the algorithm context containing current hashing state * @param result calculated hash in binary form */ -void rhash_sha512_final(sha512_ctx *ctx, unsigned char* result) +void rhash_sha512_final(sha512_ctx* ctx, unsigned char* result) { size_t index = ((unsigned)ctx->length & 127) >> 3; unsigned shift = ((unsigned)ctx->length & 7) * 8; diff --git a/Utilities/cmlibrhash/librhash/sha512.h b/Utilities/cmlibrhash/librhash/sha512.h index 7c689be..f80ae0d 100644 --- a/Utilities/cmlibrhash/librhash/sha512.h +++ b/Utilities/cmlibrhash/librhash/sha512.h @@ -20,10 +20,10 @@ typedef struct sha512_ctx unsigned digest_length; /* length of the algorithm digest in bytes */ } sha512_ctx; -void rhash_sha384_init(sha512_ctx *ctx); -void rhash_sha512_init(sha512_ctx *ctx); -void rhash_sha512_update(sha512_ctx *ctx, const unsigned char* data, size_t length); -void rhash_sha512_final(sha512_ctx *ctx, unsigned char* result); +void rhash_sha384_init(sha512_ctx* ctx); +void rhash_sha512_init(sha512_ctx* ctx); +void rhash_sha512_update(sha512_ctx* ctx, const unsigned char* data, size_t length); +void rhash_sha512_final(sha512_ctx* ctx, unsigned char* result); #ifdef __cplusplus } /* extern "C" */ diff --git a/Utilities/cmlibrhash/librhash/ustd.h b/Utilities/cmlibrhash/librhash/ustd.h index 019b931..917fb6b 100644 --- a/Utilities/cmlibrhash/librhash/ustd.h +++ b/Utilities/cmlibrhash/librhash/ustd.h @@ -36,4 +36,36 @@ # define uint8_t KWIML_INT_uint8_t #endif +#include <stddef.h> + +#if 0 +#if _MSC_VER > 1000 +# include <stddef.h> /* size_t for vc6.0 */ + +# if _MSC_VER >= 1600 +/* Visual Studio >= 2010 has stdint.h */ +# include <stdint.h> +# else + /* vc6.0 has bug with __int8, so using char instead */ + typedef signed char int8_t; + typedef signed __int16 int16_t; + typedef signed __int32 int32_t; + typedef signed __int64 int64_t; + typedef unsigned char uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; + typedef unsigned __int64 uint64_t; +# endif /* _MSC_VER >= 1600 */ + +/* disable warnings: The POSIX name for this item is deprecated. Use the ISO C++ conformant name. */ +# pragma warning(disable : 4996) + +#else /* _MSC_VER > 1000 */ + +# include <stdint.h> +# include <unistd.h> + +#endif /* _MSC_VER > 1000 */ +#endif + #endif /* LIBRHASH_USTD_H */ diff --git a/Utilities/cmlibrhash/librhash/util.h b/Utilities/cmlibrhash/librhash/util.h index 9f37157..57cae9b 100644 --- a/Utilities/cmlibrhash/librhash/util.h +++ b/Utilities/cmlibrhash/librhash/util.h @@ -20,7 +20,7 @@ extern "C" { # define atomic_compare_and_swap(ptr, oldval, newval) atomic_cas_32(ptr, oldval, newval) #else /* pray that it will work */ -# define atomic_compare_and_swap(ptr, oldval, newval) { if(*(ptr) == (oldval)) *(ptr) = (newval); } +# define atomic_compare_and_swap(ptr, oldval, newval) { if (*(ptr) == (oldval)) *(ptr) = (newval); } # define NO_ATOMIC_BUILTINS #endif |