Full Code of Cyan4973/xxHash for AI

dev 82cead715cbf cached
72 files
5.1 MB
1.3M tokens
507 symbols
1 requests
Download .txt
Showing preview only (5,397K chars total). Download the full file or copy to clipboard to get everything.
Repository: Cyan4973/xxHash
Branch: dev
Commit: 82cead715cbf
Files: 72
Total size: 5.1 MB

Directory structure:
gitextract_v1q1r9ds/

├── .gitattributes
├── .github/
│   ├── dependabot.yml
│   └── workflows/
│       ├── ci.yml
│       ├── cmake-cross-compile-test.yml
│       └── scorecard.yml
├── .gitignore
├── CHANGELOG
├── Doxyfile
├── Doxyfile-internal
├── LICENSE
├── Makefile
├── README.md
├── SECURITY.md
├── appveyor.yml
├── build/
│   └── make/
│       ├── README.md
│       └── multiconf.make
├── cli/
│   ├── .tipi/
│   │   ├── deps
│   │   └── opts
│   ├── COPYING
│   ├── README.md
│   ├── xsum_arch.c
│   ├── xsum_arch.h
│   ├── xsum_bench.c
│   ├── xsum_bench.h
│   ├── xsum_config.h
│   ├── xsum_os_specific.c
│   ├── xsum_os_specific.h
│   ├── xsum_output.c
│   ├── xsum_output.h
│   ├── xsum_sanity_check.c
│   ├── xsum_sanity_check.h
│   ├── xxhsum.1
│   ├── xxhsum.1.md
│   └── xxhsum.c
├── clib.json
├── doc/
│   ├── README.md
│   ├── xxhash.cry
│   └── xxhash_spec.md
├── fuzz/
│   └── fuzzer.c
├── libxxhash.pc.in
├── tests/
│   ├── Makefile
│   ├── cli-comment-line.sh
│   ├── cli-ignore-missing.sh
│   ├── collisions/
│   │   ├── .gitignore
│   │   ├── LICENSE
│   │   ├── Makefile
│   │   ├── README.md
│   │   ├── allcodecs/
│   │   │   ├── README.md
│   │   │   ├── dummy.c
│   │   │   └── dummy.h
│   │   ├── hashes.h
│   │   ├── main.c
│   │   ├── pool.c
│   │   ├── pool.h
│   │   ├── sort.cc
│   │   ├── sort.hh
│   │   ├── threading.c
│   │   └── threading.h
│   ├── filename-escape.sh
│   ├── generate_unicode_test.c
│   ├── multiInclude.c
│   ├── ppc_define.c
│   ├── sanity_test.c
│   ├── sanity_test_vectors.h
│   ├── sanity_test_vectors_generator.c
│   ├── test_alias.c
│   └── unicode_lint.sh
├── xxh3.h
├── xxh_x86dispatch.c
├── xxh_x86dispatch.h
├── xxhash.c
└── xxhash.h

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitattributes
================================================
# Set the default behavior
* text eol=lf

# Explicitly declare source files
*.c text eol=lf
*.h text eol=lf

# Denote files that should not be modified.
*.odt binary



================================================
FILE: .github/dependabot.yml
================================================
# https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
version: 2
updates:
  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "weekly"


================================================
FILE: .github/workflows/ci.yml
================================================
# Known critical issues:
# - AVX512 related tests are incomplete.  Because default environment of
#   GitHub Actions doesn't guarantee to support AVX512.
#   As of May 2021, they're using Xeon E5-2673 (which doesn't support
#   AVX512) and Xeon Platinum 8171M (which supports AVX512).
#   See also https://github.com/actions/runner/issues/1069
#
#   In this CI script, it always run `make default` which compiles xxHash
#   with AVX512 intrinsics.  But if test runner doesn't support AVX512,
#   it doesn't run `make check` which tests runtime error/consistency.
#   It means that this test stochastically detects a failure in AVX512
#   code path.
#
# Known issues:
# - This test script ignores exit code of cppcheck which can see under
#   Job:Linux x64 misc tests > cppcheck in the GitHub Actions report.
#   Because xxHash project doesn't 100% follow their recommendation.
#   Also sometimes it reports false positives.
#
# - GitHub Actions doesn't support Visual Studio 2015 and 2013.
#   https://github.com/actions/virtual-environments/issues/387
#
# - Setup procedure for msys2 environment is painfully slow.  It takes
#   3..5 minutes.
#
# Notes:
# - You can investigate various information at the right pane of GitHub
#   Actions report page.
#
#   | Item                      | Section in the right pane             |
#   | ------------------------- | ------------------------------------- |
#   | OS, VM                    | Set up job                            |
#   | git repo, commit hash     | Run actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd               |
#   | gcc, tools                | Environment info                      |
#
# - To fail earlier, order of tests in the same job are roughly sorted by
#   elapsed time.
#
# Todos:
# - [ ] Linux: Add native ARM64 runner.
# - [ ] Linux: Add native PPC64LE runner.
# - [ ] Linux: Add native S390X runner.
# - [ ] Windows: Add clang for msys2.
# - [ ] Windows: Add native or emulated ARM64 runner (note: currently unreliable)


# Name of the workflow is also displayed as a SVG badge
name: xxHash CI tests

on: [push, pull_request]

concurrency:
  group: fast-${{ github.ref }}
  cancel-in-progress: true

permissions:
  contents: read

jobs:
  xxhash-c-compilers:
    name: CC=${{ matrix.cc }}, ${{ matrix.os }}
    strategy:
      fail-fast: false  # 'false' means Don't stop matrix workflows even if some matrix entry fails.
      matrix:
        include: [
          # You can access the following values via ${{ matrix.??? }}
          #
          #   pkgs    : apt-get package names.  It can include multiple package names which are delimited by space.
          #   cc      : C compiler executable.
          #   cxx     : C++ compiler executable for `make ctocpptest`.
          #   os      : GitHub Actions YAML workflow label.  See https://github.com/actions/virtual-environments#available-environments

          # cc
          { pkgs: '',                                  cc: cc,        cxx: c++,         os: ubuntu-latest, },

          # gcc
          { pkgs: '',                                  cc: gcc,       cxx: g++,         os: ubuntu-latest, },
          { pkgs: 'gcc-14  g++-14  lib32gcc-14-dev',   cc: gcc-14,    cxx: g++-14,      os: ubuntu-24.04,  },
          { pkgs: 'gcc-13  g++-13  lib32gcc-13-dev',   cc: gcc-13,    cxx: g++-13,      os: ubuntu-24.04,  },
          { pkgs: 'gcc-12  g++-12  lib32gcc-12-dev',   cc: gcc-12,    cxx: g++-12,      os: ubuntu-22.04,  },
          { pkgs: 'gcc-11  g++-11  lib32gcc-11-dev',   cc: gcc-11,    cxx: g++-11,      os: ubuntu-22.04,  },
          { pkgs: 'gcc-10  g++-10  lib32gcc-10-dev',   cc: gcc-10,    cxx: g++-10,      os: ubuntu-22.04,  },
          { pkgs: 'gcc-9   g++-9   lib32gcc-9-dev',    cc: gcc-9,     cxx: g++-9,       os: ubuntu-22.04,  },

          # clang
          { pkgs: '',                                  cc: clang,     cxx: clang++,     os: ubuntu-latest, },
          { pkgs: 'clang-18',                          cc: clang-18,  cxx: clang++-18,  os: ubuntu-24.04,  },
          { pkgs: 'clang-17',                          cc: clang-17,  cxx: clang++-17,  os: ubuntu-24.04,  },
          { pkgs: 'clang-16',                          cc: clang-16,  cxx: clang++-16,  os: ubuntu-24.04,  },
          { pkgs: 'clang-15',                          cc: clang-15,  cxx: clang++-15,  os: ubuntu-22.04,  },
          { pkgs: 'clang-14',                          cc: clang-14,  cxx: clang++-14,  os: ubuntu-22.04,  },
          { pkgs: 'clang-13',                          cc: clang-13,  cxx: clang++-13,  os: ubuntu-22.04,  },
          { pkgs: 'clang-12',                          cc: clang-12,  cxx: clang++-12,  os: ubuntu-22.04,  },
          { pkgs: 'clang-11',                          cc: clang-11,  cxx: clang++-11,  os: ubuntu-22.04,  },
        ]

    runs-on: ${{ matrix.os }}
    env:                        # Set environment variables
      # We globally set CC and CXX to improve compatibility with .travis.yml
      CC: ${{ matrix.cc }}
      CXX: ${{ matrix.cxx }}
    steps:
    - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

    - name: apt-get install
      run: |
        sudo apt-get update
        sudo apt-get install gcc-multilib
        sudo apt-get install ${{ matrix.pkgs }}

    - name: Environment info
      run: |
        echo && type $CC && which $CC && $CC --version
        echo && type $CXX && which $CXX && $CXX --version
        echo && type make && make -v
        echo && cat /proc/cpuinfo || echo /proc/cpuinfo is not present

    - name: C90 + no-long-long compliance
      if: always()
      run: |
        CFLAGS="-std=c90 -pedantic -Wno-long-long -Werror" make clean xxhsum

    - name: C90 + XXH_NO_LONG_LONG
      if: always()
      run: |
        # strict c90, with no long long support; resulting in no XXH64_* symbol
        make clean c90test

    - name: dispatch
      if: always()
      run: |
        # removing sign conversion warnings due to a bug in gcc-5's definition of some AVX512 intrinsics
        CFLAGS="-Werror" MOREFLAGS="-Wno-sign-conversion" make clean dispatch

    - name: DISPATCH=1
      if: always()
      run: |
        CFLAGS="-Wall -Wextra -Werror" make DISPATCH=1 clean default

    - name: XXH_SIZE_OPT == 2
      if: always()
      run: |
        CFLAGS="-Os -DXXH_SIZE_OPT=2 -Wall -Wextra -Werror" make clean xxhsum

    - name: XXH_NO_XXH3
      if: always()
      run: |
        # check library can be compiled with XXH_NO_XXH3, resulting in no XXH3_* symbol
        make clean noxxh3test

    - name: XXH_NO_STREAM
      if: always()
      run: |
        # check library can be compiled with XXH_NO_STREAM, resulting in no streaming symbols
        make clean nostreamtest

    - name: make avx512f
      run: |
        CFLAGS="-O1 -mavx512f -Werror" make clean default

    - name: test-all
      if: always()
      run: |
        make clean test-all

    - name: test-alias
      run: |
        make clean
        make -C tests test_alias


  ubuntu-consistency:
    name: Linux x64 check results consistency
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

    - name: Environment info
      run: |
        echo && gcc --version
        echo && make -v
        echo && cat /proc/cpuinfo || echo /proc/cpuinfo is not present

    - name: Scalar code path
      run: |
        CPPFLAGS=-DXXH_VECTOR=XXH_SCALAR make clean check

    - name: SSE2 code path
      run: |
        CPPFLAGS=-DXXH_VECTOR=XXH_SSE2 make clean check

    - name: AVX2 code path
      run: |
        CPPFLAGS="-mavx2 -DXXH_VECTOR=XXH_AVX2" make clean check

    # As for AVX512, see "Known critical issues" at the top of this file
    - name: AVX512 code path
      run: |
        # Run "make check" if /proc/cpuinfo has flags for avx512.
        grep -q "^flags.*\bavx512\b" /proc/cpuinfo && CPPFLAGS="-mavx512f -DXXH_VECTOR=XXH_AVX512" make clean check || (echo This test runner does not support AVX512. && $(exit 0))

    - name: reroll code path (#240)
      run: |
        CPPFLAGS=-DXXH_REROLL=1 make clean check

    - name: tests/bench
      run: |
        make -C tests/bench


  ubuntu-wasm:
    name: Ubuntu Node ${{ matrix.node-version }} WebAssembly/asm.js tests
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [16.x, 17.x, 18.x]

    env:
      EM_VERSION: 3.1.33 # TODO: more emsdk versions
      EM_CACHE_FOLDER: emsdk-cache-${{ matrix.node-version }}
      CC: emcc

    steps:
    - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

    - name: Setup cache
      id: cache-system-libraries
      uses: actions/cache@v5
      with:
        path: ${{env.EM_CACHE_FOLDER}}
        key: em${{env.EM_VERSION}}-node${{ matrix.node-version }}-${{ runner.os }}

    - name: Setup emsdk
      uses: mymindstorm/setup-emsdk@v14
      with:
        version: ${{env.EM_VERSION}}
        actions-cache-folder: ${{env.EM_CACHE_FOLDER}}

    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v6
      with:
        node-version: ${{ matrix.node-version }}

    - name: Environment info
      run: |
        echo && node -p '`node version: ${process.versions.node}, v8 version: ${process.versions.v8}`'
        echo && emcc --version
        echo && make -v
        echo && cat /proc/cpuinfo || echo /proc/cpuinfo is not present

    - name: Scalar code path
      run: |
        CPPFLAGS="-DXXH_VECTOR=XXH_SCALAR" RUN_ENV="node" NODE_JS=1 make clean check

    - name: SIMD128 (via NEON SIMDe) code path (XXH_VECTOR=XXH_NEON)
      run: |
        CPPFLAGS="-DXXH_VECTOR=XXH_NEON -msimd128" RUN_ENV="node" NODE_JS=1 make clean check

    - name: Scalar asm.js (-sWASM=0)
      run: |
        CPPFLAGS="-DXXH_VECTOR=XXH_SCALAR" RUN_ENV="node" NODE_JS=1 LDFLAGS="-sWASM=0" make clean check


  ubuntu-misc:
    name: Linux x64 misc tests
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

    - name: apt-get install
      run: |
        sudo apt-get update
        sudo apt-get install valgrind cppcheck

    - name: Environment info
      run: |
        echo && gcc --version
        echo && clang --version
        echo && valgrind --version
        echo && cppcheck --version
        echo && make -v
        echo && cat /proc/cpuinfo || echo /proc/cpuinfo is not present

    - name: cppcheck
      run: |
        # This test script ignores exit code of cppcheck.  See knowin issues
        # at the top of this file.
        make clean cppcheck || echo There are some cppcheck reports

    - name: test-mem (valgrind)
      run: |
        make clean test-mem

    - name: usan
      run: |
        make clean usan

    - name: Lint Unicode in root-dir, cli/, tests/, tests/bench/, tests/collisions/.
      run: |
        make lint-unicode

    - name: test-filename-escape
      # See also issue #695 - https://github.com/Cyan4973/xxHash/issues/695
      run: |
        make clean test-filename-escape

    - name: test-cli-comment-line
      run: |
        make clean test-cli-comment-line

  ubuntu-cmake-unofficial:
    name: Linux x64 cmake unofficial build test
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

    - name: Environment info
      run: |
        echo && gcc --version
        echo && cmake --version
        echo && make -v
        echo && cat /proc/cpuinfo || echo /proc/cpuinfo is not present

    - name: Configure, build & stage (CMake)
      run: |
        BUILD_DIR="${{ github.workspace }}/cmakebuild"

        # 1) configure
        cmake -S build/cmake -B "$BUILD_DIR" \
              -DCMAKE_C_FLAGS="-Werror" \
              -DCMAKE_INSTALL_PREFIX=/usr  # real prefix inside DESTDIR

        # 2) build (uses default Makefile generator on Linux runners)
        cmake --build "$BUILD_DIR" --parallel

        # 3) staged install
        DESTDIR="$BUILD_DIR/stage" cmake --install "$BUILD_DIR" --prefix /usr

    - name: Generate & validate libxxhash.pc (CMake)
      run: |
        SRC_DIR=build/cmake
        BUILD_PKG_DIR="${{ github.workspace }}/cmakebuildpkg"

        # 1) configure an out‑of‑tree build that writes the .pc file
        cmake -S "$SRC_DIR" -B "$BUILD_PKG_DIR" \
              -DCMAKE_INSTALL_PREFIX=/usr \
              -DCMAKE_INSTALL_INCLUDEDIR=/usr/include \
              -DCMAKE_INSTALL_LIBDIR=/usr/lib

        # 2) sanity‑check the resulting pkg‑config file
        PC_FILE="$BUILD_PKG_DIR/libxxhash.pc"
        test -f "$PC_FILE"                            # file exists
        grep -q '^libdir=/usr/lib$' "$PC_FILE"
        grep -q '^includedir=/usr/include$' "$PC_FILE"

    - name: cmake minimum version v3.10 test
      run: |
        CMAKE_VERSION="3.10.0"
        CMAKE_MAJOR_MINOR="3.10"
        BASE_DIR="$(pwd)"
        DOWNLOAD_DIR="${BASE_DIR}/cmake_download"
        CMAKE_BIN_DIR="${DOWNLOAD_DIR}/cmake-${CMAKE_VERSION}-Linux-x86_64"
        CMAKE_BIN="${CMAKE_BIN_DIR}/bin/cmake"
        BUILD_DIR="${BASE_DIR}/cmake_build"
        INSTALL_TEST_DIR="${BASE_DIR}/cmake_install_test"

        # Create necessary directories
        mkdir -p "${DOWNLOAD_DIR}" "${BUILD_DIR}" "${INSTALL_TEST_DIR}"

        # Download and extract CMake
        echo "Downloading CMake ${CMAKE_VERSION}..."
        wget "https://cmake.org/files/v${CMAKE_MAJOR_MINOR}/cmake-${CMAKE_VERSION}-Linux-x86_64.tar.gz" -P "${DOWNLOAD_DIR}"
        tar xzf "${DOWNLOAD_DIR}/cmake-${CMAKE_VERSION}-Linux-x86_64.tar.gz" -C "${DOWNLOAD_DIR}"

        # Verify CMake version
        echo "Using CMake version:"
        "${CMAKE_BIN}" --version

        # Configure the build
        echo "Configuring build..."
        (cd "${BUILD_DIR}" && "${CMAKE_BIN}" "${BASE_DIR}/build/cmake")

        # Build the project
        echo "Building project..."
        "${CMAKE_BIN}" --build "${BUILD_DIR}"

        # Install to test directory
        echo "Installing to test directory..."
        DESTDIR="${INSTALL_TEST_DIR}" "${CMAKE_BIN}" --build "${BUILD_DIR}" --target install

        echo "Test completed successfully with cmake ${CMAKE_VERSION}"

        # cleaning
        rm -rf "${DOWNLOAD_DIR}" "${BUILD_DIR}" "${INSTALL_TEST_DIR}"



  # Linux, { ARM, ARM64, PPC64LE, PPC64, S390X }
  # All tests are using QEMU and gcc cross compiler.

  qemu-consistency:
    name: QEMU ${{ matrix.name }}
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false  # 'false' means Don't stop matrix workflows even if some matrix failed.
      matrix:
        include: [
          { name: 'ARM',             xcc_pkg: gcc-arm-linux-gnueabi,        xcc: arm-linux-gnueabi-gcc,        xemu_pkg: qemu-system-arm,    xemu: qemu-arm-static,     os: ubuntu-latest, },
          { name: 'AARCH64',         xcc_pkg: gcc-aarch64-linux-gnu,        xcc: aarch64-linux-gnu-gcc,        xemu_pkg: qemu-system-arm,    xemu: qemu-aarch64-static, os: ubuntu-latest, },
          { name: 'PPC64LE',         xcc_pkg: gcc-powerpc64le-linux-gnu,    xcc: powerpc64le-linux-gnu-gcc,    xemu_pkg: qemu-system-ppc,    xemu: qemu-ppc64le-static, os: ubuntu-latest, },
          { name: 'PPC64',           xcc_pkg: gcc-powerpc64-linux-gnu,      xcc: powerpc64-linux-gnu-gcc,      xemu_pkg: qemu-system-ppc,    xemu: qemu-ppc64-static,   os: ubuntu-latest, },
          { name: 'S390X',           xcc_pkg: gcc-s390x-linux-gnu,          xcc: s390x-linux-gnu-gcc,          xemu_pkg: qemu-system-s390x,  xemu: qemu-s390x-static,   os: ubuntu-latest, },
          { name: 'MIPS',            xcc_pkg: gcc-mips-linux-gnu,           xcc: mips-linux-gnu-gcc,           xemu_pkg: qemu-system-mips,   xemu: qemu-mips-static,    os: ubuntu-latest, },
          { name: 'M68K',            xcc_pkg: gcc-m68k-linux-gnu,           xcc: m68k-linux-gnu-gcc,           xemu_pkg: qemu-system-m68k,   xemu: qemu-m68k-static,    os: ubuntu-latest, },
          { name: 'RISC-V',          xcc_pkg: gcc-riscv64-linux-gnu,        xcc: riscv64-linux-gnu-gcc,        xemu_pkg: qemu-system-riscv64,xemu: qemu-riscv64-static, os: ubuntu-latest, },
          { name: 'SPARC',           xcc_pkg: gcc-sparc64-linux-gnu,        xcc: sparc64-linux-gnu-gcc,        xemu_pkg: qemu-system-sparc,  xemu: qemu-sparc64-static, os: ubuntu-latest, },
          { name: 'LoongArch',       xcc_pkg: gcc-14-loongarch64-linux-gnu, xcc: loongarch64-linux-gnu-gcc-14, xemu_pkg: qemu-system-loongarch64, xemu: qemu-loongarch64-static, os: ubuntu-24.04, },
        ]
    env:                        # Set environment variables
      XCC: ${{ matrix.xcc }}
      XEMU: ${{ matrix.xemu }}
      MOREFLAGS: -Werror
    steps:
    - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
    - name: apt update & install (1)
      run: |
        sudo apt-get update
        sudo apt-get install gcc-multilib g++-multilib qemu-utils qemu-user-static

    - name: Environment info (1)
      run: |
        echo && apt-cache search "^gcc-" | grep "linux" | sort

    - name: apt update & install (2)
      run: |
        sudo apt-get install ${{ matrix.xcc_pkg }} ${{ matrix.xemu_pkg }}

    - name: Environment info (2)
      run: |
        echo && which $XCC
        echo && $XCC --version
        echo && $XCC -v  # Show built-in specs
        echo && which $XEMU
        echo && $XEMU --version

    - name: ARM (XXH_VECTOR=[ scalar, NEON ])
      if: ${{ startsWith(matrix.name, 'ARM') }}
      run: |
        CPPFLAGS="-DXXH_VECTOR=XXH_SCALAR" LDFLAGS="-static" CC=$XCC RUN_ENV=$XEMU make clean check
        CPPFLAGS="-DXXH_VECTOR=XXH_NEON" CFLAGS="-O3 -march=armv7-a -fPIC -mfloat-abi=softfp -mfpu=neon-vfpv4" LDFLAGS="-static" CC=$XCC RUN_ENV=$XEMU make clean check
        make -C tests clean
        CPPFLAGS="-DXXH_VECTOR=XXH_SCALAR" LDFLAGS="-static" CC=$XCC RUN_ENV=$XEMU make -C tests sanity_test_vectors.h test_sanity

    - name: AARCH64 (XXH_VECTOR=[ scalar, NEON, SVE ])
      if: ${{ startsWith(matrix.name, 'AARCH64') }}
      run: |
        CPPFLAGS="-DXXH_VECTOR=XXH_SCALAR" LDFLAGS="-static" CC=$XCC RUN_ENV=$XEMU make clean check
        CPPFLAGS="-DXXH_VECTOR=XXH_NEON" LDFLAGS="-static" CC=$XCC RUN_ENV=$XEMU make clean check
        CPPFLAGS="-DXXH_VECTOR=XXH_SVE" LDFLAGS="-static" CC="$XCC -march=armv8.2-a+sve" RUN_ENV="$XEMU -cpu max,sve128=on,sve256=off,sve512=off,sve1024=off,sve2048=off" make clean check
        CPPFLAGS="-DXXH_VECTOR=XXH_SVE" LDFLAGS="-static" CC="$XCC -march=armv8.2-a+sve" RUN_ENV="$XEMU -cpu max,sve128=on,sve256=on,sve512=off,sve1024=off,sve2048=off" make clean check
        CPPFLAGS="-DXXH_VECTOR=XXH_SVE" LDFLAGS="-static" CC="$XCC -march=armv8.2-a+sve" RUN_ENV="$XEMU -cpu max,sve128=on,sve256=on,sve512=on,sve1024=off,sve2048=off" make clean check
        CPPFLAGS="-DXXH_VECTOR=XXH_SVE" LDFLAGS="-static" CC="$XCC -march=armv8.2-a+sve" RUN_ENV="$XEMU -cpu max,sve128=on,sve256=on,sve512=on,sve1024=on,sve2048=off" make clean check
        CPPFLAGS="-DXXH_VECTOR=XXH_SVE" LDFLAGS="-static" CC="$XCC -march=armv8.2-a+sve" RUN_ENV="$XEMU -cpu max,sve128=on,sve256=on,sve512=on,sve1024=on,sve2048=on" make clean check

    - name: PPC64(LE) (XXH_VECTOR=[ scalar, VSX ])
      if: ${{ startsWith(matrix.name, 'PPC64') }}
      run: |
        CPPFLAGS="-DXXH_VECTOR=XXH_SCALAR" LDFLAGS="-static" CC=$XCC RUN_ENV=$XEMU make clean check
        CPPFLAGS="-DXXH_VECTOR=XXH_VSX" CFLAGS="-O3 -maltivec -mvsx -mpower8-vector -mcpu=power8" LDFLAGS="-static" CC=$XCC RUN_ENV=$XEMU make clean check

    - name: S390X (XXH_VECTOR=[ scalar, VSX ])
      if: ${{ startsWith(matrix.name, 'S390X') }}
      run: |
        CPPFLAGS="-DXXH_VECTOR=XXH_SCALAR" LDFLAGS="-static" CC=$XCC RUN_ENV=$XEMU make clean check
        CPPFLAGS=-DXXH_VECTOR=XXH_VSX CFLAGS="-O3 -march=arch11 -mzvector" LDFLAGS="-static" CC=$XCC RUN_ENV=$XEMU make clean check

    - name: MIPS-M68K-SPARC (XXH_VECTOR=[ scalar ])
      if: ${{ startsWith(matrix.name, 'MIPS') || startsWith(matrix.name, 'M68K') || startsWith(matrix.name, 'SPARC') }}
      run: |
        make clean; LDFLAGS="-static" CC=$XCC RUN_ENV=$XEMU make check

    - name: RISCV (XXH_VECTOR=[scalar, rvv])
      if: ${{startsWith(matrix.name, 'RISC-V')}}
      run: |
        make clean; LDFLAGS="-static" CC=$XCC RUN_ENV=$XEMU make check
        CPPFLAGS="-march=rv64gcv -O2 -DXXH_VECTOR=XXH_RVV" LDFLAGS="-static" CC=$XCC RUN_ENV="$XEMU -cpu rv64,v=true,vlen=128,rvv_ta_all_1s=on,rvv_ma_all_1s=on" make clean check
        CPPFLAGS="-march=rv64gcv -O2 -DXXH_VECTOR=XXH_RVV" LDFLAGS="-static" CC=$XCC RUN_ENV="$XEMU -cpu rv64,v=true,vlen=256,rvv_ta_all_1s=on,rvv_ma_all_1s=on" make clean check
        CPPFLAGS="-march=rv64gcv -O2 -DXXH_VECTOR=XXH_RVV" LDFLAGS="-static" CC=$XCC RUN_ENV="$XEMU -cpu rv64,v=true,vlen=512,rvv_ta_all_1s=on,rvv_ma_all_1s=on" make clean check

    - name: LoongArch (XXH_VECTOR=[ scalar, LSX ])
      if: ${{ startsWith(matrix.name, 'LoongArch') }}
      run: |
        CPPFLAGS="-DXXH_VECTOR=XXH_SCALAR" LDFLAGS="-static" CC=$XCC RUN_ENV=$XEMU make clean check
        CPPFLAGS=-DXXH_VECTOR=XXH_LSX CFLAGS="-O3 -march=la464 -mlsx" LDFLAGS="-static" CC=$XCC RUN_ENV=$XEMU make clean check

  # macOS

  macos-general:
    name: ${{ matrix.system.os }}
    runs-on: ${{ matrix.system.os }}
    strategy:
      fail-fast: false  # 'false' means Don't stop matrix workflows even if some matrix failed.
      matrix:
        system: [
          { os: macos-14     },
          { os: macos-15     },
          { os: macos-latest },
        ]
    steps:
    - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

    - name: Environment info
      run: |
        echo && clang --version
        echo && sysctl -a | grep machdep.cpu   # cpuinfo

    - name: make
      run: |
        CFLAGS="-Werror" make clean default

    - name: make test
      run: |
        # test scenario where "stdout" is not the console
        make clean test MOREFLAGS='-Werror' | tee


  # Windows, { VC++2022, VC++2019 } x { x64, Win32, ARM, ARM64 }
  #
  # - Default shell for Windows environment is PowerShell Core.
  #   https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#using-a-specific-shell
  #
  # - "windows-2022" uses Visual Studio 2022.
  #   https://github.com/actions/virtual-environments/blob/main/images/win/Windows2022-Readme.md#visual-studio-enterprise-2022
  #
  # - "windows-2019" uses Visual Studio 2019.
  #   https://github.com/actions/virtual-environments/blob/main/images/win/Windows2019-Readme.md#visual-studio-enterprise-2019

  windows-visualc-general:
    name: ${{ matrix.system.vc }}, ${{ matrix.arch }}
    runs-on: ${{ matrix.system.os }}   # Runs-on foreach value of strategy.matrix.system.os
    env:
      SRC_DIR: build/cmake
    strategy:
      fail-fast: false  # 'false' means: Don't stop matrix workflows even if some matrix failed.
      matrix:
        system: [
          { os: windows-2022, vc: "VC++ 2022", clangcl: 'true', },
        ]
        arch: [ x64, Win32, ARM64 ]
    # make every PowerShell step start with `$ErrorActionPreference = 'Stop'`
    defaults:
      run:
        shell: pwsh -NoLogo -NoProfile -Command "$ErrorActionPreference='Stop'; $PSNativeCommandUseErrorActionPreference=$true; & {0}"

    steps:
    - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

    - name: Build ${{ matrix.system.os }}, ${{ matrix.arch }}
      run: |
        $BUILD_DIR   = "$env:GITHUB_WORKSPACE\cmake_visual_${{ matrix.arch }}"
        $INSTALL_DIR = "C:/install"

        cmake -S $env:SRC_DIR -B $BUILD_DIR `
              -A "${{ matrix.arch }}" `
              -DCMAKE_C_FLAGS="/W4 /WX"

        cmake --build $BUILD_DIR --config Release --parallel
        cmake --install $BUILD_DIR --config Release --prefix $INSTALL_DIR

    - name: Test produced binary
      # Run benchmark for testing only if target arch is x64 or Win32.
      if: ${{ matrix.arch == 'x64' || matrix.arch == 'Win32' }}
      run: |
        C:\install\bin\xxhsum.exe -bi1


    - name: Build ${{ matrix.system.os }}, ${{ matrix.arch }}, with DISPATCH
      # DISPATCH only if target arch is x64 or Win32.
      if: ${{ ( matrix.arch == 'x64' || matrix.arch == 'Win32' ) }}
      run: |
        $BUILD_DIR = "$env:GITHUB_WORKSPACE\cmake_visual_dispatch_${{ matrix.arch }}"
        $INSTALL_DIR = "C:/install_dispatch"

        cmake -S $env:SRC_DIR -B $BUILD_DIR `
              -A "${{ matrix.arch }}" `
              -DDISPATCH=ON `
              -DCMAKE_C_FLAGS="/W4 /WX"

        cmake --build $BUILD_DIR --config Release --parallel
        cmake --install $BUILD_DIR --config Release --prefix $INSTALL_DIR

        # Runtime test bundled, this they have same $arch conditions
        $exe = "$INSTALL_DIR\bin\xxhsum.exe"
        & "$exe" -V   | Select-String autoVec   # PowerShell’s ‘grep’
        & "$exe" -bi1


    - name: Build ${{ matrix.system.os }}, clang-cl, ${{ matrix.arch }}
      if: ${{ matrix.system.clangcl == 'true' }}
      run: |
        $BUILD_DIR = "$env:GITHUB_WORKSPACE\cmake_visual_cl_${{ matrix.arch }}"

        cmake -S $env:SRC_DIR -B $BUILD_DIR `
              -A "${{ matrix.arch }}" `
              -DCMAKE_GENERATOR_TOOLSET=ClangCL `
              -DCMAKE_C_FLAGS="/W4 /WX"

        cmake --build $BUILD_DIR --config Release --parallel
        cmake --install $BUILD_DIR --config Release --prefix "C:/install_cl"

    - name: Test (clang-cl)
      # Run benchmark for testing only if target arch is x64 or Win32.
      if: ${{ matrix.system.clangcl == 'true' && ( matrix.arch == 'x64' || matrix.arch == 'Win32' ) }}
      run: |
        C:\install_cl\bin\xxhsum.exe -bi1


  # Windows, { mingw64, mingw32 }
  #
  # - Shell for msys2 is sh (msys2).  defaults.run.shell is for this setting.
  #
  # https://github.com/msys2/MINGW-packages/blob/master/.github/workflows/main.yml
  # https://github.com/actions/starter-workflows/issues/95

  windows-msys2-general:
    name: Windows ${{ matrix.msystem }}
    runs-on: windows-latest
    strategy:
      fail-fast: false  # 'false' means Don't stop matrix workflows even if some matrix failed.
      matrix:
        include: [
          { msystem: mingw64, toolchain: mingw-w64-x86_64-toolchain },
          { msystem: mingw32, toolchain: mingw-w64-i686-toolchain },
        ]
    defaults:
      run:
        shell: msys2 {0}
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
      - uses: msys2/setup-msys2@7efe20baefed56359985e327d329042cde2434ff # v2
        with:
          msystem: MSYS
          install: mingw-w64-i686-make ${{ matrix.toolchain }}
          update: true

      - name: Update
        run: |
          pacman --noconfirm -Suuy
          pacman --noconfirm -Suu

      - name: mingw64
        if: ${{ matrix.msystem == 'mingw64' }}
        run: |
          PATH=/mingw64/bin:$PATH /mingw32/bin/mingw32-make clean test gcc-og-test MOREFLAGS=-Werror
          PATH=/mingw64/bin:$PATH /mingw32/bin/mingw32-make -C tests/bench
          # Abort if result of "file ./xxhsum.exe" doesn't contain 'x86-64'.
          # Expected output is "./xxhsum.exe: PE32+ executable (console) x86-64, for MS Windows"
          file ./xxhsum.exe
          file ./xxhsum.exe | grep -q 'x86-64' || $(exit 1)
          ./xxhsum.exe --version

      - name: mingw32
        if: ${{ matrix.msystem == 'mingw32' }}
        run: |
          PATH=/mingw32/bin:$PATH /mingw32/bin/mingw32-make.exe clean test MOREFLAGS=-Werror
          PATH=/mingw32/bin:$PATH /mingw32/bin/mingw32-make.exe -C tests/bench
          # Abort if result of "file ./xxhsum.exe" doesn't contain '80386'.
          # Expected output is "./xxhsum.exe: PE32 executable (console) Intel i386, for MS Windows"
          file ./xxhsum.exe
          file ./xxhsum.exe | grep -q '386' || $(exit 1)
          ./xxhsum.exe --version


================================================
FILE: .github/workflows/cmake-cross-compile-test.yml
================================================
name: CMake Cross-Compile Test

on: [push, pull_request]

permissions:
  contents: read

jobs:
  cmake-cross-compile-host-vs-target:
    name: Cross-compile x86_64 → ARM64 (shows host/target bug)
    runs-on: ubuntu-latest
    
    steps:
      - uses: actions/checkout@v6.0.2
      
      - name: Install ARM64 cross-compiler
        run: |
          sudo apt-get update
          sudo apt-get install -y gcc-aarch64-linux-gnu
      
      - name: Create ARM64 toolchain file
        run: |
          cat > /tmp/arm64-toolchain.cmake << 'EOF'
          set(CMAKE_SYSTEM_NAME Linux)
          set(CMAKE_SYSTEM_PROCESSOR aarch64)
          set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc)
          EOF
      
      - name: Configure with DISPATCH (demonstrates bug)
        run: |
          cmake -S build/cmake -B build_cross \
                -DCMAKE_TOOLCHAIN_FILE=/tmp/arm64-toolchain.cmake \
                -DDISPATCH=ON
      
      - name: Build (expected to fail)
        run: |
          # Bug: CMAKE_HOST_SYSTEM_INFORMATION detects x86_64 (host) instead of aarch64 (target)
          # Result: Enables x86 dispatch code which fails to compile for ARM64
          cmake --build build_cross


================================================
FILE: .github/workflows/scorecard.yml
================================================
# This workflow uses actions that are not certified by GitHub. They are provided
# by a third-party and are governed by separate terms of service, privacy
# policy, and support documentation.

name: Scorecard supply-chain security
on:
  # For Branch-Protection check. Only the default branch is supported. See
  # https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection
  branch_protection_rule:
  # To guarantee Maintained check is occasionally updated. See
  # https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained
  schedule:
    - cron: '35 19 * * 2'
  push:
    branches: [ "dev" ]

# Declare default permissions as read only.
permissions: read-all

jobs:
  analysis:
    name: Scorecard analysis
    runs-on: ubuntu-latest
    permissions:
      # Needed to upload the results to code-scanning dashboard.
      security-events: write
      # Needed to publish results and get a badge (see publish_results below).
      id-token: write
      # Uncomment the permissions below if installing in a private repository.
      # contents: read
      # actions: read

    steps:
      - name: "Checkout code"
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false

      - name: "Run analysis"
        uses: ossf/scorecard-action@05b42c624433fc40578a4040d5cf5e36ddca8cde # v2.4.2
        with:
          results_file: results.sarif
          results_format: sarif
          # (Optional) "write" PAT token. Uncomment the `repo_token` line below if:
          # - you want to enable the Branch-Protection check on a *public* repository, or
          # - you are installing Scorecard on a *private* repository
          # To create the PAT, follow the steps in https://github.com/ossf/scorecard-action#authentication-with-pat.
          # repo_token: ${{ secrets.SCORECARD_TOKEN }}

          # Public repositories:
          #   - Publish results to OpenSSF REST API for easy access by consumers
          #   - Allows the repository to include the Scorecard badge.
          #   - See https://github.com/ossf/scorecard-action#publishing-results.
          # For private repositories:
          #   - `publish_results` will always be set to `false`, regardless
          #     of the value entered here.
          publish_results: true

      # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
      # format to the repository Actions tab.
      - name: "Upload artifact"
        uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
        with:
          name: SARIF file
          path: results.sarif
          retention-days: 5

      # Upload the results to GitHub's code scanning dashboard.
      - name: "Upload to code-scanning"
        uses: github/codeql-action/upload-sarif@c6c77c8c2d62cfd5b2e8d548817fd3d1582ac744 # v2.14.5
        with:
          sarif_file: results.sarif


================================================
FILE: .gitignore
================================================
# objects
*.o
*.obj
*.s

# libraries
libxxhash.*
!libxxhash.pc.in

# Executables
*.exe
xxh32sum
xxh64sum
xxh128sum
xxh3sum
xxhsum
xxhsum32
xxhsum_privateXXH
xxhsum_inlinedXXH
dispatch
tests/generate_unicode_test
tests/sanity_test
tests/sanity_test_vectors_generator
tests/test_alias
fuzzer

# Mac OS-X artefacts
*.dSYM
.DS_Store

# Wasm / emcc / emscripten artefacts
*.html
*.wasm
*.js

# build artifacts
cachedObjs/
cmakebuild/


# project managers artifacts
.projectile

# analyzer artifacts
infer-out

# test artifacts
.test*
tmp*
tests/*.unicode
tests/unicode_test*
*.txt
!CMakeLists.txt
*.xxhsum

# editor artifacts
.clang_complete
.clangd
*.swp
.vscode/
.vs/

# Doxygen
doxygen/


================================================
FILE: CHANGELOG
================================================
v0.8.3
- fix  : variant `XXH3_128bits_withSecretandSeed()` could produce an invalid result in some specific set of conditions, #894 by @hltj
- cli  : vector extension detected at runtime on x86/x64, enabled by default
- cli  : new commands `--filelist` and `--files-from`, by @Ian-Clowes
- cli  : XXH3 64-bits GNU format can now be generated and checked (command `-H3`)
- portability: LoongArch SX SIMD extension, by @lrzlin
- portability: can build on AIX, suggested by @likema
- portability: validated for SPARC cpus

v0.8.2
- fix  : XXH3 S390x vector implementation (@hzhuang1)
- fix  : PowerPC vector compilation with IBM XL compiler (@MaxiBoether)
- perf : improved WASM speed by x2/x3 using SIMD128 (@easyaspi314)
- perf : improved speed (+20%) for XXH3 on ARM NEON (@easyaspi314)
- cli  : Fix filename contain /LF character (@t-mat)
- cli  : Support # comment lines in --check files (@t-mat)
- cli  : Support commands --binary and --ignore-missing (@t-mat)
- build: fix -Og compilation (@easyaspi314, @t-mat)
- build: fix pkgconfig generation with cmake (@ilya-fedin)
- build: fix icc compilation
- build: fix cmake install directories
- build: new build options XXH_NO_XXH3, XXH_SIZE_OPT and XXH_NO_STREAM to reduce binary size (@easyaspi314)
- build: dedicated install targets (@ffontaine)
- build: support DISPATCH mode in cmake (@hzhuang1)
- portability: fix x86dispatch when building with Visual + clang-cl (@t-mat)
- portability: SVE vector implementation of XXH3 (@hzhuang1)
- portability: compatibility with freestanding environments, using XXH_NO_STDLIB
- portability: can build on Haiku (@Begasus)
- portability: validated on m68k and risc-v
- doc  : XXH3 specification (@Adrien1018)
- doc  : improved doxygen documentation (@easyaspi314, @t-mat)
- misc : dedicated sanity test binary (@t-mat)

v0.8.1
- perf : much improved performance for XXH3 streaming variants, notably on gcc and msvc
- perf : improved XXH64 speed and latency on small inputs
- perf : small XXH32 speed and latency improvement on small inputs of random size
- perf : minor stack usage improvement for XXH32 and XXH64
- api  : new experimental variants XXH3_*_withSecretandSeed()
- api  : update XXH3_generateSecret(), can no generate secret of any size (>= XXH3_SECRET_SIZE_MIN)
- cli  : xxhsum can now generate and check XXH3 checksums, using command `-H3`
- build: can build xxhash without XXH3, with new build macro XXH_NO_XXH3
- build: fix xxh_x86dispatch build with MSVC, by @apankrat
- build: XXH_INLINE_ALL can always be used safely, even after XXH_NAMESPACE or a previous XXH_INLINE_ALL
- build: improved PPC64LE vector support, by @mpe
- install: fix pkgconfig, by @ellert
- install: compatibility with Haiku, by @Begasus
- doc  : code comments made compatible with doxygen, by @easyaspi314
- misc : XXH_ACCEPT_NULL_INPUT_POINTER is no longer necessary, all functions can accept NULL input pointers, as long as size == 0
- misc : complete refactor of CI tests on Github Actions, offering much larger coverage, by @t-mat
- misc : xxhsum code base split into multiple specialized units, within directory cli/, by @easyaspi314

v0.8.0
- api : stabilize XXH3
- cli : xxhsum can parse BSD-style --check lines, by @WayneD
- cli : `xxhsum -` accepts console input, requested by @jaki
- cli : xxhsum accepts -- separator, by @jaki
- cli : fix : print correct default algo for symlinked helpers, by @martinetd
- install: improved pkgconfig script, allowing custom install locations, requested by @ellert

v0.7.4
- perf: automatic vector detection and selection at runtime (`xxh_x86dispatch.h`), initiated by @easyaspi314
- perf: added AVX512 support, by @gzm55
- api : new: secret generator `XXH_generateSecret()`, suggested by @koraa
- api : fix: XXH3_state_t is movable, identified by @koraa
- api : fix: state is correctly aligned in AVX mode (unlike `malloc()`), by @easyaspi314
- api : fix: streaming generated wrong values in some combination of random ingestion lengths, reported by @WayneD
- cli : fix unicode print on Windows, by @easyaspi314
- cli : can `-c` check file generated by sfv
- build: `make DISPATCH=1` generates `xxhsum` and `libxxhash` with runtime vector detection (x86/x64 only)
- install: cygwin installation support
- doc : Cryptol specification of XXH32 and XXH64, by @weaversa

v0.7.3
- perf: improved speed for large inputs (~+20%)
- perf: improved latency for small inputs (~10%)
- perf: s390x Vectorial code, by @easyaspi314
- cli: improved support for Unicode filenames on Windows, thanks to @easyaspi314 and @t-mat
- api: `xxhash.h` can now be included in any order, with and without `XXH_STATIC_LINKING_ONLY` and `XXH_INLINE_ALL`
- build: xxHash's implementation transferred into `xxhash.h`. No more need to have `xxhash.c` in the `/include` directory for `XXH_INLINE_ALL` to work
- install: created pkg-config file, by @bket
- install: VCpkg installation instructions, by @LilyWangL
- doc: Highly improved code documentation, by @easyaspi314
- misc: New test tool in `/tests/collisions`: brute force collision tester for 64-bit hashes

v0.7.2
- Fixed collision ratio of `XXH128` for some specific input lengths, reported by @svpv
- Improved `VSX` and `NEON` variants, by @easyaspi314
- Improved performance of scalar code path (`XXH_VECTOR=0`), by @easyaspi314
- `xxhsum`: can generate 128-bit hashes with the `-H2` option (note: for experimental purposes only! `XXH128` is not yet frozen)
- `xxhsum`: option `-q` removes status notifications

v0.7.1
- Secret first: the algorithm computation can be altered by providing a "secret", which is any blob of bytes, of size >= `XXH3_SECRET_SIZE_MIN`.
- `seed` is still available, and acts as a secret generator
- updated `ARM NEON` variant by @easyaspi314
- Streaming implementation is available
- Improve compatibility and performance with Visual Studio, with help from @aras-p
- Better integration when using `XXH_INLINE_ALL`: do not pollute host namespace, use its own macros, such as `XXH_ASSERT()`, `XXH_ALIGN`, etc.
- 128-bit variant provides helper functions for comparison of hashes.
- Better `clang` generation of `rotl` instruction, thanks to @easyaspi314
- `XXH_REROLL` build macro to reduce binary size, by @easyaspi314
- Improved `cmake` script, by @Mezozoysky
- Full benchmark program provided in `/tests/bench`


================================================
FILE: Doxyfile
================================================
# Doxygen config for xxHash
DOXYFILE_ENCODING      = UTF-8

PROJECT_NAME           = "xxHash"
PROJECT_NUMBER         = "0.8.3"
PROJECT_BRIEF          = "Extremely fast non-cryptographic hash function"
OUTPUT_DIRECTORY       = doxygen
OUTPUT_LANGUAGE        = English

# We already separate the internal docs.
INTERNAL_DOCS          = NO
# Consistency
SORT_MEMBER_DOCS       = NO
BRIEF_MEMBER_DESC      = YES
REPEAT_BRIEF           = YES

# Warnings
QUIET                  = YES
# Until we document everything
WARN_IF_UNDOCUMENTED   = NO

# TODO: Add the other files. It is just xxhash.h for now.
FILE_PATTERNS          = xxhash.h xxh_x86dispatch.c
# Note: xxHash's source files are technically ASCII only.
INPUT_ENCODING         = UTF-8
TAB_SIZE               = 4
MARKDOWN_SUPPORT       = YES

# xxHash is a C library
OPTIMIZE_OUTPUT_FOR_C  = YES
# We hide private part from public document
EXTRACT_STATIC         = NO
# We hide private part from public document
EXTRACT_PRIVATE        = NO
# Document the macros
MACRO_EXPANSION        = YES
EXPAND_ONLY_PREDEF     = YES
# Predefine some macros to clean up the output.
PREDEFINED             = "XXH_DOXYGEN=" \
                         "XXH_PUBLIC_API=" \
                         "XXH_NOESCAPE=" \
                         "XXH_FORCE_INLINE=static inline" \
                         "XXH_NO_INLINE=static" \
                         "XXH_RESTRICT=restrict" \
                         "XSUM_API=" \
                         "XXH_STATIC_LINKING_ONLY" \
                         "XXH_IMPLEMENTATION" \
                         "XXH_PUREF=[[gnu::pure]]" \
                         "XXH_CONSTF=[[gnu::const]]" \
                         "XXH_MALLOCF=[[gnu::malloc]]" \
                         "XXH_ALIGN(N)=alignas(N)" \
                         "XXH_ALIGN_MEMBER(align,type)=alignas(align) type"

# We want HTML docs
GENERATE_HTML          = YES
HTML_OUTPUT            = html
HTML_FILE_EXTENSION    = .html
# Tweak the colors a bit
HTML_COLORSTYLE_HUE    = 220
HTML_COLORSTYLE_GAMMA  = 100
HTML_COLORSTYLE_SAT    = 100

# We don't want LaTeX.
GENERATE_LATEX         = NO


================================================
FILE: Doxyfile-internal
================================================
# Doxygen config for xxHash
DOXYFILE_ENCODING      = UTF-8

PROJECT_NAME           = "xxHash"
PROJECT_NUMBER         = "0.8.2"
PROJECT_BRIEF          = "Extremely fast non-cryptographic hash function"
OUTPUT_DIRECTORY       = doxygen
OUTPUT_LANGUAGE        = English

# We already separate the internal docs.
INTERNAL_DOCS          = YES
# Consistency
SORT_MEMBER_DOCS       = NO
BRIEF_MEMBER_DESC      = YES
REPEAT_BRIEF           = YES

# Warnings
QUIET                  = YES
# Until we document everything
WARN_IF_UNDOCUMENTED   = NO

# TODO: Add the other files. It is just xxhash.h for now.
FILE_PATTERNS          = xxhash.h xxh_x86dispatch.c
# Note: xxHash's source files are technically ASCII only.
INPUT_ENCODING         = UTF-8
TAB_SIZE               = 4
MARKDOWN_SUPPORT       = YES

# xxHash is a C library
OPTIMIZE_OUTPUT_FOR_C  = YES
# So we can document the internals
EXTRACT_STATIC         = YES
# We show private part in the internal document
EXTRACT_PRIVATE        = YES
# Document the macros
MACRO_EXPANSION        = YES
EXPAND_ONLY_PREDEF     = YES
# Predefine some macros to clean up the output.
PREDEFINED             = "XXH_DOXYGEN=" \
                         "XXH_PUBLIC_API=" \
                         "XXH_NOESCAPE=" \
                         "XXH_FORCE_INLINE=static inline" \
                         "XXH_NO_INLINE=static" \
                         "XXH_RESTRICT=restrict" \
                         "XSUM_API=" \
                         "XXH_STATIC_LINKING_ONLY" \
                         "XXH_IMPLEMENTATION" \
                         "XXH_PUREF=[[gnu::pure]]" \
                         "XXH_CONSTF=[[gnu::const]]" \
                         "XXH_MALLOCF=[[gnu::malloc]]" \
                         "XXH_ALIGN(N)=alignas(N)" \
                         "XXH_ALIGN_MEMBER(align,type)=alignas(align) type"

# We want HTML docs
GENERATE_HTML          = YES
HTML_OUTPUT            = html
HTML_FILE_EXTENSION    = .html
# Tweak the colors a bit
HTML_COLORSTYLE_HUE    = 220
HTML_COLORSTYLE_GAMMA  = 100
HTML_COLORSTYLE_SAT    = 100

# We don't want LaTeX.
GENERATE_LATEX         = NO


================================================
FILE: LICENSE
================================================
xxHash Library
Copyright (c) 2012-2021 Yann Collet
All rights reserved.

BSD 2-Clause License (https://www.opensource.org/licenses/bsd-license.php)

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice, this
  list of conditions and the following disclaimer in the documentation and/or
  other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


================================================
FILE: Makefile
================================================
# ################################################################
# xxHash Makefile
# Copyright (C) 2012-2024 Yann Collet
#
# GPL v2 License
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# You can contact the author at:
#   - xxHash homepage: https://www.xxhash.com
#   - xxHash source repository: https://github.com/Cyan4973/xxHash
# ################################################################
# xxhsum: provides 32/64 bits hash of one or multiple files, or stdin
# ################################################################

# Version numbers
SED ?= sed
SED_ERE_OPT ?= -E
LIBVER_MAJOR_SCRIPT:=`$(SED) -n '/define XXH_VERSION_MAJOR/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < xxhash.h`
LIBVER_MINOR_SCRIPT:=`$(SED) -n '/define XXH_VERSION_MINOR/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < xxhash.h`
LIBVER_PATCH_SCRIPT:=`$(SED) -n '/define XXH_VERSION_RELEASE/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < xxhash.h`
LIBVER_MAJOR := $(shell echo $(LIBVER_MAJOR_SCRIPT))
LIBVER_MINOR := $(shell echo $(LIBVER_MINOR_SCRIPT))
LIBVER_PATCH := $(shell echo $(LIBVER_PATCH_SCRIPT))
LIBVER := $(LIBVER_MAJOR).$(LIBVER_MINOR).$(LIBVER_PATCH)

MAKEFLAGS += --no-print-directory
CFLAGS ?= -O3
DEBUGFLAGS+=-Wall -Wextra -Wconversion -Wcast-qual -Wcast-align -Wshadow \
            -Wstrict-aliasing=1 -Wswitch-enum -Wdeclaration-after-statement \
            -Wstrict-prototypes -Wundef -Wpointer-arith -Wformat-security \
            -Wvla -Wformat=2 -Winit-self -Wfloat-equal -Wwrite-strings \
            -Wredundant-decls -Wstrict-overflow=2
CFLAGS += $(DEBUGFLAGS) $(MOREFLAGS)
FLAGS   = $(CFLAGS) $(CPPFLAGS)
XXHSUM_VERSION = $(LIBVER)

# Define *.exe as extension for Windows systems
ifneq (,$(filter Windows%,$(OS)))
EXT =.exe
else
EXT =
endif

# automatically enable runtime vector dispatch on x86/64 targets
detect_x86_arch = $(shell $(CC) -dumpmachine | grep -E 'i[3-6]86|x86_64')
ifneq ($(strip $(call detect_x86_arch)),)
    #note: can be overridden at compile time, by setting DISPATCH=0
    DISPATCH ?= 1
else
    ifeq ($(DISPATCH),1)
        $(info "Note: DISPATCH=1 is only supported on x86/x64 targets")
    endif
    override DISPATCH := 0
endif

ifeq ($(NODE_JS),1)
    # Link in unrestricted filesystem support
    LDFLAGS += -sNODERAWFS
    # Set flag to fix isatty() support
    CPPFLAGS += -DXSUM_NODE_JS=1
endif

# OS X linker doesn't support -soname, and use different extension
# see: https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/DynamicLibraryDesignGuidelines.html
UNAME ?= $(shell uname)
ifeq ($(UNAME), Darwin)
	SHARED_EXT = dylib
	SHARED_EXT_MAJOR = $(LIBVER_MAJOR).$(SHARED_EXT)
	SHARED_EXT_VER = $(LIBVER).$(SHARED_EXT)
	SONAME_FLAGS = -install_name $(LIBDIR)/libxxhash.$(SHARED_EXT_MAJOR) -compatibility_version $(LIBVER_MAJOR) -current_version $(LIBVER)
else
	SONAME_FLAGS = -Wl,-soname=libxxhash.$(SHARED_EXT).$(LIBVER_MAJOR)
	SHARED_EXT = so
	SHARED_EXT_MAJOR = $(SHARED_EXT).$(LIBVER_MAJOR)
	SHARED_EXT_VER = $(SHARED_EXT).$(LIBVER)
endif

LIBXXH = libxxhash.$(SHARED_EXT_VER)

CLI_DIR = cli
CLI_SRCS = $(wildcard $(CLI_DIR)/*.c)
CLI_OBJS = $(CLI_SRCS:.c=.o)

## define default before including multiconf.make
## generate CLI and libraries in release mode (default for `make`)
.PHONY: default
default: DEBUGFLAGS=
default: lib xxhsum_and_links

C_SRCDIRS = . $(CLI_DIR) fuzz
include build/make/multiconf.make

.PHONY: all
all: lib xxhsum xxhsum_inlinedXXH

## xxhsum is the command line interface (CLI)
ifeq ($(DISPATCH),1)
xxhsum: CPPFLAGS += -DXXHSUM_DISPATCH=1
XXHSUM_ADD_O = xxh_x86dispatch.o
endif
$(eval $(call c_program,xxhsum,xxhash.o $(CLI_OBJS) $(XXHSUM_ADD_O)))

.PHONY: xxhsum_and_links
xxhsum_and_links: xxhsum xxh32sum xxh64sum xxh128sum xxh3sum

LN ?= ln

xxh32sum xxh64sum xxh128sum xxh3sum: xxhsum
	$(LN) -sf $<$(EXT) $@$(EXT)

## generate CLI in 32-bits mode
xxhsum32: CFLAGS += -m32
ifeq ($(DISPATCH),1)
xxhsum32: CPPFLAGS += -DXXHSUM_DISPATCH=1
endif
$(eval $(call c_program,xxhsum32,xxhash.o $(CLI_OBJS) $(XXHSUM_ADD_O)))

## Warning: dispatch only works for x86/x64 systems
dispatch: CPPFLAGS += -DXXHSUM_DISPATCH=1
$(eval $(call c_program,dispatch,xxhash.o xxh_x86dispatch.o $(CLI_OBJS)))

xxhsum_inlinedXXH: CPPFLAGS += -DXXH_INLINE_ALL
$(eval $(call c_program,xxhsum_inlinedXXH,$(CLI_OBJS)))


# =================================================
# library

libxxhash.a:
$(eval $(call static_library,libxxhash.a,xxhash.o))

$(LIBXXH): LDFLAGS += $(SONAME_FLAGS)
ifeq (,$(filter Windows%,$(OS)))
$(LIBXXH): CFLAGS += -fPIC
endif
LIBXXHASH_OBJS := xxhash.o $(if $(filter 1,$(LIBXXH_DISPATCH)),xxh_x86dispatch.o)
$(eval $(call c_dynamic_library,$(LIBXXH),$(LIBXXHASH_OBJS)))

libxxhash.$(SHARED_EXT_MAJOR): $(LIBXXH)
	$(LN) -sf $< $@

libxxhash.$(SHARED_EXT): libxxhash.$(SHARED_EXT_MAJOR)
	$(LN) -sf $< $@

.PHONY: libxxhash  ## generate dynamic xxhash library
libxxhash: $(LIBXXH) libxxhash.$(SHARED_EXT_MAJOR) libxxhash.$(SHARED_EXT)

.PHONY: lib  ## generate static and dynamic xxhash libraries
lib: libxxhash.a libxxhash


# helper targets

AWK  ?= awk
GREP ?= grep
SORT ?= sort
NM   ?= nm

.PHONY: list
list:  ## list all Makefile targets
	$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | $(AWK) -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | $(SORT) | egrep -v -e '^[^[:alnum:]]' -e '^$@$$' | xargs

.PHONY: help
help:  ## list documented targets
	$(GREP) -E '^[0-9a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \
	$(SORT) | \
	$(AWK) 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'

.PHONY: clean
clean:
	$(RM) -r *.dSYM   # Mac OS-X specific
	$(RM) core *.o *.obj *.$(SHARED_EXT) *.$(SHARED_EXT).* *.a libxxhash.pc
	$(RM) xxhsum.wasm xxhsum.js xxhsum.html
	$(RM) xxh32sum$(EXT) xxh64sum$(EXT) xxh128sum$(EXT) xxh3sum$(EXT)
	$(RM) fuzzer
	$(MAKE) -C tests clean
	$(MAKE) -C tests/bench clean
	$(MAKE) -C tests/collisions clean
	@echo cleaning completed


# =================================================
# tests
# =================================================

# make check can be run with cross-compiled binaries on emulated environments (qemu user mode)
# by setting $(RUN_ENV) to the target emulation environment
.PHONY: check
check: xxhsum test_sanity   ## basic tests for xxhsum CLI, set RUN_ENV for emulated environments
	# stdin
	# If you get "Wrong parameters" on Emscripten+Node.js, recompile with `NODE_JS=1`
	$(RUN_ENV) ./xxhsum$(EXT) < xxhash.c
	# multiple files
	$(RUN_ENV) ./xxhsum$(EXT) xxhash.*
	# internal bench
	$(RUN_ENV) ./xxhsum$(EXT) -bi0
	# long bench command
	$(RUN_ENV) ./xxhsum$(EXT) --benchmark-all -i0
	# bench multiple variants
	$(RUN_ENV) ./xxhsum$(EXT) -b1,2,3 -i0
	# file bench
	$(RUN_ENV) ./xxhsum$(EXT) -bi0 xxhash.c
	# 32-bit
	$(RUN_ENV) ./xxhsum$(EXT) -H0 xxhash.c
	# 128-bit
	$(RUN_ENV) ./xxhsum$(EXT) -H2 xxhash.c
	# XXH3 (enforce BSD style)
	$(RUN_ENV) ./xxhsum$(EXT) -H3 xxhash.c | grep "XXH3"
	# request incorrect variant
	$(RUN_ENV) ./xxhsum$(EXT) -H9 xxhash.c ; test $$? -eq 1
	@printf "\n .......   checks completed successfully   ....... \n"

.PHONY: test-unicode
test-unicode:
	$(MAKE) -C tests test_unicode

.PHONY: test_sanity
test_sanity:
	$(MAKE) -C tests test_sanity

.PHONY: test-mem
VALGRIND = valgrind --leak-check=yes --error-exitcode=1
test-mem: RUN_ENV = $(VALGRIND)
test-mem: xxhsum check

.PHONY: test32
test32: xxhsum32
	@echo ---- test 32-bit ----
	./xxhsum32 -bi0 xxhash.c

TEST_FILES = xxhsum$(EXT) xxhash.c xxhash.h
.PHONY: test-xxhsum-c
test-xxhsum-c: xxhsum
	# xxhsum to/from pipe
	./xxhsum $(TEST_FILES) | ./xxhsum -c -
	./xxhsum -H0 $(TEST_FILES) | ./xxhsum -c -
	# xxhsum -c is unable to verify checksum of file from STDIN (#470)
	./xxhsum < README.md > .test.README.md.xxh
	./xxhsum -c .test.README.md.xxh < README.md
	# xxhsum -q does not display "Loading" message into stderr (#251)
	! ./xxhsum -q $(TEST_FILES) 2>&1 | grep Loading
	# xxhsum does not display "Loading" message into stderr either
	! ./xxhsum $(TEST_FILES) 2>&1 | grep Loading
	# Check that xxhsum do display filename that it failed to open.
	LC_ALL=C ./xxhsum nonexistent 2>&1 | grep "Error: Could not open 'nonexistent'"
	# xxhsum to/from file, shell redirection
	./xxhsum $(TEST_FILES) > .test.xxh64
	./xxhsum --tag $(TEST_FILES) > .test.xxh64_tag
	./xxhsum --little-endian $(TEST_FILES) > .test.le_xxh64
	./xxhsum --tag --little-endian $(TEST_FILES) > .test.le_xxh64_tag
	./xxhsum -H0 $(TEST_FILES) > .test.xxh32
	./xxhsum -H0 --tag $(TEST_FILES) > .test.xxh32_tag
	./xxhsum -H0 --little-endian $(TEST_FILES) > .test.le_xxh32
	./xxhsum -H0 --tag --little-endian $(TEST_FILES) > .test.le_xxh32_tag
	./xxhsum -H2 $(TEST_FILES) > .test.xxh128
	./xxhsum -H2 --tag $(TEST_FILES) > .test.xxh128_tag
	./xxhsum -H2 --little-endian $(TEST_FILES) > .test.le_xxh128
	./xxhsum -H2 --tag --little-endian $(TEST_FILES) > .test.le_xxh128_tag
	./xxhsum -H3 $(TEST_FILES) > .test.xxh3
	./xxhsum -H3 --tag $(TEST_FILES) > .test.xxh3_tag
	./xxhsum -H3 --little-endian $(TEST_FILES) > .test.le_xxh3
	./xxhsum -H3 --tag --little-endian $(TEST_FILES) > .test.le_xxh3_tag
	./xxhsum -c .test.xxh*
	./xxhsum -c --little-endian .test.le_xxh*
	./xxhsum -c .test.*_tag
	# read list of files from stdin
	./xxhsum -c < .test.xxh32
	./xxhsum -c < .test.xxh64
	./xxhsum -c < .test.xxh128
	./xxhsum -c < .test.xxh3
	cat .test.xxh* | ./xxhsum -c -
	# check variant with '*' marker as second separator
	$(SED) 's/  / \*/' .test.xxh32 | ./xxhsum -c
	# bsd-style output
	./xxhsum --tag xxhsum* | $(GREP) XXH64
	./xxhsum --tag -H0 xxhsum* | $(GREP) XXH32
	./xxhsum --tag -H1 xxhsum* | $(GREP) XXH64
	./xxhsum --tag -H2 xxhsum* | $(GREP) XXH128
	./xxhsum --tag -H3 xxhsum* | $(GREP) XXH3
	./xxhsum       -H3 xxhsum* | $(GREP) XXH3_ # prefix for GNU format
	./xxhsum --tag -H32 xxhsum* | $(GREP) XXH32
	./xxhsum --tag -H64 xxhsum* | $(GREP) XXH64
	./xxhsum --tag -H128 xxhsum* | $(GREP) XXH128
	./xxhsum --tag -H0 --little-endian xxhsum* | $(GREP) XXH32_LE
	./xxhsum --tag -H1 --little-endian xxhsum* | $(GREP) XXH64_LE
	./xxhsum --tag -H2 --little-endian xxhsum* | $(GREP) XXH128_LE
	./xxhsum --tag -H3 --little-endian xxhsum* | $(GREP) XXH3_LE
	./xxhsum --tag -H32 --little-endian xxhsum* | $(GREP) XXH32_LE
	./xxhsum --tag -H64 --little-endian xxhsum* | $(GREP) XXH64_LE
	./xxhsum --tag -H128 --little-endian xxhsum* | $(GREP) XXH128_LE
	# check bsd-style
	./xxhsum --tag xxhsum* | ./xxhsum -c
	./xxhsum --tag -H32 --little-endian xxhsum* | ./xxhsum -c
	# xxhsum -c warns improperly format lines.
	echo '12345678 ' >>.test.xxh32
	./xxhsum -c .test.xxh32 | $(GREP) improperly
	echo '123456789  file' >>.test.xxh64
	./xxhsum -c .test.xxh64 | $(GREP) improperly
	# Expects "FAILED"
	echo "0000000000000000  LICENSE" | ./xxhsum -c -; test $$? -eq 1
	echo "00000000  LICENSE" | ./xxhsum -c -; test $$? -eq 1
	# Expects "FAILED open or read"
	echo "0000000000000000  test-expects-file-not-found" | ./xxhsum -c -; test $$? -eq 1
	echo "00000000  test-expects-file-not-found" | ./xxhsum -c -; test $$? -eq 1
	# --filelist
	echo xxhash.c > .test.filenames
	$(RUN_ENV) ./xxhsum$(EXT) --filelist .test.filenames
	# --filelist from stdin
	cat .test.filenames | $(RUN_ENV) ./xxhsum$(EXT) --filelist
	@$(RM) .test.*

CC_VERSION := $(shell $(CC) --version 2>/dev/null)
ifneq (,$(findstring clang,$(CC_VERSION)))
fuzzer: CFLAGS += -fsanitize=fuzzer
$(eval $(call c_program,fuzzer, fuzz/fuzzer.o xxhash.o))
else
fuzzer: this_target_requires_clang # intentional fail
endif

.PHONY: test-seed
test-seed:
	echo -n "test1234" > .test.input

	@echo ---- test all algorithms with seed ----
	xxhsum -H0 --seed 1234 .test.input | grep -q "c2002a7a" && echo "XXH32: OK" || echo "XXH32: FAIL"
	xxhsum -H1 --seed 1234 .test.input | grep -q "9d23d128b345c34d" && echo "XXH64: OK" || echo "XXH64: FAIL"
	xxhsum -H2 --seed 1234 .test.input | grep -q "9bdd89fa9bd1965abe0c0d13a6b8164d" && echo "XXH3_128: OK" || echo "XXH3_128: FAIL"
	xxhsum -H3 --seed 1234 .test.input | grep -q "652aa233139ae947" && echo "XXH3_64: OK" || echo "XXH3_64: FAIL"

	@$(RM) .test.*

.PHONY: test-filename-escape
test-filename-escape:
	$(MAKE) -C tests test_filename_escape

.PHONY: test-cli-comment-line
test-cli-comment-line:
	$(MAKE) -C tests test_cli_comment_line

.PHONY: test-cli-ignore-missing
test-cli-ignore-missing:
	$(MAKE) -C tests test_cli_ignore_missing

.PHONY: armtest
armtest:
	@echo ---- test ARM compilation ----
	CC=arm-linux-gnueabi-gcc MOREFLAGS="-Werror -static" $(MAKE) xxhsum

.PHONY: arm64test
arm64test:
	@echo ---- test ARM64 compilation ----
	CC=aarch64-linux-gnu-gcc MOREFLAGS="-Werror -static" $(MAKE) xxhsum

.PHONY: clangtest
clangtest:
	@echo ---- test clang compilation ----
	CC=clang MOREFLAGS="-Werror -Wconversion -Wno-sign-conversion" $(MAKE) all

.PHONY: gcc-og-test
gcc-og-test:
	@echo ---- test gcc -Og compilation ----
	CFLAGS="-Og -Wall -Wextra -Wundef -Wshadow -Wcast-align -Werror -fPIC" CPPFLAGS="-DXXH_NO_INLINE_HINTS" MOREFLAGS="-Werror" $(MAKE) all

.PHONY: cxxtest
cxxtest:
	@echo ---- test C++ compilation ----
	CC="$(CXX) -Wno-deprecated" $(MAKE) all CFLAGS="-O3 -Wall -Wextra -Wundef -Wshadow -Wcast-align -Werror -fPIC"

# In strict C90 mode, there is no `long long` type support,
# consequently, only XXH32 can be compiled.
.PHONY: c90test
ifeq ($(NO_C90_TEST),true)
c90test:
	@echo no c90 compatibility test
else
c90test: CPPFLAGS += -DXXH_NO_LONG_LONG
c90test: CFLAGS += -std=c90 -Werror -pedantic
c90test: xxhash.c
	@echo ---- test strict C90 compilation [xxh32 only] ----
	$(RM) xxhash.o
	$(CC) $(FLAGS) $^ -c
	$(NM) xxhash.o | $(GREP) XXH64 ; test $$? -eq 1
	$(RM) xxhash.o
endif

.PHONY: noxxh3test
noxxh3test: CPPFLAGS += -DXXH_NO_XXH3
noxxh3test: CFLAGS += -Werror -pedantic -Wno-long-long  # XXH64 requires long long support
noxxh3test: OFILE = xxh_noxxh3.o
noxxh3test: xxhash.c
	@echo ---- test compilation without XXH3 ----
	$(CC) $(FLAGS) -c $^ -o $(OFILE)
	$(NM) $(OFILE) | $(GREP) XXH3_ ; test $$? -eq 1
	$(RM) $(OFILE)

.PHONY: nostreamtest
nostreamtest: CPPFLAGS += -DXXH_NO_STREAM
nostreamtest: CFLAGS += -Werror -pedantic -Wno-long-long  # XXH64 requires long long support
nostreamtest: OFILE = xxh_nostream.o
nostreamtest: xxhash.c
	@echo ---- test compilation without streaming ----
	$(CC) $(FLAGS) -c $^ -o $(OFILE)
	$(NM) $(OFILE) | $(GREP) update ; test $$? -eq 1
	$(RM) $(OFILE)

.PHONY: nostdlibtest
nostdlibtest: CPPFLAGS += -DXXH_NO_STDLIB
nostdlibtest: CFLAGS += -Werror -pedantic -Wno-long-long  # XXH64 requires long long support
nostdlibtest: OFILE = xxh_nostdlib.o
nostdlibtest: xxhash.c
	@echo ---- test compilation without \<stdlib.h\> ----
	$(CC) $(FLAGS) -c $^ -o $(OFILE)
	$(NM) $(OFILE) | $(GREP) "U _free\|U free" ; test $$? -eq 1
	$(RM) $(OFILE)

.PHONY: usan
usan: CC=clang
usan: CXX=clang++
usan:  ## check CLI runtime for undefined behavior, using clang's sanitizer
	@echo ---- check undefined behavior - sanitize ----
	$(MAKE) test CC=$(CC) CXX=$(CXX) MOREFLAGS="-g -fsanitize=undefined -fno-sanitize-recover=all"

.PHONY: staticAnalyze
SCANBUILD ?= scan-build
staticAnalyze: clean  ## check C source files using $(SCANBUILD) static analyzer
	@echo ---- static analyzer - $(SCANBUILD) ----
	CFLAGS="-g -Werror" $(SCANBUILD) --status-bugs -v $(MAKE) all

CPPCHECK ?= cppcheck
.PHONY: cppcheck
cppcheck:  ## check C source files using $(CPPCHECK) static analyzer
	@echo ---- static analyzer - $(CPPCHECK) ----
	$(CPPCHECK) . --force --enable=warning,portability,performance,style --error-exitcode=1 > /dev/null

.PHONY: namespaceTest
namespaceTest:  ## ensure XXH_NAMESPACE redefines all public symbols
	$(CC) -c xxhash.c
	$(CC) -DXXH_NAMESPACE=TEST_ -c xxhash.c -o xxhash2.o
	$(CC) xxhash.o xxhash2.o $(CLI_SRCS)  -o xxhsum2  # will fail if one namespace missing (symbol collision)
	$(RM) *.o xxhsum2  # clean

MAN = $(CLI_DIR)/xxhsum.1
MD2ROFF ?= ronn
MD2ROFF_FLAGS ?= --roff --warnings --manual="User Commands" --organization="xxhsum $(XXHSUM_VERSION)"
$(MAN): $(CLI_DIR)/xxhsum.1.md xxhash.h
	cat $< | $(MD2ROFF) $(MD2ROFF_FLAGS) | $(SED) -n '/^\.\\\".*/!p' > $@

.PHONY: man
man: $(MAN)  ## generate man page from markdown source

.PHONY: clean-man
clean-man:
	$(RM) xxhsum.1

.PHONY: preview-man
preview-man: man
	man ./xxhsum.1

.PHONY: test
test: DEBUGFLAGS += -DXXH_DEBUGLEVEL=1
test: all namespaceTest check test-xxhsum-c c90test test-tools noxxh3test nostdlibtest

# this test checks that including "xxhash.h" multiple times and with different directives still compiles properly
.PHONY: test-multiInclude
test-multiInclude:
	$(MAKE) -C tests test_multiInclude

.PHONY: test-inline-notexposed
test-inline-notexposed: xxhsum_inlinedXXH
	$(NM) xxhsum_inlinedXXH | $(GREP) "t _XXH32_" ; test $$? -eq 1  # no XXH32 symbol should be left
	$(NM) xxhsum_inlinedXXH | $(GREP) "t _XXH64_" ; test $$? -eq 1  # no XXH64 symbol should be left

.PHONY: test-inline
test-inline: test-inline-notexposed test-multiInclude


.PHONY: test-all
test-all: CFLAGS += -Werror
test-all: test test32 test-unicode clangtest gcc-og-test cxxtest usan test-inline listL120 trailingWhitespace test-xxh-nnn-sums

.PHONY: test-tools
test-tools:
	CFLAGS=-Werror $(MAKE) -C tests/bench
	CFLAGS=-Werror $(MAKE) -C tests/collisions check

.PHONY: test-xxh-nnn-sums
test-xxh-nnn-sums: xxhsum_and_links
	./xxhsum    README.md > tmp.xxhsum.out    # xxhsum outputs xxh64
	./xxh32sum  README.md > tmp.xxh32sum.out
	./xxh64sum  README.md > tmp.xxh64sum.out
	./xxh128sum README.md > tmp.xxh128sum.out
	./xxh3sum   README.md > tmp.xxh3sum.out
	cat tmp.xxhsum.out
	cat tmp.xxh32sum.out
	cat tmp.xxh64sum.out
	cat tmp.xxh128sum.out
	cat tmp.xxh3sum.out
	./xxhsum -c tmp.xxhsum.out
	./xxhsum -c tmp.xxh32sum.out
	./xxhsum -c tmp.xxh64sum.out
	./xxhsum -c tmp.xxh128sum.out
	./xxhsum -c tmp.xxh3sum.out
	./xxh32sum -c tmp.xxhsum.out            ; test $$? -eq 1  # expects "no properly formatted"
	./xxh32sum -c tmp.xxh32sum.out
	./xxh32sum -c tmp.xxh64sum.out          ; test $$? -eq 1  # expects "no properly formatted"
	./xxh32sum -c tmp.xxh128sum.out         ; test $$? -eq 1  # expects "no properly formatted"
	./xxh32sum -c tmp.xxh3sum.out           ; test $$? -eq 1  # expects "no properly formatted"
	./xxh64sum -c tmp.xxhsum.out
	./xxh64sum -c tmp.xxh32sum.out          ; test $$? -eq 1  # expects "no properly formatted"
	./xxh64sum -c tmp.xxh64sum.out
	./xxh64sum -c tmp.xxh128sum.out         ; test $$? -eq 1  # expects "no properly formatted"
	./xxh64sum -c tmp.xxh3sum.out           ; test $$? -eq 1  # expects "no properly formatted"
	./xxh128sum -c tmp.xxhsum.out           ; test $$? -eq 1  # expects "no properly formatted"
	./xxh128sum -c tmp.xxh32sum.out         ; test $$? -eq 1  # expects "no properly formatted"
	./xxh128sum -c tmp.xxh64sum.out         ; test $$? -eq 1  # expects "no properly formatted"
	./xxh128sum -c tmp.xxh128sum.out
	./xxh128sum -c tmp.xxh3sum.out          ; test $$? -eq 1  # expects "no properly formatted"
	./xxh3sum -c tmp.xxhsum.out             ; test $$? -eq 1  # expects "no properly formatted"
	./xxh3sum -c tmp.xxh32sum.out           ; test $$? -eq 1  # expects "no properly formatted"
	./xxh3sum -c tmp.xxh64sum.out           ; test $$? -eq 1  # expects "no properly formatted"
	./xxh3sum -c tmp.xxh128sum.out          ; test $$? -eq 1  # expects "no properly formatted"
	./xxh3sum -c tmp.xxh3sum.out

.PHONY: listL120
listL120:  # extract lines >= 120 characters in *.{c,h}, by Takayuki Matsuoka (note: $$, for Makefile compatibility)
	find . -type f -name '*.c' -o -name '*.h' | while read -r filename; do awk 'length > 120 {print FILENAME "(" FNR "): " $$0}' $$filename; done

.PHONY: trailingWhitespace
trailingWhitespace:
	@$(GREP) -n -E "`printf '[ \\t]$$'`" cli/*.c cli/*.h cli/*.1 *.c *.h LICENSE Makefile build/cmake/CMakeLists.txt && { echo "Error: trailing whitespace detected"; exit 1; } || true

.PHONY: lint-unicode
lint-unicode:
	./tests/unicode_lint.sh

# =========================================================
# make install is validated only for the following targets
# =========================================================
ifneq (,$(filter Linux Darwin GNU/kFreeBSD GNU Haiku OpenBSD FreeBSD NetBSD DragonFly SunOS CYGWIN% , $(UNAME)))

DESTDIR     ?=
# directory variables: GNU conventions prefer lowercase
# see https://www.gnu.org/prep/standards/html_node/Makefile-Conventions.html
# support both lower and uppercase (BSD), use uppercase in script
prefix      ?= /usr/local
PREFIX      ?= $(prefix)
exec_prefix ?= $(PREFIX)
EXEC_PREFIX ?= $(exec_prefix)
libdir      ?= $(EXEC_PREFIX)/lib
LIBDIR      ?= $(libdir)
includedir  ?= $(PREFIX)/include
INCLUDEDIR  ?= $(includedir)
bindir      ?= $(EXEC_PREFIX)/bin
BINDIR      ?= $(bindir)
datarootdir ?= $(PREFIX)/share
mandir      ?= $(datarootdir)/man
man1dir     ?= $(mandir)/man1

ifneq (,$(filter $(UNAME),FreeBSD NetBSD DragonFly))
PKGCONFIGDIR ?= $(PREFIX)/libdata/pkgconfig
else
PKGCONFIGDIR ?= $(LIBDIR)/pkgconfig
endif

ifneq (,$(filter $(UNAME),OpenBSD NetBSD DragonFly SunOS))
MANDIR  ?= $(PREFIX)/man/man1
else
MANDIR  ?= $(man1dir)
endif

ifneq (,$(filter $(UNAME),SunOS))
INSTALL ?= ginstall
else
INSTALL ?= install
endif

INSTALL_PROGRAM ?= $(INSTALL)
INSTALL_DATA    ?= $(INSTALL) -m 644
MAKE_DIR        ?= $(INSTALL) -d -m 755


# Escape special symbols by putting each character into its separate class
EXEC_PREFIX_REGEX ?= $(shell echo "$(EXEC_PREFIX)" | $(SED) $(SED_ERE_OPT) -e "s/([^^])/[\1]/g" -e "s/\\^/\\\\^/g")
PREFIX_REGEX ?= $(shell echo "$(PREFIX)" | $(SED) $(SED_ERE_OPT) -e "s/([^^])/[\1]/g" -e "s/\\^/\\\\^/g")

PCLIBDIR ?= $(shell echo "$(LIBDIR)"     | $(SED) -n $(SED_ERE_OPT) -e "s@^$(EXEC_PREFIX_REGEX)(/|$$)@@p")
PCINCDIR ?= $(shell echo "$(INCLUDEDIR)" | $(SED) -n $(SED_ERE_OPT) -e "s@^$(PREFIX_REGEX)(/|$$)@@p")
PCEXECDIR?= $(if $(filter $(PREFIX),$(EXEC_PREFIX)),$$\{prefix\},$(EXEC_PREFIX))

ifeq (,$(PCLIBDIR))
# Additional prefix check is required, since the empty string is technically a
# valid PCLIBDIR
ifeq (,$(shell echo "$(LIBDIR)" | $(SED) -n $(SED_ERE_OPT) -e "\\@^$(EXEC_PREFIX_REGEX)(/|$$)@ p"))
$(error configured libdir ($(LIBDIR)) is outside of exec_prefix ($(EXEC_PREFIX)), can't generate pkg-config file)
endif
endif

ifeq (,$(PCINCDIR))
# Additional prefix check is required, since the empty string is technically a
# valid PCINCDIR
ifeq (,$(shell echo "$(INCLUDEDIR)" | $(SED) -n $(SED_ERE_OPT) -e "\\@^$(PREFIX_REGEX)(/|$$)@ p"))
$(error configured includedir ($(INCLUDEDIR)) is outside of prefix ($(PREFIX)), can't generate pkg-config file)
endif
endif

libxxhash.pc: libxxhash.pc.in
	@echo creating pkgconfig
	$(SED) $(SED_ERE_OPT) -e 's|@PREFIX@|$(PREFIX)|' \
          -e 's|@EXECPREFIX@|$(PCEXECDIR)|' \
          -e 's|@LIBDIR@|$$\{exec_prefix\}/$(PCLIBDIR)|' \
          -e 's|@INCLUDEDIR@|$$\{prefix\}/$(PCINCDIR)|' \
          -e 's|@VERSION@|$(LIBVER)|' \
          $< > $@


install_libxxhash.a: libxxhash.a
	@echo Installing libxxhash.a
	$(MAKE_DIR) $(DESTDIR)$(LIBDIR)
	$(INSTALL_DATA) libxxhash.a $(DESTDIR)$(LIBDIR)

install_libxxhash: libxxhash
	@echo Installing libxxhash
	$(MAKE_DIR) $(DESTDIR)$(LIBDIR)
	$(INSTALL_PROGRAM) $(LIBXXH) $(DESTDIR)$(LIBDIR)
	ln -sf $(LIBXXH) $(DESTDIR)$(LIBDIR)/libxxhash.$(SHARED_EXT_MAJOR)
	ln -sf libxxhash.$(SHARED_EXT_MAJOR) $(DESTDIR)$(LIBDIR)/libxxhash.$(SHARED_EXT)

install_libxxhash.includes:
	$(INSTALL) -d -m 755 $(DESTDIR)$(INCLUDEDIR)   # includes
	$(INSTALL_DATA) xxhash.h $(DESTDIR)$(INCLUDEDIR)
	$(INSTALL_DATA) xxh3.h $(DESTDIR)$(INCLUDEDIR) # for compatibility, will be removed in v0.9.0
ifeq ($(LIBXXH_DISPATCH),1)
	$(INSTALL_DATA) xxh_x86dispatch.h $(DESTDIR)$(INCLUDEDIR)
endif

install_libxxhash.pc: libxxhash.pc
	@echo Installing pkgconfig
	$(MAKE_DIR) $(DESTDIR)$(PKGCONFIGDIR)/
	$(INSTALL_DATA) libxxhash.pc $(DESTDIR)$(PKGCONFIGDIR)/

install_xxhsum: xxhsum
	@echo Installing xxhsum
	$(MAKE_DIR) $(DESTDIR)$(BINDIR)/
	$(INSTALL_PROGRAM) xxhsum$(EXT) $(DESTDIR)$(BINDIR)/xxhsum$(EXT)
	ln -sf xxhsum$(EXT) $(DESTDIR)$(BINDIR)/xxh32sum$(EXT)
	ln -sf xxhsum$(EXT) $(DESTDIR)$(BINDIR)/xxh64sum$(EXT)
	ln -sf xxhsum$(EXT) $(DESTDIR)$(BINDIR)/xxh128sum$(EXT)
	ln -sf xxhsum$(EXT) $(DESTDIR)$(BINDIR)/xxh3sum$(EXT)

install_man:
	@echo Installing man pages
	$(MAKE_DIR) $(DESTDIR)$(MANDIR)/
	$(INSTALL_DATA) $(MAN) $(DESTDIR)$(MANDIR)/xxhsum.1
	ln -sf xxhsum.1 $(DESTDIR)$(MANDIR)/xxh32sum.1
	ln -sf xxhsum.1 $(DESTDIR)$(MANDIR)/xxh64sum.1
	ln -sf xxhsum.1 $(DESTDIR)$(MANDIR)/xxh128sum.1
	ln -sf xxhsum.1 $(DESTDIR)$(MANDIR)/xxh3sum.1

.PHONY: install
## install libraries, CLI, links and man pages
install: install_libxxhash.a install_libxxhash install_libxxhash.includes install_libxxhash.pc install_xxhsum install_man
	@echo xxhash installation completed

.PHONY: uninstall
uninstall:  ## uninstall libraries, CLI, links and man page
	$(RM) $(DESTDIR)$(LIBDIR)/libxxhash.a
	$(RM) $(DESTDIR)$(LIBDIR)/libxxhash.$(SHARED_EXT)
	$(RM) $(DESTDIR)$(LIBDIR)/libxxhash.$(SHARED_EXT_MAJOR)
	$(RM) $(DESTDIR)$(LIBDIR)/$(LIBXXH)
	$(RM) $(DESTDIR)$(INCLUDEDIR)/xxhash.h
	$(RM) $(DESTDIR)$(INCLUDEDIR)/xxh3.h
	$(RM) $(DESTDIR)$(INCLUDEDIR)/xxh_x86dispatch.h
	$(RM) $(DESTDIR)$(PKGCONFIGDIR)/libxxhash.pc
	$(RM) $(DESTDIR)$(BINDIR)/xxh32sum
	$(RM) $(DESTDIR)$(BINDIR)/xxh64sum
	$(RM) $(DESTDIR)$(BINDIR)/xxh128sum
	$(RM) $(DESTDIR)$(BINDIR)/xxh3sum
	$(RM) $(DESTDIR)$(BINDIR)/xxhsum
	$(RM) $(DESTDIR)$(MANDIR)/xxh32sum.1
	$(RM) $(DESTDIR)$(MANDIR)/xxh64sum.1
	$(RM) $(DESTDIR)$(MANDIR)/xxh128sum.1
	$(RM) $(DESTDIR)$(MANDIR)/xxh3sum.1
	$(RM) $(DESTDIR)$(MANDIR)/xxhsum.1
	@echo xxhsum successfully uninstalled

endif


================================================
FILE: README.md
================================================

xxHash - Extremely fast hash algorithm
======================================

xxHash is an Extremely fast Hash algorithm, processing at RAM speed limits.
Code is highly portable, and produces hashes identical across all platforms (little / big endian).
The library includes the following algorithms :
- XXH32 : generates 32-bit hashes, using 32-bit arithmetic
- XXH64 : generates 64-bit hashes, using 64-bit arithmetic
- XXH3 (since `v0.8.0`): generates 64 or 128-bit hashes, using vectorized arithmetic.
  The 128-bit variant is called XXH128.

All variants successfully complete the [SMHasher](https://code.google.com/p/smhasher/wiki/SMHasher) test suite
which evaluates the quality of hash functions (collision, dispersion and randomness).
Additional tests, which evaluate more thoroughly speed and collision properties of 64-bit hashes, [are also provided](https://github.com/Cyan4973/xxHash/tree/dev/tests).

|Branch      |Status   |
|------------|---------|
|release     | [![Build Status](https://github.com/Cyan4973/xxHash/actions/workflows/ci.yml/badge.svg?branch=release)](https://github.com/Cyan4973/xxHash/actions?query=branch%3Arelease+) |
|dev         | [![Build Status](https://github.com/Cyan4973/xxHash/actions/workflows/ci.yml/badge.svg?branch=dev)](https://github.com/Cyan4973/xxHash/actions?query=branch%3Adev+) |


Benchmarks
-------------------------

The benchmarked reference system uses an Intel i7-9700K cpu, and runs Ubuntu x64 20.04.
The [open source benchmark program] is compiled with `clang` v10.0 using `-O3` flag.

| Hash Name     | Width | Bandwidth (GB/s) | Small Data Velocity | Quality | Comment |
| ---------     | ----- | ---------------- | ----- | --- | --- |
| __XXH3__ (SSE2) |  64 | 31.5 GB/s        | 133.1 | 10
| __XXH128__ (SSE2) | 128 | 29.6 GB/s      | 118.1 | 10
| _RAM sequential read_ | N/A | 28.0 GB/s  |   N/A | N/A | _for reference_
| City64        |    64 | 22.0 GB/s        |  76.6 | 10
| T1ha2         |    64 | 22.0 GB/s        |  99.0 |  9 | Slightly worse [collisions]
| City128       |   128 | 21.7 GB/s        |  57.7 | 10
| __XXH64__     |    64 | 19.4 GB/s        |  71.0 | 10
| SpookyHash    |    64 | 19.3 GB/s        |  53.2 | 10
| Mum           |    64 | 18.0 GB/s        |  67.0 |  9 | Slightly worse [collisions]
| __XXH32__     |    32 |  9.7 GB/s        |  71.9 | 10
| City32        |    32 |  9.1 GB/s        |  66.0 | 10
| Murmur3       |    32 |  3.9 GB/s        |  56.1 | 10
| SipHash       |    64 |  3.0 GB/s        |  43.2 | 10
| FNV64         |    64 |  1.2 GB/s        |  62.7 |  5 | Poor avalanche properties
| Blake2        |   256 |  1.1 GB/s        |   5.1 | 10 | Cryptographic
| SHA1          |   160 |  0.8 GB/s        |   5.6 | 10 | Cryptographic but broken
| MD5           |   128 |  0.6 GB/s        |   7.8 | 10 | Cryptographic but broken

[open source benchmark program]: https://github.com/Cyan4973/xxHash/tree/release/tests/bench
[collisions]: https://github.com/Cyan4973/xxHash/wiki/Collision-ratio-comparison#collision-study

note 1: Small data velocity is a _rough_ evaluation of algorithm's efficiency on small data. For more detailed analysis, please refer to next paragraph.

note 2: some algorithms feature _faster than RAM_ speed. In which case, they can only reach their full speed potential when input is already in CPU cache (L3 or better). Otherwise, they max out on RAM speed limit.

### Small data

Performance on large data is only one part of the picture.
Hashing is also very useful in constructions like hash tables and bloom filters.
In these use cases, it's frequent to hash a lot of small data (starting at a few bytes).
Algorithm's performance can be very different for such scenarios, since parts of the algorithm,
such as initialization or finalization, become fixed cost.
The impact of branch mis-prediction also becomes much more present.

XXH3 has been designed for excellent performance on both long and small inputs,
which can be observed in the following graph:

![XXH3, latency, random size](https://user-images.githubusercontent.com/750081/61976089-aedeab00-af9f-11e9-9239-e5375d6c080f.png)

For a more detailed analysis, please visit the wiki :
https://github.com/Cyan4973/xxHash/wiki/Performance-comparison#benchmarks-concentrating-on-small-data-

Quality
-------------------------

Speed is not the only property that matters.
Produced hash values must respect excellent dispersion and randomness properties,
so that any sub-section of it can be used to maximally spread out a table or index,
as well as reduce the amount of collisions to the minimal theoretical level, following the [birthday paradox].

`xxHash` has been tested with Austin Appleby's excellent SMHasher test suite,
and passes all tests, ensuring reasonable quality levels.
It also passes extended tests from [newer forks of SMHasher], featuring additional scenarios and conditions.

Finally, xxHash provides its own [massive collision tester](https://github.com/Cyan4973/xxHash/tree/dev/tests/collisions),
able to generate and compare billions of hashes to test the limits of 64-bit hash algorithms.
On this front too, xxHash features good results, in line with the [birthday paradox].
A more detailed analysis is documented [in the wiki](https://github.com/Cyan4973/xxHash/wiki/Collision-ratio-comparison).

[birthday paradox]: https://en.wikipedia.org/wiki/Birthday_problem
[newer forks of SMHasher]: https://github.com/rurban/smhasher


### Build modifiers

The following macros can be set at compilation time to modify `libxxhash`'s behavior. They are generally disabled by default.

- `XXH_INLINE_ALL`: Make all functions `inline`, implementation is directly included within `xxhash.h`.
                    Inlining functions is beneficial for speed, notably for small keys.
                    It's _extremely effective_ when key's length is expressed as _a compile time constant_,
                    with performance improvements observed in the +200% range .
                    See [this article](https://fastcompression.blogspot.com/2018/03/xxhash-for-small-keys-impressive-power.html) for details.
- `XXH_PRIVATE_API`: same outcome as `XXH_INLINE_ALL`. Still available for legacy support.
                     The name underlines that `XXH_*` symbol names will not be exported.
- `XXH_STATIC_LINKING_ONLY`: gives access to internal state declaration, required for static allocation.
                             Incompatible with dynamic linking, due to risks of ABI changes.
- `XXH_NAMESPACE`: Prefixes all symbols with the value of `XXH_NAMESPACE`.
                   This macro can only use compilable character set.
                   Useful to evade symbol naming collisions,
                   in case of multiple inclusions of xxHash's source code.
                   Client applications still use the regular function names,
                   as symbols are automatically translated through `xxhash.h`.
- `XXH_FORCE_ALIGN_CHECK`: Use a faster direct read path when input is aligned.
                           This option can result in dramatic performance improvement on architectures unable to load memory from unaligned addresses
                           when input to hash happens to be aligned on 32 or 64-bit boundaries.
                           It is (slightly) detrimental on platform with good unaligned memory access performance (same instruction for both aligned and unaligned accesses).
                           This option is automatically disabled on `x86`, `x64` and `aarch64`, and enabled on all other platforms.
- `XXH_FORCE_MEMORY_ACCESS`: The default method `0` uses a portable `memcpy()` notation.
                             Method `1` uses a gcc-specific `packed` attribute, which can provide better performance for some targets.
                             Method `2` forces unaligned reads, which is not standard compliant, but might sometimes be the only way to extract better read performance.
                             Method `3` uses a byteshift operation, which is best for old compilers which don't inline `memcpy()` or big-endian systems without a byteswap instruction.
- `XXH_CPU_LITTLE_ENDIAN`: By default, endianness is determined by a runtime test resolved at compile time.
                           If, for some reason, the compiler cannot simplify the runtime test, it can cost performance.
                           It's possible to skip auto-detection and simply state that the architecture is little-endian by setting this macro to 1.
                           Setting it to 0 states big-endian.
- `XXH_ENABLE_AUTOVECTORIZE`: Auto-vectorization may be triggered for XXH32 and XXH64, depending on cpu vector capabilities and compiler version.
                              Note: auto-vectorization tends to be triggered more easily with recent versions of `clang`.
                              For XXH32, SSE4.1 or equivalent (NEON) is enough, while XXH64 requires AVX512.
                              Unfortunately, auto-vectorization is generally detrimental to XXH performance.
                              For this reason, the xxhash source code tries to prevent auto-vectorization by default.
                              That being said, systems evolve, and this conclusion is not forthcoming.
                              For example, it has been reported that recent Zen4 cpus are more likely to improve performance with vectorization.
                              Therefore, should you prefer or want to test vectorized code, you can enable this flag:
                              it will remove the no-vectorization protection code, thus making it more likely for XXH32 and XXH64 to be auto-vectorized.
- `XXH32_ENDJMP`: Switch multi-branch finalization stage of XXH32 by a single jump.
                  This is generally undesirable for performance, especially when hashing inputs of random sizes.
                  But depending on exact architecture and compiler, a jump might provide slightly better performance on small inputs. Disabled by default.
- `XXH_IMPORT`: MSVC specific: should only be defined for dynamic linking, as it prevents linkage errors.
- `XXH_NO_STDLIB`: Disable invocation of `<stdlib.h>` functions, notably `malloc()` and `free()`.
                   `libxxhash`'s `XXH*_createState()` will always fail and return `NULL`.
                   But one-shot hashing (like `XXH32()`) or streaming using statically allocated states
                   still work as expected.
                   This build flag is useful for embedded environments without dynamic allocation.
- `XXH_memcpy`, `XXH_memset`, `XXH_memcmp` : redirect `memcpy()`, `memset()` and `memcmp()` to some user-selected symbol at compile time.
                   Redirecting all 3 removes the need to include `<string.h>` standard library.
- `XXH_NO_EXTERNC_GUARD`: When `xxhash.h` is compiled in C++ mode, removes the `extern "C" { .. }` block guard.
- `XXH_DEBUGLEVEL` : When set to any value >= 1, enables `assert()` statements.
                     This (slightly) slows down execution, but may help finding bugs during debugging sessions.

#### Binary size control
- `XXH_NO_XXH3` : removes symbols related to `XXH3` (both 64 & 128 bits) from generated binary.
                  `XXH3` is by far the largest contributor to `libxxhash` size,
                  so it's useful to reduce binary size for applications which do not employ `XXH3`.
- `XXH_NO_LONG_LONG`: removes compilation of algorithms relying on 64-bit `long long` types
                      which include `XXH3` and `XXH64`.
                      Only `XXH32` will be compiled.
                      Useful for targets (architectures and compilers) without 64-bit support.
- `XXH_NO_STREAM`: Disables the streaming API, limiting the library to single shot variants only.
- `XXH_NO_INLINE_HINTS`: By default, xxHash uses `__attribute__((always_inline))` and `__forceinline` to improve performance at the cost of code size.
                         Defining this macro to 1 will mark all internal functions as `static`, allowing the compiler to decide whether to inline a function or not.
                         This is very useful when optimizing for smallest binary size,
                         and is automatically defined when compiling with `-O0`, `-Os`, `-Oz`, or `-fno-inline` on GCC and Clang.
                         It may also be required to successfully compile using `-Og`, depending on compiler version.
- `XXH_SIZE_OPT`: `0`: default, optimize for speed
                  `1`: default for `-Os` and `-Oz`: disables some speed hacks for size optimization
                  `2`: makes code as small as possible, performance may cry

#### Build modifiers specific for XXH3
- `XXH_VECTOR` : manually select a vector instruction set (default: auto-selected at compilation time). Available instruction sets are `XXH_SCALAR`, `XXH_SSE2`, `XXH_AVX2`, `XXH_AVX512`, `XXH_NEON` and `XXH_VSX`. Compiler may require additional flags to ensure proper support (for example, `gcc` on x86_64 requires `-mavx2` for `AVX2`, or `-mavx512f` for `AVX512`).
- `XXH_PREFETCH_DIST` : select prefetching distance. For close-to-metal adaptation to specific hardware platforms. XXH3 only.
- `XXH_NO_PREFETCH` : disable prefetching. Some platforms or situations may perform better without prefetching. XXH3 only.

#### Build modifiers for `xxhsum` CLI
- `XXH_1ST_SPEED_TARGET` : select an initial speed target, expressed in MB/s, for the first speed test in benchmark mode. Benchmark will adjust the target at subsequent iterations, but the first test is made "blindly" by targeting this speed. Currently conservatively set to 10 MB/s, to support very slow (emulated) platforms.

#### Makefile variables
When compiling the Command Line Interface `xxhsum` using `make`, the following environment variables can also be set :
- `DISPATCH=1` : use `xxh_x86dispatch.c`, select at runtime between `scalar`, `sse2`, `avx2` or `avx512` instruction set. This option is only valid for `x86`/`x64` systems. It is enabled by default when target `x86`/`x64` is detected. It can be forcefully turned off using `DISPATCH=0`.
- `LIBXXH_DISPATCH=1` : same idea, implemented a runtime vector extension detector, but within `libxxhash`. This parameter is disabled by default. When enabled (only valid for `x86`/`x64` systems), new symbols published in `xxh_x86dispatch.h` become accessible. At the time of this writing, it's required to include `xxh_x86dispatch.h` in order to access the symbols with runtime vector extension detection.
- `NODE_JS=1` : When compiling `xxhsum` for Node.js with Emscripten, this links the `NODERAWFS` library for unrestricted filesystem access and patches `isatty` to make the command line utility correctly detect the terminal. This does make the binary specific to Node.js.

### Building xxHash - Using vcpkg

You can download and install xxHash using the [vcpkg](https://github.com/Microsoft/vcpkg) dependency manager:

    git clone https://github.com/Microsoft/vcpkg.git
    cd vcpkg
    ./bootstrap-vcpkg.sh
    ./vcpkg integrate install
    ./vcpkg install xxhash

The xxHash port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.

### Example

The simplest example calls xxhash 64-bit variant as a one-shot function
generating a hash value from a single buffer, and invoked from a C/C++ program:

```C
#include "xxhash.h"

    (...)
    XXH64_hash_t hash = XXH64(buffer, size, seed);
}
```

Streaming variant is more involved, but makes it possible to provide data incrementally:

```C
#include "stdlib.h"   /* abort() */
#include "xxhash.h"


XXH64_hash_t calcul_hash_streaming(FileHandler fh)
{
    /* create a hash state */
    XXH64_state_t* const state = XXH64_createState();
    if (state==NULL) abort();

    size_t const bufferSize = SOME_SIZE;
    void* const buffer = malloc(bufferSize);
    if (buffer==NULL) abort();

    /* Initialize state with selected seed */
    XXH64_hash_t const seed = 0;   /* or any other value */
    if (XXH64_reset(state, seed) == XXH_ERROR) abort();

    /* Feed the state with input data, any size, any number of times */
    (...)
    while ( /* some data left */ ) {
        size_t const length = get_more_data(buffer, bufferSize, fh);
        if (XXH64_update(state, buffer, length) == XXH_ERROR) abort();
        (...)
    }
    (...)

    /* Produce the final hash value */
    XXH64_hash_t const hash = XXH64_digest(state);

    /* State could be re-used; but in this example, it is simply freed  */
    free(buffer);
    XXH64_freeState(state);

    return hash;
}
```


### License

The library files `xxhash.c` and `xxhash.h` are BSD licensed.
The utility `xxhsum` is GPL licensed.


### Other programming languages

Beyond the C reference version,
xxHash is also available from many different programming languages,
thanks to great contributors.
They are [listed here](http://www.xxhash.com/#other-languages).


### Packaging status

Many distributions bundle a package manager
which allows easy xxhash installation as both a `libxxhash` library
and `xxhsum` command line interface.

[![Packaging status](https://repology.org/badge/vertical-allrepos/xxhash.svg)](https://repology.org/project/xxhash/versions)


### Special Thanks

- Takayuki Matsuoka, aka @t-mat, for creating `xxhsum -c` and great support during early xxh releases
- Mathias Westerdahl, aka @JCash, for introducing the first version of `XXH64`
- Devin Hussey, aka @easyaspi314, for incredible low-level optimizations on `XXH3` and `XXH128`


================================================
FILE: SECURITY.md
================================================
# Security Policy

## Supported Versions

Security updates are applied only to the latest release.

## Reporting a Vulnerability

If you have discovered a security vulnerability in this project, please report it privately. **Do not disclose it as a public issue.** This gives us time to work with you to fix the issue before public exposure, reducing the chance that the exploit will be used before a patch is released.

Please disclose it at [security advisory](https://github.com/Cyan4973/xxHash/security/advisories/new).

This project is maintained by a team of volunteers on a reasonable-effort basis. As such, please give us at least 90 days to work on a fix before public exposure.


================================================
FILE: appveyor.yml
================================================
# ==============================================================================
#                            AppVeyor CI Configuration
# ==============================================================================

version: 1.0.{build}
max_jobs: 2
clone_depth: 2

# ==============================================================================
#                              Build Matrix
# ==============================================================================

environment:
  matrix:
    # Visual Studio 2017 build (not supported by GitHub Actions) - both Win32 and x64
    - COMPILER: "visual"
      ARCHS: "Win32,x64"
      AVX2: "true"
      APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2017"
      TEST_XXHSUM: "true"

    # Visual Studio 2019 build (no longer supported by GitHub Actions) - Win32 and x64
    - COMPILER: "visual"
      ARCHS: "Win32,x64"
      AVX2: "true"
      APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2019"
      TEST_XXHSUM: "true"

    # ARM build (no testing - cannot run on x86/x64 CI)
    - COMPILER: "visual"
      ARCHS: "ARM"
      AVX2: "false"
      TEST_XXHSUM: "false"

# ==============================================================================
#                              Build Scripts
# ==============================================================================

build_script:
  - echo "========================================"
  - echo "Building Visual Studio configurations"
  - echo "========================================"

  # Visual Studio build process
  - ps: |
      Set-Location "build/cmake"

      # Split architectures and build each one
      $architectures = $env:ARCHS -split ","

      foreach ($arch in $architectures) {
        $arch = $arch.Trim()
        Write-Host "========================================"
        Write-Host "Building for architecture: $arch"
        Write-Host "========================================"

        # Create architecture-specific build directory
        $buildDir = "build_$arch"
        New-Item -Path $buildDir -ItemType Directory -Force | Out-Null
        Set-Location $buildDir

        # Configure CMake for this architecture with fast Debug builds
        cmake .. -A $arch -DXXHASH_C_FLAGS="/W4 /WX" -DCMAKE_C_FLAGS_DEBUG="/Od /Zi /MDd"

        # Build Debug configuration (fast compilation, no optimizations)
        Write-Host "Building Debug configuration for $arch..."
        cmake --build . --config Debug

        # Build Debug with SSE2 if Win32 (x64 has SSE2 by default, ARM doesn't support it)
        if ($arch -eq "Win32") {
          Write-Host "Building Debug configuration with SSE2 for $arch..."
          cmake .. -A $arch -DXXHASH_C_FLAGS="/W4 /WX /arch:SSE2" -DCMAKE_C_FLAGS_DEBUG="/Od /Zi /MDd"
          cmake --build . --config Debug
        }

        # Build Debug with AVX2 if enabled and supported
        if ($env:AVX2 -eq "true" -and $arch -ne "ARM") {
          Write-Host "Building Debug configuration with AVX2 for $arch..."
          cmake .. -A $arch -DXXHASH_C_FLAGS="/W4 /WX /arch:AVX2" -DCMAKE_C_FLAGS_DEBUG="/Od /Zi /MDd"
          cmake --build . --config Debug
        }

        # Build Release configuration
        Write-Host "Building Release configuration for $arch..."
        cmake --build . --config Release

        # Go back to cmake directory for next architecture
        Set-Location ..
      }

# ==============================================================================
#                              Test Scripts
# ==============================================================================

test_script:
  # Test xxhsum Release binaries (only for x86/x64 architectures that can run on CI)
  - ps: |
      if ($env:TEST_XXHSUM -eq "true") {
        Set-Location "build/cmake"

        # Split architectures and test each one
        $architectures = $env:ARCHS -split ","

        foreach ($arch in $architectures) {
          $arch = $arch.Trim()

          # Only test architectures that can run on CI (x86/x64)
          if ($arch -eq "ARM") {
            Write-Host "Skipping testing for $arch (cannot run on x86/x64 CI)"
            continue
          }

          Write-Host "========================================"
          Write-Host "Testing Visual Studio $arch"
          Write-Host "========================================"

          Set-Location "build_$arch"

          # Test Release configuration only
          Write-Host "Testing Release binary for $arch..."
          Set-Location "Release"
          cmd /c "xxhsum.exe -b99i0"
          if ($LASTEXITCODE -ne 0) {
            Write-Host "Release xxhsum.exe failed for $arch with exit code $LASTEXITCODE"
            exit 1
          }
          Write-Host "Release binary test completed successfully for $arch"

          # Go back to cmake directory for next architecture
          Set-Location "../.."
        }

        Write-Host "------- All xxhsum testing completed successfully -------"
      }

# ==============================================================================
#                              Artifacts
# ==============================================================================
# Currently no artifacts are collected
# Future: Consider collecting built binaries for distribution

# ==============================================================================
#                              Build Notes
# ==============================================================================
# 1. ARM/ARM64 builds cannot be tested on x86/x64 CI infrastructure
# 2. AppVeyor focuses on legacy Visual Studio versions (2013, 2015, 2017)
# 3. Modern Visual Studio versions (2019, 2022) are tested on GitHub Actions


================================================
FILE: build/make/README.md
================================================
# multiconf.make

**multiconf.make** is a self-contained Makefile include that lets you build the **same targets under many different flag sets**. For example debug vs release, ASan vs UBSan, GCC vs Clang.
Each different set of flags generates object files into its own **dedicated cache directory**, so objects compiled with one configuration are never reused by another.
Object files from previous configurations are preserved, so swapping back to a previous configuration only requires compiling objects which have actually changed.

---

## Benefits at a glance

| Benefit | What `multiconf.make` does |
| --- | --- |
| **Isolated configs** | Stores objects into `cachedObjs/<hash>/`, one directory per unique flag set. |
| **Fast switching** | Reusing an old config is instant—link only, no recompilation. |
| **Header deps** | Edits to headers trigger only needed rebuilds. |
| **One-liner targets** | Macros (`c_program`, `cxx_program`, …) hide all rule boilerplate. |
| **Parallel-ready** | Safe with `make -j`, no duplicate compiles of shared sources. |
| **Controlled verbosity** | Default only lists objects, while `V=1` display full commands. |
| **`clean` included** | `make clean` deletes all objects, binaries and links. |

---

## Quick Start

### 1 · List your sources

```make
C_SRCDIRS   := src src/cdeps    # all .c are in these directories
CXX_SRCDIRS := src src/cxxdeps  # all .cpp are in these directories
```

### 2 · Add and include

```make
# root/Makefile
include multiconf.make
```

### 3 · Declare targets

```make
app:
$(eval $(call c_program,app,app.o cdeps/obj.o))

test:
$(eval $(call cxx_program,test, test.o cxxdeps/objcxx.o))

lib.a:
$(eval $(call static_library,lib.a, lib.o cdeps/obj.o))

lib.so:
$(eval $(call c_dynamic_library,lib.so, lib.o cdeps/obj.o))
```

### 4 · Build any config you like

```sh
# Release with GCC
make CFLAGS="-O3"

# Debug with Clang + AddressSanitizer (new cache dir)
make CC=clang CFLAGS="-g -O0 -fsanitize=address"

# Switch back to GCC release (objects still valid, relink only)
make CFLAGS="-O3"
```

Objects for each command live in different sub-folders; nothing overlaps.

---



================================================
FILE: build/make/multiconf.make
================================================
# ##########################################################################
# multiconf.make
# Copyright (C) Yann Collet
#
# GPL v2 License
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# ##########################################################################


# Provides c_program(_shared_o) and cxx_program(_shared_o) target generation macros
# Provides static_library and c_dynamic_library target generation macros
# Support recompilation of only impacted units when an associated *.h is updated.
# Provides V=1 / VERBOSE=1 support. V=2 is used for debugging purposes.
# Complement target clean: delete objects and binaries created by this script

# Requires:
# - C_SRCDIRS, CXX_SRCDIRS, ASM_SRCDIRS defined
#   OR
#   C_SRCS, CXX_SRCS and ASM_SRCS variables defined
#   *and* vpath set to find all source files
#   OR
#   C_OBJS, CXX_OBJS and ASM_OBJS variables defined
#   *and* vpath set to find all source files
# - directory `cachedObjs/` available to cache object files.
#   alternatively: set CACHE_ROOT to some different value.
# Optional:
# - HASH can be set to a different custom hash program.

# *_program*: generates a recipe for a target that will be built in a cache directory.
# The cache directory is automatically derived from CACHE_ROOT and list of flags and compilers.
# *_shared_o* variants are optional optimization variants, that share the same objects across multiple targets.
# However, as a consequence, all these objects must have exactly the same list of flags,
# which in practice means that there must be no target-level modification (like: target: CFLAGS += someFlag).
# If unsure, only use the standard variants, c_program and cxx_program.

# All *_program* macro functions take up to 4 argument:
# - The name of the target
# - The list of object files to build in the cache directory
# - An optional list of dependencies for linking, that will not be built
# - An optional complementary recipe code, that will run after compilation and link


# Silent mode is default; use V = 1 or VERBOSE = 1 to see compilation lines
VERBOSE ?= $(V)
$(VERBOSE).SILENT:

# Directory where object files will be built
CACHE_ROOT ?= cachedObjs

# --------------------------------------------------------------------------------------------

# Dependency management
DEPFLAGS = -MT $@ -MMD -MP -MF

# Include dependency files
include $(wildcard $(CACHE_ROOT)/**/*.d)
include $(wildcard $(CACHE_ROOT)/generic/*/*.d)

# --------------------------------------------------------------------------------------------

# Automatic determination of build artifacts cache directory, keyed on build
# flags, so that we can do incremental, parallel builds of different binaries
# with different build flags without collisions.

UNAME ?= $(shell uname)
ifeq ($(UNAME), Darwin)
  HASH ?= md5
else ifeq ($(UNAME), FreeBSD)
  HASH ?= gmd5sum
else ifeq ($(UNAME), OpenBSD)
  HASH ?= md5
endif
HASH ?= md5sum

HAVE_HASH := $(shell echo 1 | $(HASH) > /dev/null && echo 1 || echo 0)
ifeq ($(HAVE_HASH),0)
  $(info warning : could not find HASH ($(HASH)), required to differentiate builds using different flags)
  HASH_FUNC = generic/$(1)
else
  HASH_FUNC = $(firstword $(shell echo $(2) | $(HASH) ))
endif


MKDIR ?= mkdir
LN ?= ln

# --------------------------------------------------------------------------------------------
# The following macros are used to create object files in the cache directory.
# The object files are named after the source file, but with a different path.

# Create build directories on-demand.
#
# For some reason, make treats the directory as an intermediate file and tries
# to delete it. So we work around that by marking it "precious". Solution found
# here:
# http://ismail.badawi.io/blog/2017/03/28/automatic-directory-creation-in-make/
.PRECIOUS: $(CACHE_ROOT)/%/.
$(CACHE_ROOT)/%/. :
	$(MKDIR) -p $@


define addTargetAsmObject  # targetName, addlDeps
$$(if $$(filter 2,$$(V)),$$(info $$(call $(0),$(1),$(2))))

.PRECIOUS: $$(CACHE_ROOT)/%/$(1)
$$(CACHE_ROOT)/%/$(1) : $(1:.o=.S) $(2) | $$(CACHE_ROOT)/%/.
	@echo AS $$@
	$$(CC) $$(CPPFLAGS) $$(CXXFLAGS) $$(DEPFLAGS) $$(CACHE_ROOT)/$$*/$(1:.o=.d) -c $$< -o $$@

endef # addTargetAsmObject

define addTargetCObject  # targetName, addlDeps
$$(if $$(filter 2,$$(V)),$$(info $$(call $(0),$(1),$(2)))) #debug print

.PRECIOUS: $$(CACHE_ROOT)/%/$(1)
$$(CACHE_ROOT)/%/$(1) : $(1:.o=.c) $(2) | $$(CACHE_ROOT)/%/.
	@echo CC $$@
	$$(CC) $$(CPPFLAGS) $$(CFLAGS) $$(DEPFLAGS) $$(CACHE_ROOT)/$$*/$(1:.o=.d) -c $$< -o $$@

endef # addTargetCObject

define addTargetCxxObject  # targetName, suffix, addlDeps
$$(if $$(filter 2,$$(V)),$$(info $$(call $(0),$(1),$(2),$(3))))

.PRECIOUS: $$(CACHE_ROOT)/%/$(1)
$$(CACHE_ROOT)/%/$(1) : $(1:.o=.$(2)) $(3) | $$(CACHE_ROOT)/%/.
	@echo CXX $$@
	$$(CXX) $$(CPPFLAGS) $$(CXXFLAGS) $$(DEPFLAGS) $$(CACHE_ROOT)/$$*/$(1:.o=.d) -c $$< -o $$@

endef # addTargetCxxObject

# Create targets for individual object files
C_SRCDIRS += .
vpath %.c $(C_SRCDIRS)
CXX_SRCDIRS += .
vpath %.cpp $(CXX_SRCDIRS)
vpath %.cc $(CXX_SRCDIRS)
ASM_SRCDIRS += .
vpath %.S $(ASM_SRCDIRS)

# If C_SRCDIRS, CXX_SRCDIRS and ASM_SRCDIRS are not defined, use C_SRCS, CXX_SRCS and ASM_SRCS
C_SRCS   ?= $(notdir $(foreach dir,$(C_SRCDIRS),$(wildcard $(dir)/*.c)))
CPP_SRCS ?= $(notdir $(foreach dir,$(CXX_SRCDIRS),$(wildcard $(dir)/*.cpp)))
CC_SRCS  ?= $(notdir $(foreach dir,$(CXX_SRCDIRS),$(wildcard $(dir)/*.cc)))
CXX_SRCS ?= $(CPP_SRCS) $(CC_SRCS)
ASM_SRCS ?= $(notdir $(foreach dir,$(ASM_SRCDIRS),$(wildcard $(dir)/*.S)))

# If C_SRCS, CXX_SRCS and ASM_SRCS are not defined, use C_OBJS, CXX_OBJS and ASM_OBJS
C_OBJS   ?= $(patsubst %.c,%.o,$(C_SRCS))
CPP_OBJS ?= $(patsubst %.cpp,%.o,$(CPP_SRCS))
CC_OBJS  ?= $(patsubst %.cc,%.o,$(CC_SRCS))
CXX_OBJS ?= $(CPP_OBJS) $(CC_OBJS) # Note: not used
ASM_OBJS ?= $(patsubst %.S,%.o,$(ASM_SRCS))

$(foreach OBJ,$(C_OBJS),$(eval $(call addTargetCObject,$(OBJ))))
$(foreach OBJ,$(CPP_OBJS),$(eval $(call addTargetCxxObject,$(OBJ),cpp)))
$(foreach OBJ,$(CC_OBJS),$(eval $(call addTargetCxxObject,$(OBJ),cc)))
$(foreach OBJ,$(ASM_OBJS),$(eval $(call addTargetAsmObject,$(OBJ))))

# --------------------------------------------------------------------------------------------
# The following macros are used to create targets in the user Makefile.
# Binaries are built in the cache directory, and then symlinked to the current directory.
# The cache directory is automatically derived from CACHE_ROOT and list of flags and compilers.


# static_library - Create build rules for a static library with caching
# Parameters:
#   1. libName       - Library name (becomes output file and phony target)
#   2. objectDeps    - Object file dependencies (will be built in cache path)
# The following parameters are all optional:
#   3. extraDeps     - Additional dependencies (no cache path prefix)
#   4. postBuildCmds - Extra commands to run after AR
#   5. extraHash     - Additional key to compute the unique cache path
# Example:
#   $(call static_library,libmath.a,vector.o matrix.o,$(CONFIG_H),strip $@,$(VERSION))
define static_library  # libName, objectDeps, extraDeps, postBuildCmds, extraHash

$$(if $$(filter 2,$$(V)),$$(info $$(call $(0),$(1),$(2),$(3),$(4),$(5))))
MCM_ALL_BINS += $(1)

$$(CACHE_ROOT)/%/$(1) : $$(addprefix $$(CACHE_ROOT)/%/,$(2)) $(3)
	@echo AR $$@
	$$(AR) $$(ARFLAGS) $$@ $$^
	$(4)

.PHONY: $(1)
$(1) : ARFLAGS = rcs
$(1) : $$(CACHE_ROOT)/$$(call HASH_FUNC,$(1),$(2) $$(CPPFLAGS) $$(CC) $$(CFLAGS) $$(CXX) $$(CXXFLAGS) $$(AR) $$(ARFLAGS) $(5))/$(1)
	$$(LN) -sf $$< $$@

endef # static_library


# c_dynamic_library - Create build rules for a C dynamic/shared library with caching
# Parameters:
#   1. libName      - Library name (becomes output file and phony target)
#   2. objectDeps   - Object file dependencies (will be built in cache path)
# The following parameters are all optional:
#   3. extraDeps    - Additional dependencies (no cache path prefix)
#   4. postLinkCmds - Extra commands to run after linking
#   5. extraHash    - Additional key to compute the unique cache path
# Example:
#   $(call c_dynamic_library,libmath.so,vector.o matrix.o,$(CONFIG_H),strip $@,$(VERSION))
define c_dynamic_library  # libName, objectDeps, extraDeps, postLinkCmds, extraHash

$$(if $$(filter 2,$$(V)),$$(info $$(call $(0),$(1),$(2),$(3),$(4),$(5))))
MCM_ALL_BINS += $(1)

$$(CACHE_ROOT)/%/$(1) : $$(addprefix $$(CACHE_ROOT)/%/,$(2)) $(3)
	@echo LD $$@
	$$(CC) $$(CPPFLAGS) $$(CFLAGS) $$(LDFLAGS) -shared -o $$@ $$^ $$(LDLIBS)
	$(4)

.PHONY: $(1)
$(1) : CFLAGS += -fPIC
$(1) : $$(CACHE_ROOT)/$$(call HASH_FUNC,$(1),$(2) $$(CPPFLAGS) $$(CC) $$(CFLAGS) $$(LDFLAGS) $$(LDLIBS) $(5))/$(1)
	$$(LN) -sf $$< $$@

endef # c_dynamic_library


# program_base - Create build rules for an executable program with caching
# Parameters:
#   1. progName      - Executable name (becomes output file and phony target)
#   2. objectDeps    - Object file dependencies (will be prefixed with cache path)
# Parameters 3 to 5 are optional:
#   3. extraDeps     - Additional dependencies (without cache path prefix)
#   4. postLinkCmds  - Extra commands to run after linking
#   5. extraHash     - Additional data to include in cache path hash
# Parameters 6 & 7 are compulsory:
#   6. compiler      - Variable name of compiler to use (CC or CXX)
#   7. compilerFlags - Variable name of compiler flags to use (CFLAGS or CXXFLAGS)
# Example:
#   $(call program_base,myapp,main.o utils.o,$(CONFIG_H),strip $@,$(VERSION),CC,CFLAGS)
#   $(call program_base,mycppapp,main.o utils.o,$(CONFIG_H),strip $@,$(VERSION),CXX,CXXFLAGS)
define program_base  # progName, objectDeps, extraDeps, postLinkCmds, extraHash, compiler, compilerFlags

$$(if $$(filter 2,$$(V)),$$(info $$(call $(0),$(1),$(2),$(3),$(4),$(5),$(6),$(7))))
MCM_ALL_BINS += $(1)

$$(CACHE_ROOT)/%/$(1) : $$(addprefix $$(CACHE_ROOT)/%/,$(2)) $(3)
	@echo LD $$@
	$$($(6)) $$(CPPFLAGS) $$($(7)) $$^ -o $$@ $$(LDFLAGS) $$(LDLIBS)
	$(4)

.PHONY: $(1)
$(1) : $$(CACHE_ROOT)/$$(call HASH_FUNC,$(1),$$($(6)) $$(CPPFLAGS) $$($(7)) $$(LDFLAGS) $$(LDLIBS) $(5))/$(1)
	$$(LN) -sf $$< $$@$(EXT)

endef # program_base
# Note: $(EXT) must be set to .exe for Windows

define c_program  # progName, objectDeps, extraDeps, postLinkCmds
$$(eval $$(call program_base,$(1),$(2),$(3),$(4),$(1)$(2),CC,CFLAGS))
endef # c_program

define c_program_shared_o  # progName, objectDeps, extraDeps, postLinkCmds
$$(eval $$(call program_base,$(1),$(2),$(3),$(4),,CC,CFLAGS))
endef # c_program_shared_o

define cxx_program  # progName, objectDeps, extraDeps, postLinkCmds
$$(eval $$(call program_base,$(1),$(2),$(3),$(4),$(1)$(2),CXX,CXXFLAGS))
endef # cxx_program

define cxx_program_shared_o  # progName, objectDeps, extraDeps, postLinkCmds
$$(eval $$(call program_base,$(1),$(2),$(3),$(4),,CXX,CXXFLAGS))
endef # cxx_program_shared_o

# --------------------------------------------------------------------------------------------

# Cleaning: delete all objects and binaries created by this script
.PHONY: clean_cache
clean_cache:
	$(RM) -rf $(CACHE_ROOT)
	$(RM) $(MCM_ALL_BINS)

# automatically attach to standard clean target
.PHONY: clean
clean: clean_cache


================================================
FILE: cli/.tipi/deps
================================================
{
    "Cyan4973/xxHash": { }
}

================================================
FILE: cli/.tipi/opts
================================================


================================================
FILE: cli/COPYING
================================================
                    GNU GENERAL PUBLIC LICENSE
                       Version 2, June 1991

 Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

                            Preamble

  The licenses for most software are designed to take away your
freedom to share and change it.  By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users.  This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it.  (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.)  You can apply it to
your programs, too.

  When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.

  To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.

  For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have.  You must make sure that they, too, receive or can get the
source code.  And you must show them these terms so they know their
rights.

  We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.

  Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software.  If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.

  Finally, any free program is threatened constantly by software
patents.  We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary.  To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.

  The precise terms and conditions for copying, distribution and
modification follow.

                    GNU GENERAL PUBLIC LICENSE
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

  0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License.  The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language.  (Hereinafter, translation is included without limitation in
the term "modification".)  Each licensee is addressed as "you".

Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope.  The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.

  1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.

You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.

  2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:

    a) You must cause the modified files to carry prominent notices
    stating that you changed the files and the date of any change.

    b) You must cause any work that you distribute or publish, that in
    whole or in part contains or is derived from the Program or any
    part thereof, to be licensed as a whole at no charge to all third
    parties under the terms of this License.

    c) If the modified program normally reads commands interactively
    when run, you must cause it, when started running for such
    interactive use in the most ordinary way, to print or display an
    announcement including an appropriate copyright notice and a
    notice that there is no warranty (or else, saying that you provide
    a warranty) and that users may redistribute the program under
    these conditions, and telling the user how to view a copy of this
    License.  (Exception: if the Program itself is interactive but
    does not normally print such an announcement, your work based on
    the Program is not required to print an announcement.)

These requirements apply to the modified work as a whole.  If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works.  But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.

Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.

In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.

  3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:

    a) Accompany it with the complete corresponding machine-readable
    source code, which must be distributed under the terms of Sections
    1 and 2 above on a medium customarily used for software interchange; or,

    b) Accompany it with a written offer, valid for at least three
    years, to give any third party, for a charge no more than your
    cost of physically performing source distribution, a complete
    machine-readable copy of the corresponding source code, to be
    distributed under the terms of Sections 1 and 2 above on a medium
    customarily used for software interchange; or,

    c) Accompany it with the information you received as to the offer
    to distribute corresponding source code.  (This alternative is
    allowed only for noncommercial distribution and only if you
    received the program in object code or executable form with such
    an offer, in accord with Subsection b above.)

The source code for a work means the preferred form of the work for
making modifications to it.  For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable.  However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.

If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.

  4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License.  Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.

  5. You are not required to accept this License, since you have not
signed it.  However, nothing else grants you permission to modify or
distribute the Program or its derivative works.  These actions are
prohibited by law if you do not accept this License.  Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.

  6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions.  You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.

  7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all.  For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.

If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.

It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices.  Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.

This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.

  8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded.  In such case, this License incorporates
the limitation as if written in the body of this License.

  9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time.  Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

Each version is given a distinguishing version number.  If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation.  If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.

  10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission.  For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this.  Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.

                            NO WARRANTY

  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.

  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.

                     END OF TERMS AND CONDITIONS

            How to Apply These Terms to Your New Programs

  If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.

  To do so, attach the following notices to the program.  It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.

    <one line to give the program's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

Also add information on how to contact you by electronic and paper mail.

If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:

    Gnomovision version 69, Copyright (C) year name of author
    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
    This is free software, and you are welcome to redistribute it
    under certain conditions; type `show c' for details.

The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License.  Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.

You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary.  Here is a sample; alter the names:

  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
  `Gnomovision' (which makes passes at compilers) written by James Hacker.

  <signature of Ty Coon>, 1 April 1989
  Ty Coon, President of Vice

This General Public License does not permit incorporating your program into
proprietary programs.  If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library.  If this is what you want to do, use the GNU Lesser General
Public License instead of this License.


================================================
FILE: cli/README.md
================================================
This directory contains source code dedicated to the `xxhsum` command line utility,
which is a user program of `libxxhash`.

Note that, in contrast with the library `libxxhash`, the command line utility `xxhsum` ships with GPLv2 license.


================================================
FILE: cli/xsum_arch.c
================================================
/*
 * xxhsum - Command line interface for xxhash algorithms
 * Copyright (C) 2013-2024 Yann Collet
 *
 * GPL v2 License
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * You can contact the author at:
 *   - xxHash homepage: https://www.xxhash.com
 *   - xxHash source repository: https://github.com/Cyan4973/xxHash
 */

int g_xsumarch_avoid_empty_unit = 0;

#if ((defined(__x86_64__) || defined(_M_X64)) && !defined(_M_ARM64EC)) || defined(__i386__) || defined(_M_IX86) || defined(_M_IX86_FP)
#if defined(XXHSUM_DISPATCH)

#include "../xxh_x86dispatch.h"

const char* XSUM_autox86(void)
{
    int vecVersion = XXH_featureTest();
    switch(vecVersion) {
        case XXH_SCALAR:
            return "x86 autoVec (scalar: no vector extension detected)";
        case XXH_SSE2:
            return "x86 autoVec (SSE2 detected)";
        case XXH_AVX2:
            return "x86 autoVec (AVX2 detected)";
        case XXH_AVX512:
            return "x86 autoVec (AVX512 detected)";
        default:;
    }
    return " autoVec (error detecting vector extension)";
}

#endif /* XXHSUM_DISPATCH */
#endif /* x86 */


================================================
FILE: cli/xsum_arch.h
================================================
/*
 * xxhsum - Command line interface for xxhash algorithms
 * Copyright (C) 2013-2021 Yann Collet
 *
 * GPL v2 License
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * You can contact the author at:
 *   - xxHash homepage: https://www.xxhash.com
 *   - xxHash source repository: https://github.com/Cyan4973/xxHash
 */

/*
 * Checks for predefined macros by the compiler to try and get both the arch
 * and the compiler version.
 */
#ifndef XSUM_ARCH_H
#define XSUM_ARCH_H

#include "xsum_config.h"

#define XSUM_LIB_VERSION XXH_VERSION_MAJOR.XXH_VERSION_MINOR.XXH_VERSION_RELEASE
#define XSUM_QUOTE(str) #str
#define XSUM_EXPAND_AND_QUOTE(str) XSUM_QUOTE(str)
#define XSUM_PROGRAM_VERSION XSUM_EXPAND_AND_QUOTE(XSUM_LIB_VERSION)


/* Show compiler versions in WELCOME_MESSAGE. XSUM_CC_VERSION_FMT will return the printf specifiers,
 * and VERSION will contain the comma separated list of arguments to the XSUM_CC_VERSION_FMT string. */
#if defined(__clang_version__)
/* Clang does its own thing. */
#  ifdef __apple_build_version__
#    define XSUM_CC_VERSION_FMT "Apple Clang %s"
#  else
#    define XSUM_CC_VERSION_FMT "Clang %s"
#  endif
#  define XSUM_CC_VERSION  __clang_version__
#elif defined(__VERSION__)
/* GCC and ICC */
#  define XSUM_CC_VERSION_FMT "%s"
#  ifdef __INTEL_COMPILER /* icc adds its prefix */
#    define XSUM_CC_VERSION __VERSION__
#  else /* assume GCC */
#    define XSUM_CC_VERSION "GCC " __VERSION__
#  endif
#elif defined(_MSC_FULL_VER) && defined(_MSC_BUILD)
/*
 * MSVC
 *  "For example, if the version number of the Visual C++ compiler is
 *   15.00.20706.01, the _MSC_FULL_VER macro evaluates to 150020706."
 *
 *   https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros?view=vs-2017
 */
#  define XSUM_CC_VERSION_FMT "MSVC %02i.%02i.%05i.%02i"
#  define XSUM_CC_VERSION  _MSC_FULL_VER / 10000000 % 100, _MSC_FULL_VER / 100000 % 100, _MSC_FULL_VER % 100000, _MSC_BUILD
#elif defined(_MSC_VER) /* old MSVC */
#  define XSUM_CC_VERSION_FMT "MSVC %02i.%02i"
#  define XSUM_CC_VERSION _MSC_VER / 100, _MSC_VER % 100
#elif defined(__TINYC__)
/* tcc stores its version in the __TINYC__ macro. */
#  define XSUM_CC_VERSION_FMT "tcc %i.%i.%i"
#  define XSUM_CC_VERSION __TINYC__ / 10000 % 100, __TINYC__ / 100 % 100, __TINYC__ % 100
#else
#  define XSUM_CC_VERSION_FMT "%s"
#  define XSUM_CC_VERSION "unknown compiler"
#endif

/* makes the next part easier */
#if (defined(__x86_64__) || defined(_M_X64)) && !defined(_M_ARM64EC)
#   define XSUM_ARCH_X64 1
#   define XSUM_ARCH_X86 "x86_64"
#elif defined(__i386__) || defined(_M_IX86) || defined(_M_IX86_FP)
#   define XSUM_ARCH_X86 "i386"
#endif

/* Try to detect the architecture. */
#if defined(XSUM_ARCH_X86)
#  if defined(XXHSUM_DISPATCH)
     const char* XSUM_autox86(void);
#    define XSUM_ARCH XSUM_autox86()
#  elif defined(__AVX512F__)
#    define XSUM_ARCH XSUM_ARCH_X86 " + AVX512"
#  elif defined(__AVX2__)
#    define XSUM_ARCH XSUM_ARCH_X86 " + AVX2"
#  elif defined(__AVX__)
#    define XSUM_ARCH XSUM_ARCH_X86 " + AVX"
#  elif defined(_M_X64) || defined(__x86_64__) \
      || defined(__SSE2__) || (defined(_M_IX86_FP) && _M_IX86_FP == 2)
#     define XSUM_ARCH XSUM_ARCH_X86 " + SSE2"
#  else
#     define XSUM_ARCH XSUM_ARCH_X86
#  endif
#elif defined(__aarch64__) || defined(__arm64__) || defined(_M_ARM64) || defined(_M_ARM64EC)
#  if defined(__ARM_FEATURE_SVE)
#    define XSUM_ARCH "aarch64 + SVE"
#  else
#    define XSUM_ARCH "aarch64 + NEON"
#  endif
#elif defined(__arm__) || defined(__thumb__) || defined(__thumb2__) || defined(_M_ARM)
/* ARM has a lot of different features that can change xxHash significantly. */
#  ifdef __ARM_ARCH
#    define XSUM_ARCH_ARM_VER XSUM_EXPAND_AND_QUOTE(__ARM_ARCH)
#  else
#    define XSUM_ARCH_ARM_VER XSUM_EXPAND_AND_QUOTE(_M_ARM)
#  endif
#  if defined(_M_ARM) /* windows arm is always thumb-2 */ \
    || defined(__thumb2__) || (defined(__thumb__) && (__thumb__ == 2 || __ARM_ARCH >= 7))
#    define XSUM_ARCH_THUMB " Thumb-2"
#  elif defined(__thumb__)
#    define XSUM_ARCH_THUMB " Thumb-1"
#  else
#    define XSUM_ARCH_THUMB ""
#  endif
/* ARMv7 has unaligned by default */
#  if defined(__ARM_FEATURE_UNALIGNED) || __ARM_ARCH >= 7 || defined(_M_ARM)
#    define XSUM_ARCH_UNALIGNED " + unaligned"
#  else
#    define XSUM_ARCH_UNALIGNED ""
#  endif
#  if defined(__ARM_NEON) || defined(__ARM_NEON__) || defined(_M_ARM)
#    define XSUM_ARCH_NEON " + NEON"
#  else
#    define XSUM_ARCH_NEON ""
#  endif
#  define XSUM_ARCH "ARMv" XSUM_ARCH_ARM_VER XSUM_ARCH_THUMB XSUM_ARCH_NEON XSUM_ARCH_UNALIGNED
#elif defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__)
#  if defined(__GNUC__) && defined(__POWER9_VECTOR__)
#    define XSUM_ARCH "ppc64 + POWER9 vector"
#  elif defined(__GNUC__) && defined(__POWER8_VECTOR__)
#    define XSUM_ARCH "ppc64 + POWER8 vector"
#  else
#    define XSUM_ARCH "ppc64"
#  endif
#elif defined(__powerpc__) || defined(__ppc__) || defined(__PPC__)
#  define XSUM_ARCH "ppc"
#elif defined(__AVR)
#  define XSUM_ARCH "AVR"
#elif defined(__mips64)
#  define XSUM_ARCH "mips64"
#elif defined(__mips)
#  define XSUM_ARCH "mips"
#elif defined(__s390x__)
#  define XSUM_ARCH "s390x"
#elif defined(__s390__)
#  define XSUM_ARCH "s390"
#elif defined(__wasm__) || defined(__asmjs__) || defined(__EMSCRIPTEN__)
#  if defined(__wasm_simd128__)
#    define XSUM_ARCH "wasm/asmjs + simd128"
#  else
#    define XSUM_ARCH "wasm/asmjs"
#  endif
#elif defined(__riscv)
#    define XSUM_ARCH "riscv"
#elif defined(__loongarch_lp64)
#  if defined(__loongarch_asx)
#    define XSUM_ARCH "loongarch64 + lasx"
#  elif defined(__loongarch_sx)
#    define XSUM_ARCH "loongarch64 + lsx"
#  else
#    define XSUM_ARCH "loongarch64"
#  endif
#else
#  define XSUM_ARCH "unknown"
#endif


#endif /* XSUM_ARCH_H */


================================================
FILE: cli/xsum_bench.c
================================================
/*
 * xsum_bench - Benchmark functions for xxhsum
 * Copyright (C) 2013-2021 Yann Collet
 *
 * GPL v2 License
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * You can contact the author at:
 *   - xxHash homepage: https://www.xxhash.com
 *   - xxHash source repository: https://github.com/Cyan4973/xxHash
 */

#include "xsum_output.h"  /* XSUM_logLevel */
#include "xsum_bench.h"
#include "xsum_sanity_check.h" /* XSUM_fillTestBuffer */
#include "xsum_os_specific.h"  /* XSUM_getFileSize */
#ifndef XXH_STATIC_LINKING_ONLY
#  define XXH_STATIC_LINKING_ONLY
#endif
#include "../xxhash.h"
#ifdef XXHSUM_DISPATCH
#  include "../xxh_x86dispatch.h"  /* activate _dispatch() redirectors */
#endif

#include <stdlib.h>  /* malloc, free */
#include <assert.h>
#include <string.h>  /* strlen, memcpy */
#include <time.h>   /* clock_t, clock, CLOCKS_PER_SEC */
#include <errno.h>  /* errno */

#define TIMELOOP_S 1
#define TIMELOOP  (TIMELOOP_S * CLOCKS_PER_SEC)   /* target timing per iteration */
#define TIMELOOP_MIN (TIMELOOP / 2)               /* minimum timing to validate a result */

/* Each benchmark iteration attempts to match TIMELOOP (1 second).
 * The nb of loops is adjusted at each iteration to reach that target.
 * However, initially, there is no information, so 1st iteration blindly targets an arbitrary speed.
 * If it's too small, it will be adjusted, and a new attempt will be made.
 * But if it's too large, the first iteration can be very long,
 * before being fixed at second attempt.
 * So prefer starting with small speed targets.
 * XXH_1ST_SPEED_TARGET is defined in MB/s */
#ifndef XXH_1ST_SPEED_TARGET
# define XXH_1ST_SPEED_TARGET 10
#endif

#define MAX_MEM    (2 GB - 64 MB)

static clock_t XSUM_clockSpan( clock_t start )
{
    return clock() - start;   /* works even if overflow; Typical max span ~ 30 mn */
}

static size_t XSUM_findMaxMem(XSUM_U64 requiredMem)
{
    size_t const step = 64 MB;
    void* testmem = NULL;

    requiredMem = (((requiredMem >> 26) + 1) << 26);
    requiredMem += 2*step;
    if (requiredMem > MAX_MEM) requiredMem = MAX_MEM;

    while (!testmem) {
        if (requiredMem > step) requiredMem -= step;
        else requiredMem >>= 1;
        testmem = malloc ((size_t)requiredMem);
    }
    free (testmem);

    /* keep some space available */
    if (requiredMem > step) requiredMem -= step;
    else requiredMem >>= 1;

    return (size_t)requiredMem;
}

/*
 * A secret buffer used for benchmarking XXH3's withSecret variants.
 *
 * In order for the bench to be realistic, the secret buffer would need to be
 * pre-generated.
 *
 * Adding a pointer to the parameter list would be messy.
 */
static XSUM_U8 g_benchSecretBuf[XXH3_SECRET_SIZE_MIN];

/*
 * Wrappers for the benchmark.
 *
 * If you would like to add other hashes to the bench, create a wrapper and add
 * it to the g_hashesToBench table. It will automatically be added.
 */
typedef XSUM_U32 (*hashFunction)(const void* buffer, size_t bufferSize, XSUM_U32 seed);

static XSUM_U32 localXXH32(const void* buffer, size_t bufferSize, XSUM_U32 seed)
{
    return XXH32(buffer, bufferSize, seed);
}
static XSUM_U32 localXXH32_stream(const void* buffer, size_t bufferSize, XSUM_U32 seed)
{
    XXH32_state_t state;
    (void)seed;
    XXH32_reset(&state, seed);
    XXH32_update(&state, buffer, bufferSize);
    return (XSUM_U32)XXH32_digest(&state);
}
static XSUM_U32 localXXH64(const void* buffer, size_t bufferSize, XSUM_U32 seed)
{
    return (XSUM_U32)XXH64(buffer, bufferSize, seed);
}
static XSUM_U32 localXXH64_stream(const void* buffer, size_t bufferSize, XSUM_U32 seed)
{
    XXH64_state_t state;
    (void)seed;
    XXH64_reset(&state, seed);
    XXH64_update(&state, buffer, bufferSize);
    return (XSUM_U32)XXH64_digest(&state);
}
static XSUM_U32 localXXH3_64b(const void* buffer, size_t bufferSize, XSUM_U32 seed)
{
    (void)seed;
    return (XSUM_U32)XXH3_64bits(buffer, bufferSize);
}
static XSUM_U32 localXXH3_64b_seeded(const void* buffer, size_t bufferSize, XSUM_U32 seed)
{
    return (XSUM_U32)XXH3_64bits_withSeed(buffer, bufferSize, seed);
}
static XSUM_U32 localXXH3_64b_secret(const void* buffer, size_t bufferSize, XSUM_U32 seed)
{
    (void)seed;
    return (XSUM_U32)XXH3_64bits_withSecret(buffer, bufferSize, g_benchSecretBuf, sizeof(g_benchSecretBuf));
}
static XSUM_U32 localXXH3_128b(const void* buffer, size_t bufferSize, XSUM_U32 seed)
{
    (void)seed;
    return (XSUM_U32)(XXH3_128bits(buffer, bufferSize).low64);
}
static XSUM_U32 localXXH3_128b_seeded(const void* buffer, size_t bufferSize, XSUM_U32 seed)
{
    return (XSUM_U32)(XXH3_128bits_withSeed(buffer, bufferSize, seed).low64);
}
static XSUM_U32 localXXH3_128b_secret(const void* buffer, size_t bufferSize, XSUM_U32 seed)
{
    (void)seed;
    return (XSUM_U32)(XXH3_128bits_withSecret(buffer, bufferSize, g_benchSecretBuf, sizeof(g_benchSecretBuf)).low64);
}
static XSUM_U32 localXXH3_stream(const void* buffer, size_t bufferSize, XSUM_U32 seed)
{
    XXH3_state_t state;
    (void)seed;
    XXH3_64bits_reset(&state);
    XXH3_64bits_update(&state, buffer, bufferSize);
    return (XSUM_U32)XXH3_64bits_digest(&state);
}
static XSUM_U32 localXXH3_stream_seeded(const void* buffer, size_t bufferSize, XSUM_U32 seed)
{
    XXH3_state_t state;
    XXH3_INITSTATE(&state);
    XXH3_64bits_reset_withSeed(&state, (XXH64_hash_t)seed);
    XXH3_64bits_update(&state, buffer, bufferSize);
    return (XSUM_U32)XXH3_64bits_digest(&state);
}
static XSUM_U32 localXXH128_stream(const void* buffer, size_t bufferSize, XSUM_U32 seed)
{
    XXH3_state_t state;
    (void)seed;
    XXH3_128bits_reset(&state);
    XXH3_128bits_update(&state, buffer, bufferSize);
    return (XSUM_U32)(XXH3_128bits_digest(&state).low64);
}
static XSUM_U32 localXXH128_stream_seeded(const void* buffer, size_t bufferSize, XSUM_U32 seed)
{
    XXH3_state_t state;
    XXH3_INITSTATE(&state);
    XXH3_128bits_reset_withSeed(&state, (XXH64_hash_t)seed);
    XXH3_128bits_update(&state, buffer, bufferSize);
    return (XSUM_U32)(XXH3_128bits_digest(&state).low64);
}


typedef struct {
    const char*  name;
    hashFunction func;
} hashInfo;

static const hashInfo g_hashesToBench[] = {
    { "XXH32",             &localXXH32 },
    { "XXH64",             &localXXH64 },
    { "XXH3_64b",          &localXXH3_64b },
    { "XXH3_64b w/seed",   &localXXH3_64b_seeded },
    { "XXH3_64b w/secret", &localXXH3_64b_secret },
    { "XXH128",            &localXXH3_128b },
    { "XXH128 w/seed",     &localXXH3_128b_seeded },
    { "XXH128 w/secret",   &localXXH3_128b_secret },
    { "XXH32_stream",      &localXXH32_stream },
    { "XXH64_stream",      &localXXH64_stream },
    { "XXH3_stream",       &localXXH3_stream },
    { "XXH3_stream w/seed",&localXXH3_stream_seeded },
    { "XXH128_stream",     &localXXH128_stream },
    { "XXH128_stream w/seed",&localXXH128_stream_seeded },
};
#define NB_HASHFUNC (sizeof(g_hashesToBench) / sizeof(*g_hashesToBench))

#define NB_TESTFUNC (1 + 2 * NB_HASHFUNC)
int const g_nbTestFunctions = NB_TESTFUNC;
char g_testIDs[NB_TESTFUNC] = { 0 };
const char k_testIDs_default[NB_TESTFUNC] = { 0,
        1 /*XXH32*/, 0,
        1 /*XXH64*/, 0,
        1 /*XXH3*/, 0, 0, 0, 0, 0,
        1 /*XXH128*/ };

int g_nbIterations = NBLOOPS_DEFAULT;
#define HASHNAME_MAX 29
static void XSUM_benchHash(hashFunction h, const char* hName, int testID,
                           const void* buffer, size_t bufferSize)
{
    XSUM_U32 nbh_perIteration = (XSUM_U32)((XXH_1ST_SPEED_TARGET MB) / (bufferSize+1)) + 1;
    int iterationNb, nbIterations = g_nbIterations + !g_nbIterations /* min 1 */;
    double fastestH = 100000000.;
    assert(HASHNAME_MAX > 2);
    XSUM_logVerbose(2, "\r%80s\r", "");       /* Clean display line */

    for (iterationNb = 1; iterationNb <= nbIterations; iterationNb++) {
        XSUM_U32 r=0;
        clock_t cStart;

        XSUM_logVerbose(2, "%2i-%-*.*s : %10u ->\r",
                        iterationNb,
                        HASHNAME_MAX, HASHNAME_MAX, hName,
                        (unsigned)bufferSize);
        cStart = clock();
        while (clock() == cStart);   /* starts clock() at its exact beginning */
        cStart = clock();

        {   XSUM_U32 u;
            for (u=0; u<nbh_perIteration; u++)
                r += h(buffer, bufferSize, u);
        }
        if (r==0) XSUM_logVerbose(3,".\r");  /* do something with r to defeat compiler "optimizing" hash away */

        {   clock_t const nbTicks = XSUM_clockSpan(cStart);
            double const ticksPerHash = ((double)nbTicks / TIMELOOP) / nbh_perIteration;
            /*
             * clock() is the only decent portable timer, but it isn't very
             * precise.
             *
             * Sometimes, this lack of precision is enough that the benchmark
             * finishes before there are enough ticks to get a meaningful result.
             *
             * For example, on a Core 2 Duo (without any sort of Turbo Boost),
             * the imprecise timer caused peculiar results like so:
             *
             *    XXH3_64b                   4800.0 MB/s // conveniently even
             *    XXH3_64b unaligned         4800.0 MB/s
             *    XXH3_64b seeded            9600.0 MB/s // magical 2x speedup?!
             *    XXH3_64b seeded unaligned  4800.0 MB/s
             *
             * If we sense a suspiciously low number of ticks, we increase the
             * iterations until we can get something meaningful.
             */
            if (nbTicks < TIMELOOP_MIN) {
                /* Not enough time spent in benchmarking, risk of rounding bias */
                if (nbTicks == 0) { /* faster than resolution timer */
                    nbh_perIteration *= 100;
                } else {
                    /*
                     * update nbh_perIteration so that the next round lasts
                     * approximately 1 second.
                     */
                    double nbh_perSecond = (1 / ticksPerHash) + 1;
                    if (nbh_perSecond > (double)(4000U<<20)) nbh_perSecond = (double)(4000U<<20);   /* avoid overflow */
                    nbh_perIteration = (XSUM_U32)nbh_perSecond;
                }
                /* g_nbIterations==0 => quick evaluation, no claim of accuracy */
                if (g_nbIterations>0) {
                    iterationNb--;   /* new round for a more accurate speed evaluation */
                    continue;
                }
            }
            if (ticksPerHash < fastestH) fastestH = ticksPerHash;
            if (fastestH>0.) { /* avoid div by zero */
                XSUM_logVerbose(2, "%2i-%-*.*s : %10u -> %8.0f it/s (%7.1f MB/s) \r",
                            iterationNb,
                            HASHNAME_MAX, HASHNAME_MAX, hName,
                            (unsigned)bufferSize,
                            (double)1 / fastestH,
                            ((double)bufferSize / (1 MB)) / fastestH);
        }   }
        {   double nbh_perSecond = (1 / fastestH) + 1;
            if (nbh_perSecond > (double)(4000U<<20)) nbh_perSecond = (double)(4000U<<20);   /* avoid overflow */
            nbh_perIteration = (XSUM_U32)nbh_perSecond;
        }
    }
    XSUM_logVerbose(1, "%2i#%-*.*s : %10u -> %8.0f it/s (%7.1f MB/s) \n",
                    testID,
                    HASHNAME_MAX, HASHNAME_MAX, hName,
                    (unsigned)bufferSize,
                    (double)1 / fastestH,
                    ((double)bufferSize / (1 MB)) / fastestH);
    if (XSUM_logLevel<1)
        XSUM_logVerbose(0, "%u, ", (unsigned)((double)1 / fastestH));
}


/*
 * Allocates a string containing s1 and s2 concatenated. Acts like strdup.
 * The result must be freed.
 */
static char* XSUM_strcatDup(const char* s1, const char* s2)
{
    assert(s1 != NULL);
    assert(s2 != NULL);
    {   size_t len1 = strlen(s1);
        size_t len2 = strlen(s2);
        char* buf = (char*)malloc(len1 + len2 + 1);
        if (buf != NULL) {
            /* strcpy(buf, s1) */
            memcpy(buf, s1, len1);
            /* strcat(buf, s2) */
            memcpy(buf + len1, s2, len2 + 1);
        }
        return buf;
    }
}


/*!
 * XSUM_benchMem():
 * Benchmark provided content up to twice per function:
 * - once at provided aligned memory address (%16)
 * - second time at unaligned memory address (+3)
 * Enabled functions and modes are provided via @g_hashesToBench global variable.
 * @buffer: Must be 16-byte aligned.
 * The allocated size of underlying @buffer must be >= (@bufferSize+3).
 * This function also fills @g_benchSecretBuf, to bench XXH3's _withSecret() variants.
 */
static void XSUM_benchMem(const void* buffer, size_t bufferSize)
{
    assert((((size_t)buffer) & 15) == 0);  /* ensure alignment */
    XSUM_fillTestBuffer(g_benchSecretBuf, sizeof(g_benchSecretBuf));
    {   int i;
        for (i = 1; i < (int)NB_TESTFUNC; i++) {
            int const hashFuncID = (i-1) / 2;
            assert(g_hashesToBench[hashFuncID].name != NULL);
            if (g_testIDs[i] == 0) continue;
            /* aligned */
            if ((i % 2) == 1) {
                XSUM_benchHash(g_hashesToBench[hashFuncID].func, g_hashesToBench[hashFuncID].name, i, buffer, bufferSize);
            }
            /* unaligned */
            if ((i % 2) == 0) {
                /* Append "unaligned". */
                char* const hashNameBuf = XSUM_strcatDup(g_hashesToBench[hashFuncID].name, " unaligned");
                assert(hashNameBuf != NULL);
                XSUM_benchHash(g_hashesToBench[hashFuncID].func, hashNameBuf, i, ((const char*)buffer)+3, bufferSize);
                free(hashNameBuf);
            }
    }   }
}

static size_t XSUM_selectBenchedSize(const char* fileName)
{
    XSUM_U64 const inFileSize = XSUM_getFileSize(fileName);
    size_t benchedSize = (size_t) XSUM_findMaxMem(inFileSize);
    if ((XSUM_U64)benchedSize > inFileSize) benchedSize = (size_t)inFileSize;
    if (benchedSize < inFileSize) {
        XSUM_log("Not enough memory for '%s' full size; testing %i MB only...\n", fileName, (int)(benchedSize>>20));
    }
    return benchedSize;
}


int XSUM_benchFiles(const char* fileNamesTable[], int nbFiles)
{
    int fileIdx;
    for (fileIdx=0; fileIdx<nbFiles; fileIdx++) {
        const char* const inFileName = fileNamesTable[fileIdx];
        assert(inFileName != NULL);

        {   FILE* const inFile = XSUM_fopen( inFileName, "rb" );
            size_t const benchedSize = XSUM_selectBenchedSize(inFileName);
            char* const buffer = (char*)calloc(benchedSize+16+3, 1);
            void* const alignedBuffer = (buffer+15) - (((size_t)(buffer+15)) & 0xF);  /* align on next 16 bytes */

            /* Checks */
            if (inFile==NULL){
                XSUM_log("Error: Could not open '%s': %s.\n", inFileName, strerror(errno));
                free(buffer);
                exit(11);
            }
            if(!buffer) {
                XSUM_log("\nError: Out of memory.\n");
                fclose(inFile);
                exit(12);
            }

            /* Fill input buffer */
            {   size_t const readSize = fread(alignedBuffer, 1, benchedSize, inFile);
                fclose(inFile);
                if(readSize != benchedSize) {
                    XSUM_log("\nError: Could not read '%s': %s.\n", inFileName, strerror(errno));
                    free(buffer);
                    exit(13);
            }   }

            /* bench */
            XSUM_benchMem(alignedBuffer, benchedSize);

            free(buffer);
    }   }
    return 0;
}


int XSUM_benchInternal(size_t keySize)
{
    void* const buffer = calloc(keySize+16+3, 1);
    if (buffer == NULL) {
        XSUM_log("\nError: Out of memory.\n");
        exit(12);
    }

    {   const void* const alignedBuffer = ((char*)buffer+15) - (((size_t)((char*)buffer+15)) & 0xF);  /* align on next 16 bytes */

        /* bench */
        XSUM_logVerbose(1, "Sample of ");
        if (keySize > 10 KB) {
            XSUM_logVerbose(1, "%u KB", (unsigned)(keySize >> 10));
        } else {
            XSUM_logVerbose(1, "%u bytes", (unsigned)keySize);
        }
        XSUM_logVerbose(1, "...        \n");

        XSUM_benchMem(alignedBuffer, keySize);
        free(buffer);
    }
    return 0;
}


================================================
FILE: cli/xsum_bench.h
================================================
/*
 * xsum_bench - Benchmark functions for xxhsum
 * Copyright (C) 2013-2021 Yann Collet
 *
 * GPL v2 License
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * You can contact the author at:
 *   - xxHash homepage: https://www.xxhash.com
 *   - xxHash source repository: https://github.com/Cyan4973/xxHash
 */

#ifndef XSUM_BENCH_H
#define XSUM_BENCH_H

#include <stddef.h>  /* size_t */

#define NBLOOPS_DEFAULT    3    /* Default number of benchmark iterations */

extern int const g_nbTestFunctions;
extern char g_testIDs[];  /* size : g_nbTestFunctions */
extern const char k_testIDs_default[];
extern int g_nbIterations;

int XSUM_benchInternal(size_t keySize);
int XSUM_benchFiles(const char* fileNamesTable[], int nbFiles);


#ifdef __cplusplus
extern "C" {
#endif


#ifdef __cplusplus
}
#endif

#endif /* XSUM_BENCH_H */


================================================
FILE: cli/xsum_config.h
================================================
/*
 * xxhsum - Command line interface for xxhash algorithms
 * Copyright (C) 2013-2021 Yann Collet
 *
 * GPL v2 License
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * You can contact the author at:
 *   - xxHash homepage: https://www.xxhash.com
 *   - xxHash source repository: https://github.com/Cyan4973/xxHash
 */

/*
 * This contains various configuration parameters and feature detection for
 * xxhsum.
 *
 * Similar to config.h in Autotools, this should be the first header included.
 */

#ifndef XSUM_CONFIG_H
#define XSUM_CONFIG_H


/* ************************************
 *  Compiler Options
 **************************************/
/*
 * Disable Visual C's warnings when using the "insecure" CRT functions instead
 * of the "secure" _s functions.
 *
 * These functions are not portable, and aren't necessary if you are using the
 * original functions properly.
 */
#if defined(_MSC_VER) || defined(_WIN32)
#  ifndef _CRT_SECURE_NO_WARNINGS
#    define _CRT_SECURE_NO_WARNINGS
#  endif
#endif

#if defined(_MSC_VER)
#  pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
#endif

/* Under Linux at least, pull in the *64 commands */
#ifndef _LARGEFILE64_SOURCE
#  define _LARGEFILE64_SOURCE
#endif
#ifndef _FILE_OFFSET_BITS
#  define _FILE_OFFSET_BITS 64
#endif

/*
 * So we can use __attribute__((__format__))
 */
#ifdef __GNUC__
#  define XSUM_ATTRIBUTE(x) __attribute__(x)
#else
#  define XSUM_ATTRIBUTE(x)
#endif

#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)) /* UNIX-like OS */ \
   || defined(__midipix__) || defined(__VMS))
#  if (defined(__APPLE__) && defined(__MACH__)) || defined(__SVR4) || defined(_AIX) || defined(__hpux) /* POSIX.1-2001 (SUSv3) conformant */ \
     || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)  /* BSD distros */
#    define XSUM_PLATFORM_POSIX_VERSION 200112L
#  else
#    if defined(__linux__) || defined(__linux)
#      ifndef _POSIX_C_SOURCE
#        define _POSIX_C_SOURCE 200112L  /* use feature test macro */
#      endif
#    endif
#    include <unistd.h>  /* declares _POSIX_VERSION */
#    if defined(_POSIX_VERSION)  /* POSIX compliant */
#      define XSUM_PLATFORM_POSIX_VERSION _POSIX_VERSION
#    else
#      define XSUM_PLATFORM_POSIX_VERSION 0
#    endif
#  endif
#endif
#if !defined(XSUM_PLATFORM_POSIX_VERSION)
#  define XSUM_PLATFORM_POSIX_VERSION -1
#endif

#if !defined(S_ISREG)
#  define S_ISREG(x) (((x) & S_IFMT) == S_IFREG)
#endif


/* ************************************
 * Windows helpers
 **************************************/

/*
 * Whether to use the Windows UTF-16 APIs instead of the portable libc 8-bit
 * ("ANSI") APIs.
 *
 * Windows is not UTF-8 clean by default, and the only way to access every file
 * on the OS is to use UTF-16.
 *
 * Do note that xxhsum uses UTF-8 internally and only uses UTF-16 for command
 * line arguments, console I/O, and opening files.
 *
 * Additionally, this guarantees all piped output is UTF-8.
 */
#if defined(XSUM_WIN32_USE_WCHAR) && !defined(_WIN32)
/* We use Windows APIs, only use this on Windows. */
#  undef XSUM_WIN32_USE_WCHAR
#endif

#ifndef XSUM_WIN32_USE_WCHAR
#  if defined(_WIN32)
#    include <wchar.h>
#    if WCHAR_MAX == 0xFFFFU /* UTF-16 wchar_t */
#       define XSUM_WIN32_USE_WCHAR 1
#    else
#       define XSUM_WIN32_USE_WCHAR 0
#    endif
#  else
#    define XSUM_WIN32_USE_WCHAR 0
#  endif
#endif

#if !XSUM_WIN32_USE_WCHAR
/*
 * It doesn't make sense to have one without the other.
 * Due to XSUM_WIN32_USE_WCHAR being undef'd, this also handles
 * non-WIN32 platforms.
 */
#  undef  XSUM_WIN32_USE_WMAIN
#  define XSUM_WIN32_USE_WMAIN 0
#else
/*
 * Whether to use wmain() or main().
 *
 * wmain() is preferred because we don't have to mess with internal hidden
 * APIs.
 *
 * It always works on MSVC, but in MinGW, it only works on MinGW-w64 with the
 * -municode flag.
 *
 * Therefore we have to use main() -- there is no better option.
 */
#  ifndef XSUM_WIN32_USE_WMAIN
#    if defined(_UNICODE) || defined(UNICODE) /* MinGW -municode */ \
        || defined(_MSC_VER) /* MSVC */
#      define XSUM_WIN32_USE_WMAIN 1
#    else
#      define XSUM_WIN32_USE_WMAIN 0
#    endif
#  endif
/*
 * It is always good practice to define these to prevent accidental use of the
 * ANSI APIs, even if the program primarily uses UTF-8.
 */
#  ifndef _UNICODE
#    define _UNICODE
#  endif
#  ifndef UNICODE
#    define UNICODE
#  endif
#endif /* XSUM_WIN32_USE_WCHAR */

#ifndef XSUM_API
#  define XSUM_API
#endif

#ifndef XSUM_NO_TESTS
#  define XSUM_NO_TESTS 0
#endif

/* ***************************
 * Basic types
 * ***************************/

#if defined(__cplusplus) /* C++ */ \
 || (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L)  /* C99 */
#  include <stdint.h>
    typedef uint8_t  XSUM_U8;
    typedef uint32_t XSUM_U32;
    typedef uint64_t XSUM_U64;
# else
#   include <limits.h>
    typedef unsigned char      XSUM_U8;
#   if UINT_MAX == 0xFFFFFFFFUL
      typedef unsigned int     XSUM_U32;
#   else
      typedef unsigned long    XSUM_U32;
#   endif
    typedef unsigned long long XSUM_U64;
#endif /* not C++/C99 */

/* ***************************
 * Common constants
 * ***************************/

#define KB *( 1<<10)
#define MB *( 1<<20)
#define GB *(1U<<30)


#endif /* XSUM_CONFIG_H */


================================================
FILE: cli/xsum_os_specific.c
================================================
/*
 * xxhsum - Command line interface for xxhash algorithms
 * Copyright (C) 2013-2021 Yann Collet
 *
 * GPL v2 License
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * You can contact the author at:
 *   - xxHash homepage: https://www.xxhash.com
 *   - xxHash source repository: https://github.com/Cyan4973/xxHash
 */

#include "xsum_os_specific.h"  /* XSUM_API */
#include <sys/stat.h>   /* stat() / _stat64() */

/*
 * This file contains all of the ugly boilerplate to make xxhsum work across
 * platforms.
 */
#if defined(_MSC_VER) || XSUM_WIN32_USE_WCHAR
    typedef struct __stat64 XSUM_stat_t;
# if defined(_MSC_VER)
    typedef int mode_t;
# endif
#else
    typedef struct stat XSUM_stat_t;
#endif

#if defined(__EMSCRIPTEN__) && defined(XSUM_NODE_JS)
#  include <unistd.h>   /* isatty */
#  include <emscripten.h> /* EM_ASM_INT */

/* The Emscripten SDK does not properly detect when the standard streams
 * are piped to node.js, and there does not seem to be any way to tell in
 * plain C. To work around it, inline JavaScript is used to call Node's
 * isatty() function. */
static int XSUM_IS_CONSOLE(FILE* stdStream)
{
    /* https://github.com/iliakan/detect-node */
    int is_node = EM_ASM_INT((
        return (Object.prototype.toString.call(
            typeof process !== 'undefined' ? process : 0
        ) == '[object process]') | 0
    ));
    if (is_node) {
        return EM_ASM_INT(
            return require('node:tty').isatty($0),
            fileno(stdStream)
        );
    } else {
        return isatty(fileno(stdStream));
    }
}
#elif defined(__EMSCRIPTEN__) || (defined(__linux__) && (XSUM_PLATFORM_POSIX_VERSION >= 1)) \
 || (XSUM_PLATFORM_POSIX_VERSION >= 200112L) \
 || defined(__DJGPP__) \
 || defined(__MSYS__) \
 || defined(__HAIKU__)
#  ifdef __OpenBSD__
#    include <errno.h>       /* errno */
#    include <string.h>      /* strerror */
#    include "xsum_output.h" /* XSUM_log */
#  endif
#  include <unistd.h>   /* isatty */
#  define XSUM_IS_CONSOLE(stdStream) isatty(fileno(stdStream))
#elif defined(MSDOS) || defined(OS2)
#  include <io.h>       /* _isatty */
#  define XSUM_IS_CONSOLE(stdStream) _isatty(_fileno(stdStream))
#elif defined(_WIN32)
#  include <io.h>      /* _isatty */
#  include <windows.h> /* DeviceIoControl, HANDLE, FSCTL_SET_SPARSE */
#  include <stdio.h>   /* FILE */
static __inline int XSUM_IS_CONSOLE(FILE* stdStream)
{
    DWORD dummy;
    return _isatty(_fileno(stdStream)) && GetConsoleMode((HANDLE)_get_osfhandle(_fileno(stdStream)), &dummy);
}
#else
#  define XSUM_IS_CONSOLE(stdStream) 0
#endif

#if defined(MSDOS) || defined(OS2) || defined(_WIN32)
#  include <fcntl.h>   /* _O_BINARY */
#  include <io.h>      /* _setmode, _fileno, _get_osfhandle */
#  if !defined(__DJGPP__)
#    include <windows.h> /* DeviceIoControl, HANDLE, FSCTL_SET_SPARSE */
#    include <winioctl.h> /* FSCTL_SET_SPARSE */
#    define XSUM_SET_BINARY_MODE(file) { int const unused=_setmode(_fileno(file), _O_BINARY); (void)unused; }
#  else
#    define XSUM_SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
#  endif
#else
#  define XSUM_SET_BINARY_MODE(file) ((void)file)
#endif

XSUM_API int XSUM_isConsole(FILE* stream)
{
    return XSUM_IS_CONSOLE(stream);
}

XSUM_API void XSUM_setBinaryMode(FILE* stream)
{
    XSUM_SET_BINARY_MODE(stream);
}

#if !XSUM_WIN32_USE_WCHAR

XSUM_API FILE* XSUM_fopen(const char* filename, const char* mode)
{
    return fopen(filename, mode);
}
XSUM_ATTRIBUTE((__format__(__printf__, 2, 0)))
XSUM_API int XSUM_vfprintf(FILE* stream, const char* format, va_list ap)
{
    return vfprintf(stream, format, ap);
}

static int XSUM_stat(const char* infilename, XSUM_stat_t* statbuf)
{
#if defined(_MSC_VER)
    return _stat64(infilename, statbuf);
#else
    return stat(infilename, statbuf);
#endif
}

#ifndef XSUM_NO_MAIN
int main(int argc, const char* argv[])
{
#ifdef __OpenBSD__
    /*
     * xxhsum(1) does not create or write files, permit reading only.
     */
    if (pledge("stdio rpath", NULL) == -1) {
        XSUM_log("pledge: %s\n", strerror(errno));
        return 1;
    }
#endif

    return XSUM_main(argc, argv);
}
#endif

/* Unicode helpers for Windows to make UTF-8 act as it should. */
#else
#  include <windows.h>
#  include <wchar.h>

/*****************************************************************************
 *                       Unicode conversion tools
 *****************************************************************************/

/*
 * Converts a UTF-8 string to UTF-16. Acts like strdup. The string must be freed afterwards.
 * This version allows keeping the output length.
 */
static wchar_t* XSUM_widenString(const char* str, int* lenOut)
{
    int const len = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
    if (lenOut != NULL) *lenOut = len;
    if (len == 0) return NULL;
    {   wchar_t* buf = (wchar_t*)malloc((size_t)len * sizeof(wchar_t));
        if (buf != NULL) {
            if (MultiByteToWideChar(CP_UTF8, 0, str, -1, buf, len) == 0) {
                free(buf);
                return NULL;
       }    }
       return buf;
    }
}

/*
 * Converts a UTF-16 string to UTF-8. Acts like strdup. The string must be freed afterwards.
 * This version allows keeping the output length.
 */
static char* XSUM_narrowString(const wchar_t *str, int *lenOut)
{
    int len = WideCharToMultiByte(CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL);
    if (lenOut != NULL) *lenOut = len;
    if (len == 0) return NULL;
    {   char* const buf = (char*)malloc((size_t)len * sizeof(char));
        if (buf != NULL) {
            if (WideCharToMultiByte(CP_UTF8, 0, str, -1, buf, len, NULL, NULL) == 0) {
                free(buf);
                return NULL;
        }    }
        return buf;
    }
}



/*****************************************************************************
 *                             File helpers
 *****************************************************************************/
/*
 * fopen wrapper that supports UTF-8
 *
 * fopen will only accept ANSI filenames, which means that we can't open Unicode filenames.
 *
 * In order to open a Unicode filename, we need to convert filenames to UTF-16 and use _wfopen.
 */
XSUM_API FILE* XSUM_fopen(const char* filename, const char* mode)
{
    FILE* f = NULL;
    wchar_t* const wide_filename = XSUM_widenString(filename, NULL);
    if (wide_filename != NULL) {
        wchar_t* const wide_mode = XSUM_widenString(mode, NULL);
        if (wide_mode != NULL) {
            f = _wfopen(wide_filename, wide_mode);
            free(wide_mode);
        }
        free(wide_filename);
    }
    return f;
}

/*
 * stat() wrapper which supports UTF-8 filenames.
 */
static int XSUM_stat(const char* infilename, XSUM_stat_t* statbuf)
{
    int r = -1;
    wchar_t* const wide_filename = XSUM_widenString(infilename, NULL);
    if (wide_filename != NULL) {
        r = _wstat64(wide_filename, statbuf);
        free(wide_filename);
    }
    return r;
}

/*
 * In case it isn't available, this is what MSVC 2019 defines in stdarg.h.
 */
#if defined(_MSC_VER) && !defined(__clang__) && !defined(va_copy)
#  define XSUM_va_copy(destination, source) ((destination) = (source))
#else
#  define XSUM_va_copy(destination, source) va_copy(destination, source)
#endif

/*
 * vasprintf for Windows.
 */
XSUM_ATTRIBUTE((__format__(__printf__, 2, 0)))
static int XSUM_vasprintf(char** strp, const char* format, va_list ap)
{
    int size;
    va_list copy;
    /*
     * To be safe, make a va_copy.
     *
     * Note that Microsoft doesn't use va_copy in its sample code:
     *   https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/vsprintf-vsprintf-l-vswprintf-vswprintf-l-vswprintf-l?view=vs-2019
     */
    XSUM_va_copy(copy, ap);
    /* Calculate how many characters we need */
    size = _vscprintf(format, ap);
    va_end(copy);

    if (size < 0) {
        *strp = NULL;
        return size;
    } else {
        int ret;
        *strp = (char*) malloc((size_t)size + 1);
        if (*strp == NULL) {
            return -1;
        }
        /* vsprintf into the new buffer */
        ret = vsprintf(*strp, format, ap);
        if (ret < 0) {
            free(*strp);
            *strp = NULL;
        }
        return ret;
    }
}

/*
 * fprintf wrapper that supports UTF-8.
 *
 * fprintf doesn't properly handle Unicode on Windows.
 *
 * Additionally, it is codepage sensitive on console and may crash the program.
 *
 * Instead, we use vsnprintf, and either print with fwrite or convert to UTF-16
 * for console output and use the codepage-independent WriteConsoleW.
 *
 * Credit to t-mat: https://github.com/t-mat/xxHash/commit/5691423
 */
XSUM_ATTRIBUTE((__format__(__printf__, 2, 0)))
XSUM_API int XSUM_vfprintf(FILE *stream, const char *format, va_list ap)
{
    int result;
    char* u8_str = NULL;

    /*
     * Generate the UTF-8 output string with vasprintf.
     */
    result = XSUM_vasprintf(&u8_str, format, ap);

    if (result >= 0) {
        const size_t nchar = (size_t)result + 1;

        /*
         * Check if we are outputting to a console. Don't use XSUM_isConsole
         * directly -- we don't need to call _get_osfhandle twice.
         */
        int fileNb = _fileno(stream);
        intptr_t handle_raw = _get_osfhandle(fileNb);
        HANDLE handle = (HANDLE)handle_raw;
        DWORD dwTemp;

        if (handle_raw < 0) {
             result = -1;
        } else if (_isatty(fileNb) && GetConsoleMode(handle, &dwTemp)) {
            /*
             * Convert to UTF-16 and output with WriteConsoleW.
             *
             * This is codepage independent and works on Windows XP's default
             * msvcrt.dll.
             */
            int len;
            wchar_t* const u16_buf = XSUM_widenString(u8_str, &len);
            if (u16_buf == NULL) {
                result = -1;
            } else {
                if (WriteConsoleW(handle, u16_buf, (DWORD)len - 1, &dwTemp, NULL)) {
                    result = (int)dwTemp;
                } else {
                    result = -1;
                }
                free(u16_buf);
            }
        } else {
            /* fwrite the UTF-8 string if we are printing to a file */
            result = (int)fwrite(u8_str, 1, nchar - 1, stream);
            if (result == 0) {
                result = -1;
            }
        }
        free(u8_str);
    }
    return result;
}

#ifndef XSUM_NO_MAIN
/*****************************************************************************
 *                    Command Line argument parsing
 *****************************************************************************/

/* Converts a UTF-16 argv to UTF-8. */
static char** XSUM_convertArgv(int argc, wchar_t* utf16_argv[])
{
    char** const utf8_argv = (char**)malloc((size_t)(argc + 1) * sizeof(char*));
    if (utf8_argv != NULL) {
        int i;
        for (i = 0; i < argc; i++) {
            utf8_argv[i] = XSUM_narrowString(utf16_argv[i], NULL);
            if (utf8_argv[i] == NULL) {
                /* Out of memory, whoops. */
                while (i-- > 0) {
                    free(utf8_argv[i]);
                }
                free(utf8_argv);
                return NULL;
            }
        }
        utf8_argv[argc] = NULL;
    }
    return utf8_argv;
}
/* Frees arguments returned by XSUM_convertArgv */
static void XSUM_freeArgv(int argc, char** argv)
{
    int i;
    if (argv == NULL) {
        return;
    }
    for (i = 0; i < argc; i++) {
        free(argv[i]);
    }
    free(argv);
}

static int XSUM_wmain(int argc, wchar_t* utf16_argv[])
{
    /* Convert the UTF-16 arguments to UTF-8. */
    char** utf8_argv = XSUM_convertArgv(argc, utf16_argv);

    if (utf8_argv == NULL) {
        /* An unfortunate but incredibly unlikely error. */
        fprintf(stderr, "xxhsum: error converting command line arguments!\n");
        abort();
    } else {
        int ret;

        /*
         * MinGW's terminal uses full block buffering for stderr.
         *
         * This is nonstandard behavior and causes text to not display until
         * the buffer fills.
         *
         * `setvbuf()` can easily correct this to make text display instantly.
         */
        setvbuf(stderr, NULL, _IONBF, 0);

        /* Call our real main function */
        ret = XSUM_main(argc, (void*)utf8_argv);

        /* Cleanup */
        XSUM_freeArgv(argc, utf8_argv);
        return ret;
    }
}

#if XSUM_WIN32_USE_WMAIN

/*
 * The preferred method of obtaining the real UTF-16 arguments. Always works
 * on MSVC, sometimes works on MinGW-w64 depending on the compiler flags.
 */
#ifdef __cplusplus
extern "C"
#endif
int __cdecl wmain(int argc, wchar_t* utf16_argv[])
{
    return XSUM_wmain(argc, utf16_argv);
}
#else /* !XSUM_WIN32_USE_WMAIN */

/*
 * Wrap `XSUM_wmain()` using `main()` and `__wgetmainargs()` on MinGW without
 * Unicode support.
 *
 * `__wgetmainargs()` is used in the CRT startup to retrieve the arguments for
 * `wmain()`, so we use it on MinGW to emulate `wmain()`.
 *
 * It is an internal function and not declared in any public headers, so we
 * have to declare it manually.
 *
 * An alternative that doesn't mess with internal APIs is `GetCommandLineW()`
 * with `CommandLineToArgvW()`, but the former doesn't expand wildcards and the
 * latter requires linking to Shell32.dll and its numerous dependencies.
 *
 * This method keeps our dependencies to kernel32.dll and the CRT.
 *
 * https://docs.microsoft.com/en-us/cpp/c-runtime-library/getmainargs-wgetmainargs?view=vs-2019
 */
typedef struct {
    int newmode;
} _startupinfo;

#ifdef __cplusplus
extern "C"
#endif
int __cdecl __wgetmainargs(
    int*          Argc,
    wchar_t***    Argv,
    wchar_t***    Env,
    int           DoWildCard,
    _startupinfo* StartInfo
);

int main(int ansi_argc, const char* ansi_argv[])
{
    int       utf16_argc;
    wchar_t** utf16_argv;
    wchar_t** utf16_envp;         /* Unused but required */
    _startupinfo startinfo = {0}; /* 0 == don't change new mode */

    /* Get wmain's UTF-16 arguments. Make sure we expand wildcards. */
    if (__wgetmainargs(&utf16_argc, &utf16_argv, &utf16_envp, 1, &startinfo) < 0)
        /* In the very unlikely case of an error, use the ANSI arguments. */
        return XSUM_main(ansi_argc, ansi_argv);

    /* Call XSUM_wmain with our UTF-16 arguments */
    return XSUM_wmain(utf16_argc, utf16_argv);
}

#endif /* !XSUM_WIN32_USE_WMAIN */
#endif /* !XSUM_NO_MAIN */
#endif /* XSUM_WIN32_USE_WCHAR */


/*
 * Determines whether the file at filename is a directory.
 */
XSUM_API int XSUM_isDirectory(const char* filename)
{
    XSUM_stat_t statbuf;
    int r = XSUM_stat(filename, &statbuf);
#ifdef _MSC_VER
    if (!r && (statbuf.st_mode & _S_IFDIR)) return 1;
#else
    if (!r && S_ISDIR(statbuf.st_mode)) return 1;
#endif
    return 0;
}

/*
 * Returns the filesize of the file at filename.
 */
XSUM_API XSUM_U64 XSUM_getFileSize(const char* filename)
{
    XSUM_stat_t statbuf;
    int r = XSUM_stat(filename, &statbuf);
    if (r || !S_ISREG(statbuf.st_mode)) return 0;   /* No good... */
    return (XSUM_U64)statbuf.st_size;
}


================================================
FILE: cli/xsum_os_specific.h
================================================
/*
 * xxhsum - Command line interface for xxhash algorithms
 * Copyright (C) 2013-2021 Yann Collet
 *
 * GPL v2 License
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * You can contact the author at:
 *   - xxHash homepage: https://www.xxhash.com
 *   - xxHash source repository: https://github.com/Cyan4973/xxHash
 */

#ifndef XSUM_OS_SPECIFIC_H
#define XSUM_OS_SPECIFIC_H

#include "xsum_config.h"
#include <stdio.h>
#include <stdarg.h>

#ifdef __cplusplus
extern "C" {
#endif

/*
 * Declared here to be implemented in user code.
 *
 * Functions like main(), but is passed UTF-8 arguments even on Windows.
 */
XSUM_API int XSUM_main(int argc, const char* argv[]);

/*
 * Returns whether stream is a console.
 *
 * Functionally equivalent to isatty(fileno(stream)).
 */
XSUM_API int XSUM_isConsole(FILE* stream);

/*
 * Sets stream to pure binary mode (a.k.a. no CRLF conversions).
 */
XSUM_API void XSUM_setBinaryMode(FILE* stream);

/*
 * Returns whether the file at filename is a directory.
 */
XSUM_API int XSUM_isDirectory(const char* filename);

/*
 * Returns the file size of the file at filename.
 */
XSUM_API XSUM_U64 XSUM_getFileSize(const char* filename);

/*
 * UTF-8 stdio wrappers primarily for Windows
 */

/*
 * fopen() wrapper. Accepts UTF-8 filenames on Windows.
 *
 * Specifically, on Windows, the arguments will be converted to UTF-16
 * and passed to _wfopen().
 */
XSUM_API FILE* XSUM_fopen(const char* filename, const char* mode);

/*
 * vfprintf() wrapper which prints UTF-8 strings to Windows consoles
 * if applicable.
 */
XSUM_ATTRIBUTE((__format__(__printf__, 2, 0)))
XSUM_API int XSUM_vfprintf(FILE* stream, const char* format, va_list ap);

#ifdef __cplusplus
}
#endif

#endif /* XSUM_OS_SPECIFIC_H */


================================================
FILE: cli/xsum_output.c
================================================
/*
 * xxhsum - Command line interface for xxhash algorithms
 * Copyright (C) 2013-2021 Yann Collet
 *
 * GPL v2 License
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * You can contact the author at:
 *   - xxHash homepage: https://www.xxhash.com
 *   - xxHash source repository: https://github.com/Cyan4973/xxHash
 */

#include "xsum_output.h"
#include "xsum_os_specific.h"  /* XSUM_API */

int XSUM_logLevel = 2;

XSUM_ATTRIBUTE((__format__(__printf__, 1, 2)))
XSUM_API int XSUM_log(const char* format, ...)
{
    int ret;
    va_list ap;
    va_start(ap, format);
    ret = XSUM_vfprintf(stderr, format, ap);
    va_end(ap);
    return ret;
}


XSUM_ATTRIBUTE((__format__(__printf__, 1, 2)))
XSUM_API int XSUM_output(const char* format, ...)
{
    int ret;
    va_list ap;
    va_start(ap, format);
    ret = XSUM_vfprintf(stdout, format, ap);
    va_end(ap);
    return ret;
}

XSUM_ATTRIBUTE((__format__(__printf__, 2, 3)))
XSUM_API int XSUM_logVerbose(int minLevel, const char* format, ...)
{
    if (XSUM_logLevel >= minLevel) {
        int ret;
        va_list ap;
        va_start(ap, format);
        ret = XSUM_vfprintf(stderr, format, ap);
        va_end(ap);
        return ret;
    }
    return 0;
}


================================================
FILE: cli/xsum_output.h
================================================
/*
 * xxhsum - Command line interface for xxhash algorithms
 * Copyright (C) 2013-2021 Yann Collet
 *
 * GPL v2 License
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * You can contact the author at:
 *   - xxHash homepage: https://www.xxhash.com
 *   - xxHash source repository: https://github.com/Cyan4973/xxHash
 */

#ifndef XSUM_OUTPUT_H
#define XSUM_OUTPUT_H

#include "xsum_config.h"

#ifdef __cplusplus
extern "C" {
#endif

/*
 * How verbose the output is.
 */
extern int XSUM_logLevel;

/*
 * Same as fprintf(stderr, format, ...)
 */
XSUM_ATTRIBUTE((__format__(__printf__, 1, 2)))
XSUM_API int XSUM_log(const char *format, ...);

/*
 * Like XSUM_log, but only outputs if XSUM_logLevel >= minLevel.
 */
XSUM_ATTRIBUTE((__format__(__printf__, 2, 3)))
XSUM_API int XSUM_logVerbose(int minLevel, const char *format, ...);

/*
 * Same as printf(format, ...)
 */
XSUM_ATTRIBUTE((__format__(__printf__, 1, 2)))
XSUM_API int XSUM_output(const char *format, ...);

#ifdef __cplusplus
}
#endif

#endif /* XSUM_OUTPUT_H */


================================================
FILE: cli/xsum_sanity_check.c
================================================
/*
 * xxhsum - Command line interface for xxhash algorithms
 * Copyright (C) 2013-2021 Yann Collet
 *
 * GPL v2 License
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * You can contact the author at:
 *   - xxHash homepage: https://www.xxhash.com
 *   - xxHash source repository: https://github.com/Cyan4973/xxHash
 */

#include "xsum_sanity_check.h"
#include "xsum_output.h"  /* XSUM_log */
#ifndef XXH_STATIC_LINKING_ONLY
#  define XXH_STATIC_LINKING_ONLY
#endif
#include "../xxhash.h"

#include <stdlib.h>  /* exit */
#include <assert.h>
#include <string.h>  /* memcmp */

/* use #define to make them constant, required for initialization */
#define PRIME32 2654435761U
#define PRIME64 11400714785074694797ULL

/*
 * Fills a test buffer with pseudorandom data.
 *
 * This is used in the sanity check - its values must not be changed.
 */
XSUM_API void XSUM_fillTestBuffer(XSUM_U8* buffer, size_t len)
{
    XSUM_U64 byteGen = PRIME32;
    size_t i;

    assert(buffer != NULL);

    for (i=0; i<len; i++) {
        buffer[i] = (XSUM_U8)(byteGen>>56);
        byteGen *= PRIME64;
    }
}



/* ************************************************
 * Self-test:
 * ensure results consistency across platforms
 *********************************************** */
#if XSUM_NO_TESTS
XSUM_API void XSUM_sanityCheck(void)
{
    XSUM_log("This version of xxhsum is not verified.\n");
}
#else

/*
 * Test data vectors
 */
typedef struct {
    XSUM_U32 len;
    XSUM_U32 seed;
    XSUM_U32 Nresult;
} XSUM_testdata32_t;

typedef struct {
    XSUM_U32 len;
    XSUM_U64 seed;
    XSUM_U64 Nresult;
} XSUM_testdata64_t;

typedef struct {
    XSUM_U32 len;
    XSUM_U64 seed;
    XXH128_hash_t Nresult;
} XSUM_testdata128_t;

#define SECRET_SAMPLE_NBBYTES 5
typedef struct {
    XSUM_U32 seedLen;
    XSUM_U32 secretLen;
    XSUM_U8 byte[SECRET_SAMPLE_NBBYTES];
} XSUM_testdata_sample_t;

/* XXH32 */
static const XSUM_testdata32_t XSUM_XXH32_testdata[] = {
    {   0,       0, 0x02CC5D05U },
    {   0, PRIME32, 0x36B78AE7U },
    {   1,       0, 0xCF65B03EU },
    {   1, PRIME32, 0xB4545AA4U },
    {  14,       0, 0x1208E7E2U },
    {  14, PRIME32, 0x6AF1D1FEU },
    { 222,       0, 0x5BD11DBDU },
    { 222, PRIME32, 0x58803C5FU }
};

/* XXH64 */
static const XSUM_testdata64_t XSUM_XXH64_testdata[] = {
    {   0,       0, 0xEF46DB3751D8E999ULL },
    {   0, PRIME32, 0xAC75FDA2929B17EFULL },
    {   1,       0, 0xE934A84ADB052768ULL },
    {   1, PRIME32, 0x5014607643A9B4C3ULL },
    {   4,       0, 0x9136A0DCA57457EEULL },
    {  14,       0, 0x8282DCC4994E35C8ULL },
    {  14, PRIME32, 0xC3BD6BF63DEB6DF0ULL },
    { 222,       0, 0xB641AE8CB691C174ULL },
    { 222, PRIME32, 0x20CB8AB7AE10C14AULL }
};
/*
 * XXH3:
 * Due to being a more complex hash function with specializations for certain
 * lengths, a more extensive test is used for XXH3.
 */

/* XXH3_64bits, seeded */
static const XSUM_testdata64_t XSUM_XXH3_testdata[] = {
    {    0,       0, 0x2D06800538D394C2ULL },  /* empty string */
    {    0, PRIME64, 0xA8A6B918B2F0364AULL },
    {    1,       0, 0xC44BDFF4074EECDBULL },  /*  1 -  3 */
    {    1, PRIME64, 0x032BE332DD766EF8ULL },
    {    6,       0, 0x27B56A84CD2D7325ULL },  /*  4 -  8 */
    {    6, PRIME64, 0x84589C116AB59AB9ULL },
    {   12,       0, 0xA713DAF0DFBB77E7ULL },  /*  9 - 16 */
    {   12, PRIME64, 0xE7303E1B2336DE0EULL },
    {   24,       0, 0xA3FE70BF9D3510EBULL },  /* 17 - 32 */
    {   24, PRIME64, 0x850E80FC35BDD690ULL },
    {   48,       0, 0x397DA259ECBA1F11ULL },  /* 33 - 64 */
    {   48, PRIME64, 0xADC2CBAA44ACC616ULL },
    {   80,       0, 0xBCDEFBBB2C47C90AULL },  /* 65 - 96 */
    {   80, PRIME64, 0xC6DD0CB699532E73ULL },
    {  195,       0, 0xCD94217EE362EC3AULL },  /* 129-240 */
    {  195, PRIME64, 0xBA68003D370CB3D9ULL },

    {  403,       0, 0xCDEB804D65C6DEA4ULL },  /* one block, last stripe is overlapping */
    {  403, PRIME64, 0x6259F6ECFD6443FDULL },
    {  512,       0, 0x617E49599013CB6BULL },  /* one block, finishing at stripe boundary */
    {  512, PRIME64, 0x3CE457DE14C27708ULL },
    { 2048,       0, 0xDD59E2C3A5F038E0ULL },  /* 2 blocks, finishing at block boundary */
    { 2048, PRIME64, 0x66F81670669ABABCULL },
    { 2099,       0, 0xC6B9D9B3FC9AC765ULL },  /* 2 blocks + 1 partial block, to detect off-by-one scrambling issues, like #816 */
    { 2099, PRIME64, 0x184F316843663974ULL },
    { 2240,       0, 0x6E73A90539CF2948ULL },  /* 3 blocks, finishing at stripe boundary */
    { 2240, PRIME64, 0x757BA8487D1B5247ULL },
    { 2367,       0, 0xCB37AEB9E5D361EDULL },  /* 3 blocks, last stripe is overlapping */
    { 2367, PRIME64, 0xD2DB3415B942B42AULL }
};
/* XXH3_64bits, custom secret */
static const XSUM_testdata64_t XSUM_XXH3_withSecret_testdata[] = {
    {       0, 0, 0x3559D64878C5C66CULL },  /* empty string */
    {       1, 0, 0x8A52451418B2DA4DULL },  /*  1 -  3 */
    {       6, 0, 0x82C90AB0519369ADULL },  /*  4 -  8 */
    {      12, 0, 0x14631E773B78EC57ULL },  /*  9 - 16 */
    {      24, 0, 0xCDD5542E4A9D9FE8ULL },  /* 17 - 32 */
    {      48, 0, 0x33ABD54D094B2534ULL },  /* 33 - 64 */
    {      80, 0, 0xE687BA1684965297ULL },  /* 65 - 96 */
    {     195, 0, 0xA057273F5EECFB20ULL },  /* 129-240 */

    {     403, 0, 0x14546019124D43B8ULL },  /* one block, last stripe is overlapping */
    {     512, 0, 0x7564693DD526E28DULL },  /* one block, finishing at stripe boundary */
    {    2048, 0, 0xD32E975821D6519FULL },  /* >= 2 blodcks, at least one scrambling */
    {    2367, 0, 0x293FA8E5173BB5E7ULL },  /* >= 2 blocks, at least one scrambling, last stripe unaligned */

    { 64*10*3, 0, 0x751D2EC54BC6038BULL }   /* exactly 3 full blocks, not a multiple of 256 */
};
/* XXH3_128bits, seeded */
static const XSUM_testdata128_t XSUM_XXH128_testdata[] = {
    {    0,       0, { 0x6001C324468D497FULL, 0x99AA06D3014798D8ULL } },  /* empty string */
    {    0, PRIME32, { 0x5444F7869C671AB0ULL, 0x92220AE55E14AB50ULL } },
    {    1,       0, { 0xC44BDFF4074EECDBULL, 0xA6CD5E9392000F6AULL } },  /*  1 -  3 */
    {    1, PRIME32, { 0xB53D5557E7F76F8DULL, 0x89B99554BA22467CULL } },
    {    6,       0, { 0x3E7039BDDA43CFC6ULL, 0x082AFE0B8162D12AULL } },  /*  4 -  8 */
    {    6, PRIME32, { 0x269D8F70BE98856EULL, 0x5A865B5389ABD2B1ULL } },
    {   12,       0, { 0x061A192713F69AD9ULL, 0x6E3EFD8FC7802B18ULL } },  /*  9 - 16 */
    {   12, PRIME32, { 0x9BE9F9A67F3C7DFBULL, 0xD7E09D518A3405D3ULL } },
    {   24,       0, { 0x1E7044D28B1B901DULL, 0x0CE966E4678D3761ULL } },  /* 17 - 32 */
    {   24, PRIME32, { 0xD7304C54EBAD40A9ULL, 0x3162026714A6A243ULL } },
    {   48,       0, { 0xF942219AED80F67BULL, 0xA002AC4E5478227EULL } },  /* 33 - 64 */
    {   48, PRIME32, { 0x7BA3C3E453A1934EULL, 0x163ADDE36C072295ULL } },
    {   81,       0, { 0x5E8BAFB9F95FB803ULL, 0x4952F58181AB0042ULL } },  /* 65 - 96 */
    {   81, PRIME32, { 0x703FBB3D7A5F755CULL, 0x2724EC7ADC750FB6ULL } },
    {  222,       0, { 0xF1AEBD597CEC6B3AULL, 0x337E09641B948717ULL } },  /* 129-240 */
    {  222, PRIME32, { 0xAE995BB8AF917A8DULL, 0x91820016621E97F1ULL } },

    {  403,       0, { 0xCDEB804D65C6DEA4ULL, 0x1B6DE21E332DD73DULL } },  /* one block, last stripe is overlapping */
    {  403, PRIME64, { 0x6259F6ECFD6443FDULL, 0xBED311971E0BE8F2ULL } },
    {  512,       0, { 0x617E49599013CB6BULL, 0x18D2D110DCC9BCA1ULL } },  /* one block, finishing at stripe boundary */
    {  512, PRIME64, { 0x3CE457DE14C27708ULL, 0x925D06B8EC5B8040ULL } },
    { 2048,       0, { 0xDD59E2C3A5F038E0ULL, 0xF736557FD47073A5ULL } },  /* 2 blocks, finishing at block boundary */
    { 2048, PRIME32, { 0x230D43F30206260BULL, 0x7FB03F7E7186C3EAULL } },
    { 2240,       0, { 0x6E73A90539CF2948ULL, 0xCCB134FBFA7CE49DULL } },  /* 3 blocks, finishing at stripe boundary */
    { 2240, PRIME32, { 0xED385111126FBA6FULL, 0x50A1FE17B338995FULL } },
    { 2367,       0, { 0xCB37AEB9E5D361EDULL, 0xE89C0F6FF369B427ULL } },  /* 3 blocks, last stripe is overlapping */
    { 2367, PRIME32, { 0x6F5360AE69C2F406ULL, 0xD23AAE4B76C31ECBULL } }
};

/* XXH128, custom secret */
static const XSUM_testdata128_t XSUM_XXH128_withSecret_testdata[] = {
    {  0, 0, { 0x005923CCEECBE8AEULL, 0x5F70F4EA232F1D38ULL } },  /* empty string */
    {  1, 0, { 0x8A52451418B2DA4DULL, 0x3A66AF5A9819198EULL } },  /*  1 -  3 */
    {  6, 0, { 0x0B61C8ACA7D4778FULL, 0x376BD91B6432F36DULL } },  /*  4 -  8 */
    { 12, 0, { 0xAF82F6EBA263D7D8ULL, 0x90A3C2D839F57D0FULL } }   /*  9 - 16 */
};

#define SECRET_SIZE_MAX 9867
static const XSUM_testdata_sample_t XSUM_XXH3_generateSecret_testdata[] = {
    {                              0, 192, { 0xE7, 0x8C, 0x77, 0x77, 0x00 } },
    {                              1, 240, { 0x2B, 0x3E, 0xDE, 0xC1, 0x00 } },
    {     XXH3_SECRET_SIZE_MIN -   1, 277, { 0xE8, 0x39, 0x6C, 0xCC, 0x7B } },
    { XXH3_SECRET_DEFAULT_SIZE + 500, SECRET_SIZE_MAX, { 0xD6, 0x1C, 0x41, 0x17, 0xB3 } }
};

static void XSUM_checkResult32(XXH32_hash_t r1, XXH32_hash_t r2)
{
    static int nbTests = 1;
    if (r1!=r2) {
        XSUM_log("\rError: 32-bit hash test %i: Internal sanity check failed!\n", nbTests);
        XSUM_log("\rGot 0x%08X, expected 0x%08X.\n", (unsigned)r1, (unsigned)r2);
        XSUM_log("\rNote: If you modified the hash functions, make sure to either update the values\n"
                  "or temporarily recompile with XSUM_NO_TESTS=1.\n");
        exit(1);
    }
    nbTests++;
}

static void XSUM_checkResult64(XXH64_hash_t r1, XXH64_hash_t r2)
{
    static int nbTests = 1;
    if (r1!=r2) {
        XSUM_log("\rError: 64-bit hash test %i: Internal sanity check failed!\n", nbTests);
        XSUM_log("\rGot 0x%08X%08XULL, expected 0x%08X%08XULL.\n",
                (unsigned)(r1>>32), (unsigned)r1, (unsigned)(r2>>32), (unsigned)r2);
        XSUM_log("\rNote: If you modified the hash functions, make sure to either update the values\n"
                  "or temporarily recompile with XSUM_NO_TESTS=1.\n");
        exit(1);
    }
    nbTests++;
}

static void XSUM_checkResult128(XXH128_hash_t r1, XXH128_hash_t r2)
{
    static int nbTests = 1;
    if ((r1.low64 != r2.low64) || (r1.high64 != r2.high64)) {
        XSUM_log("\rError: 128-bit hash test %i: Internal sanity check failed.\n", nbTests);
        XSUM_log("\rGot { 0x%08X%08XULL, 0x%08X%08XULL }, expected { 0x%08X%08XULL, 0x%08X%08XULL } \n",
                (unsigned)(r1.low64>>32), (unsigned)r1.low64, (unsigned)(r1.high64>>32), (unsigned)r1.high64,
                (unsigned)(r2.low64>>32), (unsigned)r2.low64, (unsigned)(r2.high64>>32), (unsigned)r2.high64 );
        XSUM_log("\rNote: If you modified the hash functions, make sure to either update the values\n"
                  "or temporarily recompile with XSUM_NO_TESTS=1.\n");
        exit(1);
    }
    nbTests++;
}


static void XSUM_testXXH32(const void* data, const XSUM_testdata32_t* testData)
{
    XXH32_state_t *state = XXH32_createState();
    size_t pos;

    size_t len = testData->len;
    XSUM_U32 seed = testData->seed;
    XSUM_U32 Nresult = testData->Nresult;

    if (len == 0) {
        data = NULL;
    } else {
        assert(data != NULL);
    }

    assert(state != NULL);

    XSUM_checkResult32(XXH32(data, len, seed), Nresult);

    (void)XXH32_reset(state, seed);
    (void)XXH32_update(state, data, len);
    XSUM_checkResult32(XXH32_digest(state), Nresult);

    (void)XXH32_reset(state, seed);
    for (pos=0; pos<len; pos++)
        (void)XXH32_update(state, ((const char*)data)+pos, 1);
    XSUM_checkResult32(XXH32_digest(state), Nresult);
    XXH32_freeState(state);
}

static void XSUM_testXXH64(const void* data, const XSUM_testdata64_t* testData)
{
    XXH64_state_t *state = XXH64_createState();
    size_t pos;

    size_t len = (size_t)testData->len;
    XSUM_U64 seed = testData->seed;
    XSUM_U64 Nresult = testData->Nresult;

    if (len == 0) {
        data = NULL;
    } else {
        assert(data != NULL);
    }

    assert(state != NULL);

    XSUM_checkResult64(XXH64(data, len, seed), Nresult);

    (void)XXH64_reset(state, seed);
    (void)XXH64_update(state, data, len);
    XSUM_checkResult64(XXH64_digest(state), Nresult);

    (void)XXH64_reset(state, seed);
    for (pos=0; pos<len; pos++)
        (void)XXH64_update(state, ((const char*)data)+pos, 1);
    XSUM_checkResult64(XXH64_digest(state), Nresult);
    XXH64_freeState(state);
}

/*
 * Used to get "random" (but actually 100% reproducible) lengths for
 * XSUM_XXH3_randomUpdate.
 */
static XSUM_U32 XSUM_rand(void)
{
    static XSUM_U64 seed = PRIME32;
    seed *= PRIME64;
    return (XSUM_U32)(seed >> 40);
}

/*
 * Technically, XXH3_64bits_update is identical to XXH3_128bits_update as of
 * v0.8.0, but we treat them as separate.
 */
typedef XXH_errorcode (*XSUM_XXH3_update_t)(XXH_NOESCAPE XXH3_state_t* state, XXH_NOESCAPE const void* input, size_t length);

/*
 * Runs the passed XXH3_update variant on random lengths. This is to test the
 * more complex logic of the update function, catching bugs like this one:
 *    https://github.com/Cyan4973/xxHash/issues/378
 */
static void XSUM_XXH3_randomUpdate(XXH3_state_t* state, const void* data,
                                   size_t len, XSUM_XXH3_update_t update_fn)
{
    size_t p = 0;
    while (p < len) {
        size_t const modulo = len > 2 ? len : 2;
        size_t l = (size_t)(XSUM_rand()) % modulo;
        if (p + l > len) l = len - p;
        (void)update_fn(stat
Download .txt
gitextract_v1q1r9ds/

├── .gitattributes
├── .github/
│   ├── dependabot.yml
│   └── workflows/
│       ├── ci.yml
│       ├── cmake-cross-compile-test.yml
│       └── scorecard.yml
├── .gitignore
├── CHANGELOG
├── Doxyfile
├── Doxyfile-internal
├── LICENSE
├── Makefile
├── README.md
├── SECURITY.md
├── appveyor.yml
├── build/
│   └── make/
│       ├── README.md
│       └── multiconf.make
├── cli/
│   ├── .tipi/
│   │   ├── deps
│   │   └── opts
│   ├── COPYING
│   ├── README.md
│   ├── xsum_arch.c
│   ├── xsum_arch.h
│   ├── xsum_bench.c
│   ├── xsum_bench.h
│   ├── xsum_config.h
│   ├── xsum_os_specific.c
│   ├── xsum_os_specific.h
│   ├── xsum_output.c
│   ├── xsum_output.h
│   ├── xsum_sanity_check.c
│   ├── xsum_sanity_check.h
│   ├── xxhsum.1
│   ├── xxhsum.1.md
│   └── xxhsum.c
├── clib.json
├── doc/
│   ├── README.md
│   ├── xxhash.cry
│   └── xxhash_spec.md
├── fuzz/
│   └── fuzzer.c
├── libxxhash.pc.in
├── tests/
│   ├── Makefile
│   ├── cli-comment-line.sh
│   ├── cli-ignore-missing.sh
│   ├── collisions/
│   │   ├── .gitignore
│   │   ├── LICENSE
│   │   ├── Makefile
│   │   ├── README.md
│   │   ├── allcodecs/
│   │   │   ├── README.md
│   │   │   ├── dummy.c
│   │   │   └── dummy.h
│   │   ├── hashes.h
│   │   ├── main.c
│   │   ├── pool.c
│   │   ├── pool.h
│   │   ├── sort.cc
│   │   ├── sort.hh
│   │   ├── threading.c
│   │   └── threading.h
│   ├── filename-escape.sh
│   ├── generate_unicode_test.c
│   ├── multiInclude.c
│   ├── ppc_define.c
│   ├── sanity_test.c
│   ├── sanity_test_vectors.h
│   ├── sanity_test_vectors_generator.c
│   ├── test_alias.c
│   └── unicode_lint.sh
├── xxh3.h
├── xxh_x86dispatch.c
├── xxh_x86dispatch.h
├── xxhash.c
└── xxhash.h
Download .txt
SYMBOL INDEX (507 symbols across 23 files)

FILE: cli/xsum_bench.c
  function clock_t (line 62) | static clock_t XSUM_clockSpan( clock_t start )
  function XSUM_findMaxMem (line 67) | static size_t XSUM_findMaxMem(XSUM_U64 requiredMem)
  type XSUM_U32 (line 106) | typedef XSUM_U32 (*hashFunction)(const void* buffer, size_t bufferSize, ...
  function XSUM_U32 (line 108) | static XSUM_U32 localXXH32(const void* buffer, size_t bufferSize, XSUM_U...
  function XSUM_U32 (line 112) | static XSUM_U32 localXXH32_stream(const void* buffer, size_t bufferSize,...
  function XSUM_U32 (line 120) | static XSUM_U32 localXXH64(const void* buffer, size_t bufferSize, XSUM_U...
  function XSUM_U32 (line 124) | static XSUM_U32 localXXH64_stream(const void* buffer, size_t bufferSize,...
  function XSUM_U32 (line 132) | static XSUM_U32 localXXH3_64b(const void* buffer, size_t bufferSize, XSU...
  function XSUM_U32 (line 137) | static XSUM_U32 localXXH3_64b_seeded(const void* buffer, size_t bufferSi...
  function XSUM_U32 (line 141) | static XSUM_U32 localXXH3_64b_secret(const void* buffer, size_t bufferSi...
  function XSUM_U32 (line 146) | static XSUM_U32 localXXH3_128b(const void* buffer, size_t bufferSize, XS...
  function XSUM_U32 (line 151) | static XSUM_U32 localXXH3_128b_seeded(const void* buffer, size_t bufferS...
  function XSUM_U32 (line 155) | static XSUM_U32 localXXH3_128b_secret(const void* buffer, size_t bufferS...
  function XSUM_U32 (line 160) | static XSUM_U32 localXXH3_stream(const void* buffer, size_t bufferSize, ...
  function XSUM_U32 (line 168) | static XSUM_U32 localXXH3_stream_seeded(const void* buffer, size_t buffe...
  function XSUM_U32 (line 176) | static XSUM_U32 localXXH128_stream(const void* buffer, size_t bufferSize...
  function XSUM_U32 (line 184) | static XSUM_U32 localXXH128_stream_seeded(const void* buffer, size_t buf...
  type hashInfo (line 194) | typedef struct {
  function XSUM_benchHash (line 228) | static void XSUM_benchHash(hashFunction h, const char* hName, int testID,
  function XSUM_benchMem (line 351) | static void XSUM_benchMem(const void* buffer, size_t bufferSize)
  function XSUM_selectBenchedSize (line 375) | static size_t XSUM_selectBenchedSize(const char* fileName)
  function XSUM_benchFiles (line 387) | int XSUM_benchFiles(const char* fileNamesTable[], int nbFiles)
  function XSUM_benchInternal (line 429) | int XSUM_benchInternal(size_t keySize)

FILE: cli/xsum_config.h
  type XSUM_U8 (line 191) | typedef uint8_t  XSUM_U8;
  type XSUM_U32 (line 192) | typedef uint32_t XSUM_U32;
  type XSUM_U64 (line 193) | typedef uint64_t XSUM_U64;
  type XSUM_U8 (line 196) | typedef unsigned char      XSUM_U8;
  type XSUM_U32 (line 198) | typedef unsigned int     XSUM_U32;
  type XSUM_U32 (line 200) | typedef unsigned long    XSUM_U32;
  type XSUM_U64 (line 202) | typedef unsigned long long XSUM_U64;

FILE: cli/xsum_os_specific.c
  type XSUM_stat_t (line 34) | typedef struct __stat64 XSUM_stat_t;
  type mode_t (line 36) | typedef int mode_t;
  type XSUM_stat_t (line 39) | typedef struct stat XSUM_stat_t;
  function XSUM_IS_CONSOLE (line 50) | static int XSUM_IS_CONSOLE(FILE* stdStream)
  function XSUM_IS_CONSOLE (line 86) | static __inline int XSUM_IS_CONSOLE(FILE* stdStream)
  function XSUM_API (line 109) | XSUM_API int XSUM_isConsole(FILE* stream)
  function XSUM_API (line 114) | XSUM_API void XSUM_setBinaryMode(FILE* stream)
  function XSUM_API (line 121) | XSUM_API FILE* XSUM_fopen(const char* filename, const char* mode)
  function XSUM_vfprintf (line 126) | int XSUM_vfprintf(FILE* stream, const char* format, va_list ap)
  function XSUM_stat (line 131) | static int XSUM_stat(const char* infilename, XSUM_stat_t* statbuf)
  function main (line 141) | int main(int argc, const char* argv[])
  function wchar_t (line 170) | static wchar_t* XSUM_widenString(const char* str, int* lenOut)
  function XSUM_API (line 216) | XSUM_API FILE* XSUM_fopen(const char* filename, const char* mode)
  function XSUM_stat (line 234) | static int XSUM_stat(const char* infilename, XSUM_stat_t* statbuf)
  function XSUM_vasprintf (line 258) | static int XSUM_vasprintf(char** strp, const char* format, va_list ap)
  function XSUM_vfprintf (line 305) | int XSUM_vfprintf(FILE *stream, const char *format, va_list ap)
  function XSUM_freeArgv (line 387) | static void XSUM_freeArgv(int argc, char** argv)
  function XSUM_wmain (line 399) | static int XSUM_wmain(int argc, wchar_t* utf16_argv[])
  function wmain (line 439) | int __cdecl wmain(int argc, wchar_t* utf16_argv[])
  type _startupinfo (line 463) | typedef struct {
  function main (line 478) | int main(int ansi_argc, const char* ansi_argv[])
  function XSUM_API (line 502) | XSUM_API int XSUM_isDirectory(const char* filename)
  function XSUM_API (line 517) | XSUM_API XSUM_U64 XSUM_getFileSize(const char* filename)

FILE: cli/xsum_output.c
  function XSUM_log (line 32) | int XSUM_log(const char* format, ...)
  function XSUM_output (line 44) | int XSUM_output(const char* format, ...)
  function XSUM_logVerbose (line 55) | int XSUM_logVerbose(int minLevel, const char* format, ...)

FILE: cli/xsum_sanity_check.c
  function XSUM_API (line 46) | XSUM_API void XSUM_fillTestBuffer(XSUM_U8* buffer, size_t len)
  function XSUM_API (line 66) | XSUM_API void XSUM_sanityCheck(void)
  type XSUM_testdata32_t (line 75) | typedef struct {
  type XSUM_testdata64_t (line 81) | typedef struct {
  type XSUM_testdata128_t (line 87) | typedef struct {
  type XSUM_testdata_sample_t (line 94) | typedef struct {
  function XSUM_checkResult32 (line 227) | static void XSUM_checkResult32(XXH32_hash_t r1, XXH32_hash_t r2)
  function XSUM_checkResult64 (line 240) | static void XSUM_checkResult64(XXH64_hash_t r1, XXH64_hash_t r2)
  function XSUM_checkResult128 (line 254) | static void XSUM_checkResult128(XXH128_hash_t r1, XXH128_hash_t r2)
  function XSUM_testXXH32 (line 270) | static void XSUM_testXXH32(const void* data, const XSUM_testdata32_t* te...
  function XSUM_testXXH64 (line 300) | static void XSUM_testXXH64(const void* data, const XSUM_testdata64_t* te...
  function XSUM_U32 (line 334) | static XSUM_U32 XSUM_rand(void)
  type XXH_errorcode (line 345) | typedef XXH_errorcode (*XSUM_XXH3_update_t)(XXH_NOESCAPE XXH3_state_t* s...
  function XSUM_XXH3_randomUpdate (line 352) | static void XSUM_XXH3_randomUpdate(XXH3_state_t* state, const void* data,
  function XSUM_testXXH3 (line 365) | static void XSUM_testXXH3(const void* data, const XSUM_testdata64_t* tes...
  function XSUM_testXXH3_withSecret (line 455) | static void XSUM_testXXH3_withSecret(const void* data, const void* secret,
  function XSUM_testXXH128 (line 511) | static void XSUM_testXXH128(const void* data, const XSUM_testdata128_t* ...
  function XSUM_testXXH128_withSecret (line 606) | static void XSUM_testXXH128_withSecret(const void* data, const void* sec...
  function XSUM_testSecretGenerator (line 659) | static void XSUM_testSecretGenerator(const void* customSeed, const XSUM_...
  function XSUM_API (line 688) | XSUM_API void XSUM_sanityCheck(void)

FILE: cli/xxhsum.c
  function XSUM_isLittleEndian (line 54) | static unsigned XSUM_isLittleEndian(void)
  type AlgoSelected (line 74) | typedef enum { algo_xxh32=0, algo_xxh64=1, algo_xxh128=2, algo_xxh3=3 } ...
  type AlgoBitmask (line 77) | typedef enum {
  function XSUM_filenameNeedsEscape (line 102) | static int XSUM_filenameNeedsEscape(const char* filename) {
  function XSUM_lineNeedsUnescape (line 108) | static int XSUM_lineNeedsUnescape(const char* line) {
  function XSUM_printFilename (line 117) | static void XSUM_printFilename(const char* filename, int needsEscape) {
  function XSUM_U32 (line 198) | static XSUM_U32 XSUM_algoBitmask_ComputeAlgoBitmaskFromAlgoSelected(Algo...
  function XSUM_algoBitmask_Accepts (line 203) | static int XSUM_algoBitmask_Accepts(XSUM_U32 algoBitmask, AlgoSelected p...
  function XSUM_display_LittleEndian (line 217) | static void XSUM_display_LittleEndian(const void* ptr, size_t length)
  function XSUM_display_BigEndian (line 225) | static void XSUM_display_BigEndian(const void* ptr, size_t length)
  type Multihash (line 233) | typedef union {
  function Multihash (line 244) | static Multihash
  function XSUM_printLine_BSD_internal (line 316) | static void XSUM_printLine_BSD_internal(const char* filename,
  function XSUM_printLine_BSD_LE (line 335) | static void XSUM_printLine_BSD_LE(const char* filename, const void* cano...
  function XSUM_printLine_BSD (line 340) | static void XSUM_printLine_BSD(const char* filename, const void* canonic...
  function XSUM_displayPrefix (line 345) | static void XSUM_displayPrefix(const AlgoSelected hashType)
  function XSUM_printLine_GNU_internal (line 353) | static void XSUM_printLine_GNU_internal(const char* filename,
  function XSUM_printLine_GNU (line 370) | static void XSUM_printLine_GNU(const char* filename,
  function XSUM_printLine_GNU_LE (line 376) | static void XSUM_printLine_GNU_LE(const char* filename,
  type Display_endianness (line 382) | typedef enum { big_endian, little_endian} Display_endianness;
  type Display_convention (line 384) | typedef enum { display_gnu, display_bsd } Display_convention;
  type LineStatus (line 388) | typedef enum {
  function LineStatus (line 401) | static LineStatus XSUM_hashFile(const char* fileName,
  function XSUM_hashFiles (line 482) | static int XSUM_hashFiles(const char* fnList[], int fnTotal,
  type GetLineResult (line 541) | typedef enum {
  type CanonicalFromStringResult (line 549) | typedef enum {
  type ParseLineResult (line 554) | typedef enum {
  type Canonical (line 559) | typedef union {
  type ParsedLine (line 565) | typedef struct {
  type ParseFileReport (line 571) | typedef struct {
  type ParseFileArg (line 582) | typedef struct {
  function GetLineResult (line 607) | static GetLineResult XSUM_getLine(char** lineBuf, int* lineMax, FILE* in...
  function charToHex (line 666) | static int charToHex(char c)
  function CanonicalFromStringResult (line 687) | static CanonicalFromStringResult XSUM_canonicalFromString(unsigned char*...
  function ParseLineResult (line 728) | static ParseLineResult XSUM_parseLine1(ParsedLine* parsedLine, char* lin...
  function ParseLineResult (line 830) | static ParseLineResult XSUM_parseLine(ParsedLine* parsedLine, char* line...
  function XSUM_parseFile1 (line 843) | static void XSUM_parseFile1(ParseFileArg* XSUM_parseFileArg, int rev)
  function XSUM_checkFile (line 1019) | static int XSUM_checkFile(const char* inFileName,
  function XSUM_checkFiles (line 1116) | static int XSUM_checkFiles(const char* fnList[], int fnTotal,
  function ParseLineResult (line 1146) | static ParseLineResult XSUM_parseGenLine(ParsedLine * parsedLine,
  function XSUM_parseGenFile1 (line 1168) | static void XSUM_parseGenFile1(ParseFileArg* XSUM_parseGenArg,
  function XSUM_generateFile (line 1281) | static int XSUM_generateFile(const char* inFileName,
  function XSUM_generateFiles (line 1360) | static int XSUM_generateFiles(const char* fnList[], int fnTotal,
  function XSUM_usage (line 1388) | static int XSUM_usage(const char* exename)
  function XSUM_usage_advanced (line 1408) | static int XSUM_usage_advanced(const char* exename)
  function XSUM_badusage (line 1434) | static int XSUM_badusage(const char* exename)
  function errorOut (line 1441) | static void errorOut(const char* msg)
  function XSUM_readU32FromCharChecked (line 1462) | static int XSUM_readU32FromCharChecked(const char** stringPtr, XSUM_U32*...
  function XSUM_U32 (line 1495) | static XSUM_U32 XSUM_readU32FromChar(const char** stringPtr) {
  function XSUM_U64 (line 1505) | static XSUM_U64 XSUM_readU64FromChar( const char** number_str ){
  function XSUM_API (line 1526) | XSUM_API int XSUM_main(int argc, const char* argv[])

FILE: fuzz/fuzzer.c
  function LLVMFuzzerTestOneInput (line 5) | int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {

FILE: tests/collisions/allcodecs/dummy.c
  function badsum32 (line 30) | unsigned badsum32(const void* input, size_t len, unsigned seed)

FILE: tests/collisions/hashes.h
  type UniHash (line 38) | typedef union {
  function UniHash (line 43) | UniHash uniHash32(uint64_t v32)
  function UniHash (line 49) | UniHash uniHash64(uint64_t v64)
  function UniHash (line 55) | UniHash uniHash128(XXH128_hash_t v128)
  function UniHash (line 64) | UniHash XXH3_wrapper (const void* data, size_t size)
  function UniHash (line 69) | UniHash XXH128_wrapper (const void* data, size_t size)
  function UniHash (line 74) | UniHash XXH128l_wrapper (const void* data, size_t size)
  function UniHash (line 79) | UniHash XXH128h_wrapper (const void* data, size_t size)
  function UniHash (line 84) | UniHash XXH64_wrapper (const void* data, size_t size)
  function UniHash (line 89) | UniHash XXH32_wrapper (const void* data, size_t size)
  function UniHash (line 98) | UniHash badsum32_wrapper (const void* data, size_t size)
  type UniHash (line 107) | typedef UniHash (*hashfn) (const void* data, size_t size);
  type hashDescription (line 109) | typedef struct {

FILE: tests/collisions/main.c
  type Htype_e (line 68) | typedef enum { ht32, ht64, ht128 } Htype_e;
  function hexRaw (line 74) | static void hexRaw(const void* buffer, size_t size)
  function printHash (line 82) | void printHash(const void* table, size_t n, Htype_e htype)
  function avalanche64 (line 109) | static uint64_t avalanche64(uint64_t h64)
  function randomByte (line 119) | static unsigned char randomByte(uint64_t n)
  type sf_genMode (line 126) | typedef enum { sf_slab5, sf_sparse } sf_genMode;
  type sampleFactory (line 141) | typedef struct {
  function init_sampleFactory (line 149) | static void init_sampleFactory(sampleFactory* sf, uint64_t htotal)
  function sampleFactory (line 163) | static sampleFactory*
  function free_sampleFactory (line 178) | static void free_sampleFactory(sampleFactory* sf)
  function update_sampleFactory (line 185) | static inline void update_sampleFactory(sampleFactory* sf)
  function Cnm (line 215) | static double Cnm(int n, int m)
  function enoughCombos (line 228) | static int enoughCombos(size_t size, uint64_t htotal)
  type sampleFactory (line 242) | typedef struct {
  function init_sampleFactory (line 256) | static void init_sampleFactory(sampleFactory* sf, uint64_t htotal)
  function sampleFactory (line 270) | static sampleFactory*
  function free_sampleFactory (line 286) | static void free_sampleFactory(sampleFactory* sf)
  function flipbit (line 293) | static void flipbit(void* buffer, uint64_t bitID)
  function updateBit (line 301) | static int updateBit(void* buffer, size_t* bitIdx, int level, size_t max)
  function update_sampleFactory (line 320) | static inline void update_sampleFactory(sampleFactory* sf)
  type Filter (line 340) | typedef unsigned char Filter;
  function Filter (line 342) | Filter* create_Filter(int bflog)
  function free_Filter (line 356) | void free_Filter(Filter* bf)
  function Filter_insert (line 370) | inline int Filter_insert(Filter* bf, int bflog, uint64_t hash)
  function Filter_check (line 395) | inline int Filter_check(const Filter* bf, int bflog, uint64_t hash)
  function Filter_insert (line 423) | static inline int Filter_insert(Filter* bf, int bflog, uint64_t hash)
  function Filter (line 458) | static Filter* Filter_reduce(Filter* bf, int bflog)
  function Filter_check (line 476) | static inline int Filter_check(const Filter* bf, int bflog, uint64_t hash)
  function update_indicator (line 505) | void update_indicator(uint64_t v, uint64_t total)
  function power (line 547) | static double power(uint64_t base, int p)
  function estimateNbCollisions (line 557) | static double estimateNbCollisions(uint64_t nbH, int nbBits)
  function highestBitSet (line 562) | static int highestBitSet(uint64_t v)
  function select_nbh (line 579) | uint64_t select_nbh(int nbBits)
  type searchCollisions_results (line 590) | typedef struct {
  type searchCollisions_parameters (line 594) | typedef struct {
  function isEqual (line 609) | static int isEqual(void* hTablePtr, size_t index1, size_t index2, Htype_...
  function isHighEqual (line 623) | static int isHighEqual(void* hTablePtr, size_t index1, size_t index2, Ht...
  function addHashCandidate (line 641) | static void addHashCandidate(void* hTablePtr, UniHash h, Htype_e htype, ...
  function getNbBits_fromHtype (line 651) | static int getNbBits_fromHtype(Htype_e htype) {
  function Htype_e (line 660) | static Htype_e getHtype_fromHbits(int nbBits) {
  function search_collisions (line 669) | static size_t search_collisions(
  function getProcessMemUsage (line 869) | static size_t getProcessMemUsage(int children)
  function getProcessMemUsage (line 878) | static size_t getProcessMemUsage(int ignore) { (void)ignore; return 0; }
  function time_collisions (line 881) | void time_collisions(searchCollisions_parameters param)
  function MT_searchCollisions (line 918) | void MT_searchCollisions(void* payload)
  function readU64FromChar (line 930) | static uint64_t readU64FromChar(const char** stringPtr)
  function longCommandWArg (line 966) | static int longCommandWArg(const char** stringPtr, const char* longCommand)
  function help (line 986) | void help(const char* exeName)
  function bad_argument (line 1005) | int bad_argument(const char* exeName)
  function main (line 1013) | int main(int argc, const char** argv)

FILE: tests/collisions/pool.c
  type POOL_job (line 41) | typedef struct POOL_job_s {
  type POOL_ctx_s (line 46) | struct POOL_ctx_s {
  function POOL_ctx (line 120) | POOL_ctx* POOL_create(size_t numThreads, size_t queueSize)
  function POOL_join (line 164) | static void POOL_join(POOL_ctx* ctx) {
  function POOL_free (line 181) | void POOL_free(POOL_ctx *ctx) {
  function POOL_sizeof (line 194) | size_t POOL_sizeof(POOL_ctx *ctx) {
  function POOL_resize_internal (line 203) | static int POOL_resize_internal(POOL_ctx* ctx, size_t numThreads)
  function POOL_resize (line 232) | int POOL_resize(POOL_ctx* ctx, size_t numThreads)
  function isQueueFull (line 249) | static int isQueueFull(POOL_ctx const* ctx) {
  function POOL_add_internal (line 259) | static void POOL_add_internal(POOL_ctx* ctx, POOL_function function, voi...
  function POOL_add (line 271) | void POOL_add(POOL_ctx* ctx, POOL_function function, void* opaque)
  function POOL_tryAdd (line 284) | int POOL_tryAdd(POOL_ctx* ctx, POOL_function function, void* opaque)
  type POOL_ctx_s (line 306) | struct POOL_ctx_s {
  function POOL_ctx (line 311) | POOL_ctx* POOL_create(size_t numThreads, size_t queueSize) {
  function POOL_free (line 317) | void POOL_free(POOL_ctx* ctx) {
  function POOL_resize (line 322) | int POOL_resize(POOL_ctx* ctx, size_t numThreads) {
  function POOL_add (line 327) | void POOL_add(POOL_ctx* ctx, POOL_function function, void* opaque) {
  function POOL_tryAdd (line 332) | int POOL_tryAdd(POOL_ctx* ctx, POOL_function function, void* opaque) {
  function POOL_sizeof (line 338) | size_t POOL_sizeof(POOL_ctx* ctx) {

FILE: tests/collisions/pool.h
  type POOL_ctx (line 21) | typedef struct POOL_ctx_s POOL_ctx;

FILE: tests/collisions/sort.cc
  function sort64 (line 38) | void sort64(uint64_t* table, size_t size)
  function sort128 (line 45) | void sort128(XXH128_hash_t* table, size_t size)

FILE: tests/collisions/threading.c
  function worker (line 43) | static unsigned __stdcall worker(void *arg)
  function ZSTD_pthread_create (line 50) | int ZSTD_pthread_create(ZSTD_pthread_t* thread, const void* unused,
  function ZSTD_pthread_join (line 64) | int ZSTD_pthread_join(ZSTD_pthread_t thread, void **value_ptr)

FILE: tests/collisions/threading.h
  type ZSTD_pthread_t (line 63) | typedef struct {
  type ZSTD_pthread_mutex_t (line 103) | typedef int ZSTD_pthread_mutex_t;
  type ZSTD_pthread_cond_t (line 109) | typedef int ZSTD_pthread_cond_t;

FILE: tests/generate_unicode_test.c
  function main (line 62) | int main(void)

FILE: tests/multiInclude.c
  function hash_advanced (line 62) | void hash_advanced(void)
  function main (line 76) | int main(void)

FILE: tests/sanity_test.c
  function abortSanityTest (line 48) | static void abortSanityTest(void) {
  function fillTestBuffer (line 62) | static void fillTestBuffer(XSUM_U8* buffer, size_t bufferLenInBytes)
  function XSUM_U8 (line 82) | static XSUM_U8* createSanityBuffer(size_t bufferLenInBytes)
  function releaseSanityBuffer (line 95) | static void releaseSanityBuffer(XSUM_U8* buffer)
  function checkResult32 (line 104) | static void checkResult32(XXH32_hash_t r1, XXH32_hash_t r2, const char* ...
  function checkResult64 (line 121) | static void checkResult64(XXH64_hash_t r1, XXH64_hash_t r2, const char* ...
  function checkResult128 (line 139) | static void checkResult128(XXH128_hash_t r1, XXH128_hash_t r2, const cha...
  function checkResultTestDataSample (line 158) | static void checkResultTestDataSample(const XSUM_U8* r1, const XSUM_U8* ...
  function testXXH32 (line 177) | static void testXXH32(
  function testXXH64 (line 218) | static void testXXH64(
  function XSUM_U32 (line 262) | static XSUM_U32 SANITY_TEST_rand(XSUM_U64* pRandSeed)
  function XSUM_U64 (line 273) | static XSUM_U64 SANITY_TEST_computeRandSeed(size_t step)
  type XXH_errorcode (line 289) | typedef XXH_errorcode (*SANITY_TEST_XXH3_update_t)(XXH_NOESCAPE XXH3_sta...
  function SANITY_TEST_XXH3_randomUpdate (line 298) | static void SANITY_TEST_XXH3_randomUpdate(
  function testXXH3 (line 319) | static void testXXH3(
  function testXXH3_withSecret (line 413) | static void testXXH3_withSecret(
  function testXXH128 (line 478) | static void testXXH128(
  function testXXH128_withSecret (line 579) | static void testXXH128_withSecret(
  function testSecretGenerator (line 644) | static void testSecretGenerator(
  function main (line 667) | int main(int argc, const char* argv[])

FILE: tests/sanity_test_vectors.h
  type XSUM_testdata32_t (line 1) | typedef struct {
  type XSUM_testdata64_t (line 7) | typedef struct {
  type XSUM_testdata128_t (line 13) | typedef struct {
  type XSUM_testdata_sample_t (line 23) | typedef struct {

FILE: tests/sanity_test_vectors_generator.c
  type XSUM_testdata32_t (line 31) | typedef struct {
  type XSUM_testdata64_t (line 37) | typedef struct {
  type XSUM_testdata128_t (line 43) | typedef struct {
  type XSUM_testdata_sample_t (line 50) | typedef struct {
  function XSUM_testdata32_t (line 63) | static XSUM_testdata32_t tvgen_XXH32(const XSUM_U8* buf, size_t len, XSU...
  function XSUM_testdata64_t (line 71) | static XSUM_testdata64_t tvgen_XXH64(const XSUM_U8* buf, size_t len, XSU...
  function XSUM_testdata64_t (line 79) | static XSUM_testdata64_t tvgen_XXH3_64bits_withSeed(const XSUM_U8* buf, ...
  function XSUM_testdata64_t (line 87) | static XSUM_testdata64_t tvgen_XXH3_64bits_withSecret(const XSUM_U8* buf...
  function XSUM_testdata128_t (line 95) | static XSUM_testdata128_t tvgen_XXH3_128bits_withSeed(const XSUM_U8* buf...
  function XSUM_testdata128_t (line 103) | static XSUM_testdata128_t tvgen_XXH3_128bits_withSecret(const XSUM_U8* b...
  function XSUM_testdata_sample_t (line 111) | static XSUM_testdata_sample_t tvgen_XXH3_generateSecret(
  function fprintf_XSUM_testdata32_t (line 136) | static void fprintf_XSUM_testdata32_t(FILE* fp, XSUM_testdata32_t const ...
  function fprintf_XSUM_testdata64_t (line 140) | static void fprintf_XSUM_testdata64_t(FILE* fp, XSUM_testdata64_t const ...
  function fprintf_XSUM_testdata128_t (line 144) | static void fprintf_XSUM_testdata128_t(FILE* fp, XSUM_testdata128_t cons...
  function fprintf_XSUM_testdata_sample_t (line 149) | static void fprintf_XSUM_testdata_sample_t(FILE* fp, XSUM_testdata_sampl...
  function fillTestBuffer (line 161) | static void fillTestBuffer(XSUM_U8* buffer, size_t bufferLenInBytes)
  function XSUM_U8 (line 181) | static XSUM_U8* createSanityBuffer(size_t bufferLenInBytes)
  function releaseSanityBuffer (line 194) | static void releaseSanityBuffer(XSUM_U8* buffer)
  function generate_sanity_test_vectors_xxh32 (line 202) | static void generate_sanity_test_vectors_xxh32(FILE* fp, size_t maxLen) {
  function generate_sanity_test_vectors_xxh64 (line 228) | static void generate_sanity_test_vectors_xxh64(FILE* fp, size_t maxLen) {
  function generate_sanity_test_vectors_xxh3 (line 254) | static void generate_sanity_test_vectors_xxh3(FILE* fp, size_t maxLen) {
  function generate_sanity_test_vectors_xxh3_withSecret (line 280) | static void generate_sanity_test_vectors_xxh3_withSecret(FILE* fp, size_...
  function generate_sanity_test_vectors_xxh128 (line 306) | static void generate_sanity_test_vectors_xxh128(FILE* fp, size_t maxLen) {
  function generate_sanity_test_vectors_xxh128_withSecret (line 331) | static void generate_sanity_test_vectors_xxh128_withSecret(FILE* fp, siz...
  function generate_sanity_test_vectors_xxh3_generateSecret (line 357) | static void generate_sanity_test_vectors_xxh3_generateSecret(FILE* fp, s...
  function generate_sanity_test_vectors (line 406) | void generate_sanity_test_vectors(size_t maxLen) {
  function main (line 457) | int main(int argc, const char* argv[])

FILE: tests/test_alias.c
  function main (line 7) | int main() {

FILE: xxh_x86dispatch.c
  function XXH_cpuid (line 254) | static void XXH_cpuid(xxh_u32 eax, xxh_u32 ecx, xxh_u32* abcd)
  function xxh_u64 (line 306) | static xxh_u64 XXH_xgetbv(void)
  function XXH_featureTest (line 343) | int XXH_featureTest(void)
  type XXH64_hash_t (line 583) | typedef XXH64_hash_t (*XXH3_dispatchx86_hashLong64_withSeed)(XXH_NOESCAP...
  type XXH64_hash_t (line 585) | typedef XXH64_hash_t (*XXH3_dispatchx86_hashLong64_withSecret)(XXH_NOESC...
  type XXH_errorcode (line 587) | typedef XXH_errorcode (*XXH3_dispatchx86_update)(XXH_NOESCAPE XXH3_state...
  type XXH_dispatchFunctions_s (line 589) | typedef struct {
  type XXH128_hash_t (line 631) | typedef XXH128_hash_t (*XXH3_dispatchx86_hashLong128_default)(XXH_NOESCA...
  type XXH128_hash_t (line 633) | typedef XXH128_hash_t (*XXH3_dispatchx86_hashLong128_withSeed)(XXH_NOESC...
  type XXH128_hash_t (line 635) | typedef XXH128_hash_t (*XXH3_dispatchx86_hashLong128_withSecret)(XXH_NOE...
  type XXH_dispatch128Functions_s (line 637) | typedef struct {
  function XXH_CONSTRUCTOR (line 681) | static XXH_CONSTRUCTOR void XXH_setDispatch(void)
  function XXH64_hash_t (line 703) | static XXH64_hash_t
  function XXH64_hash_t (line 713) | XXH64_hash_t XXH3_64bits_dispatch(XXH_NOESCAPE const void* input, size_t...
  function XXH64_hash_t (line 718) | static XXH64_hash_t
  function XXH64_hash_t (line 728) | XXH64_hash_t XXH3_64bits_withSeed_dispatch(XXH_NOESCAPE const void* inpu...
  function XXH64_hash_t (line 733) | static XXH64_hash_t
  function XXH64_hash_t (line 743) | XXH64_hash_t XXH3_64bits_withSecret_dispatch(XXH_NOESCAPE const void* in...
  function XXH_errorcode (line 748) | XXH_errorcode
  function XXH128_hash_t (line 763) | static XXH128_hash_t
  function XXH128_hash_t (line 773) | XXH128_hash_t XXH3_128bits_dispatch(XXH_NOESCAPE const void* input, size...
  function XXH128_hash_t (line 778) | static XXH128_hash_t
  function XXH128_hash_t (line 788) | XXH128_hash_t XXH3_128bits_withSeed_dispatch(XXH_NOESCAPE const void* in...
  function XXH128_hash_t (line 793) | static XXH128_hash_t
  function XXH128_hash_t (line 803) | XXH128_hash_t XXH3_128bits_withSecret_dispatch(XXH_NOESCAPE const void* ...
  function XXH_errorcode (line 808) | XXH_errorcode

FILE: xxhash.h
  type XXH_errorcode (line 573) | typedef enum {
  type XXH32_hash_t (line 588) | typedef uint32_t XXH32_hash_t;
  type XXH32_hash_t (line 598) | typedef uint32_t XXH32_hash_t;
  type XXH32_hash_t (line 603) | typedef unsigned int XXH32_hash_t;
  type XXH32_hash_t (line 605) | typedef unsigned long XXH32_hash_t;
  type XXH32_state_t (line 654) | typedef struct XXH32_state_s XXH32_state_t;
  type XXH32_canonical_t (line 755) | typedef struct {
  type XXH64_hash_t (line 858) | typedef uint64_t XXH64_hash_t;
  type XXH64_hash_t (line 867) | typedef uint64_t XXH64_hash_t;
  type XXH64_hash_t (line 872) | typedef unsigned long XXH64_hash_t;
  type XXH64_hash_t (line 875) | typedef unsigned long long XXH64_hash_t;
  type XXH64_state_t (line 919) | typedef struct XXH64_state_s XXH64_state_t;
  type XXH64_canonical_t (line 1020) | typedef struct { unsigned char digest[sizeof(XXH64_hash_t)]; } XXH64_can...
  type XXH3_state_t (line 1236) | typedef struct XXH3_state_s XXH3_state_t;
  type XXH128_hash_t (line 1375) | typedef struct {
  type XXH128_canonical_t (line 1598) | typedef struct { unsigned char digest[sizeof(XXH128_hash_t)]; } XXH128_c...
  type XXH32_state_s (line 1665) | struct XXH32_state_s {
  type XXH64_state_s (line 1689) | struct XXH64_state_s {
  type XXH3_state_s (line 1765) | struct XXH3_state_s {
  function XXH_CONSTF (line 2364) | static XXH_CONSTF void* XXH_malloc(size_t s) { (void)s; return NULL; }
  function XXH_free (line 2365) | static void XXH_free(void* p) { (void)p; }
  function XXH_MALLOCF (line 2379) | static XXH_MALLOCF void* XXH_malloc(size_t s) { return malloc(s); }
  function XXH_free (line 2385) | static void XXH_free(void* p) { free(p); }
  type xxh_u8 (line 2565) | typedef uint8_t xxh_u8;
  type xxh_u8 (line 2567) | typedef unsigned char xxh_u8;
  type XXH32_hash_t (line 2569) | typedef XXH32_hash_t xxh_u32;
  function xxh_u32 (line 2641) | static xxh_u32 XXH_read32(const void* memPtr) { return *(const xxh_u32*)...
  type unalign (line 2653) | typedef union { xxh_u32 u32; } __attribute__((__packed__)) unalign;
  function xxh_u32 (line 2655) | static xxh_u32 XXH_read32(const void* ptr)
  function xxh_u32 (line 2667) | static xxh_u32 XXH_read32(const void* memPtr)
  function XXH_isLittleEndian (line 2714) | static int XXH_isLittleEndian(void)
  function xxh_u32 (line 2828) | static xxh_u32 XXH_swap32 (xxh_u32 x)
  type XXH_alignment (line 2846) | typedef enum {
  function XXH_FORCE_INLINE (line 2858) | XXH_FORCE_INLINE xxh_u32 XXH_readLE32(const void* memPtr)
  function XXH_FORCE_INLINE (line 2867) | XXH_FORCE_INLINE xxh_u32 XXH_readBE32(const void* memPtr)
  function XXH_FORCE_INLINE (line 2877) | XXH_FORCE_INLINE xxh_u32 XXH_readLE32(const void* ptr)
  function xxh_u32 (line 2882) | static xxh_u32 XXH_readBE32(const void* ptr)
  function XXH_FORCE_INLINE (line 2888) | XXH_FORCE_INLINE xxh_u32
  function XXH_versionNumber (line 2903) | XXH_PUBLIC_API unsigned XXH_versionNumber (void) { return XXH_VERSION_NU...
  function xxh_u32 (line 2943) | static xxh_u32 XXH32_round(xxh_u32 acc, xxh_u32 input)
  function xxh_u32 (line 3000) | static xxh_u32 XXH32_avalanche(xxh_u32 hash)
  function XXH_FORCE_INLINE (line 3016) | XXH_FORCE_INLINE void
  function XXH_FORCE_INLINE (line 3032) | XXH_FORCE_INLINE const xxh_u8 *
  function xxh_u32 (line 3059) | xxh_u32
  function XXH_PUREF (line 3082) | static XXH_PUREF xxh_u32
  function xxh_u32 (line 3171) | xxh_u32
  function XXH_PUBLIC_API (line 3195) | XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t len, XXH32_...
  function XXH_PUBLIC_API (line 3218) | XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void)
  function XXH_PUBLIC_API (line 3223) | XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr)
  function XXH_PUBLIC_API (line 3230) | XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dstState, const XXH32...
  function XXH_PUBLIC_API (line 3236) | XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, XXH32_...
  function XXH_PUBLIC_API (line 3246) | XXH_PUBLIC_API XXH_errorcode
  function XXH_PUBLIC_API (line 3293) | XXH_PUBLIC_API XXH32_hash_t XXH32_digest(const XXH32_state_t* state)
  function XXH_PUBLIC_API (line 3312) | XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH3...
  function XXH_PUBLIC_API (line 3319) | XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonica...
  type XXH64_hash_t (line 3337) | typedef XXH64_hash_t xxh_u64;
  function xxh_u64 (line 3351) | static xxh_u64 XXH_read64(const void* memPtr)
  type unalign64 (line 3366) | typedef union { xxh_u32 u32; xxh_u64 u64; } __attribute__((__packed__)) ...
  function xxh_u64 (line 3368) | static xxh_u64 XXH_read64(const void* ptr)
  function xxh_u64 (line 3380) | static xxh_u64 XXH_read64(const void* memPtr)
  function xxh_u64 (line 3394) | static xxh_u64 XXH_swap64(xxh_u64 x)
  function XXH_FORCE_INLINE (line 3411) | XXH_FORCE_INLINE xxh_u64 XXH_readLE64(const void* memPtr)
  function XXH_FORCE_INLINE (line 3424) | XXH_FORCE_INLINE xxh_u64 XXH_readBE64(const void* memPtr)
  function XXH_FORCE_INLINE (line 3438) | XXH_FORCE_INLINE xxh_u64 XXH_readLE64(const void* ptr)
  function xxh_u64 (line 3443) | static xxh_u64 XXH_readBE64(const void* ptr)
  function XXH_FORCE_INLINE (line 3449) | XXH_FORCE_INLINE xxh_u64
  function xxh_u64 (line 3484) | static xxh_u64 XXH64_round(xxh_u64 acc, xxh_u64 input)
  function xxh_u64 (line 3509) | static xxh_u64 XXH64_mergeRound(xxh_u64 acc, xxh_u64 val)
  function xxh_u64 (line 3518) | static xxh_u64 XXH64_avalanche(xxh_u64 hash)
  function XXH_FORCE_INLINE (line 3535) | XXH_FORCE_INLINE void
  function XXH_FORCE_INLINE (line 3551) | XXH_FORCE_INLINE const xxh_u8 *
  function xxh_u64 (line 3587) | xxh_u64
  function xxh_u64 (line 3625) | xxh_u64
  function xxh_u64 (line 3669) | xxh_u64
  function XXH_PUBLIC_API (line 3693) | XXH_PUBLIC_API XXH64_hash_t XXH64 (XXH_NOESCAPE const void* input, size_...
  function XXH_PUBLIC_API (line 3715) | XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void)
  function XXH_PUBLIC_API (line 3720) | XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr)
  function XXH_PUBLIC_API (line 3727) | XXH_PUBLIC_API void XXH64_copyState(XXH_NOESCAPE XXH64_state_t* dstState...
  function XXH_PUBLIC_API (line 3733) | XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH_NOESCAPE XXH64_state_t* sta...
  function XXH_PUBLIC_API (line 3742) | XXH_PUBLIC_API XXH_errorcode
  function XXH_PUBLIC_API (line 3788) | XXH_PUBLIC_API XXH64_hash_t XXH64_digest(XXH_NOESCAPE const XXH64_state_...
  function XXH_PUBLIC_API (line 3807) | XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH_NOESCAPE XXH64_canonical...
  function XXH_PUBLIC_API (line 3815) | XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const X...
  type uint64x2_t (line 4120) | typedef uint64x2_t xxh_aliasing_uint64x2_t
  function XXH_FORCE_INLINE (line 4136) | XXH_FORCE_INLINE uint64x2_t XXH_vld1q_u64(void const* ptr) /* silence -W...
  function XXH_FORCE_INLINE (line 4141) | XXH_FORCE_INLINE uint64x2_t XXH_vld1q_u64(void const* ptr)
  function XXH_FORCE_INLINE (line 4156) | XXH_FORCE_INLINE uint64x2_t
  function XXH_FORCE_INLINE (line 4163) | XXH_FORCE_INLINE uint64x2_t
  function XXH_FORCE_INLINE (line 4171) | XXH_FORCE_INLINE uint64x2_t
  function XXH_FORCE_INLINE (line 4178) | XXH_FORCE_INLINE uint64x2_t
  type xxh_u64x2 (line 4269) | typedef __vector unsigned long long xxh_u64x2;
  type xxh_u8x16 (line 4270) | typedef __vector unsigned char xxh_u8x16;
  type xxh_u32x4 (line 4271) | typedef __vector unsigned xxh_u32x4;
  type xxh_u64x2 (line 4276) | typedef xxh_u64x2 xxh_aliasing_u64x2
  function XXH_FORCE_INLINE (line 4297) | XXH_FORCE_INLINE xxh_u64x2 XXH_vec_revb(xxh_u64x2 val)
  function XXH_FORCE_INLINE (line 4309) | XXH_FORCE_INLINE xxh_u64x2 XXH_vec_loadu(const void *ptr)
  function XXH_FORCE_INLINE (line 4337) | XXH_FORCE_INLINE xxh_u64x2 XXH_vec_mulo(xxh_u32x4 a, xxh_u32x4 b)
  function XXH_FORCE_INLINE (line 4343) | XXH_FORCE_INLINE xxh_u64x2 XXH_vec_mule(xxh_u32x4 a, xxh_u32x4 b)
  function XXH_FORCE_INLINE (line 4437) | XXH_FORCE_INLINE xxh_u64
  function XXH128_hash_t (line 4464) | static XXH128_hash_t
  function xxh_u64 (line 4598) | static xxh_u64
  function xxh_u64 (line 4606) | xxh_u64 XXH_xorshift64(xxh_u64 v64, int shift)
  function XXH64_hash_t (line 4616) | static XXH64_hash_t XXH3_avalanche(xxh_u64 h64)
  function XXH64_hash_t (line 4629) | static XXH64_hash_t XXH3_rrmxmx(xxh_u64 h64, xxh_u64 len)
  function XXH64_hash_t (line 4673) | XXH64_hash_t
  function XXH64_hash_t (line 4695) | XXH64_hash_t
  function XXH64_hash_t (line 4711) | XXH64_hash_t
  function XXH64_hash_t (line 4728) | XXH64_hash_t
  function XXH_FORCE_INLINE (line 4765) | XXH_FORCE_INLINE xxh_u64 XXH3_mix16B(const xxh_u8* XXH_RESTRICT input,
  function XXH64_hash_t (line 4798) | XXH64_hash_t
  function XXH64_hash_t (line 4834) | XXH64_hash_t
  function XXH_FORCE_INLINE (line 4946) | XXH_FORCE_INLINE void XXH_writeLE64(void* dst, xxh_u64 v64)
  type xxh_i64 (line 4960) | typedef int64_t xxh_i64;
  type xxh_i64 (line 4963) | typedef long long xxh_i64;
  function XXH3_accumulate_512_avx512 (line 4997) | void
  function XXH_FORCE_INLINE (line 5024) | XXH_FORCE_INLINE XXH_TARGET_AVX512 XXH3_ACCUMULATE_TEMPLATE(avx512)
  function XXH3_initCustomSecret_avx512 (line 5070) | void
  function XXH3_accumulate_512_avx2 (line 5100) | void
  function XXH_FORCE_INLINE (line 5133) | XXH_FORCE_INLINE XXH_TARGET_AVX2 XXH3_ACCUMULATE_TEMPLATE(avx2)
  function XXH3_initCustomSecret_avx2 (line 5164) | void XXH3_initCustomSecret_avx2(void* XXH_RESTRICT customSecret, xxh_u64...
  function XXH3_accumulate_512_sse2 (line 5206) | void
  function XXH_FORCE_INLINE (line 5240) | XXH_FORCE_INLINE XXH_TARGET_SSE2 XXH3_ACCUMULATE_TEMPLATE(sse2)
  function XXH3_initCustomSecret_sse2 (line 5271) | void XXH3_initCustomSecret_sse2(void* XXH_RESTRICT customSecret, xxh_u64...
  function XXH_FORCE_INLINE (line 5349) | XXH_FORCE_INLINE void
  function XXH_FORCE_INLINE (line 5475) | XXH_FORCE_INLINE XXH3_ACCUMULATE_TEMPLATE(neon)
  function XXH_FORCE_INLINE (line 5536) | XXH_FORCE_INLINE void
  function XXH_FORCE_INLINE (line 5570) | XXH_FORCE_INLINE XXH3_ACCUMULATE_TEMPLATE(vsx)
  function XXH_FORCE_INLINE (line 5606) | XXH_FORCE_INLINE void
  function XXH_FORCE_INLINE (line 5646) | XXH_FORCE_INLINE void
  function XXH_FORCE_INLINE (line 5716) | XXH_FORCE_INLINE void
  function XXH_FORCE_INLINE (line 5748) | XXH_FORCE_INLINE XXH3_ACCUMULATE_TEMPLATE(lsx)
  function XXH_FORCE_INLINE (line 5780) | XXH_FORCE_INLINE void
  function XXH_FORCE_INLINE (line 5812) | XXH_FORCE_INLINE XXH3_ACCUMULATE_TEMPLATE(lasx)
  function XXH_FORCE_INLINE (line 5852) | XXH_FORCE_INLINE void
  function XXH_FORCE_INLINE (line 5895) | XXH_FORCE_INLINE XXH3_ACCUMULATE_TEMPLATE(rvv)
  function XXH_FORCE_INLINE (line 5927) | XXH_FORCE_INLINE void
  function XXH_FORCE_INLINE (line 5985) | XXH_FORCE_INLINE xxh_u64
  function XXH_FORCE_INLINE (line 5994) | XXH_FORCE_INLINE xxh_u64
  function XXH_FORCE_INLINE (line 6008) | XXH_FORCE_INLINE void
  function XXH_FORCE_INLINE (line 6031) | XXH_FORCE_INLINE void
  function XXH_FORCE_INLINE (line 6048) | XXH_FORCE_INLINE XXH3_ACCUMULATE_TEMPLATE(scalar)
  function XXH_FORCE_INLINE (line 6080) | XXH_FORCE_INLINE void
  function XXH_FORCE_INLINE (line 6089) | XXH_FORCE_INLINE void
  function XXH_FORCE_INLINE (line 6230) | XXH_FORCE_INLINE void
  function XXH_FORCE_INLINE (line 6263) | XXH_FORCE_INLINE xxh_u64
  function XXH_PUREF (line 6271) | static XXH_PUREF XXH64_hash_t
  function XXH_PUREF (line 6301) | static XXH_PUREF XXH64_hash_t
  function XXH_FORCE_INLINE (line 6310) | XXH_FORCE_INLINE XXH64_hash_t
  function XXH3_WITH_SECRET_INLINE (line 6333) | XXH3_WITH_SECRET_INLINE XXH64_hash_t
  function XXH64_hash_t (line 6347) | XXH64_hash_t
  function XXH_FORCE_INLINE (line 6366) | XXH_FORCE_INLINE XXH64_hash_t
  function XXH_NO_INLINE (line 6389) | XXH_NO_INLINE XXH64_hash_t
  type XXH64_hash_t (line 6399) | typedef XXH64_hash_t (*XXH3_hashLong64_f)(const void* XXH_RESTRICT, size_t,
  function XXH_FORCE_INLINE (line 6402) | XXH_FORCE_INLINE XXH64_hash_t
  function XXH_PUBLIC_API (line 6428) | XXH_PUBLIC_API XXH64_hash_t XXH3_64bits(XXH_NOESCAPE const void* input, ...
  function XXH_PUBLIC_API (line 6434) | XXH_PUBLIC_API XXH64_hash_t
  function XXH_PUBLIC_API (line 6441) | XXH_PUBLIC_API XXH64_hash_t
  function XXH_PUBLIC_API (line 6447) | XXH_PUBLIC_API XXH64_hash_t
  function XXH_MALLOCF (line 6481) | static XXH_MALLOCF void* XXH_alignedMalloc(size_t s, size_t align)
  function XXH_alignedFree (line 6512) | static void XXH_alignedFree(void* p)
  function XXH_PUBLIC_API (line 6534) | XXH_PUBLIC_API XXH3_state_t* XXH3_createState(void)
  function XXH_PUBLIC_API (line 6554) | XXH_PUBLIC_API XXH_errorcode XXH3_freeState(XXH3_state_t* statePtr)
  function XXH_PUBLIC_API (line 6561) | XXH_PUBLIC_API void
  function XXH3_reset_internal (line 6567) | static void
  function XXH_PUBLIC_API (line 6595) | XXH_PUBLIC_API XXH_errorcode
  function XXH_PUBLIC_API (line 6604) | XXH_PUBLIC_API XXH_errorcode
  function XXH_PUBLIC_API (line 6615) | XXH_PUBLIC_API XXH_errorcode
  function XXH_PUBLIC_API (line 6627) | XXH_PUBLIC_API XXH_errorcode
  function XXH_FORCE_INLINE (line 6655) | XXH_FORCE_INLINE const xxh_u8 *
  function XXH_NO_INLINE (line 6783) | XXH_NO_INLINE XXH_errorcode
  function XXH_PUBLIC_API (line 6791) | XXH_PUBLIC_API XXH_errorcode
  function XXH_FORCE_INLINE (line 6798) | XXH_FORCE_INLINE void
  function XXH_PUBLIC_API (line 6836) | XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (XXH_NOESCAPE const XXH3_...
  function XXH128_hash_t (line 6870) | XXH128_hash_t
  function XXH128_hash_t (line 6899) | XXH128_hash_t
  function XXH128_hash_t (line 6926) | XXH128_hash_t
  function XXH128_hash_t (line 7001) | XXH128_hash_t
  function XXH_FORCE_INLINE (line 7020) | XXH_FORCE_INLINE XXH128_hash_t
  function XXH128_hash_t (line 7032) | XXH128_hash_t
  function XXH128_hash_t (line 7076) | XXH128_hash_t
  function XXH_PUREF (line 7134) | static XXH_PUREF XXH128_hash_t
  function XXH_FORCE_INLINE (line 7145) | XXH_FORCE_INLINE XXH128_hash_t
  function XXH128_hash_t (line 7164) | XXH128_hash_t
  function XXH3_WITH_SECRET_INLINE (line 7181) | XXH3_WITH_SECRET_INLINE XXH128_hash_t
  function XXH_FORCE_INLINE (line 7191) | XXH_FORCE_INLINE XXH128_hash_t
  function XXH_NO_INLINE (line 7212) | XXH_NO_INLINE XXH128_hash_t
  type XXH128_hash_t (line 7221) | typedef XXH128_hash_t (*XXH3_hashLong128_f)(const void* XXH_RESTRICT, si...
  function XXH_FORCE_INLINE (line 7224) | XXH_FORCE_INLINE XXH128_hash_t
  function XXH_PUBLIC_API (line 7249) | XXH_PUBLIC_API XXH128_hash_t XXH3_128bits(XXH_NOESCAPE const void* input...
  function XXH_PUBLIC_API (line 7257) | XXH_PUBLIC_API XXH128_hash_t
  function XXH_PUBLIC_API (line 7266) | XXH_PUBLIC_API XXH128_hash_t
  function XXH_PUBLIC_API (line 7275) | XXH_PUBLIC_API XXH128_hash_t
  function XXH_PUBLIC_API (line 7284) | XXH_PUBLIC_API XXH128_hash_t
  function XXH_PUBLIC_API (line 7299) | XXH_PUBLIC_API XXH_errorcode
  function XXH_PUBLIC_API (line 7306) | XXH_PUBLIC_API XXH_errorcode
  function XXH_PUBLIC_API (line 7313) | XXH_PUBLIC_API XXH_errorcode
  function XXH_PUBLIC_API (line 7320) | XXH_PUBLIC_API XXH_errorcode
  function XXH_PUBLIC_API (line 7327) | XXH_PUBLIC_API XXH_errorcode
  function XXH_PUBLIC_API (line 7334) | XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest (XXH_NOESCAPE const XXH...
  function XXH_PUBLIC_API (line 7354) | XXH_PUBLIC_API int XXH128_isEqual(XXH128_hash_t h1, XXH128_hash_t h2)
  function XXH_PUBLIC_API (line 7365) | XXH_PUBLIC_API int XXH128_cmp(XXH_NOESCAPE const void* h128_1, XXH_NOESC...
  function XXH_PUBLIC_API (line 7378) | XXH_PUBLIC_API void
  function XXH_PUBLIC_API (line 7391) | XXH_PUBLIC_API XXH128_hash_t
  function XXH_FORCE_INLINE (line 7408) | XXH_FORCE_INLINE void XXH3_combine16(void* dst, XXH128_hash_t h128)
  function XXH_PUBLIC_API (line 7415) | XXH_PUBLIC_API XXH_errorcode
  function XXH_PUBLIC_API (line 7460) | XXH_PUBLIC_API void
Condensed preview — 72 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (5,461K chars).
[
  {
    "path": ".gitattributes",
    "chars": 167,
    "preview": "# Set the default behavior\n* text eol=lf\n\n# Explicitly declare source files\n*.c text eol=lf\n*.h text eol=lf\n\n# Denote fi"
  },
  {
    "path": ".github/dependabot.yml",
    "chars": 249,
    "preview": "# https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabo"
  },
  {
    "path": ".github/workflows/ci.yml",
    "chars": 27923,
    "preview": "# Known critical issues:\n# - AVX512 related tests are incomplete.  Because default environment of\n#   GitHub Actions doe"
  },
  {
    "path": ".github/workflows/cmake-cross-compile-test.yml",
    "chars": 1195,
    "preview": "name: CMake Cross-Compile Test\n\non: [push, pull_request]\n\npermissions:\n  contents: read\n\njobs:\n  cmake-cross-compile-hos"
  },
  {
    "path": ".github/workflows/scorecard.yml",
    "chars": 2978,
    "preview": "# This workflow uses actions that are not certified by GitHub. They are provided\n# by a third-party and are governed by "
  },
  {
    "path": ".gitignore",
    "chars": 685,
    "preview": "# objects\n*.o\n*.obj\n*.s\n\n# libraries\nlibxxhash.*\n!libxxhash.pc.in\n\n# Executables\n*.exe\nxxh32sum\nxxh64sum\nxxh128sum\nxxh3s"
  },
  {
    "path": "CHANGELOG",
    "chars": 6296,
    "preview": "v0.8.3\n- fix  : variant `XXH3_128bits_withSecretandSeed()` could produce an invalid result in some specific set of condi"
  },
  {
    "path": "Doxyfile",
    "chars": 2119,
    "preview": "# Doxygen config for xxHash\nDOXYFILE_ENCODING      = UTF-8\n\nPROJECT_NAME           = \"xxHash\"\nPROJECT_NUMBER         = \""
  },
  {
    "path": "Doxyfile-internal",
    "chars": 2117,
    "preview": "# Doxygen config for xxHash\nDOXYFILE_ENCODING      = UTF-8\n\nPROJECT_NAME           = \"xxHash\"\nPROJECT_NUMBER         = \""
  },
  {
    "path": "LICENSE",
    "chars": 1389,
    "preview": "xxHash Library\nCopyright (c) 2012-2021 Yann Collet\nAll rights reserved.\n\nBSD 2-Clause License (https://www.opensource.or"
  },
  {
    "path": "Makefile",
    "chars": 26143,
    "preview": "# ################################################################\n# xxHash Makefile\n# Copyright (C) 2012-2024 Yann Coll"
  },
  {
    "path": "README.md",
    "chars": 17684,
    "preview": "\nxxHash - Extremely fast hash algorithm\n======================================\n\nxxHash is an Extremely fast Hash algorit"
  },
  {
    "path": "SECURITY.md",
    "chars": 688,
    "preview": "# Security Policy\n\n## Supported Versions\n\nSecurity updates are applied only to the latest release.\n\n## Reporting a Vulne"
  },
  {
    "path": "appveyor.yml",
    "chars": 5703,
    "preview": "# ==============================================================================\n#                            AppVeyor C"
  },
  {
    "path": "build/make/README.md",
    "chars": 2150,
    "preview": "# multiconf.make\n\n**multiconf.make** is a self-contained Makefile include that lets you build the **same targets under m"
  },
  {
    "path": "build/make/multiconf.make",
    "chars": 11768,
    "preview": "# ##########################################################################\n# multiconf.make\n# Copyright (C) Yann Colle"
  },
  {
    "path": "cli/.tipi/deps",
    "chars": 30,
    "preview": "{\n    \"Cyan4973/xxHash\": { }\n}"
  },
  {
    "path": "cli/.tipi/opts",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "cli/COPYING",
    "chars": 18092,
    "preview": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 2, June 1991\n\n Copyright (C) 1989, 1991 Fr"
  },
  {
    "path": "cli/README.md",
    "chars": 238,
    "preview": "This directory contains source code dedicated to the `xxhsum` command line utility,\nwhich is a user program of `libxxhas"
  },
  {
    "path": "cli/xsum_arch.c",
    "chars": 1783,
    "preview": "/*\n * xxhsum - Command line interface for xxhash algorithms\n * Copyright (C) 2013-2024 Yann Collet\n *\n * GPL v2 License\n"
  },
  {
    "path": "cli/xsum_arch.h",
    "chars": 6464,
    "preview": "/*\n * xxhsum - Command line interface for xxhash algorithms\n * Copyright (C) 2013-2021 Yann Collet\n *\n * GPL v2 License\n"
  },
  {
    "path": "cli/xsum_bench.c",
    "chars": 16957,
    "preview": "/*\n * xsum_bench - Benchmark functions for xxhsum\n * Copyright (C) 2013-2021 Yann Collet\n *\n * GPL v2 License\n *\n * This"
  },
  {
    "path": "cli/xsum_bench.h",
    "chars": 1505,
    "preview": "/*\n * xsum_bench - Benchmark functions for xxhsum\n * Copyright (C) 2013-2021 Yann Collet\n *\n * GPL v2 License\n *\n * This"
  },
  {
    "path": "cli/xsum_config.h",
    "chars": 6079,
    "preview": "/*\n * xxhsum - Command line interface for xxhash algorithms\n * Copyright (C) 2013-2021 Yann Collet\n *\n * GPL v2 License\n"
  },
  {
    "path": "cli/xsum_os_specific.c",
    "chars": 15801,
    "preview": "/*\n * xxhsum - Command line interface for xxhash algorithms\n * Copyright (C) 2013-2021 Yann Collet\n *\n * GPL v2 License\n"
  },
  {
    "path": "cli/xsum_os_specific.h",
    "chars": 2410,
    "preview": "/*\n * xxhsum - Command line interface for xxhash algorithms\n * Copyright (C) 2013-2021 Yann Collet\n *\n * GPL v2 License\n"
  },
  {
    "path": "cli/xsum_output.c",
    "chars": 1891,
    "preview": "/*\n * xxhsum - Command line interface for xxhash algorithms\n * Copyright (C) 2013-2021 Yann Collet\n *\n * GPL v2 License\n"
  },
  {
    "path": "cli/xsum_output.h",
    "chars": 1697,
    "preview": "/*\n * xxhsum - Command line interface for xxhash algorithms\n * Copyright (C) 2013-2021 Yann Collet\n *\n * GPL v2 License\n"
  },
  {
    "path": "cli/xsum_sanity_check.c",
    "chars": 29699,
    "preview": "/*\n * xxhsum - Command line interface for xxhash algorithms\n * Copyright (C) 2013-2021 Yann Collet\n *\n * GPL v2 License\n"
  },
  {
    "path": "cli/xsum_sanity_check.h",
    "chars": 1729,
    "preview": "/*\n * xxhsum - Command line interface for xxhash algorithms\n * Copyright (C) 2013-2021 Yann Collet\n *\n * GPL v2 License\n"
  },
  {
    "path": "cli/xxhsum.1",
    "chars": 4846,
    "preview": ".\n.TH \"XXHSUM\" \"1\" \"May 2024\" \"xxhsum 0.8.3\" \"User Commands\"\n.\n.SH \"NAME\"\n\\fBxxhsum\\fR \\- print or check xxHash non\\-cry"
  },
  {
    "path": "cli/xxhsum.1.md",
    "chars": 5323,
    "preview": "xxhsum(1) -- print or check xxHash non-cryptographic checksums\n========================================================="
  },
  {
    "path": "cli/xxhsum.c",
    "chars": 61241,
    "preview": "/*\n * xxhsum - Command line interface for xxhash algorithms\n * Copyright (C) 2013-2023 Yann Collet\n *\n * GPL v2 License\n"
  },
  {
    "path": "clib.json",
    "chars": 255,
    "preview": "{\n  \"name\": \"xxhash\",\n  \"version\": \"0.8.3\",\n  \"repo\": \"Cyan4973/xxhash\",\n  \"description\": \"Extremely fast non-cryptograp"
  },
  {
    "path": "doc/README.md",
    "chars": 413,
    "preview": "xxHash Specification\n=======================\n\nThis directory contains material defining the xxHash algorithm.\nIt's descr"
  },
  {
    "path": "doc/xxhash.cry",
    "chars": 7190,
    "preview": "module xxhash where\n\n/**\n * The 32-bit variant of xxHash. The first argument is the sequence\n * of L bytes to hash. The "
  },
  {
    "path": "doc/xxhash_spec.md",
    "chars": 35240,
    "preview": "xxHash fast digest algorithm\n======================\n\n### Notices\n\nCopyright (c) Yann Collet\n\nPermission is granted to co"
  },
  {
    "path": "fuzz/fuzzer.c",
    "chars": 261,
    "preview": "#include <stdint.h>\n#include \"xxhash.h\"\n\n\nint LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {\n  volatile XXH6"
  },
  {
    "path": "libxxhash.pc.in",
    "chars": 432,
    "preview": "#   xxHash - Extremely fast hash algorithm\n#   Copyright (C) 2012-2021, Yann Collet, Facebook\n#   BSD 2-Clause License ("
  },
  {
    "path": "tests/Makefile",
    "chars": 4103,
    "preview": "# ################################################################\n# xxHash Makefile\n# Copyright (C) 2012-2021 Yann Coll"
  },
  {
    "path": "tests/cli-comment-line.sh",
    "chars": 815,
    "preview": "#!/bin/bash\n\n# Exit immediately if any command fails.\n# https://stackoverflow.com/a/2871034\nset -euxo\n\n\n# Default\n./xxhs"
  },
  {
    "path": "tests/cli-ignore-missing.sh",
    "chars": 1130,
    "preview": "#!/bin/bash\n\n# Exit immediately if any command fails.\n# https://stackoverflow.com/a/2871034\nset -e -u -x\n\n\n# Normal\n./xx"
  },
  {
    "path": "tests/collisions/.gitignore",
    "chars": 32,
    "preview": "#build artefacts\ncollisionsTest\n"
  },
  {
    "path": "tests/collisions/LICENSE",
    "chars": 18092,
    "preview": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 2, June 1991\n\n Copyright (C) 1989, 1991 Fr"
  },
  {
    "path": "tests/collisions/Makefile",
    "chars": 2358,
    "preview": "#  Brute force collision tester for 64-bit hashes\n#  Part of xxHash project\n#  Copyright (C) 2019-2021 Yann Collet\n#\n# G"
  },
  {
    "path": "tests/collisions/README.md",
    "chars": 4813,
    "preview": "\n__collisionsTest__ is a brute force hash analyzer\nwhich will measure a 64-bit hash algorithm's collision rate\nby genera"
  },
  {
    "path": "tests/collisions/allcodecs/README.md",
    "chars": 50,
    "preview": "Put in this directory all hash algorithms to test\n"
  },
  {
    "path": "tests/collisions/allcodecs/dummy.c",
    "chars": 1266,
    "preview": "/*\n * dummy.c, a fake hash algorithm, just to test integration capabilities.\n * Part of the xxHash project\n * Copyright "
  },
  {
    "path": "tests/collisions/allcodecs/dummy.h",
    "chars": 1299,
    "preview": "/*\n * dummy.c,\n * A fake hash algorithm, just to test integration capabilities.\n * Part of the xxHash project\n * Copyrig"
  },
  {
    "path": "tests/collisions/hashes.h",
    "chars": 3018,
    "preview": "/*\n * List of hashes for the brute force collision tester\n * Part of xxHash project\n * Copyright (C) 2019-2021 Yann Coll"
  },
  {
    "path": "tests/collisions/main.c",
    "chars": 37859,
    "preview": "/*\n * Brute force collision tester for 64-bit hashes\n * Part of the xxHash project\n * Copyright (C) 2019-2021 Yann Colle"
  },
  {
    "path": "tests/collisions/pool.c",
    "chars": 10475,
    "preview": "/*\n * Copyright (C) 2016-2021 Yann Collet, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed und"
  },
  {
    "path": "tests/collisions/pool.h",
    "chars": 2340,
    "preview": "/*\n * Copyright (c) 2016-2021 Yann Collet, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed und"
  },
  {
    "path": "tests/collisions/sort.cc",
    "chars": 1785,
    "preview": "/*\n * sort.cc - C++ sort functions\n * Copyright (C) 2019-2021 Yann Collet\n * GPL v2 License\n *\n * This program is free s"
  },
  {
    "path": "tests/collisions/sort.hh",
    "chars": 1294,
    "preview": "/*\n * sort.hh - headers for C++ sort functions\n * Copyright (C) 2019-2021 Yann Collet\n * GPL v2 License\n *\n * This progr"
  },
  {
    "path": "tests/collisions/threading.c",
    "chars": 1867,
    "preview": "/**\n * Copyright (c) 2016 Tino Reichardt\n * All rights reserved.\n *\n * This source code is licensed under both the BSD-s"
  },
  {
    "path": "tests/collisions/threading.h",
    "chars": 3912,
    "preview": "/**\n * Copyright (c) 2016 Tino Reichardt\n * All rights reserved.\n *\n * This source code is licensed under both the BSD-s"
  },
  {
    "path": "tests/filename-escape.sh",
    "chars": 641,
    "preview": "#!/bin/bash\n\n# Exit immediately if any command fails.\n# https://stackoverflow.com/a/2871034\nset -euxo pipefail\n\necho fil"
  },
  {
    "path": "tests/generate_unicode_test.c",
    "chars": 6245,
    "preview": "/*\n * Generates a Unicode test for xxhsum without using Unicode in the source files.\n *\n * Copyright (C) 2020 Devin Huss"
  },
  {
    "path": "tests/multiInclude.c",
    "chars": 2404,
    "preview": "/*\n * Multi-include test program\n * Validates that xxhash.h can be included multiple times and in any order\n *\n * Copyri"
  },
  {
    "path": "tests/ppc_define.c",
    "chars": 1775,
    "preview": "/*\n * Multi-include test program\n * ensure that pixel, bool and vector are not redefined\n *\n * Copyright (C) 2020 Yann C"
  },
  {
    "path": "tests/sanity_test.c",
    "chars": 27073,
    "preview": "// xxHash/tests/sanity_test.c\n// SPDX-License-Identifier: GPL-2.0-only\n//\n// Building\n// ========\n//\n// cc sanity_test.c"
  },
  {
    "path": "tests/sanity_test_vectors.h",
    "chars": 4587988,
    "preview": "typedef struct {\n    XSUM_U32 len;\n    XSUM_U32 seed;\n    XSUM_U32 Nresult;\n} XSUM_testdata32_t;\n\ntypedef struct {\n    X"
  },
  {
    "path": "tests/sanity_test_vectors_generator.c",
    "chars": 14781,
    "preview": "// xxHash/tests/sanity_test_vectors_generator.c\n// SPDX-License-Identifier: GPL-2.0-only\n//\n// So far, this program just"
  },
  {
    "path": "tests/test_alias.c",
    "chars": 394,
    "preview": "#define XXH_INLINE_ALL\n\n#include <inttypes.h>\n#include <stdio.h>\n#include \"xxhash.h\"\n\nint main() {\n\t// it seems this has"
  },
  {
    "path": "tests/unicode_lint.sh",
    "chars": 1017,
    "preview": "#!/bin/bash\n\n# `unicode_lint.sh' determines whether source files under ${dirs} directories\n# contain Unicode characters,"
  },
  {
    "path": "xxh3.h",
    "chars": 2394,
    "preview": "/*\n * xxHash - Extremely Fast Hash algorithm\n * Development source file for `xxh3`\n * Copyright (C) 2019-2021 Yann Colle"
  },
  {
    "path": "xxh_x86dispatch.c",
    "chars": 32134,
    "preview": "/*\n * xxHash - Extremely Fast Hash algorithm\n * Copyright (C) 2020-2021 Yann Collet\n *\n * BSD 2-Clause License (https://"
  },
  {
    "path": "xxh_x86dispatch.h",
    "chars": 4058,
    "preview": "/*\n * xxHash - XXH3 Dispatcher for x86-based targets\n * Copyright (C) 2020-2024 Yann Collet\n *\n * BSD 2-Clause License ("
  },
  {
    "path": "xxhash.c",
    "chars": 1855,
    "preview": "/*\n * xxHash - Extremely Fast Hash algorithm\n * Copyright (C) 2012-2023 Yann Collet\n *\n * BSD 2-Clause License (https://"
  },
  {
    "path": "xxhash.h",
    "chars": 277742,
    "preview": "/*\n * xxHash - Extremely Fast Hash algorithm\n * Header File\n * Copyright (C) 2012-2023 Yann Collet\n *\n * BSD 2-Clause Li"
  }
]

About this extraction

This page contains the full source code of the Cyan4973/xxHash GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 72 files (5.1 MB), approximately 1.3M tokens, and a symbol index with 507 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!