On Mon, May 25, 2026 at 4:56 AM Timofei Zhakov <[email protected]> wrote:
> On Sun, May 24, 2026 at 2:52 AM <[email protected]> wrote: > >> Author: brane >> Date: Sun May 24 00:52:17 2026 >> New Revision: 1934546 >> >> Log: >> Add svnbrowse to the autotools build. >> >> Building svnbrowse is optional and can be enabled with --enable-svnbrowse. >> When enabled, --with-ncurses can be used to find the ncurses installation. >> >> * Makefile.in >> (SVN_NCURSES_LIBS, >> SVN_NCURSES_INCLUDES, >> SVN_BUILD_SVNBROWSE, >> INSTALL_TUI, >> tuidir): Add variabkle expansion placeholders. >> * aclocal.m4.in: Include build/ac-macros/svnbrowse.m4. >> * build.conf (svnbrowse): Add description, conditional-compile symbol >> and compilation command. The latter is required because conditional >> compilation doesn't work without it. >> * configure.ac: Call the SVN_SVNBROWSE function. >> (BUILD_RULES): Include the 'tui' target. >> (INSTALL_STATIC_RULES): Include the 'install-tui' target. >> * build/ac-macros/svnbrowse.m4: New file. >> (SVN_SVNBROWSE, SVN_NCURSES_PREFIX, SVN_NCURSES_PKG_CONFIG): New >> functions. >> * build/generator/templates/build-outputs.mk.ezt >> [for deps]: Fix the scope of the [if-any deps.cmd] conditional. >> >> * subversion/svnbrowse/svnbrowse.h: Make the header idempotent. >> * subversion/svnbrowse/svnbrowse.c: >> Include external library headers before our own headers. >> (view_on_event): Fix compilation error due to using mixed declarations >> and statements, which is a C99 feature. >> >> Added: >> subversion/trunk/build/ac-macros/svnbrowse.m4 (contents, props >> changed) >> Modified: >> subversion/trunk/Makefile.in >> subversion/trunk/aclocal.m4.in >> subversion/trunk/build.conf >> subversion/trunk/build/generator/templates/build-outputs.mk.ezt >> subversion/trunk/configure.ac >> subversion/trunk/subversion/svnbrowse/svnbrowse.c >> subversion/trunk/subversion/svnbrowse/svnbrowse.h >> >> Modified: subversion/trunk/Makefile.in >> >> ============================================================================== >> --- subversion/trunk/Makefile.in Sun May 24 00:00:12 2026 >> (r1934545) >> +++ subversion/trunk/Makefile.in Sun May 24 00:52:17 2026 >> (r1934546) >> @@ -54,6 +54,7 @@ SVN_SERF_LIBS = @SVN_SERF_LIBS@ >> SVN_SQLITE_LIBS = @SVN_SQLITE_LIBS@ >> SVN_XML_LIBS = @SVN_XML_LIBS@ >> SVN_ZLIB_LIBS = @SVN_ZLIB_LIBS@ >> +SVN_NCURSES_LIBS = @SVN_NCURSES_LIBS@ >> SVN_LZ4_LIBS = @SVN_LZ4_LIBS@ >> SVN_UTF8PROC_LIBS = @SVN_UTF8PROC_LIBS@ >> SVN_MACOS_PLIST_LIBS = @SVN_MACOS_PLIST_LIBS@ >> @@ -72,6 +73,7 @@ gpg_agent_libdir = @libdir@ >> kwallet_libdir = @libdir@ >> serf_libdir = @libdir@ >> bindir = @bindir@ >> +tuidir = @bindir@ >> includedir = @includedir@ >> mandir = @mandir@ >> srcdir = @srcdir@ >> @@ -138,7 +140,7 @@ INCLUDES = -I$(top_srcdir)/subversion/in >> @SVN_KWALLET_INCLUDES@ @SVN_MAGIC_INCLUDES@ \ >> @SVN_SASL_INCLUDES@ @SVN_SERF_INCLUDES@ @SVN_SQLITE_INCLUDES@ >> \ >> @SVN_XML_INCLUDES@ @SVN_ZLIB_INCLUDES@ @SVN_LZ4_INCLUDES@ \ >> - @SVN_UTF8PROC_INCLUDES@ >> + @SVN_UTF8PROC_INCLUDES@ @SVN_NCURSES_INCLUDES@ >> >> APACHE_INCLUDES = @APACHE_INCLUDES@ >> APACHE_LIBEXECDIR = $(DESTDIR)@APACHE_LIBEXECDIR@ >> @@ -171,6 +173,7 @@ CTYPES_PYTHON_SRC_DIR = $(abs_srcdir)/su >> JAVAHL_JAR=subversion/bindings/javahl/svn-javahl.jar >> JAVAHL_INCLUDES= @JNI_INCLUDES@ >> -I$(abs_builddir)/subversion/bindings/javahl/include >> >> +SVN_BUILD_SVNBROWSE = @SVN_BUILD_SVNBROWSE@ >> SVN_BUILD_SVNXX = @SVN_BUILD_SVNXX@ >> SVN_BUILD_SVNXX_TESTS = @SVN_BUILD_SVNXX_TESTS@ >> SVNXX_INCLUDES = -I$(abs_srcdir)/subversion/bindings/cxx/include >> @@ -323,6 +326,7 @@ INSTALL_GNOME_KEYRING_LIB = $(INSTALL_LI >> INSTALL_KWALLET_LIB = $(INSTALL_LIB) >> INSTALL_SERF_LIB = $(INSTALL_LIB) >> INSTALL_BIN = $(LIBTOOL) --mode=install $(INSTALL) >> +INSTALL_TUI = $(INSTALL_BIN) >> INSTALL_CONTRIB = $(LIBTOOL) --mode=install $(INSTALL) >> INSTALL_TOOLS = $(LIBTOOL) --mode=install $(INSTALL) >> INSTALL_INCLUDE = $(INSTALL) -m 644 >> >> Modified: subversion/trunk/aclocal.m4.in >> >> ============================================================================== >> --- subversion/trunk/aclocal.m4.in Sun May 24 00:00:12 2026 >> (r1934545) >> +++ subversion/trunk/aclocal.m4.in Sun May 24 00:52:17 2026 >> (r1934546) >> @@ -39,6 +39,7 @@ sinclude(build/ac-macros/ax_boost_base.m >> sinclude(build/ac-macros/ax_boost_unit_test_framework.m4) >> sinclude(build/ac-macros/berkeley-db.m4) >> sinclude(build/ac-macros/compiler.m4) >> +sinclude(build/ac-macros/svnbrowse.m4) >> sinclude(build/ac-macros/ctypesgen.m4) >> sinclude(build/ac-macros/java.m4) >> sinclude(build/ac-macros/sasl.m4) >> >> Modified: subversion/trunk/build.conf >> >> ============================================================================== >> --- subversion/trunk/build.conf Sun May 24 00:00:12 2026 (r1934545) >> +++ subversion/trunk/build.conf Sun May 24 00:52:17 2026 (r1934546) >> @@ -223,7 +223,11 @@ install = bin >> manpages = subversion/svnmucc/svnmucc.1 >> >> [svnbrowse] >> +description = Subversion Repository Browser >> type = exe >> +when = SVN_BUILD_SVNBROWSE >> +# 'when' is ignored without 'compile-cmd' >> +compile-cmd = $(LT_COMPILE) -o $@ -c >> path = subversion/svnbrowse >> libs = libsvn_client libsvn_ra libsvn_subr libsvn_delta ncurses >> install = tui >> >> Added: subversion/trunk/build/ac-macros/svnbrowse.m4 >> >> ============================================================================== >> --- /dev/null 00:00:00 1970 (empty, because file is newly added) >> +++ subversion/trunk/build/ac-macros/svnbrowse.m4 Sun May 24 >> 00:52:17 2026 (r1934546) >> @@ -0,0 +1,126 @@ >> +dnl =================================================================== >> +dnl Licensed to the Apache Software Foundation (ASF) under one >> +dnl or more contributor license agreements. See the NOTICE file >> +dnl distributed with this work for additional information >> +dnl regarding copyright ownership. The ASF licenses this file >> +dnl to you under the Apache License, Version 2.0 (the >> +dnl "License"); you may not use this file except in compliance >> +dnl with the License. You may obtain a copy of the License at >> +dnl >> +dnl http://www.apache.org/licenses/LICENSE-2.0 >> +dnl >> +dnl Unless required by applicable law or agreed to in writing, >> +dnl software distributed under the License is distributed on an >> +dnl "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY >> +dnl KIND, either express or implied. See the License for the >> +dnl specific language governing permissions and limitations >> +dnl under the License. >> +dnl =================================================================== >> +dnl >> +dnl Configure svnbrowse >> + >> +AC_DEFUN(SVN_SVNBROWSE, >> +[ >> + AC_ARG_ENABLE(svnbrowse, >> + AS_HELP_STRING([--enable-svnbrowse], >> + [Enable building svnbrowse]), >> + [ >> + if test "$enableval" = "yes" ; then >> + AC_MSG_NOTICE([Enabling svnbrowse]) >> + do_svnbrowse_build=yes >> + else >> + AC_MSG_NOTICE([Disabling svnbrowse]) >> + do_svnbrowse_build=no >> + fi >> + ]) >> + >> + ncurses_skip=no >> + AC_ARG_WITH(ncurses, >> + AS_HELP_STRING([--with-ncurses=PREFIX], >> + [ncurses text-based user interface library]), >> + [ >> + if test "$withval" = "yes"; then >> + ncurses_skip=no >> + elif test "$withval" = "no"; then >> + ncurses_skip=yes >> + else >> + ncurses_skip=no >> + ncurses_prefix="$withval" >> + fi >> + ]) >> + >> + ncurses_found=no >> + if test "$do_svnbrowse_build" = "yes" && test "$ncurses_skip" = >> "no"; then >> + if test -n "$ncurses_prefix"; then >> + SVN_NCURSES_PREFIX() >> + else >> + SVN_NCURSES_PKG_CONFIG() >> + fi >> + >> + if test "$ncurses_found" = "no"; then >> + dnl Make sure previously cached values don't leak here >> + unset ac_cv_header_curses_h >> + unset ac_cv_lib_ncurses_termattrs >> + AC_MSG_NOTICE([ncurses library configuration]) >> + AC_CHECK_HEADER([curses.h],[ >> + AC_CHECK_LIB([ncurses],[termattrs],[ >> + ncurses_found="builtin" >> + SVN_NCURSES_LIBS="-lncurses" >> + ]) >> + ]) >> + fi >> + fi >> + >> + if test "$do_svnbrowse_build" = "yes"; then >> + if test "$ncurses_found" = "no"; then >> + AC_MSG_WARN([svnbrowse requires ncurses, disabling]) >> + SVN_BUILD_SVNBROWSE=false >> + else >> + SVN_BUILD_SVNBROWSE=true >> + fi >> + else >> + SVN_BUILD_SVNBROWSE=false >> + fi >> + >> + SVN_DOT_CLANGD([$SVN_ZLIB_INCLUDES]) >> + AC_SUBST(SVN_BUILD_SVNBROWSE) >> + AC_SUBST(SVN_NCURSES_INCLUDES) >> + AC_SUBST(SVN_NCURSES_LIBS) >> +]) >> + >> +AC_DEFUN(SVN_NCURSES_PREFIX, >> +[ >> + AC_MSG_NOTICE([ncurses library configuration via prefix]) >> + save_cppflags="$CPPFLAGS" >> + ncurses_includes="-I$ncurses_prefix/include" >> + CPPFLAGS="$CPPFLAGS $ncurses_includes" >> + AC_CHECK_HEADER([curses.h],[ >> + save_ldflags="$LDFLAGS" >> + >> ncurses_libs="`SVN_REMOVE_STANDARD_LIB_DIRS(-L$ncurses_prefix/lib)`" >> + LDFLAGS="$LDFLAGS $ncurses_libs" >> + AC_CHECK_LIB([ncurses],[termattrs],[ >> + ncurses_found="yes" >> + SVN_NCURSES_INCLUDES="$ncurses_includes" >> + SVN_NCURSES_LIBS="$ncurses_libs -lncurses" >> + ]) >> + LDFLAGS="$save_ldflags" >> + ]) >> + CPPFLAGS="$save_cppflags" >> +]) >> + >> +AC_DEFUN(SVN_NCURSES_PKG_CONFIG, >> +[ >> + AC_MSG_NOTICE([ncurses library configuration via pkg-config]) >> + if test -n "$PKG_CONFIG"; then >> + AC_MSG_CHECKING([for ncurses library]) >> + if $PKG_CONFIG ncurses --exists; then >> + AC_MSG_RESULT([yes]) >> + ncurses_found=yes >> + ncurses_libs=`$PKG_CONFIG ncurses --libs` >> + SVN_NCURSES_INCLUDES=`$PKG_CONFIG ncurses --cflags` >> + >> SVN_NCURSES_LIBS="`SVN_REMOVE_STANDARD_LIB_DIRS($ncurses_libs)`" >> + else >> + AC_MSG_RESULT([no]) >> + fi >> + fi >> +]) >> >> Modified: subversion/trunk/build/generator/templates/build-outputs.mk.ezt >> >> ============================================================================== >> --- subversion/trunk/build/generator/templates/build-outputs.mk.ezt >> Sun May 24 00:00:12 2026 (r1934545) >> +++ subversion/trunk/build/generator/templates/build-outputs.mk.ezt >> Sun May 24 00:52:17 2026 (r1934546) >> @@ -164,5 +164,5 @@ install-include:[for includes] [includes >> ######################################## >> [for deps] >> [deps.name]:[for deps.deps] [deps.deps][end][if-any deps.cmd] >> - [if-any deps.when]if $([deps.when]) ; then [else][end][deps.cmd] >> [if-any >> deps.generated][else]$(canonicalized_srcdir)[end][deps.source][end][if-any >> deps.when] ; else echo "fake" > [deps.name] ; fi[else][end] >> + [if-any deps.when]if $([deps.when]) ; then [else][end][deps.cmd] >> [if-any >> deps.generated][else]$(canonicalized_srcdir)[end][deps.source][if-any >> deps.when] ; else echo "fake" > [deps.name] ; fi[else][end][end] >> [end] >> >> Modified: subversion/trunk/configure.ac >> >> ============================================================================== >> --- subversion/trunk/configure.ac Sun May 24 00:00:12 2026 >> (r1934545) >> +++ subversion/trunk/configure.ac Sun May 24 00:52:17 2026 >> (r1934546) >> @@ -995,10 +995,10 @@ AS_HELP_STRING([--disable-plaintext-pass >> >> dnl Build and install rules ------------------- >> >> -INSTALL_STATIC_RULES="install-bin install-docs" >> +INSTALL_STATIC_RULES="install-bin install-tui install-docs" >> INSTALL_RULES="install-fsmod-lib install-ramod-lib install-lib >> install-include install-static" >> INSTALL_RULES="$INSTALL_RULES $INSTALL_APACHE_RULE" >> -BUILD_RULES="fsmod-lib ramod-lib lib bin test sub-test >> $BUILD_APACHE_RULE tools" >> +BUILD_RULES="fsmod-lib ramod-lib lib bin tui test sub-test >> $BUILD_APACHE_RULE tools" >> >> if test "$svn_lib_berkeley_db" = "yes"; then >> BUILD_RULES="$BUILD_RULES bdb-lib bdb-test" >> @@ -1333,6 +1333,8 @@ AS_HELP_STRING([--with-editor=PATH], >> >> ]) >> >> +SVN_SVNBROWSE >> + >> SVN_LIB_Z >> >> SVN_LZ4 >> >> Modified: subversion/trunk/subversion/svnbrowse/svnbrowse.c >> >> ============================================================================== >> --- subversion/trunk/subversion/svnbrowse/svnbrowse.c Sun May 24 >> 00:00:12 2026 (r1934545) >> +++ subversion/trunk/subversion/svnbrowse/svnbrowse.c Sun May 24 >> 00:52:17 2026 (r1934546) >> @@ -22,6 +22,8 @@ >> * ==================================================================== >> */ >> >> +#include <curses.h> >> + >> #include <apr.h> >> >> #include "private/svn_utf_private.h" >> @@ -35,8 +37,6 @@ >> >> #include "private/svn_cmdline_private.h" >> >> -#include <curses.h> >> - >> #include "svn_private_config.h" >> #include "svn_time.h" >> #include "svnbrowse.h" >> @@ -251,10 +251,11 @@ view_make(svn_browse__model_t *model, sv >> static svn_error_t * >> view_on_event(svn_browse__view_t *view, int ch, apr_pool_t *scratch_pool) >> { >> + int scrollsize; >> view_layout(view); >> >> /* scrollable height is one row less than the whole view */ >> - int scrollsize = getmaxy(view->list); >> + scrollsize = getmaxy(view->list); >> >> /* ch is received from getch() which would read the next character/key >> with >> * the following additional rules: >> >> Modified: subversion/trunk/subversion/svnbrowse/svnbrowse.h >> >> ============================================================================== >> --- subversion/trunk/subversion/svnbrowse/svnbrowse.h Sun May 24 >> 00:00:12 2026 (r1934545) >> +++ subversion/trunk/subversion/svnbrowse/svnbrowse.h Sun May 24 >> 00:52:17 2026 (r1934546) >> @@ -21,6 +21,9 @@ >> * ==================================================================== >> */ >> >> +#ifndef SVN_SVNBROWSE_SVNBROWSE_H >> +#define SVN_SVNBROWSE_SVNBROWSE_H >> + >> #include <apr.h> >> >> #include "svn_client.h" >> @@ -147,3 +150,5 @@ svn_browse__model_create(svn_browse__mod >> const svn_opt_revision_t *revision, >> apr_pool_t *result_pool, >> apr_pool_t *scratch_pool); >> + >> +#endif /* SVN_SVNBROWSE_SVNBROWSE_H */ >> >> > Thank you so much for doing that! > > I've tested the change and can confirm that it works perfectly on my > machine. > > However, I just realised that there is a crash when the program exits and > executes the pool-cleanups (that is also present in cmake build but for > some reason it wasn't printing the error message properly); > > [[[ > > where > #0 __pthread_kill_implementation > (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) > at pthread_kill.c:44 > #1 0x00007ffff749a363 in __pthread_kill_internal (threadid=<optimized > out>, signo=6) > at pthread_kill.c:89 > #2 0x00007ffff743e7d0 in __GI_raise (sig=sig@entry=6) at > ../sysdeps/posix/raise.c:26 > #3 0x00007ffff7425681 in __GI_abort () at abort.c:77 > #4 0x00007ffff7b3d4e0 in err_abort (data=0x555555758c50) at > subversion/libsvn_subr/error.c:156 > #5 0x00007ffff77cc7de in run_cleanups (cref=<optimized out>) at > memory/unix/apr_pools.c:2666 > #6 apr_pool_destroy (pool=0x555555758bd8) at memory/unix/apr_pools.c:991 > #7 0x00007ffff77cc7bd in apr_pool_destroy (pool=0x555555560528) at > memory/unix/apr_pools.c:988 > #8 0x00007ffff77ccaa1 in apr_pool_terminate () at > memory/unix/apr_pools.c:719 > #9 apr_pool_terminate () at memory/unix/apr_pools.c:711 > #10 0x00007ffff7441101 in __run_exit_handlers > (status=0, listp=0x7ffff7613680 <__exit_funcs>, > run_list_atexit=run_list_atexit@entry=true, run_dtors=run_dtors@entry=true) > at exit.c:118 > #11 0x00007ffff74411de in __GI_exit (status=<optimized out>) at exit.c:148 > #12 0x00007ffff7427748 in __libc_start_call_main > (main=main@entry=0x55555555a1f0 <main>, argc=argc@entry=1, > argv=argv@entry=0x7fffffffe488) > at ../sysdeps/nptl/libc_start_call_main.h:83 > #13 0x00007ffff7427879 in __libc_start_main_impl > (main=0x55555555a1f0 <main>, argc=1, argv=0x7fffffffe488, > init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, > stack_end=0x7fffffffe478) at ../csu/libc-start.c:360 > #14 0x00005555555575b5 in _start () > ]]] > > Which is probably caused by this line: > > [[[ > static svn_browse__view_t * > view_make(svn_browse__model_t *model, svn_browse__style_t *style, WINDOW > *win, > apr_pool_t *result_pool) > { > svn_browse__view_t *view = apr_pcalloc(result_pool, sizeof(*view)); > view->model = model; > view->style = style; > view->screen = win; > view_layout(view); > * apr_pool_cleanup_register(result_pool, view, view_cleanup, NULL);* > return view; > } > ]]] > > I think apr_pool_cleanup_register() doesn't like NULL for child_cleanup > and in the rest of the codebase we use apr_pool_cleanup_null instead. > > The following change seem to fix this issue: > > [[[ > Index: subversion/svnbrowse/svnbrowse.c > =================================================================== > --- subversion/svnbrowse/svnbrowse.c (revision 1934577) > +++ subversion/svnbrowse/svnbrowse.c (working copy) > @@ -244,7 +244,8 @@ view_make(svn_browse__model_t *model, svn_browse__ > view->style = style; > view->screen = win; > view_layout(view); > - apr_pool_cleanup_register(result_pool, view, view_cleanup, NULL); > + apr_pool_cleanup_register(result_pool, view, view_cleanup, > + apr_pool_cleanup_null); > return view; > } > ]]] > > Also I think it's a common practice with autoconf to enable all possible > features for which there are required dependencies present on the system. > Take swig, javahl, nls, etc. Is it possible to do the same for svnbrowse, > i.e. enable it whenever we have curses? > > By the way, an offtopic question: how do you use gdb with > binraries produced by a configure build? The ./subversion/svn/svn files > seem to be shell scripts which cannot be run with the debugger directly. > What is the easiest way to do it? I figured you could 'make install' it but > it's annoying to do after every change and I'm sure there is a more > convenient way. > Running it through libtool: "libtool exec gdb ./subversion/svn ..." or it might be "libtool --mode=execute gdb ./subversion/svn ..." https://www.gnu.org/software/libtool/manual/html_node/Debugging-executables.html Cheers, Nathan

