public inbox for buildroot@busybox.net
 help / color / mirror / Atom feed
From: Bernd Kuhls <bernd@kuhls.net>
To: buildroot@buildroot.org
Cc: David GOUARIN <dgouarin@gmail.com>,
	Fabrice Fontaine <fontaine.fabrice@gmail.com>,
	Laurent Cans <laurent.cans@gmail.com>,
	Mario Lang <mlang@blind.guru>,
	Maxim Kochetkov <fido_max@inbox.ru>,
	Phil Eichinger <phil.eichinger@gmail.com>
Subject: [Buildroot] [PATCH 16/20] package/kodi: switch to pcre2
Date: Thu,  9 Apr 2026 10:43:00 +0200	[thread overview]
Message-ID: <20260409084305.3960494-16-bernd@kuhls.net> (raw)
In-Reply-To: <20260409084305.3960494-1-bernd@kuhls.net>

Signed-off-by: Bernd Kuhls <bernd@kuhls.net>
---
 .../0003-RegExp-remove-unused-methods.patch   | 127 +++++
 .../0004-Introduce-PCRE2-dependency.patch     | 192 +++++++
 ...igrate-PCRE-to-PCRE2-and-remove-PCRE.patch | 486 ++++++++++++++++++
 package/kodi/Config.in                        |   3 +-
 package/kodi/kodi.mk                          |   2 +-
 5 files changed, 807 insertions(+), 3 deletions(-)
 create mode 100644 package/kodi/0003-RegExp-remove-unused-methods.patch
 create mode 100644 package/kodi/0004-Introduce-PCRE2-dependency.patch
 create mode 100644 package/kodi/0005-Migrate-PCRE-to-PCRE2-and-remove-PCRE.patch

diff --git a/package/kodi/0003-RegExp-remove-unused-methods.patch b/package/kodi/0003-RegExp-remove-unused-methods.patch
new file mode 100644
index 0000000000..5f8e1af411
--- /dev/null
+++ b/package/kodi/0003-RegExp-remove-unused-methods.patch
@@ -0,0 +1,127 @@
+From 4dd017b2eae39356cda0d96a2f5743dbb8ccf299 Mon Sep 17 00:00:00 2001
+From: fuzzard <fuzzard@kodi.tv>
+Date: Sun, 2 Jun 2024 12:13:01 +1000
+Subject: [PATCH] RegExp remove unused methods
+
+Upstream: https://github.com/xbmc/xbmc/commit/5df2e57368cf5867f588d00a503eb624e5121460
+
+Signed-off-by: Bernd Kuhls <bernd@kuhls.net>
+---
+ xbmc/utils/RegExp.cpp          | 30 ------------------------------
+ xbmc/utils/RegExp.h            |  5 -----
+ xbmc/utils/test/TestRegExp.cpp | 17 -----------------
+ 3 files changed, 52 deletions(-)
+
+diff --git a/xbmc/utils/RegExp.cpp b/xbmc/utils/RegExp.cpp
+index 9667b646a9..40263a28eb 100644
+--- a/xbmc/utils/RegExp.cpp
++++ b/xbmc/utils/RegExp.cpp
+@@ -485,11 +485,6 @@ int CRegExp::GetSubStart(int iSub) const
+   return m_iOvector[iSub*2] + m_offset;
+ }
+ 
+-int CRegExp::GetSubStart(const std::string& subName) const
+-{
+-  return GetSubStart(GetNamedSubPatternNumber(subName.c_str()));
+-}
+-
+ int CRegExp::GetSubLength(int iSub) const
+ {
+   if (!IsValidSubNumber(iSub))
+@@ -498,11 +493,6 @@ int CRegExp::GetSubLength(int iSub) const
+   return m_iOvector[(iSub*2)+1] - m_iOvector[(iSub*2)];
+ }
+ 
+-int CRegExp::GetSubLength(const std::string& subName) const
+-{
+-  return GetSubLength(GetNamedSubPatternNumber(subName.c_str()));
+-}
+-
+ std::string CRegExp::GetMatch(int iSub /* = 0 */) const
+ {
+   if (!IsValidSubNumber(iSub))
+@@ -516,26 +506,6 @@ std::string CRegExp::GetMatch(int iSub /* = 0 */) const
+   return m_subject.substr(pos, len);
+ }
+ 
+-std::string CRegExp::GetMatch(const std::string& subName) const
+-{
+-  return GetMatch(GetNamedSubPatternNumber(subName.c_str()));
+-}
+-
+-bool CRegExp::GetNamedSubPattern(const char* strName, std::string& strMatch) const
+-{
+-  strMatch.clear();
+-  int iSub = pcre_get_stringnumber(m_re, strName);
+-  if (!IsValidSubNumber(iSub))
+-    return false;
+-  strMatch = GetMatch(iSub);
+-  return true;
+-}
+-
+-int CRegExp::GetNamedSubPatternNumber(const char* strName) const
+-{
+-  return pcre_get_stringnumber(m_re, strName);
+-}
+-
+ void CRegExp::DumpOvector(int iLog /* = LOGDEBUG */)
+ {
+   if (iLog < LOGDEBUG || iLog > LOGNONE)
+diff --git a/xbmc/utils/RegExp.h b/xbmc/utils/RegExp.h
+index 53f6019a8f..feea89cd0d 100644
+--- a/xbmc/utils/RegExp.h
++++ b/xbmc/utils/RegExp.h
+@@ -111,15 +111,10 @@ public:
+   };
+   int GetSubCount() const { return m_iMatchCount - 1; } // PCRE returns the number of sub-patterns + 1
+   int GetSubStart(int iSub) const;
+-  int GetSubStart(const std::string& subName) const;
+   int GetSubLength(int iSub) const;
+-  int GetSubLength(const std::string& subName) const;
+   int GetCaptureTotal() const;
+   std::string GetMatch(int iSub = 0) const;
+-  std::string GetMatch(const std::string& subName) const;
+   const std::string& GetPattern() const { return m_pattern; }
+-  bool GetNamedSubPattern(const char* strName, std::string& strMatch) const;
+-  int GetNamedSubPatternNumber(const char* strName) const;
+   void DumpOvector(int iLog);
+   /**
+    * Check is RegExp object is ready for matching
+diff --git a/xbmc/utils/test/TestRegExp.cpp b/xbmc/utils/test/TestRegExp.cpp
+index d757127417..9435a46aa4 100644
+--- a/xbmc/utils/test/TestRegExp.cpp
++++ b/xbmc/utils/test/TestRegExp.cpp
+@@ -96,19 +96,6 @@ TEST(TestRegExp, GetPattern)
+   EXPECT_STREQ("^(Test)\\s*(.*)\\.", regex.GetPattern().c_str());
+ }
+ 
+-TEST(TestRegExp, GetNamedSubPattern)
+-{
+-  CRegExp regex;
+-  std::string match;
+-
+-  EXPECT_TRUE(regex.RegComp("^(?<first>Test)\\s*(?<second>.*)\\."));
+-  EXPECT_EQ(0, regex.RegFind("Test string."));
+-  EXPECT_TRUE(regex.GetNamedSubPattern("first", match));
+-  EXPECT_STREQ("Test", match.c_str());
+-  EXPECT_TRUE(regex.GetNamedSubPattern("second", match));
+-  EXPECT_STREQ("string", match.c_str());
+-}
+-
+ TEST(TestRegExp, operatorEqual)
+ {
+   CRegExp regex, regexcopy;
+@@ -117,10 +104,6 @@ TEST(TestRegExp, operatorEqual)
+   EXPECT_TRUE(regex.RegComp("^(?<first>Test)\\s*(?<second>.*)\\."));
+   regexcopy = regex;
+   EXPECT_EQ(0, regexcopy.RegFind("Test string."));
+-  EXPECT_TRUE(regexcopy.GetNamedSubPattern("first", match));
+-  EXPECT_STREQ("Test", match.c_str());
+-  EXPECT_TRUE(regexcopy.GetNamedSubPattern("second", match));
+-  EXPECT_STREQ("string", match.c_str());
+ }
+ 
+ class TestRegExpLog : public testing::Test
+-- 
+2.47.3
+
diff --git a/package/kodi/0004-Introduce-PCRE2-dependency.patch b/package/kodi/0004-Introduce-PCRE2-dependency.patch
new file mode 100644
index 0000000000..d72c9805b6
--- /dev/null
+++ b/package/kodi/0004-Introduce-PCRE2-dependency.patch
@@ -0,0 +1,192 @@
+From 4a4642b1d7562b553f80da279255a9755a9e20f7 Mon Sep 17 00:00:00 2001
+From: fuzzard <fuzzard@kodi.tv>
+Date: Sun, 2 Jun 2024 13:24:57 +1000
+Subject: [PATCH] Introduce PCRE2 dependency
+
+create PCRE2 in tools/depends/target
+Create Find module for PCRE2
+
+Upstream: https://github.com/xbmc/xbmc/commit/5c24bf262e5cd75b413fcb4c2c5c144d6971d7cc
+
+[Bernd: backported relevant parts to 21.3-Omega]
+Signed-off-by: Bernd Kuhls <bernd@kuhls.net>
+---
+ cmake/modules/FindPCRE2.cmake            | 151 +++++++++++++++++++++++
+ tools/depends/target/pcre2/PCRE2-VERSION |   7 ++
+ 2 files changed, 158 insertions(+)
+ create mode 100644 cmake/modules/FindPCRE2.cmake
+ create mode 100644 tools/depends/target/pcre2/PCRE2-VERSION
+
+diff --git a/cmake/modules/FindPCRE2.cmake b/cmake/modules/FindPCRE2.cmake
+new file mode 100644
+index 0000000000..7e50d5f2c1
+--- /dev/null
++++ b/cmake/modules/FindPCRE2.cmake
+@@ -0,0 +1,151 @@
++#.rst:
++# FindPCRE2
++# --------
++# Finds the PCRE2 library
++#
++# This will define the following imported target::
++#
++#   ${APP_NAME_LC}::PCRE2    - The PCRE2 library
++
++if(NOT TARGET ${APP_NAME_LC}::${CMAKE_FIND_PACKAGE_NAME})
++
++  macro(buildPCRE2)
++    set(PCRE2_VERSION ${${MODULE}_VER})
++    if(WIN32)
++      set(PCRE_DEBUG_POSTFIX d)
++    endif()
++
++    set(patches "${CORE_SOURCE_DIR}/tools/depends/target/${MODULE_LC}/001-all-enable_docs_pc.patch"
++                "${CORE_SOURCE_DIR}/tools/depends/target/${MODULE_LC}/002-all-cmake-config-installdir.patch")
++
++    generate_patchcommand("${patches}")
++
++    set(CMAKE_ARGS -DBUILD_STATIC_LIBS=ON
++                   -DPCRE2_BUILD_PCRE2_8=ON
++                   -DPCRE2_BUILD_PCRE2_16=OFF
++                   -DPCRE2_BUILD_PCRE2_32=OFF
++                   -DPCRE2_SUPPORT_JIT=ON
++                   -DPCRE2_SUPPORT_UNICODE=ON
++                   -DPCRE2_BUILD_PCRE2GREP=OFF
++                   -DPCRE2_BUILD_TESTS=OFF
++                   -DENABLE_DOCS=OFF)
++
++    if(CORE_SYSTEM_NAME STREQUAL darwin_embedded)
++      list(APPEND CMAKE_ARGS -DPCRE2_SUPPORT_JIT=OFF)
++    endif()
++
++    set(${CMAKE_FIND_PACKAGE_NAME}_COMPILEDEFINITIONS PCRE2_STATIC)
++
++    BUILD_DEP_TARGET()
++  endmacro()
++
++  include(cmake/scripts/common/ModuleHelpers.cmake)
++
++  set(MODULE_LC pcre2)
++
++  SETUP_BUILD_VARS()
++
++  if(KODI_DEPENDSBUILD OR (WIN32 OR WINDOWS_STORE))
++    set(PCRE2_USE_STATIC_LIBS ON)
++  endif()
++
++  # Check for existing PCRE2. If version >= PCRE2-VERSION file version, dont build
++  find_package(PCRE2 CONFIG COMPONENTS 8BIT QUIET)
++
++  if((PCRE2_VERSION VERSION_LESS ${${MODULE}_VER} AND ENABLE_INTERNAL_PCRE2) OR
++     ((CORE_SYSTEM_NAME STREQUAL linux OR CORE_SYSTEM_NAME STREQUAL freebsd) AND ENABLE_INTERNAL_PCRE2))
++    buildPCRE2()
++  else()
++      # if PCRE2::8BIT target exists, it meets version requirements
++      # we only do a pkgconfig search when a suitable cmake config returns nothing
++      if(TARGET PCRE2::8BIT)
++        get_target_property(_PCRE2_CONFIGURATIONS PCRE2::8BIT IMPORTED_CONFIGURATIONS)
++        if(_PCRE2_CONFIGURATIONS)
++        foreach(_pcre2_config IN LISTS _PCRE2_CONFIGURATIONS)
++          # Just set to RELEASE var so select_library_configurations can continue to work its magic
++          string(TOUPPER ${_pcre2_config} _pcre2_config_UPPER)
++          if((NOT ${_pcre2_config_UPPER} STREQUAL "RELEASE") AND
++             (NOT ${_pcre2_config_UPPER} STREQUAL "DEBUG"))
++            get_target_property(PCRE2_LIBRARY_RELEASE PCRE2::8BIT IMPORTED_LOCATION_${_pcre2_config_UPPER})
++          else()
++            get_target_property(PCRE2_LIBRARY_${_pcre2_config_UPPER} PCRE2::8BIT IMPORTED_LOCATION_${_pcre2_config_UPPER})
++          endif()
++        endforeach()
++      else()
++        get_target_property(PCRE2_LIBRARY_RELEASE PCRE2::8BIT IMPORTED_LOCATION)
++      endif()
++      get_target_property(PCRE2_INCLUDE_DIR PCRE2::8BIT INTERFACE_INCLUDE_DIRECTORIES)
++    else()
++      # ToDo: use pkgconfig data imported and drop manual find_path/find_library
++      find_package(PkgConfig)
++      if(PKG_CONFIG_FOUND)
++        pkg_check_modules(PC_PCRE2 libpcre2-8 QUIET)
++      endif()
++  
++      find_path(PCRE2_INCLUDE_DIR pcre2.h
++                                  HINTS ${PC_PCRE2_INCLUDEDIR})
++      find_library(PCRE2_LIBRARY_RELEASE NAMES pcre2-8
++                                         HINTS ${PC_PCRE2_LIBDIR})
++      set(PCRE2_VERSION ${PC_PCRE2_VERSION})
++    endif()
++  endif()
++
++  include(SelectLibraryConfigurations)
++  select_library_configurations(PCRE2)
++
++  include(FindPackageHandleStandardArgs)
++  find_package_handle_standard_args(PCRE2
++                                    REQUIRED_VARS PCRE2_LIBRARY PCRE2_INCLUDE_DIR
++                                    VERSION_VAR PCRE2_VERSION)
++
++  if(PCRE2_FOUND)
++    if(TARGET PCRE2::8BIT AND NOT TARGET pcre2)
++      add_library(${APP_NAME_LC}::${CMAKE_FIND_PACKAGE_NAME} ALIAS PCRE2::8BIT)
++    else()
++      add_library(${APP_NAME_LC}::${CMAKE_FIND_PACKAGE_NAME} UNKNOWN IMPORTED)
++      if(PCRE2_LIBRARY_RELEASE)
++        set_target_properties(${APP_NAME_LC}::${CMAKE_FIND_PACKAGE_NAME} PROPERTIES
++                                                                         IMPORTED_CONFIGURATIONS RELEASE
++                                                                         IMPORTED_LOCATION_RELEASE "${PCRE2_LIBRARY_RELEASE}")
++      endif()
++      if(PCRE2_LIBRARY_DEBUG)
++        set_target_properties(${APP_NAME_LC}::${CMAKE_FIND_PACKAGE_NAME} PROPERTIES
++                                                                         IMPORTED_LOCATION_DEBUG "${PCRE2_LIBRARY_DEBUG}")
++        set_property(TARGET ${APP_NAME_LC}::${CMAKE_FIND_PACKAGE_NAME} APPEND PROPERTY
++                                                                              IMPORTED_CONFIGURATIONS DEBUG)
++      endif()
++      set_target_properties(${APP_NAME_LC}::${CMAKE_FIND_PACKAGE_NAME} PROPERTIES
++                                                                       INTERFACE_INCLUDE_DIRECTORIES "${PCRE2_INCLUDE_DIR}")
++
++      # Add interface compile definitions. This will usually come from an INTERNAL build being required.
++      if(${CMAKE_FIND_PACKAGE_NAME}_COMPILEDEFINITIONS)
++        set_property(TARGET ${APP_NAME_LC}::${CMAKE_FIND_PACKAGE_NAME} APPEND PROPERTY
++                                                                              INTERFACE_COMPILE_DEFINITIONS ${${CMAKE_FIND_PACKAGE_NAME}_COMPILEDEFINITIONS})
++      endif()
++    endif()
++    if(TARGET pcre2)
++      add_dependencies(${APP_NAME_LC}::${CMAKE_FIND_PACKAGE_NAME} pcre2)
++    endif()
++
++    # Add internal build target when a Multi Config Generator is used
++    # We cant add a dependency based off a generator expression for targeted build types,
++    # https://gitlab.kitware.com/cmake/cmake/-/issues/19467
++    # therefore if the find heuristics only find the library, we add the internal build
++    # target to the project to allow user to manually trigger for any build type they need
++    # in case only a specific build type is actually available (eg Release found, Debug Required)
++    # This is mainly targeted for windows who required different runtime libs for different
++    # types, and they arent compatible
++    if(_multiconfig_generator)
++      if(NOT TARGET pcre2)
++        buildPCRE2()
++        set_target_properties(pcre2 PROPERTIES EXCLUDE_FROM_ALL TRUE)
++      endif()
++      add_dependencies(build_internal_depends pcre2)
++    endif()
++
++  else()
++    if(PCRE2_FIND_REQUIRED)
++      message(FATAL_ERROR "PCRE2 not found. Possibly use -DENABLE_INTERNAL_PCRE2=ON to build PCRE2")
++    endif()
++  endif()
++endif()
+diff --git a/tools/depends/target/pcre2/PCRE2-VERSION b/tools/depends/target/pcre2/PCRE2-VERSION
+new file mode 100644
+index 0000000000..800eebf0b9
+--- /dev/null
++++ b/tools/depends/target/pcre2/PCRE2-VERSION
+@@ -0,0 +1,7 @@
++LIBNAME=pcre2
++VERSION=10.42
++ARCHIVE=$(LIBNAME)-$(VERSION).tar.bz2
++SHA512=72fbde87fecec3aa4b47225dd919ea1d55e97f2cbcf02aba26e5a0d3b1ffb58c25a80a9ef069eb99f9cf4e41ba9604ad06a7ec159870e1e875d86820e12256d3
++BYPRODUCT=libpcre2-8.a
++BYPRODUCT_WIN=pcre2-8-static.lib
++
+-- 
+2.47.3
+
diff --git a/package/kodi/0005-Migrate-PCRE-to-PCRE2-and-remove-PCRE.patch b/package/kodi/0005-Migrate-PCRE-to-PCRE2-and-remove-PCRE.patch
new file mode 100644
index 0000000000..8a71a3a0a8
--- /dev/null
+++ b/package/kodi/0005-Migrate-PCRE-to-PCRE2-and-remove-PCRE.patch
@@ -0,0 +1,486 @@
+From 250d14b8e3f614147c9465ca6c1b86a3b5a5f7a2 Mon Sep 17 00:00:00 2001
+From: fuzzard <fuzzard@kodi.tv>
+Date: Sun, 2 Jun 2024 13:56:07 +1000
+Subject: [PATCH] Migrate PCRE to PCRE2 and remove PCRE
+
+Upstream: https://github.com/xbmc/xbmc/commit/8e0c4fd22a0b1f9c54b0536960752263f0d5a04f
+
+[Bernd: backported to 21.3-Omega]
+Signed-off-by: Bernd Kuhls <bernd@kuhls.net>
+---
+ CMakeLists.txt             |   4 +-
+ xbmc/utils/RegExp.cpp      | 202 ++++++++++++++++++-------------------
+ xbmc/utils/RegExp.h        |  22 ++--
+ xbmc/utils/StringUtils.cpp |   6 +-
+ 4 files changed, 111 insertions(+), 123 deletions(-)
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index eb648e9a27..319b95044f 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -92,7 +92,7 @@ dependent_option(ENABLE_INTERNAL_CEC "Enable internal libcec?")
+ dependent_option(ENABLE_INTERNAL_FLATBUFFERS "Enable internal flatbuffers?")
+ dependent_option(ENABLE_INTERNAL_FMT "Enable internal fmt?")
+ dependent_option(ENABLE_INTERNAL_NFS "Enable internal libnfs?")
+-dependent_option(ENABLE_INTERNAL_PCRE "Enable internal pcre?")
++dependent_option(ENABLE_INTERNAL_PCRE2 "Enable internal pcre2?")
+ dependent_option(ENABLE_INTERNAL_RapidJSON "Enable internal rapidjson?")
+ 
+ # If ENABLE_INTERNAL_FMT is ON, we force ENABLE_INTERNAL_SPDLOG ON as it has a hard
+@@ -215,7 +215,7 @@ set(required_deps ASS>=0.15.0
+                   LibDvd
+                   Lzo2
+                   OpenSSL>=1.1.0
+-                  PCRE
++                  PCRE2
+                   RapidJSON>=1.0.2
+                   Spdlog
+                   Sqlite3
+diff --git a/xbmc/utils/RegExp.cpp b/xbmc/utils/RegExp.cpp
+index 40263a28eb..cb620208dc 100644
+--- a/xbmc/utils/RegExp.cpp
++++ b/xbmc/utils/RegExp.cpp
+@@ -16,27 +16,6 @@
+ #include <stdlib.h>
+ #include <string.h>
+ 
+-using namespace PCRE;
+-
+-#ifndef PCRE_UCP
+-#define PCRE_UCP 0
+-#endif // PCRE_UCP
+-
+-#ifdef PCRE_CONFIG_JIT
+-#define PCRE_HAS_JIT_CODE 1
+-#endif
+-
+-#ifndef PCRE_STUDY_JIT_COMPILE
+-#define PCRE_STUDY_JIT_COMPILE 0
+-#endif
+-#ifndef PCRE_INFO_JIT
+-// some unused number
+-#define PCRE_INFO_JIT 2048
+-#endif
+-#ifndef PCRE_HAS_JIT_CODE
+-#define pcre_free_study(x) pcre_free((x))
+-#endif
+-
+ int CRegExp::m_Utf8Supported = -1;
+ int CRegExp::m_UcpSupported  = -1;
+ int CRegExp::m_JitSupported  = -1;
+@@ -51,25 +30,24 @@ void CRegExp::InitValues(bool caseless /*= false*/, CRegExp::utf8Mode utf8 /*= a
+ {
+   m_utf8Mode    = utf8;
+   m_re          = NULL;
+-  m_sd          = NULL;
+-  m_iOptions    = PCRE_DOTALL | PCRE_NEWLINE_ANY;
++  m_ctxt = nullptr;
++  m_iOptions = PCRE2_DOTALL;
+   if(caseless)
+-    m_iOptions |= PCRE_CASELESS;
++    m_iOptions |= PCRE2_CASELESS;
+   if (m_utf8Mode == forceUtf8)
+   {
+     if (IsUtf8Supported())
+-      m_iOptions |= PCRE_UTF8;
++      m_iOptions |= PCRE2_UTF;
+     if (AreUnicodePropertiesSupported())
+-      m_iOptions |= PCRE_UCP;
++      m_iOptions |= PCRE2_UCP;
+   }
+ 
+   m_offset      = 0;
+   m_jitCompiled = false;
+   m_bMatched    = false;
+   m_iMatchCount = 0;
+-  m_jitStack    = NULL;
+-
+-  memset(m_iOvector, 0, sizeof(m_iOvector));
++  m_iOvector = nullptr;
++  m_jitStack = NULL;
+ }
+ 
+ CRegExp::CRegExp(bool caseless, CRegExp::utf8Mode utf8, const char *re, studyMode study /*= NoStudy*/)
+@@ -225,7 +203,8 @@ bool CRegExp::isCharClassWithUnicode(const std::string& regexp, size_t& pos)
+ CRegExp::CRegExp(const CRegExp& re)
+ {
+   m_re = NULL;
+-  m_sd = NULL;
++  m_ctxt = nullptr;
++  m_iOvector = nullptr;
+   m_jitStack = NULL;
+   m_utf8Mode = re.m_utf8Mode;
+   m_iOptions = re.m_iOptions;
+@@ -240,12 +219,13 @@ CRegExp& CRegExp::operator=(const CRegExp& re)
+   m_pattern = re.m_pattern;
+   if (re.m_re)
+   {
+-    if (pcre_fullinfo(re.m_re, NULL, PCRE_INFO_SIZE, &size) >= 0)
++    if (pcre2_pattern_info(re.m_re, PCRE2_INFO_SIZE, &size) >= 0)
+     {
+-      if ((m_re = (pcre*)malloc(size)))
++      if ((m_re = pcre2_code_copy(re.m_re)))
+       {
+-        memcpy(m_re, re.m_re, size);
+-        memcpy(m_iOvector, re.m_iOvector, OVECCOUNT*sizeof(int));
++        if (re.m_ctxt)
++          m_ctxt = pcre2_match_context_copy(re.m_ctxt);
++        m_iOvector = re.m_iOvector;
+         m_offset = re.m_offset;
+         m_iMatchCount = re.m_iMatchCount;
+         m_bMatched = re.m_bMatched;
+@@ -273,18 +253,27 @@ bool CRegExp::RegComp(const char *re, studyMode study /*= NoStudy*/)
+   m_jitCompiled      = false;
+   m_bMatched         = false;
+   m_iMatchCount      = 0;
+-  const char *errMsg = NULL;
+-  int errOffset      = 0;
+-  int options        = m_iOptions;
++  pcre2_compile_context* ctxt;
++  int errCode;
++  char errMsg[120];
++  PCRE2_SIZE errOffset;
++  uint32_t options = m_iOptions;
+   if (m_utf8Mode == autoUtf8 && requireUtf8(re))
+-    options |= (IsUtf8Supported() ? PCRE_UTF8 : 0) | (AreUnicodePropertiesSupported() ? PCRE_UCP : 0);
++    options |=
++        (IsUtf8Supported() ? PCRE2_UTF : 0) | (AreUnicodePropertiesSupported() ? PCRE2_UCP : 0);
+ 
+   Cleanup();
+ 
+-  m_re = pcre_compile(re, options, &errMsg, &errOffset, NULL);
++  ctxt = pcre2_compile_context_create(NULL);
++  pcre2_set_newline(ctxt, PCRE2_NEWLINE_ANY);
++  m_re = pcre2_compile(reinterpret_cast<PCRE2_SPTR>(re), PCRE2_ZERO_TERMINATED, options, &errCode,
++                       &errOffset, ctxt);
++  pcre2_compile_context_free(ctxt);
++
+   if (!m_re)
+   {
+     m_pattern.clear();
++    pcre2_get_error_message(errCode, reinterpret_cast<PCRE2_UCHAR*>(errMsg), sizeof(errMsg));
+     CLog::Log(LOGERROR, "PCRE: {}. Compilation failed at offset {} in expression '{}'", errMsg,
+               errOffset, re);
+     return false;
+@@ -295,23 +284,12 @@ bool CRegExp::RegComp(const char *re, studyMode study /*= NoStudy*/)
+   if (study)
+   {
+     const bool jitCompile = (study == StudyWithJitComp) && IsJitSupported();
+-    const int studyOptions = jitCompile ? PCRE_STUDY_JIT_COMPILE : 0;
+-
+-    m_sd = pcre_study(m_re, studyOptions, &errMsg);
+-    if (errMsg != NULL)
+-    {
+-      CLog::Log(LOGWARNING, "{}: PCRE error \"{}\" while studying expression", __FUNCTION__,
+-                errMsg);
+-      if (m_sd != NULL)
+-      {
+-        pcre_free_study(m_sd);
+-        m_sd = NULL;
+-      }
+-    }
+-    else if (jitCompile)
++    if (jitCompile)
+     {
+-      int jitPresent = 0;
+-      m_jitCompiled = (pcre_fullinfo(m_re, m_sd, PCRE_INFO_JIT, &jitPresent) == 0 && jitPresent == 1);
++      pcre2_jit_compile(m_re, PCRE2_JIT_COMPLETE);
++      size_t jitPresent = 0;
++      m_jitCompiled =
++          (pcre2_pattern_info(m_re, PCRE2_INFO_JITSIZE, &jitPresent) == 0 && jitPresent > 0);
+     }
+   }
+ 
+@@ -325,6 +303,9 @@ int CRegExp::RegFind(const char *str, unsigned int startoffset /*= 0*/, int maxN
+ 
+ int CRegExp::PrivateRegFind(size_t bufferLen, const char *str, unsigned int startoffset /* = 0*/, int maxNumberOfCharsToTest /*= -1*/)
+ {
++  pcre2_match_data* md;
++  PCRE2_SIZE offset;
++
+   m_offset      = 0;
+   m_bMatched    = false;
+   m_iMatchCount = 0;
+@@ -347,37 +328,46 @@ int CRegExp::PrivateRegFind(size_t bufferLen, const char *str, unsigned int star
+     return -1;
+   }
+ 
+-#ifdef PCRE_HAS_JIT_CODE
++  if (!m_ctxt)
++    m_ctxt = pcre2_match_context_create(NULL);
++
+   if (m_jitCompiled && !m_jitStack)
+   {
+-    m_jitStack = pcre_jit_stack_alloc(32*1024, 512*1024);
++    m_jitStack = pcre2_jit_stack_create(32 * 1024, 512 * 1024, NULL);
+     if (m_jitStack == NULL)
+       CLog::Log(LOGWARNING, "{}: can't allocate address space for JIT stack", __FUNCTION__);
+ 
+-    pcre_assign_jit_stack(m_sd, NULL, m_jitStack);
++    pcre2_jit_stack_assign(m_ctxt, NULL, m_jitStack);
+   }
+-#endif
+ 
+   if (maxNumberOfCharsToTest >= 0)
+     bufferLen = std::min<size_t>(bufferLen, startoffset + maxNumberOfCharsToTest);
+ 
+   m_subject.assign(str + startoffset, bufferLen - startoffset);
+-  int rc = pcre_exec(m_re, NULL, m_subject.c_str(), m_subject.length(), 0, 0, m_iOvector, OVECCOUNT);
++  md = pcre2_match_data_create(OVECCOUNT, nullptr);
++  int rc = pcre2_match(m_re, reinterpret_cast<PCRE2_SPTR>(m_subject.c_str()), m_subject.length(), 0,
++                       0, md, m_ctxt);
++  m_iOvector = pcre2_get_ovector_pointer(md);
++  offset = pcre2_get_startchar(md);
++  pcre2_match_data_free(md);
+ 
+   if (rc<1)
+   {
+     static const int fragmentLen = 80; // length of excerpt before erroneous char for log
+     switch(rc)
+     {
+-    case PCRE_ERROR_NOMATCH:
+-      return -1;
++      case PCRE2_ERROR_NOMATCH:
++        return -1;
+ 
+-    case PCRE_ERROR_MATCHLIMIT:
+-      CLog::Log(LOGERROR, "PCRE: Match limit reached");
+-      return -1;
++      case PCRE2_ERROR_MATCHLIMIT:
++        CLog::Log(LOGERROR, "PCRE: Match limit reached");
++        return -1;
+ 
+-#ifdef PCRE_ERROR_SHORTUTF8
+-    case PCRE_ERROR_SHORTUTF8:
++      case PCRE2_ERROR_UTF8_ERR1:
++      case PCRE2_ERROR_UTF8_ERR2:
++      case PCRE2_ERROR_UTF8_ERR3:
++      case PCRE2_ERROR_UTF8_ERR4:
++      case PCRE2_ERROR_UTF8_ERR5:
+       {
+         const size_t startPos = (m_subject.length() > fragmentLen) ? CUtf8Utils::RFindValidUtf8Char(m_subject, m_subject.length() - fragmentLen) : 0;
+         if (startPos != std::string::npos)
+@@ -389,28 +379,44 @@ int CRegExp::PrivateRegFind(size_t bufferLen, const char *str, unsigned int star
+           CLog::Log(LOGERROR, "PCRE: Bad UTF-8 character at the end of string");
+         return -1;
+       }
+-#endif
+-    case PCRE_ERROR_BADUTF8:
++      case PCRE2_ERROR_UTF8_ERR6:
++      case PCRE2_ERROR_UTF8_ERR7:
++      case PCRE2_ERROR_UTF8_ERR8:
++      case PCRE2_ERROR_UTF8_ERR9:
++      case PCRE2_ERROR_UTF8_ERR10:
++      case PCRE2_ERROR_UTF8_ERR11:
++      case PCRE2_ERROR_UTF8_ERR12:
++      case PCRE2_ERROR_UTF8_ERR13:
++      case PCRE2_ERROR_UTF8_ERR14:
++      case PCRE2_ERROR_UTF8_ERR15:
++      case PCRE2_ERROR_UTF8_ERR16:
++      case PCRE2_ERROR_UTF8_ERR17:
++      case PCRE2_ERROR_UTF8_ERR18:
++      case PCRE2_ERROR_UTF8_ERR19:
++      case PCRE2_ERROR_UTF8_ERR20:
++      case PCRE2_ERROR_UTF8_ERR21:
+       {
++        char errbuf[120];
++
++        pcre2_get_error_message(rc, reinterpret_cast<PCRE2_UCHAR*>(errbuf), sizeof(errbuf));
+         const size_t startPos = (m_iOvector[0] > fragmentLen) ? CUtf8Utils::RFindValidUtf8Char(m_subject, m_iOvector[0] - fragmentLen) : 0;
+-        if (m_iOvector[0] >= 0 && startPos != std::string::npos)
++        if ((int)m_iOvector[0] >= 0 && startPos != std::string::npos)
+           CLog::Log(LOGERROR,
+                     "PCRE: Bad UTF-8 character, error code: {}, position: {}. Text before bad "
+                     "char: \"{}\"",
+-                    m_iOvector[1], m_iOvector[0],
+-                    m_subject.substr(startPos, m_iOvector[0] - startPos + 1));
++                    errbuf, offset, m_subject.substr(startPos, m_iOvector[0] - startPos + 1));
+         else
+-          CLog::Log(LOGERROR, "PCRE: Bad UTF-8 character, error code: {}, position: {}",
+-                    m_iOvector[1], m_iOvector[0]);
++          CLog::Log(LOGERROR, "PCRE: Bad UTF-8 character, error code: {}, position: {}", errbuf,
++                    offset);
+         return -1;
+       }
+-    case PCRE_ERROR_BADUTF8_OFFSET:
+-      CLog::Log(LOGERROR, "PCRE: Offset is pointing to the middle of UTF-8 character");
+-      return -1;
++      case PCRE2_ERROR_BADUTFOFFSET:
++        CLog::Log(LOGERROR, "PCRE: Offset is pointing to the middle of UTF-8 character");
++        return -1;
+ 
+-    default:
+-      CLog::Log(LOGERROR, "PCRE: Unknown error: {}", rc);
+-      return -1;
++      default:
++        CLog::Log(LOGERROR, "PCRE: Unknown error: {}", rc);
++        return -1;
+     }
+   }
+   m_offset = startoffset;
+@@ -423,7 +429,7 @@ int CRegExp::GetCaptureTotal() const
+ {
+   int c = -1;
+   if (m_re)
+-    pcre_fullinfo(m_re, NULL, PCRE_INFO_CAPTURECOUNT, &c);
++    pcre2_pattern_info(m_re, PCRE2_INFO_CAPTURECOUNT, &c);
+   return c;
+ }
+ 
+@@ -528,23 +534,21 @@ void CRegExp::Cleanup()
+ {
+   if (m_re)
+   {
+-    pcre_free(m_re);
+-    m_re = NULL;
++    pcre2_code_free(m_re);
++    m_re = nullptr;
+   }
+ 
+-  if (m_sd)
++  if (m_ctxt)
+   {
+-    pcre_free_study(m_sd);
+-    m_sd = NULL;
++    pcre2_match_context_free(m_ctxt);
++    m_ctxt = nullptr;
+   }
+ 
+-#ifdef PCRE_HAS_JIT_CODE
+   if (m_jitStack)
+   {
+-    pcre_jit_stack_free(m_jitStack);
++    pcre2_jit_stack_free(m_jitStack);
+     m_jitStack = NULL;
+   }
+-#endif
+ }
+ 
+ inline bool CRegExp::IsValidSubNumber(int iSub) const
+@@ -557,7 +561,7 @@ bool CRegExp::IsUtf8Supported(void)
+ {
+   if (m_Utf8Supported == -1)
+   {
+-    if (pcre_config(PCRE_CONFIG_UTF8, &m_Utf8Supported) != 0)
++    if (pcre2_config(PCRE2_CONFIG_UNICODE, &m_Utf8Supported) < 0)
+       m_Utf8Supported = 0;
+   }
+ 
+@@ -566,13 +570,11 @@ bool CRegExp::IsUtf8Supported(void)
+ 
+ bool CRegExp::AreUnicodePropertiesSupported(void)
+ {
+-#if defined(PCRE_CONFIG_UNICODE_PROPERTIES) && PCRE_UCP != 0
+   if (m_UcpSupported == -1)
+   {
+-    if (pcre_config(PCRE_CONFIG_UNICODE_PROPERTIES, &m_UcpSupported) != 0)
++    if (pcre2_config(PCRE2_CONFIG_UNICODE, &m_UcpSupported) < 0)
+       m_UcpSupported = 0;
+   }
+-#endif
+ 
+   return m_UcpSupported == 1;
+ }
+@@ -595,13 +597,13 @@ bool CRegExp::LogCheckUtf8Support(void)
+ 
+   if (!utf8FullSupport)
+   {
++    char ver[24];
++
++    pcre2_config(PCRE2_CONFIG_VERSION, ver);
+     CLog::Log(LOGINFO,
+-              "Consider installing PCRE lib version 8.10 or later with enabled Unicode properties "
++              "Consider installing PCRE lib version 10.10 or later with enabled Unicode properties "
+               "and UTF-8 support. Your PCRE lib version: {}",
+-              PCRE::pcre_version());
+-#if PCRE_UCP == 0
+-    CLog::Log(LOGINFO, "You will need to rebuild XBMC after PCRE lib update.");
+-#endif
++              ver);
+   }
+ 
+   return utf8FullSupport;
+@@ -611,9 +613,7 @@ bool CRegExp::IsJitSupported(void)
+ {
+   if (m_JitSupported == -1)
+   {
+-#ifdef PCRE_HAS_JIT_CODE
+-    if (pcre_config(PCRE_CONFIG_JIT, &m_JitSupported) != 0)
+-#endif
++    if (pcre2_config(PCRE2_CONFIG_JIT, &m_JitSupported) < 0)
+       m_JitSupported = 0;
+   }
+ 
+diff --git a/xbmc/utils/RegExp.h b/xbmc/utils/RegExp.h
+index feea89cd0d..90d3db541e 100644
+--- a/xbmc/utils/RegExp.h
++++ b/xbmc/utils/RegExp.h
+@@ -13,16 +13,8 @@
+ #include <string>
+ #include <vector>
+ 
+-/* make sure stdlib.h is included before including pcre.h inside the
+-   namespace; this works around stdlib.h definitions also living in
+-   the PCRE namespace */
+-#include <stdlib.h>
+-
+-namespace PCRE {
+-struct real_pcre_jit_stack; // forward declaration for PCRE without JIT
+-typedef struct real_pcre_jit_stack pcre_jit_stack;
+-#include <pcre.h>
+-}
++#define PCRE2_CODE_UNIT_WIDTH 8
++#include <pcre2.h>
+ 
+ class CRegExp
+ {
+@@ -138,17 +130,17 @@ private:
+   void Cleanup();
+   inline bool IsValidSubNumber(int iSub) const;
+ 
+-  PCRE::pcre* m_re;
+-  PCRE::pcre_extra* m_sd;
++  pcre2_code* m_re;
++  pcre2_match_context* m_ctxt;
+   static const int OVECCOUNT=(m_MaxNumOfBackrefrences + 1) * 3;
+   unsigned int m_offset;
+-  int         m_iOvector[OVECCOUNT];
++  PCRE2_SIZE* m_iOvector;
+   utf8Mode    m_utf8Mode;
+   int         m_iMatchCount;
+-  int         m_iOptions;
++  uint32_t m_iOptions;
+   bool        m_jitCompiled;
+   bool        m_bMatched;
+-  PCRE::pcre_jit_stack* m_jitStack;
++  pcre2_jit_stack* m_jitStack;
+   std::string m_subject;
+   std::string m_pattern;
+   static int  m_Utf8Supported;
+diff --git a/xbmc/utils/StringUtils.cpp b/xbmc/utils/StringUtils.cpp
+index 2c77e58ebd..d390113dd7 100644
+--- a/xbmc/utils/StringUtils.cpp
++++ b/xbmc/utils/StringUtils.cpp
+@@ -30,6 +30,7 @@
+ #include "LangInfo.h"
+ #include "StringUtils.h"
+ #include "XBDateTime.h"
++#include "utils/RegExp.h"
+ 
+ #include <algorithm>
+ #include <array>
+@@ -46,11 +47,6 @@
+ #include <fstrcmp.h>
+ #include <memory.h>
+ 
+-// don't move or std functions end up in PCRE namespace
+-// clang-format off
+-#include "utils/RegExp.h"
+-// clang-format on
+-
+ #define FORMAT_BLOCK_SIZE 512 // # of bytes for initial allocation for printf
+ 
+ namespace
+-- 
+2.47.3
+
diff --git a/package/kodi/Config.in b/package/kodi/Config.in
index 9661ab47bc..a05a180eb3 100644
--- a/package/kodi/Config.in
+++ b/package/kodi/Config.in
@@ -91,8 +91,7 @@ menuconfig BR2_PACKAGE_KODI
 	select BR2_PACKAGE_LIBPNG
 	select BR2_PACKAGE_LZO
 	select BR2_PACKAGE_OPENSSL
-	select BR2_PACKAGE_PCRE
-	select BR2_PACKAGE_PCRE_UCP
+	select BR2_PACKAGE_PCRE2
 	select BR2_PACKAGE_PYTHON3_2TO3
 	select BR2_PACKAGE_PYTHON3_PYEXPAT
 	select BR2_PACKAGE_PYTHON3_SQLITE
diff --git a/package/kodi/kodi.mk b/package/kodi/kodi.mk
index c31e789503..0c177a94dd 100644
--- a/package/kodi/kodi.mk
+++ b/package/kodi/kodi.mk
@@ -47,7 +47,7 @@ KODI_DEPENDENCIES = \
 	libpng \
 	lzo \
 	openssl \
-	pcre \
+	pcre2 \
 	python3 \
 	rapidjson \
 	spdlog \
-- 
2.47.3

_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot

  parent reply	other threads:[~2026-04-09  8:45 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-09  8:42 [Buildroot] [PATCH 01/20] package/shadowsocks-libev: bump version to 3.3.6 Bernd Kuhls
2026-04-09  8:42 ` [Buildroot] [PATCH 02/20] package/c-icap: fix musl build Bernd Kuhls
2026-04-09  8:42 ` [Buildroot] [PATCH 03/20] package/c-icap: bump version to 0.5.14 Bernd Kuhls
2026-04-09  8:42 ` [Buildroot] [PATCH 04/20] package/c-icap-modules: bump version to 0.5.7 Bernd Kuhls
2026-04-09  8:42 ` [Buildroot] [PATCH 05/20] package/c-icap: switch to pcre2 Bernd Kuhls
2026-04-09  8:42 ` [Buildroot] [PATCH 06/20] package/brltty: remove optional support for pcre, keep pcre2 Bernd Kuhls
2026-04-09  8:42 ` [Buildroot] [PATCH 07/20] package/haproxy: " Bernd Kuhls
2026-04-09  8:42 ` [Buildroot] [PATCH 08/20] package/kismet: " Bernd Kuhls
2026-04-09  8:42 ` [Buildroot] [PATCH 09/20] package/pound: " Bernd Kuhls
2026-04-09  8:42 ` [Buildroot] [PATCH 10/20] package/sngrep: " Bernd Kuhls
2026-04-09  8:42 ` [Buildroot] [PATCH 11/20] package/tvheadend: " Bernd Kuhls
2026-04-09  8:42 ` [Buildroot] [PATCH 12/20] package/wget: " Bernd Kuhls
2026-04-09  8:42 ` [Buildroot] [PATCH 13/20] package/aircrack-ng: switch to pcre2 Bernd Kuhls
2026-04-09  8:42 ` [Buildroot] [PATCH 14/20] package/freeradius-server: " Bernd Kuhls
2026-04-09  8:42 ` [Buildroot] [PATCH 15/20] package/freeswitch: " Bernd Kuhls
2026-04-09  8:43 ` Bernd Kuhls [this message]
2026-04-09  8:43 ` [Buildroot] [PATCH 17/20] package/postgis: " Bernd Kuhls
2026-04-09  8:43 ` [Buildroot] [PATCH 18/20] package/slang: disable pcre module Bernd Kuhls
2026-04-09  8:43 ` [Buildroot] [PATCH 19/20] package/zsh: switch to pcre2 Bernd Kuhls
2026-04-09  8:43 ` [Buildroot] [PATCH 20/20] package/pcre: remove package Bernd Kuhls

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260409084305.3960494-16-bernd@kuhls.net \
    --to=bernd@kuhls.net \
    --cc=buildroot@buildroot.org \
    --cc=dgouarin@gmail.com \
    --cc=fido_max@inbox.ru \
    --cc=fontaine.fabrice@gmail.com \
    --cc=laurent.cans@gmail.com \
    --cc=mlang@blind.guru \
    --cc=phil.eichinger@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox