svn commit: r1934310 - in subversion/branches/javahl-1.15: . .github/workflows build/cmake build/generator/templates subversion/libsvn_subr subversion/svnbrowse subversion/tests/libsvn_subr tools/dist

[email protected]
Newsgroups gmane.comp.version-control.subversion.svn
Message-ID <177904214707.4072735.9759742100581404352@svn03-he-fi>
Author: dsahlberg
Date: Sun May 17 18:22:26 2026
New Revision: 1934310

Log:
On the javahl-1.15 branch:

Catchup merge with trunk (to simplify review).

Added:
   subversion/branches/javahl-1.15/build/cmake/FindCURSES.cmake
      - copied unchanged from r1934309, subversion/trunk/build/cmake/FindCURSES.cmake
Modified:
   subversion/branches/javahl-1.15/   (props changed)
   subversion/branches/javahl-1.15/.github/workflows/autoconf.yml
   subversion/branches/javahl-1.15/.github/workflows/cmake.yml
   subversion/branches/javahl-1.15/.github/workflows/detect-backport-conflicts.yml
   subversion/branches/javahl-1.15/CMakeLists.txt
   subversion/branches/javahl-1.15/COMMITTERS
   subversion/branches/javahl-1.15/INSTALL
   subversion/branches/javahl-1.15/build/cmake/FindHttpd.cmake
   subversion/branches/javahl-1.15/build/generator/templates/targets.cmake.ezt
   subversion/branches/javahl-1.15/subversion/libsvn_subr/config_file.c
   subversion/branches/javahl-1.15/subversion/libsvn_subr/utf.c
   subversion/branches/javahl-1.15/subversion/svnbrowse/model.c
   subversion/branches/javahl-1.15/subversion/svnbrowse/svnbrowse.c
   subversion/branches/javahl-1.15/subversion/svnbrowse/svnbrowse.h
   subversion/branches/javahl-1.15/subversion/tests/libsvn_subr/utf-test.c
   subversion/branches/javahl-1.15/tools/dist/detect-conflicting-backports.py

Modified: subversion/branches/javahl-1.15/.github/workflows/autoconf.yml
==============================================================================
--- subversion/branches/javahl-1.15/.github/workflows/autoconf.yml	Sun May 17 17:52:52 2026	(r1934309)
+++ subversion/branches/javahl-1.15/.github/workflows/autoconf.yml	Sun May 17 18:22:26 2026	(r1934310)
@@ -100,7 +100,7 @@ jobs:
 
       - name: Archive test logs
         if: always()
-        uses: actions/upload-artifact@v4
+        uses: actions/upload-artifact@v7
         with:
           name: tests-${{matrix.os}}-${{matrix.check-target}}-${{matrix.httpd}}
           path: |

Modified: subversion/branches/javahl-1.15/.github/workflows/cmake.yml
==============================================================================
--- subversion/branches/javahl-1.15/.github/workflows/cmake.yml	Sun May 17 17:52:52 2026	(r1934309)
+++ subversion/branches/javahl-1.15/.github/workflows/cmake.yml	Sun May 17 18:22:26 2026	(r1934310)
@@ -42,27 +42,27 @@ jobs:
       matrix:
         include:
           - name: Windows, shared, x64, with tests
-            os: windows-latest
+            os: windows-2022
             build_shared: ON
             cmake_generator: Ninja
             vcpkg_triplet: x64-windows
             arch: x64
             run_tests: true
           - name: Windows, shared, x64, vs2022, with tests
-            os: windows-latest
+            os: windows-2022
             build_shared: ON
             cmake_generator: 'Visual Studio 17 2022'
             vcpkg_triplet: x64-windows
             arch: x64
             run_tests: true
           - name: Windows, shared, x86
-            os: windows-latest
+            os: windows-2022
             build_shared: ON
             cmake_generator: Ninja
             vcpkg_triplet: x86-windows
             arch: x86
           - name: Windows, static, x64, with tests
-            os: windows-latest
+            os: windows-2022
             build_shared: OFF
             cmake_generator: Ninja
             vcpkg_triplet: x64-windows-static-md
@@ -115,7 +115,7 @@ jobs:
 
       - name: Restore vcpkg archives (Windows, vcpkg)
         if: runner.os == 'Windows'
-        uses: actions/cache/restore@v4
+        uses: actions/cache/restore@v5
         with:
           path: vcpkg-archives
           key: vcpkg/${{ runner.os }}/${{ matrix.vcpkg_triplet }}/${{ steps.vcpkg-sha.outputs.sha }}
@@ -130,13 +130,13 @@ jobs:
             New-Item $env:VCPKG_DEFAULT_BINARY_CACHE -ItemType Directory | Out-Null
           }
           C:\vcpkg\vcpkg.exe install --triplet ${{ matrix.vcpkg_triplet }} `
-            apr apr-util serf expat zlib sqlite3
+            apr apr-util serf expat zlib sqlite3 gettext[tools] pdcurses
 
           "CMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake" >> $env:GITHUB_ENV
 
       - name: Save vcpkg archives (Windows, vcpkg)
         if: runner.os == 'Windows'
-        uses: actions/cache/save@v4
+        uses: actions/cache/save@v5
         with:
           path: vcpkg-archives
           key: vcpkg/${{ runner.os }}/${{ matrix.vcpkg_triplet }}/${{ steps.vcpkg-sha.outputs.sha }}
@@ -154,14 +154,18 @@ jobs:
           libexpat1-dev
           zlib1g-dev
           libsqlite3-dev
+          apache2-dev
+          gettext
+          libncurses-dev
           ninja-build
           ${{ matrix.extra_packages }}
 
       - name: Install dependencies (Mac OS, homebrew)
         if: runner.os == 'macOS'
         run: |
-          $packages = @('apr', 'apr-util', 'expat', 'sqlite', 'apache-serf')
-          brew install ninja $packages
+          $packages = @('apr', 'apr-util', 'expat', 'sqlite', 'apache-serf',
+                        'gettext', 'ncurses')
+          brew install ninja apache2 $packages
           $PKG_CONFIG_PATH = `
             $packages | `
             % { "$(& brew --prefix $_)/lib/pkgconfig" } | `
@@ -180,10 +184,16 @@ jobs:
 
       - name: Configure CMake
         run: >
+          if ($env:RUNNER_OS -eq 'Windows') {
+            $env:PATH += ";${env:VCPKG_ROOT}\installed\${{ matrix.vcpkg_triplet }}\bin";
+          };
           cmake -B out
           -DBUILD_SHARED_LIBS=${{ matrix.build_shared }}
           -DSVN_ENABLE_TESTS=ON
           -DSVN_ENABLE_RA_SERF=ON
+          -DSVN_ENABLE_NLS=ON
+          -DSVN_ENABLE_APACHE_MODULES=${{ runner.os != 'Windows' && 'ON' || 'OFF' }}
+          -DSVN_ENABLE_TUI=ON
           -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/installdir
           -DVCPKG_TARGET_TRIPLET=${{ matrix.vcpkg_triplet }}
           -DSVN_TEST_CONFIGURE_FOR_PARALLEL=ON

Modified: subversion/branches/javahl-1.15/.github/workflows/detect-backport-conflicts.yml
==============================================================================
--- subversion/branches/javahl-1.15/.github/workflows/detect-backport-conflicts.yml	Sun May 17 17:52:52 2026	(r1934309)
+++ subversion/branches/javahl-1.15/.github/workflows/detect-backport-conflicts.yml	Sun May 17 18:22:26 2026	(r1934310)
@@ -24,9 +24,7 @@ name: backportbot
 
 on:
   push:
-    branches: ["1.14.x"]
-  pull_request:
-    branches: ["1.14.x"]
+    branches: ["1.14.x", "1.15.x"]
 
 concurrency:
   group: ${{ github.workflow }}-${{ github.ref }}
@@ -43,10 +41,13 @@ jobs:
           sudo apt-get update &&
           sudo apt-get install
           subversion
-          
+
+      - name: Obtain tools/dist
+        run: svn export https://svn.apache.org/repos/asf/subversion/trunk/tools/dist tools-dist
+
       - name: Checkout backport branch
-        run: svn co https://svn.apache.org/repos/asf/subversion/branches/1.14.x
+        run: svn co https://svn.apache.org/repos/asf/subversion/branches/${{ github.ref_name }} branch-wc
 
       - name: Detect conflicting backports
-        run: cd 1.14.x && ./tools/dist/detect-conflicting-backports.py
+        run: cd branch-wc && ../tools-dist/detect-conflicting-backports.py
 

Modified: subversion/branches/javahl-1.15/CMakeLists.txt
==============================================================================
--- subversion/branches/javahl-1.15/CMakeLists.txt	Sun May 17 17:52:52 2026	(r1934309)
+++ subversion/branches/javahl-1.15/CMakeLists.txt	Sun May 17 18:22:26 2026	(r1934310)
@@ -298,6 +298,88 @@ if (NOT EXISTS "${CMAKE_SOURCE_DIR}/buil
   )
 endif()
 
+### Intl
+
+if(SVN_ENABLE_NLS)
+  # Note: when installing these dependecies with vcpkg, you will need to
+  # install 'gettext' package with 'tools' feature. Use the following command
+  # for this: `./vcpkg install gettext[tools]`. This package contains both,
+  # Gettext and Intl dependecies.
+  find_package(Gettext REQUIRED)
+  find_package(Intl REQUIRED)
+
+  # If using CMake of version < 3.20, FindIntl would not define IMPORTED target.
+  # https://cmake.org/cmake/help/latest/module/FindIntl.html
+  if(NOT TARGET Intl::Intl)
+    add_library(Intl::Intl INTERFACE IMPORTED)
+    include_directories("${Intl_INCLUDE_DIRS}")
+    set_target_properties(Intl::Intl PROPERTIES
+      INTERFACE_LINK_LIBRARIES "${Intl_LIBRARIES}"
+    )
+  endif()
+
+  add_library(external-intl ALIAS Intl::Intl)
+
+  add_private_config_definition(
+    "Define to 1 if translation of program messages to the user's native language is requested."
+    "ENABLE_NLS" "1"
+  )
+
+  if (NOT WIN32)
+    add_private_config_definition(
+      "Defined to be the path to the installed locale dirs"
+      "SVN_LOCALE_DIR" "\"${CMAKE_INSTALL_PREFIX}/share/locale\""
+    )
+  endif()
+
+  add_custom_target(locale ALL)
+
+  file(GLOB SVN_PO_FILES "subversion/po/*.po")
+
+  foreach(po_file ${SVN_PO_FILES})
+    get_filename_component(lang ${po_file} NAME_WLE)
+    set(mo_file "${CMAKE_BINARY_DIR}/${lang}.mo")
+
+    add_custom_command(
+      DEPENDS
+        "${po_file}"
+      OUTPUT
+        "${mo_file}"
+      COMMAND
+        "${GETTEXT_MSGFMT_EXECUTABLE}" -c -o ${mo_file} ${po_file}
+    )
+
+    target_sources(locale PRIVATE ${mo_file})
+
+    install(
+      FILES "${mo_file}"
+      DESTINATION "share/locale/${lang}/LC_MESSAGES"
+      RENAME "subversion.mo"
+    )
+  endforeach()
+else()
+  # Declare empty target for Intl if we don't use it.
+  add_library(external-intl INTERFACE)
+endif()
+
+# Link all targets with Intl library. The 'external-intl' target is always,
+# even if we don't use NLS functionality.
+#
+# Following the CMake documentation [1], the link_libraries affects only on
+# the targets declared later, so it should be here.
+#
+# [1] https://cmake.org/cmake/help/latest/command/link_libraries.html
+#     -- "Link libraries to all targets added later."
+link_libraries(external-intl)
+
+### Httpd
+
+if(SVN_ENABLE_APACHE_MODULES)
+  find_package(Httpd REQUIRED)
+  add_library(external-libhttpd ALIAS httpd::httpd)
+  add_library(external-mod_dav ALIAS httpd::mod_dav)
+endif()
+
 add_library(ra-libs INTERFACE)
 add_library(fs-libs INTERFACE)
 
@@ -497,14 +579,6 @@ elseif(SVN_ENABLE_TESTS)
   )
 endif()
 
-### Httpd
-
-if(SVN_ENABLE_APACHE_MODULES)
-  find_package(Httpd REQUIRED)
-  add_library(external-libhttpd ALIAS httpd::httpd)
-  add_library(external-mod_dav ALIAS httpd::mod_dav)
-endif()
-
 ### KWallet
 
 if(SVN_ENABLE_AUTH_KWALLET)
@@ -560,7 +634,8 @@ if (SVN_ENABLE_TUI)
     pkg_check_modules(ncurses REQUIRED IMPORTED_TARGET ncurses)
     target_link_libraries(external-ncurses INTERFACE PkgConfig::ncurses)
   else()
-    message(SEND_ERROR "not supported")
+    find_package(CURSES REQUIRED)
+    target_link_libraries(external-ncurses INTERFACE CURSES::CURSES)
   endif()
 endif()
 
@@ -788,78 +863,6 @@ if (MSVC)
   )
 endif()
 
-if(SVN_ENABLE_NLS)
-  # Note: when installing these dependecies with vcpkg, you will need to
-  # install 'gettext' package with 'tools' feature. Use the following command
-  # for this: `./vcpkg install gettext[tools]`. This package contains both,
-  # Gettext and Intl dependecies.
-  find_package(Gettext REQUIRED)
-  find_package(Intl REQUIRED)
-
-  # If using CMake of version < 3.20, FindIntl would not define IMPORTED target.
-  # https://cmake.org/cmake/help/latest/module/FindIntl.html
-  if(NOT TARGET Intl::Intl)
-    add_library(Intl::Intl INTERFACE IMPORTED)
-    set_target_properties(Intl::Intl PROPERTIES
-      INTERFACE_INCLUDE_DIRECTORIES "${Intl_INCLUDE_DIRS}"
-      INTERFACE_LINK_LIBRARIES "${Intl_LIBRARIES}"
-    )
-  endif()
-
-  add_library(external-intl ALIAS Intl::Intl)
-
-  add_private_config_definition(
-    "Define to 1 if translation of program messages to the user's native language is requested."
-    "ENABLE_NLS" "1"
-  )
-
-  if (NOT WIN32)
-    add_private_config_definition(
-      "Defined to be the path to the installed locale dirs"
-      "SVN_LOCALE_DIR" "\"${CMAKE_INSTALL_PREFIX}/share/locale\""
-    )
-  endif()
-
-  add_custom_target(locale ALL)
-
-  file(GLOB SVN_PO_FILES "subversion/po/*.po")
-
-  foreach(po_file ${SVN_PO_FILES})
-    get_filename_component(lang ${po_file} NAME_WLE)
-    set(mo_file "${CMAKE_BINARY_DIR}/${lang}.mo")
-
-    add_custom_command(
-      DEPENDS
-        "${po_file}"
-      OUTPUT
-        "${mo_file}"
-      COMMAND
-        "${GETTEXT_MSGFMT_EXECUTABLE}" -c -o ${mo_file} ${po_file}
-    )
-
-    target_sources(locale PRIVATE ${mo_file})
-
-    install(
-      FILES "${mo_file}"
-      DESTINATION "share/locale/${lang}/LC_MESSAGES"
-      RENAME "subversion.mo"
-    )
-  endforeach()
-else()
-  # Declare empty target for Intl if we don't use it.
-  add_library(external-intl INTERFACE)
-endif()
-
-# Link all targets with Intl library. The 'external-intl' target is always,
-# even if we don't use NLS functionality.
-#
-# Following the CMake documentation [1], the link_libraries affects only on
-# the targets declared later, so it should be here.
-#
-# [1] https://cmake.org/cmake/help/latest/command/link_libraries.html
-#     -- "Link libraries to all targets added later."
-link_libraries(external-intl)
-
 # Build shared libraries and theirs implibs with 'lib' prefix, for example
 # libsvn_subr-1.[lib|a] and libsvn_subr-1.[dll|so]
 set(CMAKE_SHARED_LIBRARY_PREFIX "lib")

Modified: subversion/branches/javahl-1.15/COMMITTERS
==============================================================================
--- subversion/branches/javahl-1.15/COMMITTERS	Sun May 17 17:52:52 2026	(r1934309)
+++ subversion/branches/javahl-1.15/COMMITTERS	Sun May 17 18:22:26 2026	(r1934310)
@@ -46,7 +46,6 @@ Blanket commit access:
       arfrever   Arfrever Frehtes Taifersar Arahesis <[email protected]>
           stsp   Stefan Sperling <[email protected]>
            kou   Kouhei Sutou <[email protected]>
-      danielsh   Daniel Shahaf <[email protected]>
         peters   Peter Samuelson <[email protected]>
       rhuijben   Bert Huijben <[email protected]>
       stylesen   Senthil Kumaran S <[email protected]>
@@ -87,6 +86,7 @@ Full committers who have asked to be lis
          naked   Nuutti Kotivuori <[email protected]>
      ringstrom   Tobias Ringström <tobias-cF8t/[email protected]>
       luke1410   Stefan Hett <[email protected]>
+      danielsh   Daniel Shahaf <[email protected]>
 
 
 Partial committers who have asked to be listed as dormant:

Modified: subversion/branches/javahl-1.15/INSTALL
==============================================================================
--- subversion/branches/javahl-1.15/INSTALL	Sun May 17 17:52:52 2026	(r1934309)
+++ subversion/branches/javahl-1.15/INSTALL	Sun May 17 18:22:26 2026	(r1934310)
@@ -848,6 +848,11 @@ II.   INSTALLATION
   E.  Building the Latest Source under Windows
       ----------------------------------------
 
+      Windows users may find it easier to build Subversion using CMake and
+      vcpkg (see section F below).
+
+      The following procedure does not use CMake or vcpkg.
+
   E.1 Prerequisites
 
       * Microsoft Visual Studio. Any recent (2005+) version containing the
@@ -1194,9 +1199,8 @@ II.   INSTALLATION
   F.  Building using CMake
       --------------------
 
-      Get the sources, either a release tarball or by checking out the
-      official repository. The CMake build system currently only exists in
-      /trunk and it will be included in the 1.15 release.
+      Get the sources, either from a release tarball or by checking out the
+      official repository.
 
       The process for building on Unix and Windows is the same.
 
@@ -1204,11 +1208,14 @@ II.   INSTALLATION
           $ cmake -B out [build options]
           $ cmake --build out
 
+      Note: If you're using the tarball distribution, the first gen-make step
+      can be skipped.
+
       "out" in the commands above is the build directory used by CMake.
 
       Build options can be added, for example:
 
-          $ cmake -B out -DCMAKE_INSTALL_PREFIX=/usr/local/subversion -DSVN_ENABLE_RA_SERF=ON
+          $ cmake -B out -DCMAKE_INSTALL_PREFIX=/usr/local/subversion -DSVN_ENABLE_TESTS=ON
 
       Build options can be listed using:
 

Copied: subversion/branches/javahl-1.15/build/cmake/FindCURSES.cmake (from r1934309, subversion/trunk/build/cmake/FindCURSES.cmake)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ subversion/branches/javahl-1.15/build/cmake/FindCURSES.cmake	Sun May 17 18:22:26 2026	(r1934310, copy of r1934309, subversion/trunk/build/cmake/FindCURSES.cmake)
@@ -0,0 +1,52 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# FindCURSES.cmake -- Find the curses library
+#
+
+find_path(CURSES_INCLUDE_DIR
+  NAMES curses.h
+  PATH_SUFFIXES
+    include
+)
+
+find_library(CURSES_LIBRARY
+  NAMES ncurses pdcurses curses 
+  PATH_SUFFIXES lib
+)
+
+mark_as_advanced(
+  CURSES_INCLUDE_DIR
+  CURSES_LIBRARY
+)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(
+  CURSES
+  REQUIRED_VARS
+    CURSES_LIBRARY
+    CURSES_INCLUDE_DIR
+)
+
+if (CURSES_FOUND)
+  add_library(CURSES::CURSES IMPORTED STATIC)
+  set_target_properties(CURSES::CURSES PROPERTIES
+    IMPORTED_LOCATION ${CURSES_LIBRARY}
+    INTERFACE_INCLUDE_DIRECTORIES ${CURSES_INCLUDE_DIR}
+  )
+endif()

Modified: subversion/branches/javahl-1.15/build/cmake/FindHttpd.cmake
==============================================================================
--- subversion/branches/javahl-1.15/build/cmake/FindHttpd.cmake	Sun May 17 17:52:52 2026	(r1934309)
+++ subversion/branches/javahl-1.15/build/cmake/FindHttpd.cmake	Sun May 17 18:22:26 2026	(r1934310)
@@ -1,62 +1,123 @@
-find_path(HTTPD_INCLUDE_DIR
-  NAMES httpd.h
-  PATH_SUFFIXES
-    include
-)
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# FindHttpd.cmake -- CMake module for Httpd library
+#
+
+include(GNUInstallDirs)
+
+if(WIN32)
+  find_path(HTTPD_INCLUDE_DIR
+    NAMES httpd.h
+    PATH_SUFFIXES
+      include
+  )
 
-find_library(HTTPD_LIBRARY
-  NAMES libhttpd
-  PATH_SUFFIXES lib
-)
+  find_library(HTTPD_LIBRARY
+    NAMES libhttpd
+    PATH_SUFFIXES lib
+  )
 
-find_file(HTTPD_DLL
-  NAMES libhttpd.dll
-  PATH_SUFFIXES bin
-)
+  find_library(MOD_DAV_LIBRARY
+    NAMES mod_dav
+    PATH_SUFFIXES lib
+  )
 
-find_library(MOD_DAV_LIBRARY
-  NAMES mod_dav
-  PATH_SUFFIXES lib
-)
+  if (HTTPD_INCLUDE_DIR AND EXISTS "${HTTPD_INCLUDE_DIR}/ap_release.h")
+    file(
+      STRINGS "${HTTPD_INCLUDE_DIR}/ap_release.h" VERSION_STRINGS
+      REGEX "#define (AP_SERVER_MAJORVERSION_NUMBER|AP_SERVER_MINORVERSION_NUMBER|AP_SERVER_PATCHLEVEL_NUMBER)"
+    )
 
-if (HTTPD_INCLUDE_DIR AND EXISTS "${HTTPD_INCLUDE_DIR}/ap_release.h")
-  file(
-    STRINGS "${HTTPD_INCLUDE_DIR}/ap_release.h" VERSION_STRINGS
-    REGEX "#define (AP_SERVER_MAJORVERSION_NUMBER|AP_SERVER_MINORVERSION_NUMBER|AP_SERVER_PATCHLEVEL_NUMBER)"
-  )
+    string(REGEX REPLACE ".*AP_SERVER_MAJORVERSION_NUMBER +([0-9]+).*" "\\1" HTTPD_VERSION_MAJOR ${VERSION_STRINGS})
+    string(REGEX REPLACE ".*AP_SERVER_MINORVERSION_NUMBER +([0-9]+).*" "\\1" HTTPD_VERSION_MINOR ${VERSION_STRINGS})
+    string(REGEX REPLACE ".*AP_SERVER_PATCHLEVEL_NUMBER +([0-9]+).*" "\\1" HTTPD_VERSION_PATCH ${VERSION_STRINGS})
 
-  string(REGEX REPLACE ".*AP_SERVER_MAJORVERSION_NUMBER +([0-9]+).*" "\\1" HTTPD_VERSION_MAJOR ${VERSION_STRINGS})
-  string(REGEX REPLACE ".*AP_SERVER_MINORVERSION_NUMBER +([0-9]+).*" "\\1" HTTPD_VERSION_MINOR ${VERSION_STRINGS})
-  string(REGEX REPLACE ".*AP_SERVER_PATCHLEVEL_NUMBER +([0-9]+).*" "\\1" HTTPD_VERSION_PATCH ${VERSION_STRINGS})
+    set(HTTPD_VERSION "${HTTPD_VERSION_MAJOR}.${HTTPD_VERSION_MINOR}.${HTTPD_VERSION_PATCH}")
+  endif()
+  set(_httpd_modules_dir "${CMAKE_INSTALL_BINDIR}")
+
+else()
+  find_program(APXS_EXECUTABLE
+               NAMES apxs2 apxs
+               PATH /usr/local/apache2/bin /usr/local/apache/bin /usr/bin /usr/sbin)
+
+  function(_APXS_CONFIG_VAR VARNAME OUTVAR)
+    execute_process(COMMAND "${APXS_EXECUTABLE}" -q ${VARNAME}
+                    RESULT_VARIABLE _APXS_SUCCESS
+                    OUTPUT_VARIABLE _APXS_OUTPUT
+                    OUTPUT_STRIP_TRAILING_WHITESPACE
+                    ERROR_QUIET)
+    set(${OUTVAR} "${_APXS_OUTPUT}" PARENT_SCOPE)
+  endfunction()
+
+  if(APXS_EXECUTABLE)
+    _APXS_CONFIG_VAR("HTTPD_VERSION" HTTPD_VERSION)
+    _APXS_CONFIG_VAR("INCLUDEDIR" HTTPD_INCLUDE_DIR)
+    set(_httpd_modules_dir "${CMAKE_INSTALL_LIBEXECDIR}")
+    set(HTTPD_FOUND TRUE)
+  endif()
 
-  set(HTTPD_VERSION "${HTTPD_VERSION_MAJOR}.${HTTPD_VERSION_MINOR}.${HTTPD_VERSION_PATCH}")
 endif()
 
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(
+set(HTTPD_MODULES_DIR "${_httpd_modules_dir}"
+    CACHE PATH "Install directory for Apache modules")
+
+find_package_handle_standard_args(
   Httpd
   REQUIRED_VARS
-    HTTPD_LIBRARY
     HTTPD_INCLUDE_DIR
-    MOD_DAV_LIBRARY
+    HTTPD_MODULES_DIR
   VERSION_VAR
     HTTPD_VERSION
 )
 
 if(HTTPD_FOUND)
   if(NOT TARGET httpd::httpd)
-    add_library(httpd::httpd SHARED IMPORTED)
+    add_library(httpd::httpd INTERFACE IMPORTED)
     set_target_properties(httpd::httpd PROPERTIES
       INTERFACE_INCLUDE_DIRECTORIES ${HTTPD_INCLUDE_DIR}
-      IMPORTED_LOCATION ${HTTPD_DLL}
-      IMPORTED_IMPLIB ${HTTPD_LIBRARY}
     )
+    if(WIN32)
+      set_target_properties(httpd::httpd PROPERTIES
+        INTERFACE_LINK_LIBRARIES ${HTTPD_LIBRARY}
+      )
+    elseif(APPLE)
+      target_link_options(httpd::httpd INTERFACE
+        "-Wl,-undefined,dynamic_lookup"
+      )
+    endif()
   endif()
 
   if(NOT TARGET httpd::mod_dav)
-    add_library(httpd::mod_dav STATIC IMPORTED)
+    add_library(httpd::mod_dav INTERFACE IMPORTED)
     set_target_properties(httpd::mod_dav PROPERTIES
       INTERFACE_INCLUDE_DIRECTORIES ${HTTPD_INCLUDE_DIR}
-      IMPORTED_LOCATION ${MOD_DAV_LIBRARY}
     )
+    if(WIN32)
+      set_target_properties(httpd::mod_dav PROPERTIES
+        INTERFACE_LINK_LIBRARIES ${MOD_DAV_LIBRARY}
+      )
+    elseif(APPLE)
+      target_link_options(httpd::mod_dav INTERFACE
+        "-Wl,-undefined,dynamic_lookup"
+      )
+    endif()
   endif()
+
 endif()

Modified: subversion/branches/javahl-1.15/build/generator/templates/targets.cmake.ezt
==============================================================================
--- subversion/branches/javahl-1.15/build/generator/templates/targets.cmake.ezt	Sun May 17 17:52:52 2026	(r1934309)
+++ subversion/branches/javahl-1.15/build/generator/templates/targets.cmake.ezt	Sun May 17 18:22:26 2026	(r1934310)
@@ -49,7 +49,10 @@ if ([targets.enable_condition])[is targe
     [targets.msvc_export][end]
   )[end]
   set_target_properties([targets.name] PROPERTIES OUTPUT_NAME "[targets.output_name]")[if-any targets.is_apache_mod]
-  set_target_properties([targets.name] PROPERTIES PREFIX "" SUFFIX ".so")[else]
+  set_target_properties([targets.name] PROPERTIES PREFIX "" SUFFIX ".so")
+  if(WIN32)
+    set_target_properties([targets.name] PROPERTIES IMPORT_PREFIX "")
+  endif()[else]
   set_target_properties([targets.name] PROPERTIES SOVERSION "${SVN_SOVERSION}" VERSION "${SVN_SOVERSION}.${SVN_VER_MINOR}.${SVN_VER_PATCH}")[end]
   target_include_directories([targets.name] PUBLIC
     "${CMAKE_CURRENT_SOURCE_DIR}/subversion/include"
@@ -91,6 +94,8 @@ if ([targets.enable_condition])[is targe
   if (WIN32)
     target_sources([targets.name] PRIVATE build/win32/svn.rc)
   endif()[if-any targets.install_target]
-  install(TARGETS [targets.name])[end][end]
+  install(TARGETS [targets.name][if-any targets.is_apache_mod]
+    LIBRARY DESTINATION "${HTTPD_MODULES_DIR}"
+  [end])[end][end]
 endif()
 [end]

Modified: subversion/branches/javahl-1.15/subversion/libsvn_subr/config_file.c
==============================================================================
--- subversion/branches/javahl-1.15/subversion/libsvn_subr/config_file.c	Sun May 17 17:52:52 2026	(r1934309)
+++ subversion/branches/javahl-1.15/subversion/libsvn_subr/config_file.c	Sun May 17 18:22:26 2026	(r1934310)
@@ -610,7 +610,7 @@ svn_config__sys_config_path(const char *
   {
     char folder[B_PATH_NAME_LENGTH];
 
-    status_t error = find_directory(B_COMMON_SETTINGS_DIRECTORY, -1, false,
+    status_t error = find_directory(B_SYSTEM_SETTINGS_DIRECTORY, -1, false,
                                     folder, sizeof(folder));
     if (error)
       return SVN_NO_ERROR;

Modified: subversion/branches/javahl-1.15/subversion/libsvn_subr/utf.c
==============================================================================
--- subversion/branches/javahl-1.15/subversion/libsvn_subr/utf.c	Sun May 17 17:52:52 2026	(r1934309)
+++ subversion/branches/javahl-1.15/subversion/libsvn_subr/utf.c	Sun May 17 18:22:26 2026	(r1934310)
@@ -1048,7 +1048,8 @@ membuf_insert_ucs4(svn_membuf_t *buf, ap
   ((apr_int32_t*)buf->data)[offset] = value;
 }
 
-/* TODO: Use compiler intrinsics for byte swaps. */
+/* Modern compilers with -O2 optimise it out and replace these with special
+ * instructions (bswap or rev). */
 #define SWAP_SHORT(x)  ((((x) & 0xff) << 8) | (((x) >> 8) & 0xff))
 #define SWAP_LONG(x)   ((((x) & 0xff) << 24) | (((x) & 0xff00) << 8)    \
                         | (((x) >> 8) & 0xff00) | (((x) >> 24) & 0xff))

Modified: subversion/branches/javahl-1.15/subversion/svnbrowse/model.c
==============================================================================
--- subversion/branches/javahl-1.15/subversion/svnbrowse/model.c	Sun May 17 17:52:52 2026	(r1934309)
+++ subversion/branches/javahl-1.15/subversion/svnbrowse/model.c	Sun May 17 18:22:26 2026	(r1934310)
@@ -85,12 +85,12 @@ sort_item_comparison_func(const void *le
 }
 
 svn_error_t *
-svn_browse__state_create(svn_browse__state_t **state_p,
-                         svn_ra_session_t *session,
-                         const char *relpath,
-                         svn_revnum_t revision,
-                         apr_pool_t *result_pool,
-                         apr_pool_t *scratch_pool)
+state_from_dir(svn_browse__state_t **state_p,
+               svn_ra_session_t *session,
+               const char *relpath,
+               svn_revnum_t revision,
+               apr_pool_t *result_pool,
+               apr_pool_t *scratch_pool)
 {
   svn_browse__state_t *state = apr_pcalloc(result_pool, sizeof(*state));
   svn_revnum_t fetched_revnum;
@@ -100,6 +100,7 @@ svn_browse__state_create(svn_browse__sta
   SVN_ERR(svn_ra_get_dir2(session, &dirents, &fetched_revnum, NULL, relpath,
                           revision, SVN_DIRENT_ALL, scratch_pool));
 
+  state->type = svn_browse__state_dir;
   state->relpath = apr_pstrdup(result_pool, relpath);
   state->revision = fetched_revnum;
   state->selection = 0;
@@ -129,6 +130,51 @@ svn_browse__state_create(svn_browse__sta
 }
 
 svn_error_t *
+state_from_file(svn_browse__state_t **state_p,
+                svn_ra_session_t *session,
+                const char *relpath,
+                svn_revnum_t revision,
+                apr_pool_t *result_pool,
+                apr_pool_t *scratch_pool)
+{
+  svn_browse__state_t *state = apr_pcalloc(result_pool, sizeof(*state));
+  svn_revnum_t fetched_revnum;
+  apr_hash_index_t *hi;
+  svn_dirent_t *dirent;
+
+  SVN_ERR(svn_ra_stat(session, relpath, revision, &dirent, scratch_pool));
+
+  state->type = svn_browse__state_file;
+  state->relpath = apr_pstrdup(result_pool, relpath);
+  state->revision = fetched_revnum;
+  state->this_dirent = svn_dirent_dup(dirent, result_pool);
+  state->pool = result_pool;
+
+  *state_p = state;
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_browse__state_create(svn_browse__state_t **state_p,
+                         svn_ra_session_t *session,
+                         const char *relpath,
+                         svn_revnum_t revision,
+                         apr_pool_t *result_pool,
+                         apr_pool_t *scratch_pool)
+{
+  svn_error_t *err;
+
+  err = state_from_dir(state_p, session, relpath, revision, result_pool,
+                       scratch_pool);
+
+  if (err && err->apr_err == SVN_ERR_FS_NOT_DIRECTORY)
+    return svn_error_trace(state_from_file(state_p, session, relpath, revision,
+                                           result_pool, scratch_pool));
+  else
+    return svn_error_trace(err);
+}
+
+svn_error_t *
 svn_browse__model_enter_path(svn_browse__model_t *ctx, const char *relpath,
                  apr_pool_t *scratch_pool)
 {

Modified: subversion/branches/javahl-1.15/subversion/svnbrowse/svnbrowse.c
==============================================================================
--- subversion/branches/javahl-1.15/subversion/svnbrowse/svnbrowse.c	Sun May 17 17:52:52 2026	(r1934309)
+++ subversion/branches/javahl-1.15/subversion/svnbrowse/svnbrowse.c	Sun May 17 18:22:26 2026	(r1934310)
@@ -37,6 +37,7 @@
 #include <curses.h>
 
 #include "svn_private_config.h"
+#include "svn_time.h"
 #include "svnbrowse.h"
 
 /* Option codes and descriptions for the command line client.
@@ -263,22 +264,9 @@ view_on_event(svn_browse__view_t *view,
    * 3. The rest of keys remain as their equivalents on the current layout.
    * 4. If shift is held, they just become uppercased.
    */
+
   switch (ch)
     {
-      case KEY_UP:
-      case 'k':
-      case CTRL('p'):
-        SVN_ERR(svn_browse__model_move_selection(view->model, -1));
-        break;
-      case KEY_DOWN:
-      case 'j':
-      case CTRL('n'):
-        SVN_ERR(svn_browse__model_move_selection(view->model, 1));
-        break;
-      case '\n':
-      case '\r':
-        SVN_ERR(svn_browse__model_go_enter(view->model, scratch_pool));
-        break;
       case KEY_BACKSPACE:
       case '-':
       case 'u':
@@ -286,45 +274,72 @@ view_on_event(svn_browse__view_t *view,
         view->model->current->scroller_offset =
             view->model->current->selection - scrollsize / 2;
         break;
-      case CTRL('e'):
-        view->model->current->scroller_offset += 1;
-        break;
-      case CTRL('y'):
-        view->model->current->scroller_offset -= 1;
-        break;
-      case CTRL('d'):
-        SVN_ERR(svn_browse__model_move_selection(view->model, scrollsize / 2));
-        break;
-      case CTRL('f'):
-      case KEY_NPAGE:
-        SVN_ERR(svn_browse__model_move_selection(view->model, scrollsize));
-        break;
-      case CTRL('u'):
-        SVN_ERR(svn_browse__model_move_selection(view->model, -scrollsize / 2));
-        break;
-      case CTRL('b'):
-      case KEY_PPAGE:
-        SVN_ERR(svn_browse__model_move_selection(view->model, -scrollsize));
-        break;
-      case 'g':
-      case KEY_HOME:
-        view->model->current->selection = 0;
-        break;
-      case 'G':
-      case KEY_END:
-        view->model->current->selection =
-            view->model->current->list->nelts - 1;
-        break;
-      case 'z':
-        view->model->current->scroller_offset =
-            view->model->current->selection - scrollsize / 2;
-        break;
       case 'q':
       case KEY_ESC:
         return svn_error_create(SVN_ERR_CANCELLED, NULL, NULL);
+      default:
+        break;
     }
 
-  SVN_ERR(svn_browse__model_scroll_in_view(view->model, scrollsize));
+  if (view->model->current->type == svn_browse__state_dir)
+    {
+      switch (ch)
+        {
+          case KEY_UP:
+          case 'k':
+          case CTRL('p'):
+            SVN_ERR(svn_browse__model_move_selection(view->model, -1));
+            break;
+          case KEY_DOWN:
+          case 'j':
+          case CTRL('n'):
+            SVN_ERR(svn_browse__model_move_selection(view->model, 1));
+            break;
+          case '\n':
+          case '\r':
+            SVN_ERR(svn_browse__model_go_enter(view->model, scratch_pool));
+            break;
+          case CTRL('e'):
+            view->model->current->scroller_offset += 1;
+            break;
+          case CTRL('y'):
+            view->model->current->scroller_offset -= 1;
+            break;
+          case CTRL('d'):
+            SVN_ERR(svn_browse__model_move_selection(view->model,
+                                                     scrollsize / 2));
+            break;
+          case CTRL('f'):
+          case KEY_NPAGE:
+            SVN_ERR(svn_browse__model_move_selection(view->model,
+                                                     scrollsize));
+            break;
+          case CTRL('u'):
+            SVN_ERR(svn_browse__model_move_selection(view->model,
+                                                     -scrollsize / 2));
+            break;
+          case CTRL('b'):
+          case KEY_PPAGE:
+            SVN_ERR(svn_browse__model_move_selection(view->model,
+                                                     -scrollsize));
+            break;
+          case 'g':
+          case KEY_HOME:
+            view->model->current->selection = 0;
+            break;
+          case 'G':
+          case KEY_END:
+            view->model->current->selection =
+                view->model->current->list->nelts - 1;
+            break;
+          case 'z':
+            view->model->current->scroller_offset =
+                view->model->current->selection - scrollsize / 2;
+            break;
+        }
+
+      SVN_ERR(svn_browse__model_scroll_in_view(view->model, scrollsize));
+    }
 
   return SVN_NO_ERROR;
 }
@@ -494,6 +509,15 @@ format_percentage_scroll(int scroll, int
     }
 }
 
+static int
+view_get_list_height(const svn_browse__state_t *state)
+{
+  if (state->type == svn_browse__state_dir)
+    return state->list->nelts;
+  else
+    return 0;
+}
+
 static void
 view_draw_footer(svn_browse__view_t *view, WINDOW *win,
                  apr_pool_t *scratch_pool)
@@ -508,26 +532,24 @@ view_draw_footer(svn_browse__view_t *vie
                         getmaxx(win) - 4 - strlen(brand) - 16,
                         scratch_pool));
   waddstr(win, brand);
+
   waddstr(win, leftpad(apr_psprintf(scratch_pool, "%d/%d",
-                                    state->selection + 1, state->list->nelts),
+                                    state->selection + 1,
+                                    view_get_list_height(state)),
                        8, scratch_pool));
   waddstr(win, leftpad(format_percentage_scroll(state->scroller_offset,
-                                                state->list->nelts,
+                                                view_get_list_height(state),
                                                 getmaxy(view->list),
                                                 scratch_pool),
                        8, scratch_pool));
   waddstr(win, "  ");
 }
 
-
 static void
-view_draw(svn_browse__view_t *view, apr_pool_t *pool)
+dir_draw(svn_browse__view_t *view, apr_pool_t *pool)
 {
   int i;
 
-  view_draw_header(view, view->header, pool);
-  view_draw_footer(view, view->footer, pool);
-
   for (i = 0; i < view->model->current->list->nelts; i++)
     {
       svn_browse__item_t *item = APR_ARRAY_IDX(view->model->current->list, i,
@@ -540,6 +562,39 @@ view_draw(svn_browse__view_t *view, apr_
     }
 }
 
+static void
+file_draw(svn_browse__view_t *view, apr_pool_t *pool)
+{
+  const svn_browse__state_t *state = view->model->current;
+
+  mvwprintw(view->list, 0, 0, " File: %s",
+            svn_relpath_basename(state->relpath, pool));
+
+  mvwprintw(view->list, 1, 0, " Last Changed Rev: %ld",
+            state->this_dirent->created_rev);
+  mvwprintw(view->list, 2, 0, " Last Changed Author: %s",
+            state->this_dirent->last_author);
+  mvwprintw(view->list, 3, 0, " Last Changed Date: %s",
+            svn_time_to_human_cstring(state->this_dirent->time, pool));
+}
+
+static void
+view_draw(svn_browse__view_t *view, apr_pool_t *pool)
+{
+  view_draw_header(view, view->header, pool);
+  view_draw_footer(view, view->footer, pool);
+
+  switch (view->model->current->type)
+    {
+      case svn_browse__state_dir:
+        dir_draw(view, pool);
+        break;
+      case svn_browse__state_file:
+        file_draw(view, pool);
+        break;
+    }
+}
+
 static svn_error_t *
 show_usage(apr_pool_t *scratch_pool)
 {

Modified: subversion/branches/javahl-1.15/subversion/svnbrowse/svnbrowse.h
==============================================================================
--- subversion/branches/javahl-1.15/subversion/svnbrowse/svnbrowse.h	Sun May 17 17:52:52 2026	(r1934309)
+++ subversion/branches/javahl-1.15/subversion/svnbrowse/svnbrowse.h	Sun May 17 18:22:26 2026	(r1934310)
@@ -68,15 +68,26 @@ typedef struct svn_browse__item_t {
   const svn_dirent_t *dirent;
 } svn_browse__item_t;
 
+typedef enum svn_browse__state_type_e {
+  svn_browse__state_dir,
+  svn_browse__state_file,
+} svn_browse__state_type_e;
+
 /* a state of a single directory */
 typedef struct svn_browse__state_t {
+  svn_browse__state_type_e type;
+
   /* information about this node */
   const char *relpath;
   svn_revnum_t revision;
 
-  /* stores the list of nodes in this state; an array of svn_browse__item_t */
+  /* stores the list of nodes in this state; an array of svn_browse__item_t or
+   * NULL if 'type' is set to svn_browse__state_file */
   apr_array_header_t *list;
 
+  /* only available for files */
+  const svn_dirent_t *this_dirent;
+
   /* the index of hovered item */
   int selection;
   int scroller_offset;

Modified: subversion/branches/javahl-1.15/subversion/tests/libsvn_subr/utf-test.c
==============================================================================
--- subversion/branches/javahl-1.15/subversion/tests/libsvn_subr/utf-test.c	Sun May 17 17:52:52 2026	(r1934309)
+++ subversion/branches/javahl-1.15/subversion/tests/libsvn_subr/utf-test.c	Sun May 17 18:22:26 2026	(r1934310)
@@ -228,7 +228,8 @@ test_utf_cstring_to_utf8_ex2(apr_pool_t
       const char *from_page;
   } tests[] = {
       {"ascii text\n", "ascii text\n", "unexistent-page"},
-      {"Edelwei\xdf", "Edelwei\xc3\x9f", "ISO-8859-1"}
+      {"Edelwei\xdf", "Edelwei\xc3\x9f", "ISO-8859-1"},
+      {"abc\xF0\x9F\x98\x80", "abc\xF0\x9F\x98\x80", "UTF-8"}
   };
 
   for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
@@ -268,7 +269,8 @@ test_utf_cstring_from_utf8_ex2(apr_pool_
       const char *to_page;
   } tests[] = {
       {"ascii text\n", "ascii text\n", "unexistent-page"},
-      {"Edelwei\xc3\x9f", "Edelwei\xdf", "ISO-8859-1"}
+      {"Edelwei\xc3\x9f", "Edelwei\xdf", "ISO-8859-1"},
+      {"abc\xF0\x9F\x98\x80", "abc\xF0\x9F\x98\x80", "UTF-8"}
   };
 
   for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)

Modified: subversion/branches/javahl-1.15/tools/dist/detect-conflicting-backports.py
==============================================================================
--- subversion/branches/javahl-1.15/tools/dist/detect-conflicting-backports.py	Sun May 17 17:52:52 2026	(r1934309)
+++ subversion/branches/javahl-1.15/tools/dist/detect-conflicting-backports.py	Sun May 17 18:22:26 2026	(r1934310)
@@ -86,7 +86,7 @@ for entry_para in sf.entries_paras():
     if backport.merger.svn_version() < (1,6):
       output = re.compile('^(......)', re.MULTILINE).sub(r'\1 ', output)
 
-    pattern = re.compile(r'(?:C......|.C.....|......C)\s(.*)', re.MULTILINE)
+    pattern = re.compile(r'^(?:C......|.C.....|......C)\s(.*)$', re.MULTILINE)
     conflicts = pattern.findall(output)
     if conflicts and not entry.depends:
       if len(conflicts) == 1:
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.