Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 15 Feb 2026 13:05:28 +0000
From:      Dimitry Andric <dim@FreeBSD.org>
To:        ports-committers@FreeBSD.org, dev-commits-ports-all@FreeBSD.org, dev-commits-ports-branches@FreeBSD.org
Subject:   git: 7b3fa26bfa43 - 2026Q1 - devel/libddwaf: fix build with clang 21
Message-ID:  <6991c498.3f38e.705915b7@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch 2026Q1 has been updated by dim:

URL: https://cgit.FreeBSD.org/ports/commit/?id=7b3fa26bfa43fd79b4129cf30fe46cc6f21fe9fc

commit 7b3fa26bfa43fd79b4129cf30fe46cc6f21fe9fc
Author:     Dimitry Andric <dim@FreeBSD.org>
AuthorDate: 2026-02-13 19:22:32 +0000
Commit:     Dimitry Andric <dim@FreeBSD.org>
CommitDate: 2026-02-15 13:05:21 +0000

    devel/libddwaf: fix build with clang 21
    
    With clang 21 devel/libddwaf fails to build, with errors similar to:
    
        In file included from /wrkdirs/usr/ports/devel/libddwaf/work/libddwaf-1.30.1/src/vendor/fmt/format.cc:8:
        /wrkdirs/usr/ports/devel/libddwaf/work/libddwaf-1.30.1/src/vendor/fmt/format-inl.h:61:19: error: call to consteval function 'ddwaf::fmt::basic_format_string<char, ddwaf::fmt::basic_string_view<char> &, const char (&)[3]>::basic_format_string<FMT_COMPILE_STRING, 0>' is not a constant expression
           61 |     format_to(it, FMT_STRING("{}{}"), message, SEP);
              |                   ^
        /wrkdirs/usr/ports/devel/libddwaf/work/libddwaf-1.30.1/src/vendor/fmt/format.h:1905:23: note: expanded from macro 'FMT_STRING'
         1905 | #define FMT_STRING(s) FMT_STRING_IMPL(s, fmt::detail::compile_string, )
              |                       ^
        /wrkdirs/usr/ports/devel/libddwaf/work/libddwaf-1.30.1/src/vendor/fmt/format.h:1882:3: note: expanded from macro 'FMT_STRING_IMPL'
         1882 |   [] {                                                                        \
              |   ^
        /wrkdirs/usr/ports/devel/libddwaf/work/libddwaf-1.30.1/src/vendor/fmt/core.h:688:54: note: subexpression not valid in a constant expression
          688 |     format_str_.remove_prefix(detail::to_unsigned(it - begin()));
              |                                                   ~~~^~~~~~~~~
        /wrkdirs/usr/ports/devel/libddwaf/work/libddwaf-1.30.1/src/vendor/fmt/core.h:2639:5: note: in call to 'this->context_.advance_to(&"{}{}"[1])'
         2639 |     context_.advance_to(begin);
              |     ^~~~~~~~~~~~~~~~~~~~~~~~~~
        /wrkdirs/usr/ports/devel/libddwaf/work/libddwaf-1.30.1/src/vendor/fmt/core.h:2634:5: note: in call to 'this->on_format_specs(0, &"{}{}"[1], &"{}{}"[1])'
         2634 |     on_format_specs(id, begin, begin);  // Call parse() on empty specs.
              |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        /wrkdirs/usr/ports/devel/libddwaf/work/libddwaf-1.30.1/src/vendor/fmt/core.h:2459:5: note: in call to 'handler.on_replacement_field(0, &"{}{}"[1])'
         2459 |     handler.on_replacement_field(handler.on_arg_id(), begin);
              |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        /wrkdirs/usr/ports/devel/libddwaf/work/libddwaf-1.30.1/src/vendor/fmt/core.h:2491:21: note: in call to 'parse_replacement_field<char, ddwaf::fmt::detail::format_string_checker<char, ddwaf::fmt::basic_string_view<char>, char[3]> &>(&"{}{}"[1], &"{}{}"[4], checker(s))'
         2491 |         begin = p = parse_replacement_field(p - 1, end, handler);
              |                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        /wrkdirs/usr/ports/devel/libddwaf/work/libddwaf-1.30.1/src/vendor/fmt/core.h:2742:7: note: in call to 'parse_format_string<true, char, ddwaf::fmt::detail::format_string_checker<char, ddwaf::fmt::basic_string_view<char>, char[3]>>({&"{}{}"[0], 4}, checker(s))'
         2742 |       detail::parse_format_string<true>(str_, checker(s));
              |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        /wrkdirs/usr/ports/devel/libddwaf/work/libddwaf-1.30.1/src/vendor/fmt/format-inl.h:61:19: note: in call to 'basic_format_string<FMT_COMPILE_STRING, 0>([] {
            struct __attribute__((visibility("hidden")))  FMT_COMPILE_STRING : fmt::detail::compile_string {
                using char_type [[maybe_unused]] = fmt::remove_cvref_t<decltype("{}{}"[0])>;
                [[maybe_unused]] constexpr operator fmt::basic_string_view<char_type>() const {
                    return fmt::detail_exported::compile_string_to_view<char_type>("{}{}");
                }
            };
            return FMT_COMPILE_STRING();
        }())'
           61 |     format_to(it, FMT_STRING("{}{}"), message, SEP);
              |                   ^~~~~~~~~~~~~~~~~~
        /wrkdirs/usr/ports/devel/libddwaf/work/libddwaf-1.30.1/src/vendor/fmt/format.h:1905:23: note: expanded from macro 'FMT_STRING'
         1905 | #define FMT_STRING(s) FMT_STRING_IMPL(s, fmt::detail::compile_string, )
              |                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        /wrkdirs/usr/ports/devel/libddwaf/work/libddwaf-1.30.1/src/vendor/fmt/format.h:1882:3: note: expanded from macro 'FMT_STRING_IMPL'
         1882 |   [] {                                                                        \
              |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         1883 |     /* Use the hidden visibility as a workaround for a GCC bug (#1973). */    \
              |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         1884 |     /* Use a macro-like name to avoid shadowing warnings. */                  \
              |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         1885 |     struct FMT_VISIBILITY("hidden") FMT_COMPILE_STRING : base {               \
              |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         1886 |       using char_type FMT_MAYBE_UNUSED = fmt::remove_cvref_t<decltype(s[0])>; \
              |       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         1887 |       FMT_MAYBE_UNUSED FMT_CONSTEXPR explicit                                 \
              |       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         1888 |       operator fmt::basic_string_view<char_type>() const {                    \
              |       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         1889 |         return fmt::detail_exported::compile_string_to_view<char_type>(s);    \
              |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         1890 |       }                                                                       \
              |       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         1891 |     };                                                                        \
              |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         1892 |     return FMT_COMPILE_STRING();                                              \
              |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         1893 |   }()
              |   ~~~
    
    This is caused by an outdated vendored version of the fmt library, from
    <https://github.com/fmtlib/fmt>. Upstream libddwaf updated their
    vendored copy in <https://github.com/DataDog/libddwaf/commit/d9dd3eb>,
    which is a bit large due to the vendor update, but the patch applies
    with a minimum of fuzz, and makes libddwaf build with clang 21.
    
    PR:             293165
    Approved by:    sunpoet (maintainer)
    MFH:            2026Q1
    
    (cherry picked from commit 76122faa9d1b5e85f9a5f32a5671103d7eef1695)
---
 devel/libddwaf/files/patch-update-fmt | 12986 ++++++++++++++++++++++++++++++++
 1 file changed, 12986 insertions(+)

diff --git a/devel/libddwaf/files/patch-update-fmt b/devel/libddwaf/files/patch-update-fmt
new file mode 100644
index 000000000000..846fca81f085
--- /dev/null
+++ b/devel/libddwaf/files/patch-update-fmt
@@ -0,0 +1,12986 @@
+commit 84a7a52b24e07a02d3c42ec5d247bcd3a02cb7cb
+Author: Anil Mahtani <929854+Anilm3@users.noreply.github.com>
+Date:   2025-11-05T16:22:50Z
+
+    Cherry-pick: Upgrade fmt dependency and use as header-only (#478)
+
+diff --git .github/workflows/build.yml .github/workflows/build.yml
+index d1a909e..9188a54 100644
+--- .github/workflows/build.yml
++++ .github/workflows/build.yml
+@@ -362,11 +362,11 @@ jobs:
+ 
+       - name: Generate Comparison Table
+         run: |
+-          echo "### Artifact Size Comparison 📦" > comparison.md
++          echo "### Dynamic Artifact Size Comparison 📦" > comparison.md
+           echo "| Artifact | Previous Release | This PR | Difference |" >> comparison.md
+           echo "|----------|-----------------|---------|------------|" >> comparison.md
+ 
+-          find ./candidate -regex ".*\.\(a\|a\.stripped\|so\|dll\|lib\|dylib\)" | sed "s@./candidate/\(.*\)@\1@g" | sort | while read file; do
++          find ./candidate -regex ".*\.\(so\|dll\|dylib\)" | sed "s@./candidate/\(.*\)@\1@g" | sort | while read file; do
+               baseline_size=$(du -b ./baseline/$file | awk '{print $1}')
+               candidate_size=$(du -b ./candidate/$file | awk '{print $1}')
+ 
+@@ -378,6 +378,24 @@ jobs:
+               fi
+           done
+ 
++          echo "---" >> comparison.md
++          echo "### Static Artifact Size Comparison 📦" >> comparison.md
++          echo "| Artifact | Previous Release | This PR | Difference |" >> comparison.md
++          echo "|----------|-----------------|---------|------------|" >> comparison.md
++
++          find ./candidate -regex ".*\.\(a\|a\.stripped\|lib\)" | sed "s@./candidate/\(.*\)@\1@g" | sort | while read file; do
++              baseline_size=$(du -b ./baseline/$file | awk '{print $1}')
++              candidate_size=$(du -b ./candidate/$file | awk '{print $1}')
++
++              if [[ $baseline_size -gt 0 ]]; then
++                diff=$(echo "scale=2; ($candidate_size-$baseline_size)/($baseline_size + 1)" | bc -l | awk '{printf "%.2f\n", $0}')
++                echo "| $( echo $file | sed 's@\([^/]*\)/\([^/]*/\)*\(.*\)@\1::\3@g')| $baseline_size | $candidate_size | $diff% |" >> comparison.md
++              else
++                echo "| $( echo $file | sed 's@\([^/]*\)/\([^/]*/\)*\(.*\)@\1::\3@g')| $baseline_size | $candidate_size | ∞ |" >> comparison.md
++              fi
++          done
++
++
+       - name: Post PR comment
+         uses: thollander/actions-comment-pull-request@24bffb9b452ba05a4f3f77933840a6a841d1b32b
+         with:
+diff --git CMakeLists.txt CMakeLists.txt
+index cd2f9de..d639967 100644
+--- CMakeLists.txt
++++ CMakeLists.txt
+@@ -54,6 +54,7 @@ else()
+         add_compile_options(/MT)
+     endif()
+ 
++    add_compile_options(/utf-8)
+     add_compile_definitions(-D_CRT_SECURE_NO_WARNINGS=1 -Dstrdup=_strdup -Dputenv=_putenv)
+ endif()
+ 
+diff --git cmake/objects.cmake cmake/objects.cmake
+index f589f23..8e8692f 100644
+--- cmake/objects.cmake
++++ cmake/objects.cmake
+@@ -92,7 +92,6 @@ set(LIBDDWAF_SOURCE
+     ${libddwaf_SOURCE_DIR}/src/transformer/css_decode.cpp
+     ${libddwaf_SOURCE_DIR}/src/transformer/html_entity_decode.cpp
+     ${libddwaf_SOURCE_DIR}/src/transformer/js_decode.cpp
+-    ${libddwaf_SOURCE_DIR}/src/vendor/fmt/format.cc
+     ${libddwaf_SOURCE_DIR}/src/vendor/radixlib/radixlib.c
+     ${libddwaf_SOURCE_DIR}/src/vendor/lua-aho-corasick/ac_fast.cxx
+     ${libddwaf_SOURCE_DIR}/src/vendor/lua-aho-corasick/ac_slow.cxx
+diff --git src/configuration/configuration_manager.cpp src/configuration/configuration_manager.cpp
+index 10910a4..b982453 100644
+--- src/configuration/configuration_manager.cpp
++++ src/configuration/configuration_manager.cpp
+@@ -26,7 +26,7 @@
+ #include "configuration/rule_override_parser.hpp"
+ #include "configuration/rule_parser.hpp"
+ #include "configuration/scanner_parser.hpp"
+-#include "fmt/core.h"
++#include "fmt/format.h"
+ #include "log.hpp"
+ #include "ruleset_info.hpp"
+ 
+diff --git src/dynamic_string.hpp src/dynamic_string.hpp
+index 3f0e79a..08d6a4d 100644
+--- src/dynamic_string.hpp
++++ src/dynamic_string.hpp
+@@ -170,7 +170,7 @@ protected:
+ 
+ template <> struct fmt::formatter<dynamic_string> : fmt::formatter<std::string_view> {
+     // Use the parse method from the base class formatter
+-    template <typename FormatContext> auto format(const dynamic_string &d, FormatContext &ctx)
++    template <typename FormatContext> auto format(const dynamic_string &d, FormatContext &ctx) const
+     {
+         return fmt::formatter<std::string_view>::format(std::string_view{d.data(), d.size()}, ctx);
+     }
+diff --git src/log.hpp src/log.hpp
+index 2543c8f..1de413a 100644
+--- src/log.hpp
++++ src/log.hpp
+@@ -51,10 +51,12 @@ constexpr const char *base_name(const char *path)
+ #  define DDWAF_LOG_HELPER(level, function, file, line, fmt_str, ...)                              \
+       {                                                                                            \
+           if (ddwaf::logger::valid(level)) {                                                       \
+-              constexpr const char *filename = base_name(file);                                    \
+-              auto message = ddwaf::fmt::format(fmt_str, ##__VA_ARGS__);                           \
+-              ddwaf::logger::log(                                                                  \
+-                  level, function, filename, line, message.c_str(), message.size());               \
++              try {                                                                                \
++                  constexpr const char *filename = base_name(file);                                \
++                  auto message = ddwaf::fmt::format(fmt_str, ##__VA_ARGS__);                       \
++                  ddwaf::logger::log(                                                              \
++                      level, function, filename, line, message.c_str(), message.size());           \
++              } catch (...) {}                                                                     \
+           }                                                                                        \
+       }
+ 
+diff --git src/semver.hpp src/semver.hpp
+index 9719bc4..c4796c4 100644
+--- src/semver.hpp
++++ src/semver.hpp
+@@ -114,7 +114,7 @@ protected:
+ 
+ template <> struct fmt::formatter<semantic_version> : fmt::formatter<std::string_view> {
+     // Use the parse method from the base class formatter
+-    template <typename FormatContext> auto format(semantic_version &v, FormatContext &ctx)
++    template <typename FormatContext> auto format(semantic_version &v, FormatContext &ctx) const
+     {
+         return fmt::formatter<std::string_view>::format(v.string(), ctx);
+     }
+diff --git src/tokenizer/sql_base.hpp src/tokenizer/sql_base.hpp
+index 460b52e..77e142d 100644
+--- src/tokenizer/sql_base.hpp
++++ src/tokenizer/sql_base.hpp
+@@ -55,7 +55,7 @@ std::ostream &operator<<(std::ostream &os, sql_dialect dialect);
+ 
+ template <> struct fmt::formatter<sql_dialect> : fmt::formatter<std::string_view> {
+     // Use the parse method from the base class formatter
+-    template <typename FormatContext> auto format(sql_dialect d, FormatContext &ctx)
++    template <typename FormatContext> auto format(sql_dialect d, FormatContext &ctx) const
+     {
+         return fmt::formatter<std::string_view>::format(sql_dialect_to_string(d), ctx);
+     }
+diff --git src/vendor/fmt/base.h src/vendor/fmt/base.h
+new file mode 100644
+index 0000000..3c12000
+--- /dev/null
++++ src/vendor/fmt/base.h
+@@ -0,0 +1,3015 @@
++// Formatting library for C++ - the base API for char/UTF-8
++//
++// Copyright (c) 2012 - present, Victor Zverovich
++// All rights reserved.
++//
++// For the license information refer to format.h.
++
++#ifndef FMT_BASE_H_
++#define FMT_BASE_H_
++
++#define FMT_HEADER_ONLY
++
++#if defined(FMT_IMPORT_STD) && !defined(FMT_MODULE)
++#  define FMT_MODULE
++#endif
++
++#ifndef FMT_MODULE
++#  include <limits.h>  // CHAR_BIT
++#  include <stdio.h>   // FILE
++#  include <string.h>  // memcmp
++
++#  include <type_traits>  // std::enable_if
++#endif
++
++// The fmt library version in the form major * 10000 + minor * 100 + patch.
++#define FMT_VERSION 120100
++
++// Detect compiler versions.
++#if defined(__clang__) && !defined(__ibmxl__)
++#  define FMT_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__)
++#else
++#  define FMT_CLANG_VERSION 0
++#endif
++#if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER)
++#  define FMT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
++#else
++#  define FMT_GCC_VERSION 0
++#endif
++#if defined(__ICL)
++#  define FMT_ICC_VERSION __ICL
++#elif defined(__INTEL_COMPILER)
++#  define FMT_ICC_VERSION __INTEL_COMPILER
++#else
++#  define FMT_ICC_VERSION 0
++#endif
++#if defined(_MSC_VER)
++#  define FMT_MSC_VERSION _MSC_VER
++#else
++#  define FMT_MSC_VERSION 0
++#endif
++
++// Detect standard library versions.
++#ifdef _GLIBCXX_RELEASE
++#  define FMT_GLIBCXX_RELEASE _GLIBCXX_RELEASE
++#else
++#  define FMT_GLIBCXX_RELEASE 0
++#endif
++#ifdef _LIBCPP_VERSION
++#  define FMT_LIBCPP_VERSION _LIBCPP_VERSION
++#else
++#  define FMT_LIBCPP_VERSION 0
++#endif
++
++#ifdef _MSVC_LANG
++#  define FMT_CPLUSPLUS _MSVC_LANG
++#else
++#  define FMT_CPLUSPLUS __cplusplus
++#endif
++
++// Detect __has_*.
++#ifdef __has_feature
++#  define FMT_HAS_FEATURE(x) __has_feature(x)
++#else
++#  define FMT_HAS_FEATURE(x) 0
++#endif
++#ifdef __has_include
++#  define FMT_HAS_INCLUDE(x) __has_include(x)
++#else
++#  define FMT_HAS_INCLUDE(x) 0
++#endif
++#ifdef __has_builtin
++#  define FMT_HAS_BUILTIN(x) __has_builtin(x)
++#else
++#  define FMT_HAS_BUILTIN(x) 0
++#endif
++#ifdef __has_cpp_attribute
++#  define FMT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
++#else
++#  define FMT_HAS_CPP_ATTRIBUTE(x) 0
++#endif
++
++#define FMT_HAS_CPP14_ATTRIBUTE(attribute) \
++  (FMT_CPLUSPLUS >= 201402L && FMT_HAS_CPP_ATTRIBUTE(attribute))
++
++#define FMT_HAS_CPP17_ATTRIBUTE(attribute) \
++  (FMT_CPLUSPLUS >= 201703L && FMT_HAS_CPP_ATTRIBUTE(attribute))
++
++// Detect C++14 relaxed constexpr.
++#ifdef FMT_USE_CONSTEXPR
++// Use the provided definition.
++#elif FMT_GCC_VERSION >= 702 && FMT_CPLUSPLUS >= 201402L
++// GCC only allows constexpr member functions in non-literal types since 7.2:
++// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66297.
++#  define FMT_USE_CONSTEXPR 1
++#elif FMT_ICC_VERSION
++#  define FMT_USE_CONSTEXPR 0  // https://github.com/fmtlib/fmt/issues/1628
++#elif FMT_HAS_FEATURE(cxx_relaxed_constexpr) || FMT_MSC_VERSION >= 1912
++#  define FMT_USE_CONSTEXPR 1
++#else
++#  define FMT_USE_CONSTEXPR 0
++#endif
++#if FMT_USE_CONSTEXPR
++#  define FMT_CONSTEXPR constexpr
++#else
++#  define FMT_CONSTEXPR
++#endif
++
++// Detect consteval, C++20 constexpr extensions and std::is_constant_evaluated.
++#ifdef FMT_USE_CONSTEVAL
++// Use the provided definition.
++#elif !defined(__cpp_lib_is_constant_evaluated)
++#  define FMT_USE_CONSTEVAL 0
++#elif FMT_CPLUSPLUS < 201709L
++#  define FMT_USE_CONSTEVAL 0
++#elif FMT_GLIBCXX_RELEASE && FMT_GLIBCXX_RELEASE < 10
++#  define FMT_USE_CONSTEVAL 0
++#elif FMT_LIBCPP_VERSION && FMT_LIBCPP_VERSION < 10000
++#  define FMT_USE_CONSTEVAL 0
++#elif defined(__apple_build_version__) && __apple_build_version__ < 14000029L
++#  define FMT_USE_CONSTEVAL 0  // consteval is broken in Apple clang < 14.
++#elif FMT_MSC_VERSION && FMT_MSC_VERSION < 1929
++#  define FMT_USE_CONSTEVAL 0  // consteval is broken in MSVC VS2019 < 16.10.
++#elif defined(__cpp_consteval)
++#  define FMT_USE_CONSTEVAL 1
++#elif FMT_GCC_VERSION >= 1002 || FMT_CLANG_VERSION >= 1101
++#  define FMT_USE_CONSTEVAL 1
++#else
++#  define FMT_USE_CONSTEVAL 0
++#endif
++#if FMT_USE_CONSTEVAL
++#  define FMT_CONSTEVAL consteval
++#  define FMT_CONSTEXPR20 constexpr
++#else
++#  define FMT_CONSTEVAL
++#  define FMT_CONSTEXPR20
++#endif
++
++// Check if exceptions are disabled.
++#ifdef FMT_USE_EXCEPTIONS
++// Use the provided definition.
++#elif defined(__GNUC__) && !defined(__EXCEPTIONS)
++#  define FMT_USE_EXCEPTIONS 0
++#elif defined(__clang__) && !defined(__cpp_exceptions)
++#  define FMT_USE_EXCEPTIONS 0
++#elif FMT_MSC_VERSION && !_HAS_EXCEPTIONS
++#  define FMT_USE_EXCEPTIONS 0
++#else
++#  define FMT_USE_EXCEPTIONS 1
++#endif
++#if FMT_USE_EXCEPTIONS
++#  define FMT_TRY try
++#  define FMT_CATCH(x) catch (x)
++#else
++#  define FMT_TRY if (true)
++#  define FMT_CATCH(x) if (false)
++#endif
++
++#ifdef FMT_NO_UNIQUE_ADDRESS
++// Use the provided definition.
++#elif FMT_CPLUSPLUS < 202002L
++// Not supported.
++#elif FMT_HAS_CPP_ATTRIBUTE(no_unique_address)
++#  define FMT_NO_UNIQUE_ADDRESS [[no_unique_address]]
++// VS2019 v16.10 and later except clang-cl (https://reviews.llvm.org/D110485).
++#elif FMT_MSC_VERSION >= 1929 && !FMT_CLANG_VERSION
++#  define FMT_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]]
++#endif
++#ifndef FMT_NO_UNIQUE_ADDRESS
++#  define FMT_NO_UNIQUE_ADDRESS
++#endif
++
++#if FMT_HAS_CPP17_ATTRIBUTE(fallthrough)
++#  define FMT_FALLTHROUGH [[fallthrough]]
++#elif defined(__clang__)
++#  define FMT_FALLTHROUGH [[clang::fallthrough]]
++#elif FMT_GCC_VERSION >= 700 && \
++    (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 520)
++#  define FMT_FALLTHROUGH [[gnu::fallthrough]]
++#else
++#  define FMT_FALLTHROUGH
++#endif
++
++// Disable [[noreturn]] on MSVC/NVCC because of bogus unreachable code warnings.
++#if FMT_HAS_CPP_ATTRIBUTE(noreturn) && !FMT_MSC_VERSION && !defined(__NVCC__)
++#  define FMT_NORETURN [[noreturn]]
++#else
++#  define FMT_NORETURN
++#endif
++
++#ifdef FMT_NODISCARD
++// Use the provided definition.
++#elif FMT_HAS_CPP17_ATTRIBUTE(nodiscard)
++#  define FMT_NODISCARD [[nodiscard]]
++#else
++#  define FMT_NODISCARD
++#endif
++
++#if FMT_GCC_VERSION || FMT_CLANG_VERSION
++#  define FMT_VISIBILITY(value) __attribute__((visibility(value)))
++#else
++#  define FMT_VISIBILITY(value)
++#endif
++
++// Detect pragmas.
++#define FMT_PRAGMA_IMPL(x) _Pragma(#x)
++#if FMT_GCC_VERSION >= 504 && !defined(__NVCOMPILER)
++// Workaround a _Pragma bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59884
++// and an nvhpc warning: https://github.com/fmtlib/fmt/pull/2582.
++#  define FMT_PRAGMA_GCC(x) FMT_PRAGMA_IMPL(GCC x)
++#else
++#  define FMT_PRAGMA_GCC(x)
++#endif
++#if FMT_CLANG_VERSION
++#  define FMT_PRAGMA_CLANG(x) FMT_PRAGMA_IMPL(clang x)
++#else
++#  define FMT_PRAGMA_CLANG(x)
++#endif
++#if FMT_MSC_VERSION
++#  define FMT_MSC_WARNING(...) __pragma(warning(__VA_ARGS__))
++#else
++#  define FMT_MSC_WARNING(...)
++#endif
++
++// Enable minimal optimizations for more compact code in debug mode.
++FMT_PRAGMA_GCC(push_options)
++#if !defined(__OPTIMIZE__) && !defined(__CUDACC__) && !defined(FMT_MODULE)
++FMT_PRAGMA_GCC(optimize("Og"))
++#endif
++FMT_PRAGMA_CLANG(diagnostic push)
++FMT_PRAGMA_GCC(diagnostic push)
++
++#ifdef FMT_ALWAYS_INLINE
++// Use the provided definition.
++#elif FMT_GCC_VERSION || FMT_CLANG_VERSION
++#  define FMT_ALWAYS_INLINE inline __attribute__((always_inline))
++#else
++#  define FMT_ALWAYS_INLINE inline
++#endif
++// A version of FMT_ALWAYS_INLINE to prevent code bloat in debug mode.
++#ifdef NDEBUG
++#  define FMT_INLINE FMT_ALWAYS_INLINE
++#else
++#  define FMT_INLINE inline
++#endif
++
++#ifndef FMT_BEGIN_NAMESPACE
++#  define FMT_BEGIN_NAMESPACE \
++    namespace ddwaf {         \
++    namespace fmt {           \
++    inline namespace v12 {
++#  define FMT_END_NAMESPACE \
++    }                       \
++    }                       \
++    }
++#endif
++
++#ifndef FMT_EXPORT
++#  define FMT_EXPORT
++#  define FMT_BEGIN_EXPORT
++#  define FMT_END_EXPORT
++#endif
++
++#ifdef _WIN32
++#  define FMT_WIN32 1
++#else
++#  define FMT_WIN32 0
++#endif
++
++#if !defined(FMT_HEADER_ONLY) && FMT_WIN32
++#  if defined(FMT_LIB_EXPORT)
++#    define FMT_API __declspec(dllexport)
++#  elif defined(FMT_SHARED)
++#    define FMT_API __declspec(dllimport)
++#  endif
++#elif defined(FMT_LIB_EXPORT) || defined(FMT_SHARED)
++#  define FMT_API FMT_VISIBILITY("default")
++#endif
++#ifndef FMT_API
++#  define FMT_API
++#endif
++
++#ifndef FMT_OPTIMIZE_SIZE
++#  define FMT_OPTIMIZE_SIZE 0
++#endif
++
++// FMT_BUILTIN_TYPE=0 may result in smaller library size at the cost of higher
++// per-call binary size by passing built-in types through the extension API.
++#ifndef FMT_BUILTIN_TYPES
++#  define FMT_BUILTIN_TYPES 1
++#endif
++
++#define FMT_APPLY_VARIADIC(expr) \
++  using unused = int[];          \
++  (void)unused { 0, (expr, 0)... }
++
++FMT_BEGIN_NAMESPACE
++
++// Implementations of enable_if_t and other metafunctions for older systems.
++template <bool B, typename T = void>
++using enable_if_t = typename std::enable_if<B, T>::type;
++template <bool B, typename T, typename F>
++using conditional_t = typename std::conditional<B, T, F>::type;
++template <bool B> using bool_constant = std::integral_constant<bool, B>;
++template <typename T>
++using remove_reference_t = typename std::remove_reference<T>::type;
++template <typename T>
++using remove_const_t = typename std::remove_const<T>::type;
++template <typename T>
++using remove_cvref_t = typename std::remove_cv<remove_reference_t<T>>::type;
++template <typename T>
++using make_unsigned_t = typename std::make_unsigned<T>::type;
++template <typename T>
++using underlying_t = typename std::underlying_type<T>::type;
++template <typename T> using decay_t = typename std::decay<T>::type;
++using nullptr_t = decltype(nullptr);
++
++#if (FMT_GCC_VERSION && FMT_GCC_VERSION < 500) || FMT_MSC_VERSION
++// A workaround for gcc 4.9 & MSVC v141 to make void_t work in a SFINAE context.
++template <typename...> struct void_t_impl {
++  using type = void;
++};
++template <typename... T> using void_t = typename void_t_impl<T...>::type;
++#else
++template <typename...> using void_t = void;
++#endif
++
++struct monostate {
++  constexpr monostate() {}
++};
++
++// An enable_if helper to be used in template parameters which results in much
++// shorter symbols: https://godbolt.org/z/sWw4vP. Extra parentheses are needed
++// to workaround a bug in MSVC 2019 (see #1140 and #1186).
++#ifdef FMT_DOC
++#  define FMT_ENABLE_IF(...)
++#else
++#  define FMT_ENABLE_IF(...) fmt::enable_if_t<(__VA_ARGS__), int> = 0
++#endif
++
++template <typename T> constexpr auto min_of(T a, T b) -> T {
++  return a < b ? a : b;
++}
++template <typename T> constexpr auto max_of(T a, T b) -> T {
++  return a > b ? a : b;
++}
++
++FMT_NORETURN FMT_API void assert_fail(const char* file, int line,
++                                      const char* message);
++
++namespace detail {
++// Suppresses "unused variable" warnings with the method described in
++// https://herbsutter.com/2009/10/18/mailbag-shutting-up-compiler-warnings/.
++// (void)var does not work on many Intel compilers.
++template <typename... T> FMT_CONSTEXPR void ignore_unused(const T&...) {}
++
++constexpr auto is_constant_evaluated(bool default_value = false) noexcept
++    -> bool {
++// Workaround for incompatibility between clang 14 and libstdc++ consteval-based
++// std::is_constant_evaluated: https://github.com/fmtlib/fmt/issues/3247.
++#if FMT_CPLUSPLUS >= 202002L && FMT_GLIBCXX_RELEASE >= 12 && \
++    (FMT_CLANG_VERSION >= 1400 && FMT_CLANG_VERSION < 1500)
++  ignore_unused(default_value);
++  return __builtin_is_constant_evaluated();
++#elif defined(__cpp_lib_is_constant_evaluated)
++  ignore_unused(default_value);
++  return std::is_constant_evaluated();
++#else
++  return default_value;
++#endif
++}
++
++// Suppresses "conditional expression is constant" warnings.
++template <typename T> FMT_ALWAYS_INLINE constexpr auto const_check(T val) -> T {
++  return val;
++}
++
++FMT_NORETURN FMT_API void assert_fail(const char* file, int line,
++                                      const char* message);
++
++#if defined(FMT_ASSERT)
++// Use the provided definition.
++#elif defined(NDEBUG)
++// FMT_ASSERT is not empty to avoid -Wempty-body.
++#  define FMT_ASSERT(condition, message) \
++    fmt::detail::ignore_unused((condition), (message))
++#else
++#  define FMT_ASSERT(condition, message)                                    \
++    ((condition) /* void() fails with -Winvalid-constexpr on clang 4.0.1 */ \
++         ? (void)0                                                          \
++         : ::ddwaf::fmt::assert_fail(__FILE__, __LINE__, (message)))
++#endif
++
++#ifdef FMT_USE_INT128
++// Use the provided definition.
++#elif defined(__SIZEOF_INT128__) && !defined(__NVCC__) && \
++    !(FMT_CLANG_VERSION && FMT_MSC_VERSION)
++#  define FMT_USE_INT128 1
++using int128_opt = __int128_t;  // An optional native 128-bit integer.
++using uint128_opt = __uint128_t;
++inline auto map(int128_opt x) -> int128_opt { return x; }
++inline auto map(uint128_opt x) -> uint128_opt { return x; }
++#else
++#  define FMT_USE_INT128 0
++#endif
++#if !FMT_USE_INT128
++enum class int128_opt {};
++enum class uint128_opt {};
++// Reduce template instantiations.
++inline auto map(int128_opt) -> monostate { return {}; }
++inline auto map(uint128_opt) -> monostate { return {}; }
++#endif
++
++#ifdef FMT_USE_BITINT
++// Use the provided definition.
++#elif FMT_CLANG_VERSION >= 1500 && !defined(__CUDACC__)
++#  define FMT_USE_BITINT 1
++#else
++#  define FMT_USE_BITINT 0
++#endif
++
++#if FMT_USE_BITINT
++FMT_PRAGMA_CLANG(diagnostic ignored "-Wbit-int-extension")
++template <int N> using bitint = _BitInt(N);
++template <int N> using ubitint = unsigned _BitInt(N);
++#else
++template <int N> struct bitint {};
++template <int N> struct ubitint {};
++#endif  // FMT_USE_BITINT
++
++// Casts a nonnegative integer to unsigned.
++template <typename Int>
++FMT_CONSTEXPR auto to_unsigned(Int value) -> make_unsigned_t<Int> {
++  FMT_ASSERT(std::is_unsigned<Int>::value || value >= 0, "negative value");
++  return static_cast<make_unsigned_t<Int>>(value);
++}
++
++template <typename Char>
++using unsigned_char = conditional_t<sizeof(Char) == 1, unsigned char, unsigned>;
++
++// A heuristic to detect std::string and std::[experimental::]string_view.
++// It is mainly used to avoid dependency on <[experimental/]string_view>.
++template <typename T, typename Enable = void>
++struct is_std_string_like : std::false_type {};
++template <typename T>
++struct is_std_string_like<T, void_t<decltype(std::declval<T>().find_first_of(
++                                 typename T::value_type(), 0))>>
++    : std::is_convertible<decltype(std::declval<T>().data()),
++                          const typename T::value_type*> {};
++
++// Check if the literal encoding is UTF-8.
++enum { is_utf8_enabled = "\u00A7"[1] == '\xA7' };
++enum { use_utf8 = !FMT_WIN32 || is_utf8_enabled };
++
++#ifndef FMT_UNICODE
++#  define FMT_UNICODE 1
++#endif
++
++static_assert(!FMT_UNICODE || use_utf8,
++              "Unicode support requires compiling with /utf-8");
++
++template <typename T> constexpr auto narrow(T*) -> char* { return nullptr; }
++constexpr FMT_ALWAYS_INLINE auto narrow(const char* s) -> const char* {
++  return s;
++}
++
++template <typename Char>
++FMT_CONSTEXPR auto compare(const Char* s1, const Char* s2, size_t n) -> int {
++  if (!is_constant_evaluated() && sizeof(Char) == 1) return memcmp(s1, s2, n);
++  for (; n != 0; ++s1, ++s2, --n) {
++    if (*s1 < *s2) return -1;
++    if (*s1 > *s2) return 1;
++  }
++  return 0;
++}
++
++namespace adl {
++using namespace std;
++
++template <typename Container>
++auto invoke_back_inserter()
++    -> decltype(back_inserter(std::declval<Container&>()));
++}  // namespace adl
++
++template <typename It, typename Enable = std::true_type>
++struct is_back_insert_iterator : std::false_type {};
++
++template <typename It>
++struct is_back_insert_iterator<
++    It, bool_constant<std::is_same<
++            decltype(adl::invoke_back_inserter<typename It::container_type>()),
++            It>::value>> : std::true_type {};
++
++// Extracts a reference to the container from *insert_iterator.
++template <typename OutputIt>
++inline FMT_CONSTEXPR20 auto get_container(OutputIt it) ->
++    typename OutputIt::container_type& {
++  struct accessor : OutputIt {
++    FMT_CONSTEXPR20 accessor(OutputIt base) : OutputIt(base) {}
++    using OutputIt::container;
++  };
++  return *accessor(it).container;
++}
++}  // namespace detail
++
++// Parsing-related public API and forward declarations.
++FMT_BEGIN_EXPORT
++
++/**
++ * An implementation of `std::basic_string_view` for pre-C++17. It provides a
++ * subset of the API. `fmt::basic_string_view` is used for format strings even
++ * if `std::basic_string_view` is available to prevent issues when a library is
++ * compiled with a different `-std` option than the client code (which is not
++ * recommended).
++ */
++template <typename Char> class basic_string_view {
++ private:
++  const Char* data_;
++  size_t size_;
++
++ public:
++  using value_type = Char;
++  using iterator = const Char*;
++
++  constexpr basic_string_view() noexcept : data_(nullptr), size_(0) {}
++
++  /// Constructs a string view object from a C string and a size.
++  constexpr basic_string_view(const Char* s, size_t count) noexcept
++      : data_(s), size_(count) {}
++
++  constexpr basic_string_view(nullptr_t) = delete;
++
++  /// Constructs a string view object from a C string.
++#if FMT_GCC_VERSION
++  FMT_ALWAYS_INLINE
++#endif
++  FMT_CONSTEXPR20 basic_string_view(const Char* s) : data_(s) {
++#if FMT_HAS_BUILTIN(__builtin_strlen) || FMT_GCC_VERSION || FMT_CLANG_VERSION
++    if (std::is_same<Char, char>::value && !detail::is_constant_evaluated()) {
++      size_ = __builtin_strlen(detail::narrow(s));  // strlen is not constexpr.
++      return;
++    }
++#endif
++    size_t len = 0;
++    while (*s++) ++len;
++    size_ = len;
++  }
++
++  /// Constructs a string view from a `std::basic_string` or a
++  /// `std::basic_string_view` object.
++  template <typename S,
++            FMT_ENABLE_IF(detail::is_std_string_like<S>::value&& std::is_same<
++                          typename S::value_type, Char>::value)>
++  FMT_CONSTEXPR basic_string_view(const S& s) noexcept
++      : data_(s.data()), size_(s.size()) {}
++
++  /// Returns a pointer to the string data.
++  constexpr auto data() const noexcept -> const Char* { return data_; }
++
++  /// Returns the string size.
++  constexpr auto size() const noexcept -> size_t { return size_; }
++
++  constexpr auto begin() const noexcept -> iterator { return data_; }
++  constexpr auto end() const noexcept -> iterator { return data_ + size_; }
++
++  constexpr auto operator[](size_t pos) const noexcept -> const Char& {
++    return data_[pos];
++  }
++
++  FMT_CONSTEXPR void remove_prefix(size_t n) noexcept {
++    data_ += n;
++    size_ -= n;
++  }
++
++  FMT_CONSTEXPR auto starts_with(basic_string_view<Char> sv) const noexcept
++      -> bool {
++    return size_ >= sv.size_ && detail::compare(data_, sv.data_, sv.size_) == 0;
++  }
++  FMT_CONSTEXPR auto starts_with(Char c) const noexcept -> bool {
++    return size_ >= 1 && *data_ == c;
++  }
++  FMT_CONSTEXPR auto starts_with(const Char* s) const -> bool {
++    return starts_with(basic_string_view<Char>(s));
++  }
++
++  FMT_CONSTEXPR auto compare(basic_string_view other) const -> int {
++    int result =
++        detail::compare(data_, other.data_, min_of(size_, other.size_));
++    if (result != 0) return result;
++    return size_ == other.size_ ? 0 : (size_ < other.size_ ? -1 : 1);
++  }
++
++  FMT_CONSTEXPR friend auto operator==(basic_string_view lhs,
++                                       basic_string_view rhs) -> bool {
++    return lhs.compare(rhs) == 0;
++  }
++  friend auto operator!=(basic_string_view lhs, basic_string_view rhs) -> bool {
++    return lhs.compare(rhs) != 0;
++  }
++  friend auto operator<(basic_string_view lhs, basic_string_view rhs) -> bool {
++    return lhs.compare(rhs) < 0;
++  }
++  friend auto operator<=(basic_string_view lhs, basic_string_view rhs) -> bool {
++    return lhs.compare(rhs) <= 0;
++  }
++  friend auto operator>(basic_string_view lhs, basic_string_view rhs) -> bool {
++    return lhs.compare(rhs) > 0;
++  }
++  friend auto operator>=(basic_string_view lhs, basic_string_view rhs) -> bool {
++    return lhs.compare(rhs) >= 0;
++  }
++};
++
++using string_view = basic_string_view<char>;
++
++template <typename T> class basic_appender;
++using appender = basic_appender<char>;
++
++// Checks whether T is a container with contiguous storage.
++template <typename T> struct is_contiguous : std::false_type {};
++
++class context;
++template <typename OutputIt, typename Char> class generic_context;
++template <typename Char> class parse_context;
++
++// Longer aliases for C++20 compatibility.
++template <typename Char> using basic_format_parse_context = parse_context<Char>;
++using format_parse_context = parse_context<char>;
++template <typename OutputIt, typename Char>
++using basic_format_context =
++    conditional_t<std::is_same<OutputIt, appender>::value, context,
++                  generic_context<OutputIt, Char>>;
++using format_context = context;
++
++template <typename Char>
++using buffered_context =
++    conditional_t<std::is_same<Char, char>::value, context,
++                  generic_context<basic_appender<Char>, Char>>;
++
++template <typename Context> class basic_format_arg;
++template <typename Context> class basic_format_args;
++
++// A separate type would result in shorter symbols but break ABI compatibility
++// between clang and gcc on ARM (#1919).
++using format_args = basic_format_args<context>;
++
++// A formatter for objects of type T.
++template <typename T, typename Char = char, typename Enable = void>
++struct formatter {
++  // A deleted default constructor indicates a disabled formatter.
++  formatter() = delete;
++};
++
++/// Reports a format error at compile time or, via a `format_error` exception,
++/// at runtime.
++// This function is intentionally not constexpr to give a compile-time error.
++FMT_NORETURN FMT_API void report_error(const char* message);
++
++enum class presentation_type : unsigned char {
++  // Common specifiers:
++  none = 0,
++  debug = 1,   // '?'
++  string = 2,  // 's' (string, bool)
++
++  // Integral, bool and character specifiers:
++  dec = 3,  // 'd'
++  hex,      // 'x' or 'X'
++  oct,      // 'o'
++  bin,      // 'b' or 'B'
++  chr,      // 'c'
++
++  // String and pointer specifiers:
++  pointer = 3,  // 'p'
++
++  // Floating-point specifiers:
++  exp = 1,  // 'e' or 'E' (1 since there is no FP debug presentation)
++  fixed,    // 'f' or 'F'
++  general,  // 'g' or 'G'
++  hexfloat  // 'a' or 'A'
++};
++
++enum class align { none, left, right, center, numeric };
++enum class sign { none, minus, plus, space };
++enum class arg_id_kind { none, index, name };
++
++// Basic format specifiers for built-in and string types.
++class basic_specs {
++ private:
++  // Data is arranged as follows:
++  //
++  //  0                   1                   2                   3
++  //  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
++  // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
++  // |type |align| w | p | s |u|#|L|  f  |          unused           |
++  // +-----+-----+---+---+---+-+-+-+-----+---------------------------+
++  //
++  //   w - dynamic width info
++  //   p - dynamic precision info
++  //   s - sign
++  //   u - uppercase (e.g. 'X' for 'x')
++  //   # - alternate form ('#')
++  //   L - localized
++  //   f - fill size
++  //
++  // Bitfields are not used because of compiler bugs such as gcc bug 61414.
++  enum : unsigned {
++    type_mask = 0x00007,
++    align_mask = 0x00038,
++    width_mask = 0x000C0,
++    precision_mask = 0x00300,
++    sign_mask = 0x00C00,
++    uppercase_mask = 0x01000,
++    alternate_mask = 0x02000,
++    localized_mask = 0x04000,
++    fill_size_mask = 0x38000,
++
++    align_shift = 3,
++    width_shift = 6,
++    precision_shift = 8,
++    sign_shift = 10,
++    fill_size_shift = 15,
++
++    max_fill_size = 4
*** 12102 LINES SKIPPED ***


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6991c498.3f38e.705915b7>