bug-gnulib@gnu.org mirror (unofficial)
 help / color / mirror / Atom feed
* [PATCH 0/6] build-aux/bootstrap that doesn't need to replace itself
@ 2022-12-27 18:59 Paul Eggert
  2022-12-27 18:59 ` [PATCH 1/6] Move scriptversion= lines up in scripts Paul Eggert
                   ` (7 more replies)
  0 siblings, 8 replies; 10+ messages in thread
From: Paul Eggert @ 2022-12-27 18:59 UTC (permalink / raw)
  To: bug-gnulib; +Cc: Paul Eggert

This set of patches addresses a problem I found with gzip
<https://bugs.gnu.org/56749>.  The idea is to add a new
feature to the bootstrap process so that a package can put just a
single bootstrap script into its repository, a script that does not
need to replace itself, while still providing a way for builders
to pull and generate in separate phases.

Paul Eggert (6):
  Move scriptversion= lines up in scripts
  Make autogen a shell function too
  Make autopull a shell function too
  Bootstrap with functions, not scripts
  Support packages with just 'bootstrap'
  Add --pull, --gen options to build-aux/bootstrap

 ChangeLog                |  45 +++
 build-aux/bootstrap      | 761 +++++++++++++++++++++++++++++++++++++--
 doc/gnulib-tool.texi     |  13 +-
 doc/gnulib.texi          |  23 +-
 top/autogen.sh           | 449 +----------------------
 top/autopull.sh          | 238 +-----------
 top/bootstrap            |  46 ++-
 top/bootstrap-funclib.sh | 713 +++++++++++++++++++++++++++++++++++-
 top/gen-bootstrap.sed    |   4 -
 9 files changed, 1535 insertions(+), 757 deletions(-)

-- 
2.25.1



^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/6] Move scriptversion= lines up in scripts
  2022-12-27 18:59 [PATCH 0/6] build-aux/bootstrap that doesn't need to replace itself Paul Eggert
@ 2022-12-27 18:59 ` Paul Eggert
  2022-12-27 18:59 ` [PATCH] stdnoreturn: deprecate Paul Eggert
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Paul Eggert @ 2022-12-27 18:59 UTC (permalink / raw)
  To: bug-gnulib; +Cc: Paul Eggert

By default they need to be in the first 8 lines to be updated.
---
 build-aux/bootstrap      | 8 ++++----
 top/autogen.sh           | 4 ++--
 top/autopull.sh          | 4 ++--
 top/bootstrap            | 4 ++--
 top/bootstrap-funclib.sh | 4 ++--
 5 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/build-aux/bootstrap b/build-aux/bootstrap
index 9714a59432..d94605dd44 100755
--- a/build-aux/bootstrap
+++ b/build-aux/bootstrap
@@ -5,6 +5,8 @@
 
 # Bootstrap this package from checked-out sources.
 
+scriptversion=2022-12-27.03; # UTC
+
 # Copyright (C) 2003-2022 Free Software Foundation, Inc.
 #
 # This program is free software: you can redistribute it and/or modify
@@ -30,8 +32,6 @@
 
 # Please report bugs or propose patches to bug-gnulib@gnu.org.
 
-scriptversion=2022-07-29.23; # UTC
-
 me="$0"
 medir=`dirname "$me"`
 
@@ -39,6 +39,8 @@ medir=`dirname "$me"`
 
 # A library of shell functions for autopull.sh, autogen.sh, and bootstrap.
 
+scriptversion=2022-12-27.03; # UTC
+
 # Copyright (C) 2003-2022 Free Software Foundation, Inc.
 #
 # This program is free software: you can redistribute it and/or modify
@@ -62,8 +64,6 @@ medir=`dirname "$me"`
 # file also maintained in your version control; gnulib comes with a
 # template build-aux/bootstrap.conf to get you started.
 
-scriptversion=2022-07-24.15; # UTC
-
 nl='
 '
 
diff --git a/top/autogen.sh b/top/autogen.sh
index 81db3fe035..4ca4c05577 100755
--- a/top/autogen.sh
+++ b/top/autogen.sh
@@ -4,6 +4,8 @@
 # also regenerates all aclocal.m4, config.h.in, Makefile.in, configure files
 # with new versions of autoconf or automake.
 
+scriptversion=2022-12-27.03; # UTC
+
 # Copyright (C) 2003-2022 Free Software Foundation, Inc.
 #
 # This program is free software: you can redistribute it and/or modify
@@ -30,8 +32,6 @@
 # Alternatively, you can use an autogen.sh script that is specific
 # to your package.
 
-scriptversion=2022-07-24.15; # UTC
-
 me="$0"
 medir=`dirname "$me"`
 
diff --git a/top/autopull.sh b/top/autopull.sh
index ffb4ba7cba..f3b9a3811d 100755
--- a/top/autopull.sh
+++ b/top/autopull.sh
@@ -2,6 +2,8 @@
 # Convenience script for fetching auxiliary files that are omitted from
 # the version control repository of this package.
 
+scriptversion=2022-12-27.03; # UTC
+
 # Copyright (C) 2003-2022 Free Software Foundation, Inc.
 #
 # This program is free software: you can redistribute it and/or modify
@@ -28,8 +30,6 @@
 # Alternatively, you can use an autopull.sh script that is specific
 # to your package.
 
-scriptversion=2022-07-24.15; # UTC
-
 me="$0"
 medir=`dirname "$me"`
 
diff --git a/top/bootstrap b/top/bootstrap
index cf8d007f64..9d31b4311c 100755
--- a/top/bootstrap
+++ b/top/bootstrap
@@ -1,6 +1,8 @@
 #! /bin/sh
 # Bootstrap this package from checked-out sources.
 
+scriptversion=2022-12-27.03; # UTC
+
 # Copyright (C) 2003-2022 Free Software Foundation, Inc.
 #
 # This program is free software: you can redistribute it and/or modify
@@ -26,8 +28,6 @@
 
 # Please report bugs or propose patches to bug-gnulib@gnu.org.
 
-scriptversion=2022-07-29.23; # UTC
-
 me="$0"
 medir=`dirname "$me"`
 
diff --git a/top/bootstrap-funclib.sh b/top/bootstrap-funclib.sh
index cfad85a318..ef0fa70ae5 100644
--- a/top/bootstrap-funclib.sh
+++ b/top/bootstrap-funclib.sh
@@ -1,5 +1,7 @@
 # A library of shell functions for autopull.sh, autogen.sh, and bootstrap.
 
+scriptversion=2022-12-27.03; # UTC
+
 # Copyright (C) 2003-2022 Free Software Foundation, Inc.
 #
 # This program is free software: you can redistribute it and/or modify
@@ -23,8 +25,6 @@
 # file also maintained in your version control; gnulib comes with a
 # template build-aux/bootstrap.conf to get you started.
 
-scriptversion=2022-07-24.15; # UTC
-
 nl='
 '
 
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH] stdnoreturn: deprecate
  2022-12-27 18:59 [PATCH 0/6] build-aux/bootstrap that doesn't need to replace itself Paul Eggert
  2022-12-27 18:59 ` [PATCH 1/6] Move scriptversion= lines up in scripts Paul Eggert
@ 2022-12-27 18:59 ` Paul Eggert
  2022-12-27 18:59 ` [PATCH 2/6] Make autogen a shell function too Paul Eggert
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Paul Eggert @ 2022-12-27 18:59 UTC (permalink / raw)
  To: bug-gnulib; +Cc: Paul Eggert

C23 says <stdnoreturn.h> is obsolescent, so deprecate the
stdnoreturn module.  I don't think it was being used anyway
as it had too many problems.
* modules/stdnoreturn: Mark as obsolete.
---
 ChangeLog                          |  8 +++++++
 NEWS                               |  3 +++
 doc/noreturn.texi                  | 35 ++++++++++++++----------------
 doc/posix-headers/stdnoreturn.texi |  2 ++
 lib/stdnoreturn.in.h               |  4 +++-
 modules/stdnoreturn                |  6 +++++
 6 files changed, 38 insertions(+), 20 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 3b6c6cf98e..91370af964 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2022-12-24  Paul Eggert  <eggert@cs.ucla.edu>
+
+	stdnoreturn: deprecate
+	C23 says <stdnoreturn.h> is obsolescent, so deprecate the
+	stdnoreturn module.  I don't think it was being used anyway
+	as it had too many problems.
+	* modules/stdnoreturn: Mark as obsolete.
+
 2022-12-23  Paul Eggert  <eggert@cs.ucla.edu>
 
 	file-has-acl: improve recent NFSv4 support
diff --git a/NEWS b/NEWS
index bc620ce86a..dd2374c4fd 100644
--- a/NEWS
+++ b/NEWS
@@ -74,6 +74,9 @@ User visible incompatible changes
 
 Date        Modules         Changes
 
+2022-12-24  stdnoreturn     This module is deprecated.  Use _Noreturn
+                            or the noreturn module instead.
+
 2022-12-21  ctime           This module is deprecated.  Use localtime_r
                             and strftime (or even sprintf) instead.
 
diff --git a/doc/noreturn.texi b/doc/noreturn.texi
index a3a394409c..ad0a286f4a 100644
--- a/doc/noreturn.texi
+++ b/doc/noreturn.texi
@@ -15,22 +15,26 @@
 @cindex @code{noreturn}
 @cindex @code{stdnoreturn}
 A "non-returning" function is a function which cannot return normally.
-It can transfer control only through @code{longjmp()}, @code{throw}
-(in C++), or similar mechanisms.  The most prominent function of this
-class is the @code{abort} function.  Non-returning functions are
+Instead of returning, it can loop forever, or it can transfer control via
+@code{abort}, @code{execvp}, @code{exit}, @code{longjmp}, @code{throw}
+(in C++), or similar mechanisms.  Non-returning functions are
 declared with a @code{void} return type.
 
 It helps the compiler's ability to emit sensible warnings, following
 data-flow analysis, to declare which functions are non-returning.
+It can also help generate more-efficient code, as there is no need
+to save a return address when calling a non-returning function.
 
-To decorate function declarations and function definitions, you can
-use the @code{_Noreturn} keyword.  No modules are needed, as Gnulib
+Gnulib has multiple ways to support such a declaration''
+
+@itemize @bullet
+@item
+The @code{_Noreturn} keyword.  No modules are needed, as Gnulib
 arranges for @code{<config.h>} to define @code{_Noreturn} to an
 appropriate replacement on platforms lacking it.
+Unfortunately, although this approach works for all current C versions,
+the @code{_Noreturn} keyword is obsolescent in C23.
 
-Gnulib has two modules that support such a declaration:
-
-@itemize @bullet
 @item
 The @samp{noreturn} module.  It provides a way to put this declaration
 at function declarations, at function definitions, and in function
@@ -44,20 +48,13 @@ definitions.
 @end itemize
 @noindent
 The include file is @code{<noreturn.h>}.
-
-@item
-The @samp{stdnoreturn} module.  This can improve readability by
-letting you use @code{noreturn} instead of @code{_Noreturn};
-unfortunately, @code{noreturn} is a no-op on some platforms even
-though @code{_Noreturn} works on them.  The include file is
-@code{<stdnoreturn.h>}.
 @end itemize
 
-Which of the two modules to use?  If the non-returning functions you
+Which of the approaches to use?  If the non-returning functions you
 have to declare are unlikely to be accessed through function pointers,
-you should use module @code{stdnoreturn}; otherwise the module
+you should use @code{_Noreturn}; otherwise the module
 @code{noreturn} provides for better data-flow analysis and thus for
 better warnings.
 
-For a detailed description of the @code{stdnoreturn} module, see
-@ref{stdnoreturn.h}.
+There is also an obsolete @code{stdnoreturn} module, but its use is no
+longer recommended.
diff --git a/doc/posix-headers/stdnoreturn.texi b/doc/posix-headers/stdnoreturn.texi
index 3e1c5882db..ebe31ffc9f 100644
--- a/doc/posix-headers/stdnoreturn.texi
+++ b/doc/posix-headers/stdnoreturn.texi
@@ -22,6 +22,8 @@ MSVC/clang.
 Portability problems not fixed by Gnulib:
 @itemize
 @item
+@code{<stdnoreturn.h>} and the @code{noreturn} macro are obsolescent in C23.
+@item
 @code{<stdnoreturn.h>} cannot be #included in C++ mode on some platforms:
 FreeBSD 13.1.
 @item
diff --git a/lib/stdnoreturn.in.h b/lib/stdnoreturn.in.h
index d9e746699d..446e11b0b2 100644
--- a/lib/stdnoreturn.in.h
+++ b/lib/stdnoreturn.in.h
@@ -24,7 +24,9 @@
    References:
    ISO C11 (latest free draft
    <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf>)
-   section 7.23 */
+   section 7.23
+
+   <stdnoreturn.h> is obsolescent in C23, so new code should avoid it.  */
 
 /* The definition of _Noreturn is copied here.  */
 
diff --git a/modules/stdnoreturn b/modules/stdnoreturn
index 1ef894d51f..ce6b04a35e 100644
--- a/modules/stdnoreturn
+++ b/modules/stdnoreturn
@@ -1,6 +1,12 @@
 Description:
 A <stdnoreturn.h> that nearly conforms to ISO C11.
 
+Status:
+obsolete
+
+Notice:
+This module is obsolete.
+
 Files:
 lib/stdnoreturn.in.h
 m4/stdnoreturn.m4
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/6] Make autogen a shell function too
  2022-12-27 18:59 [PATCH 0/6] build-aux/bootstrap that doesn't need to replace itself Paul Eggert
  2022-12-27 18:59 ` [PATCH 1/6] Move scriptversion= lines up in scripts Paul Eggert
  2022-12-27 18:59 ` [PATCH] stdnoreturn: deprecate Paul Eggert
@ 2022-12-27 18:59 ` Paul Eggert
  2022-12-27 18:59 ` [PATCH 3/6] Make autopull " Paul Eggert
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Paul Eggert @ 2022-12-27 18:59 UTC (permalink / raw)
  To: bug-gnulib; +Cc: Paul Eggert

This does not change behavior.  It is helpful for future changes.
* top/autogen.sh: Call autogen to do the actual work.
(usage, version_controlled_file, gitignore_entries, insert_if_absent):
(insert_vc_ignore, symlink_to_dir): Move to top/bootstrap-funclib.sh.
* top/bootstrap-funclib.sh (autogen_usage): Rename from ‘usage’.
(autogen): New function, containing the top level of the
old top/autogen.sh.
---
 ChangeLog                |  11 +
 build-aux/bootstrap      | 451 ++++++++++++++++++++++++++++++++++++++-
 top/autogen.sh           | 449 +-------------------------------------
 top/bootstrap-funclib.sh | 451 ++++++++++++++++++++++++++++++++++++++-
 4 files changed, 912 insertions(+), 450 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index c5de4b0809..3fd73f3f74 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2022-12-27  Paul Eggert  <eggert@cs.ucla.edu>
+
+	Make autogen a shell function too
+	This does not change behavior.  It is helpful for future changes.
+	* top/autogen.sh: Call autogen to do the actual work.
+	(usage, version_controlled_file, gitignore_entries, insert_if_absent):
+	(insert_vc_ignore, symlink_to_dir): Move to top/bootstrap-funclib.sh.
+	* top/bootstrap-funclib.sh (autogen_usage): Rename from ‘usage’.
+	(autogen): New function, containing the top level of the
+	old top/autogen.sh.
+
 2022-12-27  Bruno Haible  <bruno@clisp.org>
 
 	Fix compilation errors in C++ mode on Solaris 11 OpenIndiana.
diff --git a/build-aux/bootstrap b/build-aux/bootstrap
index d94605dd44..c7566e824b 100755
--- a/build-aux/bootstrap
+++ b/build-aux/bootstrap
@@ -39,7 +39,7 @@ medir=`dirname "$me"`
 
 # A library of shell functions for autopull.sh, autogen.sh, and bootstrap.
 
-scriptversion=2022-12-27.03; # UTC
+scriptversion=2022-12-27.16; # UTC
 
 # Copyright (C) 2003-2022 Free Software Foundation, Inc.
 #
@@ -622,6 +622,455 @@ else
   use_gnulib=true
 fi
 
+
+# -------- Generate files automatically from existing sources.  --------------
+
+autogen_usage() {
+  cat <<EOF
+Usage: $me [OPTION]...
+Bootstrap this package from the checked-out sources.
+
+Optional environment variables:
+  GNULIB_SRCDIR            Specifies the local directory where gnulib
+                           sources reside.  Use this if you already
+                           have gnulib sources on your machine, and
+                           you want to use these sources.
+
+Options:
+  --copy                   copy files instead of creating symbolic links
+  --force                  attempt to bootstrap even if the sources seem
+                           not to have been checked out
+EOF
+  bootstrap_print_option_usage_hook
+  cat <<EOF
+If the file bootstrap.conf exists in the same directory as this script, its
+contents are read as shell variables to configure the bootstrap.
+
+For build prerequisites, environment variables like \$AUTOCONF and \$AMTAR
+are honored.
+
+Gnulib sources are assumed to be present:
+  * in \$GNULIB_SRCDIR, if that environment variable is set,
+  * otherwise, in the 'gnulib' submodule, if such a submodule is configured,
+  * otherwise, in the 'gnulib' subdirectory.
+
+Running without arguments will suffice in most cases.
+EOF
+}
+
+
+version_controlled_file() {
+  parent=$1
+  file=$2
+  if test -d .git; then
+    git rm -n "$file" > /dev/null 2>&1
+  elif test -d .svn; then
+    svn log -r HEAD "$file" > /dev/null 2>&1
+  elif test -d CVS; then
+    grep -F "/${file##*/}/" "$parent/CVS/Entries" 2>/dev/null |
+             grep '^/[^/]*/[0-9]' > /dev/null
+  else
+    warn_ "no version control for $file?"
+    false
+  fi
+}
+
+# Strip blank and comment lines to leave significant entries.
+gitignore_entries() {
+  sed '/^#/d; /^$/d' "$@"
+}
+
+# If $STR is not already on a line by itself in $FILE, insert it at the start.
+# Entries are inserted at the start of the ignore list to ensure existing
+# entries starting with ! are not overridden.  Such entries support
+# whitelisting exceptions after a more generic blacklist pattern.
+insert_if_absent() {
+  file=$1
+  str=$2
+  test -f $file || touch $file
+  test -r $file || die "Error: failed to read ignore file: $file"
+  duplicate_entries=$(gitignore_entries $file | sort | uniq -d)
+  if [ "$duplicate_entries" ] ; then
+    die "Error: Duplicate entries in $file: " $duplicate_entries
+  fi
+  linesold=$(gitignore_entries $file | wc -l)
+  linesnew=$( { echo "$str"; cat $file; } | gitignore_entries | sort -u | wc -l)
+  if [ $linesold != $linesnew ] ; then
+    { echo "$str" | cat - $file > $file.bak && mv $file.bak $file; } \
+      || die "insert_if_absent $file $str: failed"
+  fi
+}
+
+# Adjust $PATTERN for $VC_IGNORE_FILE and insert it with
+# insert_if_absent.
+insert_vc_ignore() {
+  vc_ignore_file="$1"
+  pattern="$2"
+  case $vc_ignore_file in
+  *.gitignore)
+    # A .gitignore entry that does not start with '/' applies
+    # recursively to subdirectories, so prepend '/' to every
+    # .gitignore entry.
+    pattern=$(echo "$pattern" | sed s,^,/,);;
+  esac
+  insert_if_absent "$vc_ignore_file" "$pattern"
+}
+
+symlink_to_dir()
+{
+  src=$1/$2
+  dst=${3-$2}
+
+  test -f "$src" && {
+
+    # If the destination directory doesn't exist, create it.
+    # This is required at least for "lib/uniwidth/cjk.h".
+    dst_dir=$(dirname "$dst")
+    if ! test -d "$dst_dir"; then
+      mkdir -p "$dst_dir"
+
+      # If we've just created a directory like lib/uniwidth,
+      # tell version control system(s) it's ignorable.
+      # FIXME: for now, this does only one level
+      parent=$(dirname "$dst_dir")
+      for dot_ig in x $vc_ignore; do
+        test $dot_ig = x && continue
+        ig=$parent/$dot_ig
+        insert_vc_ignore $ig "${dst_dir##*/}"
+      done
+    fi
+
+    if $copy; then
+      {
+        test ! -h "$dst" || {
+          echo "$me: rm -f $dst" &&
+          rm -f "$dst"
+        }
+      } &&
+      test -f "$dst" &&
+      cmp -s "$src" "$dst" || {
+        echo "$me: cp -fp $src $dst" &&
+        cp -fp "$src" "$dst"
+      }
+    else
+      # Leave any existing symlink alone, if it already points to the source,
+      # so that broken build tools that care about symlink times
+      # aren't confused into doing unnecessary builds.  Conversely, if the
+      # existing symlink's timestamp is older than the source, make it afresh,
+      # so that broken tools aren't confused into skipping needed builds.  See
+      # <https://lists.gnu.org/r/bug-gnulib/2011-05/msg00326.html>.
+      test -h "$dst" &&
+      src_ls=$(ls -diL "$src" 2>/dev/null) && set $src_ls && src_i=$1 &&
+      dst_ls=$(ls -diL "$dst" 2>/dev/null) && set $dst_ls && dst_i=$1 &&
+      test "$src_i" = "$dst_i" &&
+      both_ls=$(ls -dt "$src" "$dst") &&
+      test "X$both_ls" = "X$dst$nl$src" || {
+        dot_dots=
+        case $src in
+        /*) ;;
+        *)
+          case /$dst/ in
+          *//* | */../* | */./* | /*/*/*/*/*/)
+             die "invalid symlink calculation: $src -> $dst";;
+          /*/*/*/*/)    dot_dots=../../../;;
+          /*/*/*/)      dot_dots=../../;;
+          /*/*/)        dot_dots=../;;
+          esac;;
+        esac
+
+        echo "$me: ln -fs $dot_dots$src $dst" &&
+        ln -fs "$dot_dots$src" "$dst"
+      }
+    fi
+  }
+}
+
+# Regenerate all autogeneratable files that are omitted from the
+# version control repository.  In particular, regenerate all
+# aclocal.m4, config.h.in, Makefile.in, configure files with new
+# versions of autoconf or automake.
+autogen()
+{
+  # Ensure that CDPATH is not set.  Otherwise, the output from cd
+  # would cause trouble in at least one use below.
+  (unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+  # Environment variables that may be set by the user.
+  : "${AUTOPOINT=autopoint}"
+  : "${AUTORECONF=autoreconf}"
+
+  if test "$vc_ignore" = auto; then
+    vc_ignore=
+    test -d .git && vc_ignore=.gitignore
+    test -d CVS && vc_ignore="$vc_ignore .cvsignore"
+  fi
+
+
+  # Parse options.
+
+  # Whether to use copies instead of symlinks.
+  copy=false
+
+  for option
+  do
+    case $option in
+    --help)
+      autogen_usage
+      return;;
+    --version)
+      set -e
+      echo "autogen.sh $scriptversion"
+      echo "$copyright"
+      return 0
+      ;;
+    --force)
+      checkout_only_file=;;
+    --copy)
+      copy=true;;
+    *)
+      bootstrap_option_hook $option || die "$option: unknown option";;
+    esac
+  done
+
+  test -z "$GNULIB_SRCDIR" || test -d "$GNULIB_SRCDIR" \
+    || die "Error: \$GNULIB_SRCDIR environment variable or --gnulib-srcdir option is specified, but does not denote a directory"
+
+  if test -n "$checkout_only_file" && test ! -r "$checkout_only_file"; then
+    die "Running this script from a non-checked-out distribution is risky."
+  fi
+
+  if $use_gnulib; then
+    if test -z "$GNULIB_SRCDIR"; then
+      gnulib_path=$(test -f .gitmodules && git config --file .gitmodules submodule.gnulib.path)
+      test -z "$gnulib_path" && gnulib_path=gnulib
+      GNULIB_SRCDIR=$gnulib_path
+    fi
+  fi
+
+  # Die if there is no AC_CONFIG_AUX_DIR($build_aux) line in configure.ac.
+  found_aux_dir=no
+  grep '^[	 ]*AC_CONFIG_AUX_DIR(\['"$build_aux"'])' configure.ac \
+      >/dev/null && found_aux_dir=yes
+  grep '^[	 ]*AC_CONFIG_AUX_DIR('"$build_aux"')' configure.ac \
+      >/dev/null && found_aux_dir=yes
+  test $found_aux_dir = yes \
+    || die "configure.ac lacks 'AC_CONFIG_AUX_DIR([$build_aux])'; add it"
+
+  # If $build_aux doesn't exist, create it now, otherwise some bits
+  # below will malfunction.  If creating it, also mark it as ignored.
+  if test ! -d $build_aux; then
+    mkdir $build_aux
+    for dot_ig in x $vc_ignore; do
+      test $dot_ig = x && continue
+      insert_vc_ignore $dot_ig $build_aux
+    done
+  fi
+
+  check_build_prerequisites false
+
+  use_libtool=0
+  # We'd like to use grep -E, to see if any of LT_INIT,
+  # AC_PROG_LIBTOOL, AM_PROG_LIBTOOL is used in configure.ac,
+  # but that's not portable enough (e.g., for Solaris).
+  grep '^[	 ]*A[CM]_PROG_LIBTOOL' configure.ac >/dev/null \
+    && use_libtool=1
+  grep '^[	 ]*LT_INIT' configure.ac >/dev/null \
+    && use_libtool=1
+  if test $use_libtool = 1; then
+    find_tool LIBTOOLIZE glibtoolize libtoolize
+  fi
+
+  if $use_gnulib; then
+    gnulib_tool=$GNULIB_SRCDIR/gnulib-tool
+    <$gnulib_tool || return
+  fi
+
+  # NOTE: we have to be careful to run both autopoint and libtoolize
+  # before gnulib-tool, since gnulib-tool is likely to provide newer
+  # versions of files "installed" by these two programs.
+  # Then, *after* gnulib-tool (see below), we have to be careful to
+  # run autoreconf in such a way that it does not run either of these
+  # two just-pre-run programs.
+
+  # Import from gettext.
+  with_gettext=yes
+  grep '^[	 ]*AM_GNU_GETTEXT_VERSION(' configure.ac >/dev/null || \
+      with_gettext=no
+
+  if test $with_gettext = yes || test $use_libtool = 1; then
+
+    tempbase=.bootstrap$$
+    trap "rm -f $tempbase.0 $tempbase.1" HUP INT PIPE TERM
+
+    > $tempbase.0 > $tempbase.1 &&
+    find . ! -type d -print | sort > $tempbase.0 || return
+
+    if test $with_gettext = yes; then
+      # Released autopoint has the tendency to install macros that have been
+      # obsoleted in current gnulib, so run this before gnulib-tool.
+      echo "$0: $AUTOPOINT --force"
+      $AUTOPOINT --force || return
+    fi
+
+    # Autoreconf runs aclocal before libtoolize, which causes spurious
+    # warnings if the initial aclocal is confused by the libtoolized
+    # (or worse out-of-date) macro directory.
+    # libtoolize 1.9b added the --install option; but we support back
+    # to libtoolize 1.5.22, where the install action was default.
+    if test $use_libtool = 1; then
+      install=
+      case $($LIBTOOLIZE --help) in
+        *--install*) install=--install ;;
+      esac
+      echo "running: $LIBTOOLIZE $install --copy"
+      $LIBTOOLIZE $install --copy
+    fi
+
+    find . ! -type d -print | sort >$tempbase.1
+    old_IFS=$IFS
+    IFS=$nl
+    for file in $(comm -13 $tempbase.0 $tempbase.1); do
+      IFS=$old_IFS
+      parent=${file%/*}
+      version_controlled_file "$parent" "$file" || {
+        for dot_ig in x $vc_ignore; do
+          test $dot_ig = x && continue
+          ig=$parent/$dot_ig
+          insert_vc_ignore "$ig" "${file##*/}"
+        done
+      }
+    done
+    IFS=$old_IFS
+
+    rm -f $tempbase.0 $tempbase.1
+    trap - HUP INT PIPE TERM
+  fi
+
+  # Import from gnulib.
+
+  if $use_gnulib; then
+    gnulib_tool_options="\
+     --no-changelog\
+     --aux-dir=$build_aux\
+     --doc-base=$doc_base\
+     --lib=$gnulib_name\
+     --m4-base=$m4_base/\
+     --source-base=$source_base/\
+     --tests-base=$tests_base\
+     --local-dir=$local_gl_dir\
+     $gnulib_tool_option_extras\
+    "
+    if test $use_libtool = 1; then
+      case "$gnulib_tool_options " in
+        *' --libtool '*) ;;
+        *) gnulib_tool_options="$gnulib_tool_options --libtool" ;;
+      esac
+    fi
+    echo "$0: $gnulib_tool $gnulib_tool_options --import ..."
+    $gnulib_tool $gnulib_tool_options --import $gnulib_modules \
+      || die "gnulib-tool failed"
+
+    for file in $gnulib_files; do
+      symlink_to_dir "$GNULIB_SRCDIR" $file \
+        || die "failed to symlink $file"
+    done
+  fi
+
+  bootstrap_post_import_hook \
+    || die "bootstrap_post_import_hook failed"
+
+  # Remove any dangling symlink matching "*.m4" or "*.[ch]" in some
+  # gnulib-populated directories.  Such .m4 files would cause aclocal to fail.
+  # The following requires GNU find 4.2.3 or newer.  Considering the usual
+  # portability constraints of this script, that may seem a very demanding
+  # requirement, but it should be ok.  Ignore any failure, which is fine,
+  # since this is only a convenience to help developers avoid the relatively
+  # unusual case in which a symlinked-to .m4 file is git-removed from gnulib
+  # between successive runs of this script.
+  find "$m4_base" "$source_base" \
+    -depth \( -name '*.m4' -o -name '*.[ch]' \) \
+    -type l -xtype l -delete > /dev/null 2>&1
+
+  # Invoke autoreconf with --force --install to ensure upgrades of tools
+  # such as ylwrap.
+  AUTORECONFFLAGS="--verbose --install --force -I $m4_base $ACLOCAL_FLAGS"
+
+  # Some systems (RHEL 5) are using ancient autotools, for which the
+  # --no-recursive option had not been invented.  Detect that lack and
+  # omit the option when it's not supported.  FIXME in 2017: remove this
+  # hack when RHEL 5 autotools are updated, or when they become irrelevant.
+  case $($AUTORECONF --help) in
+    *--no-recursive*) AUTORECONFFLAGS="$AUTORECONFFLAGS --no-recursive";;
+  esac
+
+  # Tell autoreconf not to invoke autopoint or libtoolize; they were run above.
+  echo "running: AUTOPOINT=true LIBTOOLIZE=true $AUTORECONF $AUTORECONFFLAGS"
+  AUTOPOINT=true LIBTOOLIZE=true $AUTORECONF $AUTORECONFFLAGS \
+    || die "autoreconf failed"
+
+  # Get some extra files from gnulib, overriding existing files.
+  for file in $gnulib_extra_files; do
+    case $file in
+      */INSTALL) dst=INSTALL;;
+      build-aux/*) dst=$build_aux/${file#build-aux/};;
+      *) dst=$file;;
+    esac
+    symlink_to_dir "$GNULIB_SRCDIR" $file $dst \
+      || die "failed to symlink $file"
+  done
+
+  if test $with_gettext = yes; then
+    # Create gettext configuration.
+    echo "$0: Creating po/Makevars from po/Makevars.template ..."
+    rm -f po/Makevars
+    sed '
+      /^EXTRA_LOCALE_CATEGORIES *=/s/=.*/= '"$EXTRA_LOCALE_CATEGORIES"'/
+      /^COPYRIGHT_HOLDER *=/s/=.*/= '"$COPYRIGHT_HOLDER"'/
+      /^MSGID_BUGS_ADDRESS *=/s|=.*|= '"$MSGID_BUGS_ADDRESS"'|
+      /^XGETTEXT_OPTIONS *=/{
+        s/$/ \\/
+        a\
+            '"$XGETTEXT_OPTIONS"' $${end_of_xgettext_options+}
+      }
+    ' po/Makevars.template >po/Makevars \
+      || die 'cannot generate po/Makevars'
+
+    # If the 'gettext' module is in use, grab the latest Makefile.in.in.
+    # If only the 'gettext-h' module is in use, assume autopoint already
+    # put the correct version of this file into place.
+    case $gnulib_modules in
+      *gettext-h*) ;;
+      *gettext*)
+        cp $GNULIB_SRCDIR/build-aux/po/Makefile.in.in po/Makefile.in.in \
+          || die "cannot create po/Makefile.in.in"
+        ;;
+    esac
+
+    if test -d runtime-po; then
+      # Similarly for runtime-po/Makevars, but not quite the same.
+      rm -f runtime-po/Makevars
+      sed '
+        /^DOMAIN *=.*/s/=.*/= '"$package"'-runtime/
+        /^subdir *=.*/s/=.*/= runtime-po/
+        /^MSGID_BUGS_ADDRESS *=/s/=.*/= bug-'"$package"'@gnu.org/
+        /^XGETTEXT_OPTIONS *=/{
+          s/$/ \\/
+          a\
+              '"$XGETTEXT_OPTIONS_RUNTIME"' $${end_of_xgettext_options+}
+        }
+      ' po/Makevars.template >runtime-po/Makevars \
+      || die 'cannot generate runtime-po/Makevars'
+
+      # Copy identical files from po to runtime-po.
+      (cd po && cp -p Makefile.in.in *-quot *.header *.sed *.sin ../runtime-po)
+    fi
+  fi
+
+  bootstrap_epilogue
+
+  echo "$0: done.  Now you can run './configure'."
+}
+
 # ----------------------------------------------------------------------------
 
 # Local Variables:
diff --git a/top/autogen.sh b/top/autogen.sh
index 4ca4c05577..1cb918640d 100755
--- a/top/autogen.sh
+++ b/top/autogen.sh
@@ -4,8 +4,6 @@
 # also regenerates all aclocal.m4, config.h.in, Makefile.in, configure files
 # with new versions of autoconf or automake.
 
-scriptversion=2022-12-27.03; # UTC
-
 # Copyright (C) 2003-2022 Free Software Foundation, Inc.
 #
 # This program is free software: you can redistribute it and/or modify
@@ -38,449 +36,4 @@ medir=`dirname "$me"`
 # Read the function library and the configuration.
 . "$medir"/bootstrap-funclib.sh
 
-# Ensure that CDPATH is not set.  Otherwise, the output from cd
-# would cause trouble in at least one use below.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-# Environment variables that may be set by the user.
-: "${AUTOPOINT=autopoint}"
-: "${AUTORECONF=autoreconf}"
-
-if test "$vc_ignore" = auto; then
-  vc_ignore=
-  test -d .git && vc_ignore=.gitignore
-  test -d CVS && vc_ignore="$vc_ignore .cvsignore"
-fi
-
-usage() {
-  cat <<EOF
-Usage: $me [OPTION]...
-Bootstrap this package from the checked-out sources.
-
-Optional environment variables:
-  GNULIB_SRCDIR            Specifies the local directory where gnulib
-                           sources reside.  Use this if you already
-                           have gnulib sources on your machine, and
-                           you want to use these sources.
-
-Options:
-  --copy                   copy files instead of creating symbolic links
-  --force                  attempt to bootstrap even if the sources seem
-                           not to have been checked out
-EOF
-  bootstrap_print_option_usage_hook
-  cat <<EOF
-If the file bootstrap.conf exists in the same directory as this script, its
-contents are read as shell variables to configure the bootstrap.
-
-For build prerequisites, environment variables like \$AUTOCONF and \$AMTAR
-are honored.
-
-Gnulib sources are assumed to be present:
-  * in \$GNULIB_SRCDIR, if that environment variable is set,
-  * otherwise, in the 'gnulib' submodule, if such a submodule is configured,
-  * otherwise, in the 'gnulib' subdirectory.
-
-Running without arguments will suffice in most cases.
-EOF
-}
-
-# Parse options.
-
-# Whether to use copies instead of symlinks.
-copy=false
-
-for option
-do
-  case $option in
-  --help)
-    usage
-    exit;;
-  --version)
-    set -e
-    echo "autogen.sh $scriptversion"
-    echo "$copyright"
-    exit 0
-    ;;
-  --force)
-    checkout_only_file=;;
-  --copy)
-    copy=true;;
-  *)
-    bootstrap_option_hook $option || die "$option: unknown option";;
-  esac
-done
-
-test -z "$GNULIB_SRCDIR" || test -d "$GNULIB_SRCDIR" \
-  || die "Error: \$GNULIB_SRCDIR environment variable or --gnulib-srcdir option is specified, but does not denote a directory"
-
-if test -n "$checkout_only_file" && test ! -r "$checkout_only_file"; then
-  die "Running this script from a non-checked-out distribution is risky."
-fi
-
-if $use_gnulib; then
-  if test -z "$GNULIB_SRCDIR"; then
-    gnulib_path=$(test -f .gitmodules && git config --file .gitmodules submodule.gnulib.path)
-    test -z "$gnulib_path" && gnulib_path=gnulib
-    GNULIB_SRCDIR=$gnulib_path
-  fi
-fi
-
-version_controlled_file() {
-  parent=$1
-  file=$2
-  if test -d .git; then
-    git rm -n "$file" > /dev/null 2>&1
-  elif test -d .svn; then
-    svn log -r HEAD "$file" > /dev/null 2>&1
-  elif test -d CVS; then
-    grep -F "/${file##*/}/" "$parent/CVS/Entries" 2>/dev/null |
-             grep '^/[^/]*/[0-9]' > /dev/null
-  else
-    warn_ "no version control for $file?"
-    false
-  fi
-}
-
-# Strip blank and comment lines to leave significant entries.
-gitignore_entries() {
-  sed '/^#/d; /^$/d' "$@"
-}
-
-# If $STR is not already on a line by itself in $FILE, insert it at the start.
-# Entries are inserted at the start of the ignore list to ensure existing
-# entries starting with ! are not overridden.  Such entries support
-# whitelisting exceptions after a more generic blacklist pattern.
-insert_if_absent() {
-  file=$1
-  str=$2
-  test -f $file || touch $file
-  test -r $file || die "Error: failed to read ignore file: $file"
-  duplicate_entries=$(gitignore_entries $file | sort | uniq -d)
-  if [ "$duplicate_entries" ] ; then
-    die "Error: Duplicate entries in $file: " $duplicate_entries
-  fi
-  linesold=$(gitignore_entries $file | wc -l)
-  linesnew=$( { echo "$str"; cat $file; } | gitignore_entries | sort -u | wc -l)
-  if [ $linesold != $linesnew ] ; then
-    { echo "$str" | cat - $file > $file.bak && mv $file.bak $file; } \
-      || die "insert_if_absent $file $str: failed"
-  fi
-}
-
-# Adjust $PATTERN for $VC_IGNORE_FILE and insert it with
-# insert_if_absent.
-insert_vc_ignore() {
-  vc_ignore_file="$1"
-  pattern="$2"
-  case $vc_ignore_file in
-  *.gitignore)
-    # A .gitignore entry that does not start with '/' applies
-    # recursively to subdirectories, so prepend '/' to every
-    # .gitignore entry.
-    pattern=$(echo "$pattern" | sed s,^,/,);;
-  esac
-  insert_if_absent "$vc_ignore_file" "$pattern"
-}
-
-symlink_to_dir()
-{
-  src=$1/$2
-  dst=${3-$2}
-
-  test -f "$src" && {
-
-    # If the destination directory doesn't exist, create it.
-    # This is required at least for "lib/uniwidth/cjk.h".
-    dst_dir=$(dirname "$dst")
-    if ! test -d "$dst_dir"; then
-      mkdir -p "$dst_dir"
-
-      # If we've just created a directory like lib/uniwidth,
-      # tell version control system(s) it's ignorable.
-      # FIXME: for now, this does only one level
-      parent=$(dirname "$dst_dir")
-      for dot_ig in x $vc_ignore; do
-        test $dot_ig = x && continue
-        ig=$parent/$dot_ig
-        insert_vc_ignore $ig "${dst_dir##*/}"
-      done
-    fi
-
-    if $copy; then
-      {
-        test ! -h "$dst" || {
-          echo "$me: rm -f $dst" &&
-          rm -f "$dst"
-        }
-      } &&
-      test -f "$dst" &&
-      cmp -s "$src" "$dst" || {
-        echo "$me: cp -fp $src $dst" &&
-        cp -fp "$src" "$dst"
-      }
-    else
-      # Leave any existing symlink alone, if it already points to the source,
-      # so that broken build tools that care about symlink times
-      # aren't confused into doing unnecessary builds.  Conversely, if the
-      # existing symlink's timestamp is older than the source, make it afresh,
-      # so that broken tools aren't confused into skipping needed builds.  See
-      # <https://lists.gnu.org/r/bug-gnulib/2011-05/msg00326.html>.
-      test -h "$dst" &&
-      src_ls=$(ls -diL "$src" 2>/dev/null) && set $src_ls && src_i=$1 &&
-      dst_ls=$(ls -diL "$dst" 2>/dev/null) && set $dst_ls && dst_i=$1 &&
-      test "$src_i" = "$dst_i" &&
-      both_ls=$(ls -dt "$src" "$dst") &&
-      test "X$both_ls" = "X$dst$nl$src" || {
-        dot_dots=
-        case $src in
-        /*) ;;
-        *)
-          case /$dst/ in
-          *//* | */../* | */./* | /*/*/*/*/*/)
-             die "invalid symlink calculation: $src -> $dst";;
-          /*/*/*/*/)    dot_dots=../../../;;
-          /*/*/*/)      dot_dots=../../;;
-          /*/*/)        dot_dots=../;;
-          esac;;
-        esac
-
-        echo "$me: ln -fs $dot_dots$src $dst" &&
-        ln -fs "$dot_dots$src" "$dst"
-      }
-    fi
-  }
-}
-
-# Die if there is no AC_CONFIG_AUX_DIR($build_aux) line in configure.ac.
-found_aux_dir=no
-grep '^[	 ]*AC_CONFIG_AUX_DIR(\['"$build_aux"'])' configure.ac \
-    >/dev/null && found_aux_dir=yes
-grep '^[	 ]*AC_CONFIG_AUX_DIR('"$build_aux"')' configure.ac \
-    >/dev/null && found_aux_dir=yes
-test $found_aux_dir = yes \
-  || die "configure.ac lacks 'AC_CONFIG_AUX_DIR([$build_aux])'; add it"
-
-# If $build_aux doesn't exist, create it now, otherwise some bits
-# below will malfunction.  If creating it, also mark it as ignored.
-if test ! -d $build_aux; then
-  mkdir $build_aux
-  for dot_ig in x $vc_ignore; do
-    test $dot_ig = x && continue
-    insert_vc_ignore $dot_ig $build_aux
-  done
-fi
-
-check_build_prerequisites false
-
-use_libtool=0
-# We'd like to use grep -E, to see if any of LT_INIT,
-# AC_PROG_LIBTOOL, AM_PROG_LIBTOOL is used in configure.ac,
-# but that's not portable enough (e.g., for Solaris).
-grep '^[	 ]*A[CM]_PROG_LIBTOOL' configure.ac >/dev/null \
-  && use_libtool=1
-grep '^[	 ]*LT_INIT' configure.ac >/dev/null \
-  && use_libtool=1
-if test $use_libtool = 1; then
-  find_tool LIBTOOLIZE glibtoolize libtoolize
-fi
-
-if $use_gnulib; then
-  gnulib_tool=$GNULIB_SRCDIR/gnulib-tool
-  <$gnulib_tool || exit $?
-fi
-
-# NOTE: we have to be careful to run both autopoint and libtoolize
-# before gnulib-tool, since gnulib-tool is likely to provide newer
-# versions of files "installed" by these two programs.
-# Then, *after* gnulib-tool (see below), we have to be careful to
-# run autoreconf in such a way that it does not run either of these
-# two just-pre-run programs.
-
-# Import from gettext.
-with_gettext=yes
-grep '^[	 ]*AM_GNU_GETTEXT_VERSION(' configure.ac >/dev/null || \
-    with_gettext=no
-
-if test $with_gettext = yes || test $use_libtool = 1; then
-
-  tempbase=.bootstrap$$
-  trap "rm -f $tempbase.0 $tempbase.1" HUP INT PIPE TERM
-
-  > $tempbase.0 > $tempbase.1 &&
-  find . ! -type d -print | sort > $tempbase.0 || exit
-
-  if test $with_gettext = yes; then
-    # Released autopoint has the tendency to install macros that have been
-    # obsoleted in current gnulib, so run this before gnulib-tool.
-    echo "$0: $AUTOPOINT --force"
-    $AUTOPOINT --force || exit
-  fi
-
-  # Autoreconf runs aclocal before libtoolize, which causes spurious
-  # warnings if the initial aclocal is confused by the libtoolized
-  # (or worse out-of-date) macro directory.
-  # libtoolize 1.9b added the --install option; but we support back
-  # to libtoolize 1.5.22, where the install action was default.
-  if test $use_libtool = 1; then
-    install=
-    case $($LIBTOOLIZE --help) in
-      *--install*) install=--install ;;
-    esac
-    echo "running: $LIBTOOLIZE $install --copy"
-    $LIBTOOLIZE $install --copy
-  fi
-
-  find . ! -type d -print | sort >$tempbase.1
-  old_IFS=$IFS
-  IFS=$nl
-  for file in $(comm -13 $tempbase.0 $tempbase.1); do
-    IFS=$old_IFS
-    parent=${file%/*}
-    version_controlled_file "$parent" "$file" || {
-      for dot_ig in x $vc_ignore; do
-        test $dot_ig = x && continue
-        ig=$parent/$dot_ig
-        insert_vc_ignore "$ig" "${file##*/}"
-      done
-    }
-  done
-  IFS=$old_IFS
-
-  rm -f $tempbase.0 $tempbase.1
-  trap - HUP INT PIPE TERM
-fi
-
-# Import from gnulib.
-
-if $use_gnulib; then
-  gnulib_tool_options="\
-   --no-changelog\
-   --aux-dir=$build_aux\
-   --doc-base=$doc_base\
-   --lib=$gnulib_name\
-   --m4-base=$m4_base/\
-   --source-base=$source_base/\
-   --tests-base=$tests_base\
-   --local-dir=$local_gl_dir\
-   $gnulib_tool_option_extras\
-  "
-  if test $use_libtool = 1; then
-    case "$gnulib_tool_options " in
-      *' --libtool '*) ;;
-      *) gnulib_tool_options="$gnulib_tool_options --libtool" ;;
-    esac
-  fi
-  echo "$0: $gnulib_tool $gnulib_tool_options --import ..."
-  $gnulib_tool $gnulib_tool_options --import $gnulib_modules \
-    || die "gnulib-tool failed"
-
-  for file in $gnulib_files; do
-    symlink_to_dir "$GNULIB_SRCDIR" $file \
-      || die "failed to symlink $file"
-  done
-fi
-
-bootstrap_post_import_hook \
-  || die "bootstrap_post_import_hook failed"
-
-# Remove any dangling symlink matching "*.m4" or "*.[ch]" in some
-# gnulib-populated directories.  Such .m4 files would cause aclocal to fail.
-# The following requires GNU find 4.2.3 or newer.  Considering the usual
-# portability constraints of this script, that may seem a very demanding
-# requirement, but it should be ok.  Ignore any failure, which is fine,
-# since this is only a convenience to help developers avoid the relatively
-# unusual case in which a symlinked-to .m4 file is git-removed from gnulib
-# between successive runs of this script.
-find "$m4_base" "$source_base" \
-  -depth \( -name '*.m4' -o -name '*.[ch]' \) \
-  -type l -xtype l -delete > /dev/null 2>&1
-
-# Invoke autoreconf with --force --install to ensure upgrades of tools
-# such as ylwrap.
-AUTORECONFFLAGS="--verbose --install --force -I $m4_base $ACLOCAL_FLAGS"
-
-# Some systems (RHEL 5) are using ancient autotools, for which the
-# --no-recursive option had not been invented.  Detect that lack and
-# omit the option when it's not supported.  FIXME in 2017: remove this
-# hack when RHEL 5 autotools are updated, or when they become irrelevant.
-case $($AUTORECONF --help) in
-  *--no-recursive*) AUTORECONFFLAGS="$AUTORECONFFLAGS --no-recursive";;
-esac
-
-# Tell autoreconf not to invoke autopoint or libtoolize; they were run above.
-echo "running: AUTOPOINT=true LIBTOOLIZE=true $AUTORECONF $AUTORECONFFLAGS"
-AUTOPOINT=true LIBTOOLIZE=true $AUTORECONF $AUTORECONFFLAGS \
-  || die "autoreconf failed"
-
-# Get some extra files from gnulib, overriding existing files.
-for file in $gnulib_extra_files; do
-  case $file in
-    */INSTALL) dst=INSTALL;;
-    build-aux/*) dst=$build_aux/${file#build-aux/};;
-    *) dst=$file;;
-  esac
-  symlink_to_dir "$GNULIB_SRCDIR" $file $dst \
-    || die "failed to symlink $file"
-done
-
-if test $with_gettext = yes; then
-  # Create gettext configuration.
-  echo "$0: Creating po/Makevars from po/Makevars.template ..."
-  rm -f po/Makevars
-  sed '
-    /^EXTRA_LOCALE_CATEGORIES *=/s/=.*/= '"$EXTRA_LOCALE_CATEGORIES"'/
-    /^COPYRIGHT_HOLDER *=/s/=.*/= '"$COPYRIGHT_HOLDER"'/
-    /^MSGID_BUGS_ADDRESS *=/s|=.*|= '"$MSGID_BUGS_ADDRESS"'|
-    /^XGETTEXT_OPTIONS *=/{
-      s/$/ \\/
-      a\
-          '"$XGETTEXT_OPTIONS"' $${end_of_xgettext_options+}
-    }
-  ' po/Makevars.template >po/Makevars \
-    || die 'cannot generate po/Makevars'
-
-  # If the 'gettext' module is in use, grab the latest Makefile.in.in.
-  # If only the 'gettext-h' module is in use, assume autopoint already
-  # put the correct version of this file into place.
-  case $gnulib_modules in
-    *gettext-h*) ;;
-    *gettext*)
-      cp $GNULIB_SRCDIR/build-aux/po/Makefile.in.in po/Makefile.in.in \
-        || die "cannot create po/Makefile.in.in"
-      ;;
-  esac
-
-  if test -d runtime-po; then
-    # Similarly for runtime-po/Makevars, but not quite the same.
-    rm -f runtime-po/Makevars
-    sed '
-      /^DOMAIN *=.*/s/=.*/= '"$package"'-runtime/
-      /^subdir *=.*/s/=.*/= runtime-po/
-      /^MSGID_BUGS_ADDRESS *=/s/=.*/= bug-'"$package"'@gnu.org/
-      /^XGETTEXT_OPTIONS *=/{
-        s/$/ \\/
-        a\
-            '"$XGETTEXT_OPTIONS_RUNTIME"' $${end_of_xgettext_options+}
-      }
-    ' po/Makevars.template >runtime-po/Makevars \
-    || die 'cannot generate runtime-po/Makevars'
-
-    # Copy identical files from po to runtime-po.
-    (cd po && cp -p Makefile.in.in *-quot *.header *.sed *.sin ../runtime-po)
-  fi
-fi
-
-bootstrap_epilogue
-
-echo "$0: done.  Now you can run './configure'."
-
-# ----------------------------------------------------------------------------
-
-# Local Variables:
-# eval: (add-hook 'before-save-hook 'time-stamp)
-# time-stamp-start: "scriptversion="
-# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC0"
-# time-stamp-end: "; # UTC"
-# End:
+autogen "$@"
diff --git a/top/bootstrap-funclib.sh b/top/bootstrap-funclib.sh
index ef0fa70ae5..efb6a086a3 100644
--- a/top/bootstrap-funclib.sh
+++ b/top/bootstrap-funclib.sh
@@ -1,6 +1,6 @@
 # A library of shell functions for autopull.sh, autogen.sh, and bootstrap.
 
-scriptversion=2022-12-27.03; # UTC
+scriptversion=2022-12-27.16; # UTC
 
 # Copyright (C) 2003-2022 Free Software Foundation, Inc.
 #
@@ -583,6 +583,455 @@ else
   use_gnulib=true
 fi
 
+
+# -------- Generate files automatically from existing sources.  --------------
+
+autogen_usage() {
+  cat <<EOF
+Usage: $me [OPTION]...
+Bootstrap this package from the checked-out sources.
+
+Optional environment variables:
+  GNULIB_SRCDIR            Specifies the local directory where gnulib
+                           sources reside.  Use this if you already
+                           have gnulib sources on your machine, and
+                           you want to use these sources.
+
+Options:
+  --copy                   copy files instead of creating symbolic links
+  --force                  attempt to bootstrap even if the sources seem
+                           not to have been checked out
+EOF
+  bootstrap_print_option_usage_hook
+  cat <<EOF
+If the file bootstrap.conf exists in the same directory as this script, its
+contents are read as shell variables to configure the bootstrap.
+
+For build prerequisites, environment variables like \$AUTOCONF and \$AMTAR
+are honored.
+
+Gnulib sources are assumed to be present:
+  * in \$GNULIB_SRCDIR, if that environment variable is set,
+  * otherwise, in the 'gnulib' submodule, if such a submodule is configured,
+  * otherwise, in the 'gnulib' subdirectory.
+
+Running without arguments will suffice in most cases.
+EOF
+}
+
+
+version_controlled_file() {
+  parent=$1
+  file=$2
+  if test -d .git; then
+    git rm -n "$file" > /dev/null 2>&1
+  elif test -d .svn; then
+    svn log -r HEAD "$file" > /dev/null 2>&1
+  elif test -d CVS; then
+    grep -F "/${file##*/}/" "$parent/CVS/Entries" 2>/dev/null |
+             grep '^/[^/]*/[0-9]' > /dev/null
+  else
+    warn_ "no version control for $file?"
+    false
+  fi
+}
+
+# Strip blank and comment lines to leave significant entries.
+gitignore_entries() {
+  sed '/^#/d; /^$/d' "$@"
+}
+
+# If $STR is not already on a line by itself in $FILE, insert it at the start.
+# Entries are inserted at the start of the ignore list to ensure existing
+# entries starting with ! are not overridden.  Such entries support
+# whitelisting exceptions after a more generic blacklist pattern.
+insert_if_absent() {
+  file=$1
+  str=$2
+  test -f $file || touch $file
+  test -r $file || die "Error: failed to read ignore file: $file"
+  duplicate_entries=$(gitignore_entries $file | sort | uniq -d)
+  if [ "$duplicate_entries" ] ; then
+    die "Error: Duplicate entries in $file: " $duplicate_entries
+  fi
+  linesold=$(gitignore_entries $file | wc -l)
+  linesnew=$( { echo "$str"; cat $file; } | gitignore_entries | sort -u | wc -l)
+  if [ $linesold != $linesnew ] ; then
+    { echo "$str" | cat - $file > $file.bak && mv $file.bak $file; } \
+      || die "insert_if_absent $file $str: failed"
+  fi
+}
+
+# Adjust $PATTERN for $VC_IGNORE_FILE and insert it with
+# insert_if_absent.
+insert_vc_ignore() {
+  vc_ignore_file="$1"
+  pattern="$2"
+  case $vc_ignore_file in
+  *.gitignore)
+    # A .gitignore entry that does not start with '/' applies
+    # recursively to subdirectories, so prepend '/' to every
+    # .gitignore entry.
+    pattern=$(echo "$pattern" | sed s,^,/,);;
+  esac
+  insert_if_absent "$vc_ignore_file" "$pattern"
+}
+
+symlink_to_dir()
+{
+  src=$1/$2
+  dst=${3-$2}
+
+  test -f "$src" && {
+
+    # If the destination directory doesn't exist, create it.
+    # This is required at least for "lib/uniwidth/cjk.h".
+    dst_dir=$(dirname "$dst")
+    if ! test -d "$dst_dir"; then
+      mkdir -p "$dst_dir"
+
+      # If we've just created a directory like lib/uniwidth,
+      # tell version control system(s) it's ignorable.
+      # FIXME: for now, this does only one level
+      parent=$(dirname "$dst_dir")
+      for dot_ig in x $vc_ignore; do
+        test $dot_ig = x && continue
+        ig=$parent/$dot_ig
+        insert_vc_ignore $ig "${dst_dir##*/}"
+      done
+    fi
+
+    if $copy; then
+      {
+        test ! -h "$dst" || {
+          echo "$me: rm -f $dst" &&
+          rm -f "$dst"
+        }
+      } &&
+      test -f "$dst" &&
+      cmp -s "$src" "$dst" || {
+        echo "$me: cp -fp $src $dst" &&
+        cp -fp "$src" "$dst"
+      }
+    else
+      # Leave any existing symlink alone, if it already points to the source,
+      # so that broken build tools that care about symlink times
+      # aren't confused into doing unnecessary builds.  Conversely, if the
+      # existing symlink's timestamp is older than the source, make it afresh,
+      # so that broken tools aren't confused into skipping needed builds.  See
+      # <https://lists.gnu.org/r/bug-gnulib/2011-05/msg00326.html>.
+      test -h "$dst" &&
+      src_ls=$(ls -diL "$src" 2>/dev/null) && set $src_ls && src_i=$1 &&
+      dst_ls=$(ls -diL "$dst" 2>/dev/null) && set $dst_ls && dst_i=$1 &&
+      test "$src_i" = "$dst_i" &&
+      both_ls=$(ls -dt "$src" "$dst") &&
+      test "X$both_ls" = "X$dst$nl$src" || {
+        dot_dots=
+        case $src in
+        /*) ;;
+        *)
+          case /$dst/ in
+          *//* | */../* | */./* | /*/*/*/*/*/)
+             die "invalid symlink calculation: $src -> $dst";;
+          /*/*/*/*/)    dot_dots=../../../;;
+          /*/*/*/)      dot_dots=../../;;
+          /*/*/)        dot_dots=../;;
+          esac;;
+        esac
+
+        echo "$me: ln -fs $dot_dots$src $dst" &&
+        ln -fs "$dot_dots$src" "$dst"
+      }
+    fi
+  }
+}
+
+# Regenerate all autogeneratable files that are omitted from the
+# version control repository.  In particular, regenerate all
+# aclocal.m4, config.h.in, Makefile.in, configure files with new
+# versions of autoconf or automake.
+autogen()
+{
+  # Ensure that CDPATH is not set.  Otherwise, the output from cd
+  # would cause trouble in at least one use below.
+  (unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+  # Environment variables that may be set by the user.
+  : "${AUTOPOINT=autopoint}"
+  : "${AUTORECONF=autoreconf}"
+
+  if test "$vc_ignore" = auto; then
+    vc_ignore=
+    test -d .git && vc_ignore=.gitignore
+    test -d CVS && vc_ignore="$vc_ignore .cvsignore"
+  fi
+
+
+  # Parse options.
+
+  # Whether to use copies instead of symlinks.
+  copy=false
+
+  for option
+  do
+    case $option in
+    --help)
+      autogen_usage
+      return;;
+    --version)
+      set -e
+      echo "autogen.sh $scriptversion"
+      echo "$copyright"
+      return 0
+      ;;
+    --force)
+      checkout_only_file=;;
+    --copy)
+      copy=true;;
+    *)
+      bootstrap_option_hook $option || die "$option: unknown option";;
+    esac
+  done
+
+  test -z "$GNULIB_SRCDIR" || test -d "$GNULIB_SRCDIR" \
+    || die "Error: \$GNULIB_SRCDIR environment variable or --gnulib-srcdir option is specified, but does not denote a directory"
+
+  if test -n "$checkout_only_file" && test ! -r "$checkout_only_file"; then
+    die "Running this script from a non-checked-out distribution is risky."
+  fi
+
+  if $use_gnulib; then
+    if test -z "$GNULIB_SRCDIR"; then
+      gnulib_path=$(test -f .gitmodules && git config --file .gitmodules submodule.gnulib.path)
+      test -z "$gnulib_path" && gnulib_path=gnulib
+      GNULIB_SRCDIR=$gnulib_path
+    fi
+  fi
+
+  # Die if there is no AC_CONFIG_AUX_DIR($build_aux) line in configure.ac.
+  found_aux_dir=no
+  grep '^[	 ]*AC_CONFIG_AUX_DIR(\['"$build_aux"'])' configure.ac \
+      >/dev/null && found_aux_dir=yes
+  grep '^[	 ]*AC_CONFIG_AUX_DIR('"$build_aux"')' configure.ac \
+      >/dev/null && found_aux_dir=yes
+  test $found_aux_dir = yes \
+    || die "configure.ac lacks 'AC_CONFIG_AUX_DIR([$build_aux])'; add it"
+
+  # If $build_aux doesn't exist, create it now, otherwise some bits
+  # below will malfunction.  If creating it, also mark it as ignored.
+  if test ! -d $build_aux; then
+    mkdir $build_aux
+    for dot_ig in x $vc_ignore; do
+      test $dot_ig = x && continue
+      insert_vc_ignore $dot_ig $build_aux
+    done
+  fi
+
+  check_build_prerequisites false
+
+  use_libtool=0
+  # We'd like to use grep -E, to see if any of LT_INIT,
+  # AC_PROG_LIBTOOL, AM_PROG_LIBTOOL is used in configure.ac,
+  # but that's not portable enough (e.g., for Solaris).
+  grep '^[	 ]*A[CM]_PROG_LIBTOOL' configure.ac >/dev/null \
+    && use_libtool=1
+  grep '^[	 ]*LT_INIT' configure.ac >/dev/null \
+    && use_libtool=1
+  if test $use_libtool = 1; then
+    find_tool LIBTOOLIZE glibtoolize libtoolize
+  fi
+
+  if $use_gnulib; then
+    gnulib_tool=$GNULIB_SRCDIR/gnulib-tool
+    <$gnulib_tool || return
+  fi
+
+  # NOTE: we have to be careful to run both autopoint and libtoolize
+  # before gnulib-tool, since gnulib-tool is likely to provide newer
+  # versions of files "installed" by these two programs.
+  # Then, *after* gnulib-tool (see below), we have to be careful to
+  # run autoreconf in such a way that it does not run either of these
+  # two just-pre-run programs.
+
+  # Import from gettext.
+  with_gettext=yes
+  grep '^[	 ]*AM_GNU_GETTEXT_VERSION(' configure.ac >/dev/null || \
+      with_gettext=no
+
+  if test $with_gettext = yes || test $use_libtool = 1; then
+
+    tempbase=.bootstrap$$
+    trap "rm -f $tempbase.0 $tempbase.1" HUP INT PIPE TERM
+
+    > $tempbase.0 > $tempbase.1 &&
+    find . ! -type d -print | sort > $tempbase.0 || return
+
+    if test $with_gettext = yes; then
+      # Released autopoint has the tendency to install macros that have been
+      # obsoleted in current gnulib, so run this before gnulib-tool.
+      echo "$0: $AUTOPOINT --force"
+      $AUTOPOINT --force || return
+    fi
+
+    # Autoreconf runs aclocal before libtoolize, which causes spurious
+    # warnings if the initial aclocal is confused by the libtoolized
+    # (or worse out-of-date) macro directory.
+    # libtoolize 1.9b added the --install option; but we support back
+    # to libtoolize 1.5.22, where the install action was default.
+    if test $use_libtool = 1; then
+      install=
+      case $($LIBTOOLIZE --help) in
+        *--install*) install=--install ;;
+      esac
+      echo "running: $LIBTOOLIZE $install --copy"
+      $LIBTOOLIZE $install --copy
+    fi
+
+    find . ! -type d -print | sort >$tempbase.1
+    old_IFS=$IFS
+    IFS=$nl
+    for file in $(comm -13 $tempbase.0 $tempbase.1); do
+      IFS=$old_IFS
+      parent=${file%/*}
+      version_controlled_file "$parent" "$file" || {
+        for dot_ig in x $vc_ignore; do
+          test $dot_ig = x && continue
+          ig=$parent/$dot_ig
+          insert_vc_ignore "$ig" "${file##*/}"
+        done
+      }
+    done
+    IFS=$old_IFS
+
+    rm -f $tempbase.0 $tempbase.1
+    trap - HUP INT PIPE TERM
+  fi
+
+  # Import from gnulib.
+
+  if $use_gnulib; then
+    gnulib_tool_options="\
+     --no-changelog\
+     --aux-dir=$build_aux\
+     --doc-base=$doc_base\
+     --lib=$gnulib_name\
+     --m4-base=$m4_base/\
+     --source-base=$source_base/\
+     --tests-base=$tests_base\
+     --local-dir=$local_gl_dir\
+     $gnulib_tool_option_extras\
+    "
+    if test $use_libtool = 1; then
+      case "$gnulib_tool_options " in
+        *' --libtool '*) ;;
+        *) gnulib_tool_options="$gnulib_tool_options --libtool" ;;
+      esac
+    fi
+    echo "$0: $gnulib_tool $gnulib_tool_options --import ..."
+    $gnulib_tool $gnulib_tool_options --import $gnulib_modules \
+      || die "gnulib-tool failed"
+
+    for file in $gnulib_files; do
+      symlink_to_dir "$GNULIB_SRCDIR" $file \
+        || die "failed to symlink $file"
+    done
+  fi
+
+  bootstrap_post_import_hook \
+    || die "bootstrap_post_import_hook failed"
+
+  # Remove any dangling symlink matching "*.m4" or "*.[ch]" in some
+  # gnulib-populated directories.  Such .m4 files would cause aclocal to fail.
+  # The following requires GNU find 4.2.3 or newer.  Considering the usual
+  # portability constraints of this script, that may seem a very demanding
+  # requirement, but it should be ok.  Ignore any failure, which is fine,
+  # since this is only a convenience to help developers avoid the relatively
+  # unusual case in which a symlinked-to .m4 file is git-removed from gnulib
+  # between successive runs of this script.
+  find "$m4_base" "$source_base" \
+    -depth \( -name '*.m4' -o -name '*.[ch]' \) \
+    -type l -xtype l -delete > /dev/null 2>&1
+
+  # Invoke autoreconf with --force --install to ensure upgrades of tools
+  # such as ylwrap.
+  AUTORECONFFLAGS="--verbose --install --force -I $m4_base $ACLOCAL_FLAGS"
+
+  # Some systems (RHEL 5) are using ancient autotools, for which the
+  # --no-recursive option had not been invented.  Detect that lack and
+  # omit the option when it's not supported.  FIXME in 2017: remove this
+  # hack when RHEL 5 autotools are updated, or when they become irrelevant.
+  case $($AUTORECONF --help) in
+    *--no-recursive*) AUTORECONFFLAGS="$AUTORECONFFLAGS --no-recursive";;
+  esac
+
+  # Tell autoreconf not to invoke autopoint or libtoolize; they were run above.
+  echo "running: AUTOPOINT=true LIBTOOLIZE=true $AUTORECONF $AUTORECONFFLAGS"
+  AUTOPOINT=true LIBTOOLIZE=true $AUTORECONF $AUTORECONFFLAGS \
+    || die "autoreconf failed"
+
+  # Get some extra files from gnulib, overriding existing files.
+  for file in $gnulib_extra_files; do
+    case $file in
+      */INSTALL) dst=INSTALL;;
+      build-aux/*) dst=$build_aux/${file#build-aux/};;
+      *) dst=$file;;
+    esac
+    symlink_to_dir "$GNULIB_SRCDIR" $file $dst \
+      || die "failed to symlink $file"
+  done
+
+  if test $with_gettext = yes; then
+    # Create gettext configuration.
+    echo "$0: Creating po/Makevars from po/Makevars.template ..."
+    rm -f po/Makevars
+    sed '
+      /^EXTRA_LOCALE_CATEGORIES *=/s/=.*/= '"$EXTRA_LOCALE_CATEGORIES"'/
+      /^COPYRIGHT_HOLDER *=/s/=.*/= '"$COPYRIGHT_HOLDER"'/
+      /^MSGID_BUGS_ADDRESS *=/s|=.*|= '"$MSGID_BUGS_ADDRESS"'|
+      /^XGETTEXT_OPTIONS *=/{
+        s/$/ \\/
+        a\
+            '"$XGETTEXT_OPTIONS"' $${end_of_xgettext_options+}
+      }
+    ' po/Makevars.template >po/Makevars \
+      || die 'cannot generate po/Makevars'
+
+    # If the 'gettext' module is in use, grab the latest Makefile.in.in.
+    # If only the 'gettext-h' module is in use, assume autopoint already
+    # put the correct version of this file into place.
+    case $gnulib_modules in
+      *gettext-h*) ;;
+      *gettext*)
+        cp $GNULIB_SRCDIR/build-aux/po/Makefile.in.in po/Makefile.in.in \
+          || die "cannot create po/Makefile.in.in"
+        ;;
+    esac
+
+    if test -d runtime-po; then
+      # Similarly for runtime-po/Makevars, but not quite the same.
+      rm -f runtime-po/Makevars
+      sed '
+        /^DOMAIN *=.*/s/=.*/= '"$package"'-runtime/
+        /^subdir *=.*/s/=.*/= runtime-po/
+        /^MSGID_BUGS_ADDRESS *=/s/=.*/= bug-'"$package"'@gnu.org/
+        /^XGETTEXT_OPTIONS *=/{
+          s/$/ \\/
+          a\
+              '"$XGETTEXT_OPTIONS_RUNTIME"' $${end_of_xgettext_options+}
+        }
+      ' po/Makevars.template >runtime-po/Makevars \
+      || die 'cannot generate runtime-po/Makevars'
+
+      # Copy identical files from po to runtime-po.
+      (cd po && cp -p Makefile.in.in *-quot *.header *.sed *.sin ../runtime-po)
+    fi
+  fi
+
+  bootstrap_epilogue
+
+  echo "$0: done.  Now you can run './configure'."
+}
+
 # ----------------------------------------------------------------------------
 
 # Local Variables:
-- 
2.25.1




^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/6] Make autopull a shell function too
  2022-12-27 18:59 [PATCH 0/6] build-aux/bootstrap that doesn't need to replace itself Paul Eggert
                   ` (2 preceding siblings ...)
  2022-12-27 18:59 ` [PATCH 2/6] Make autogen a shell function too Paul Eggert
@ 2022-12-27 18:59 ` Paul Eggert
  2022-12-27 19:00 ` [PATCH 4/6] Bootstrap with functions, not scripts Paul Eggert
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Paul Eggert @ 2022-12-27 18:59 UTC (permalink / raw)
  To: bug-gnulib; +Cc: Paul Eggert

This does not change behavior.  It is helpful for future changes.
* top/autopull.sh: Call autopull to do the actual work.
(usage, download_po_files, update_po_files):
Move to top/bootstrap-funclib.sh.
* top/bootstrap-funclib.sh (autopull_usage): Rename from ‘usage’.
(autopull): New function, containing the top level of the
old top/autopull.sh.
---
 ChangeLog                |   9 ++
 build-aux/bootstrap      | 232 ++++++++++++++++++++++++++++++++++++++
 top/autopull.sh          | 238 +--------------------------------------
 top/bootstrap-funclib.sh | 232 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 474 insertions(+), 237 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 3fd73f3f74..21dbc68b10 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
 2022-12-27  Paul Eggert  <eggert@cs.ucla.edu>
 
+	Make autopull a shell function too
+	This does not change behavior.  It is helpful for future changes.
+	* top/autopull.sh: Call autopull to do the actual work.
+	(usage, download_po_files, update_po_files):
+	Move to top/bootstrap-funclib.sh.
+	* top/bootstrap-funclib.sh (autopull_usage): Rename from ‘usage’.
+	(autopull): New function, containing the top level of the
+	old top/autopull.sh.
+
 	Make autogen a shell function too
 	This does not change behavior.  It is helpful for future changes.
 	* top/autogen.sh: Call autogen to do the actual work.
diff --git a/build-aux/bootstrap b/build-aux/bootstrap
index c7566e824b..78e307c5ef 100755
--- a/build-aux/bootstrap
+++ b/build-aux/bootstrap
@@ -622,6 +622,238 @@ else
   use_gnulib=true
 fi
 
+# -------- Fetch auxiliary files from the network.  --------------------------
+
+autopull_usage() {
+  cat <<EOF
+Usage: $me [OPTION]...
+Bootstrap this package from the checked-out sources.
+
+Optional environment variables:
+  GNULIB_SRCDIR            Specifies the local directory where gnulib
+                           sources reside.  Use this if you already
+                           have gnulib sources on your machine, and
+                           you want to use these sources.
+  GNULIB_REFDIR            Specifies the local directory where a gnulib
+                           repository (with a .git subdirectory) resides.
+                           Use this if you already have gnulib sources
+                           and history on your machine, and do not want
+                           to waste your bandwidth downloading them again.
+  GNULIB_URL               Cloneable URL of the gnulib repository.
+
+Options:
+  --bootstrap-sync         if this bootstrap script is not identical to
+                           the version in the local gnulib sources,
+                           update this script, and then restart it with
+                           /bin/sh or the shell \$CONFIG_SHELL
+  --no-bootstrap-sync      do not check whether bootstrap is out of sync
+  --force                  attempt to bootstrap even if the sources seem
+                           not to have been checked out
+  --no-git                 do not use git to update gnulib.  Requires that
+                           \$GNULIB_SRCDIR or the --gnulib-srcdir option
+                           points to a gnulib repository with the correct
+                           revision
+  --skip-po                do not download po files
+EOF
+  bootstrap_print_option_usage_hook
+  cat <<EOF
+If the file bootstrap.conf exists in the same directory as this script, its
+contents are read as shell variables to configure the bootstrap.
+
+For build prerequisites, environment variables like \$AUTOCONF and \$AMTAR
+are honored.
+
+Gnulib sources can be fetched in various ways:
+
+ * If the environment variable GNULIB_SRCDIR is set (either as an
+   environment variable or via the --gnulib-srcdir option), then sources
+   are fetched from that local directory.  If it is a git repository and
+   the configuration variable GNULIB_REVISION is set in bootstrap.conf,
+   then that revision is checked out.
+
+ * Otherwise, if this package is in a git repository with a 'gnulib'
+   submodule configured, then that submodule is initialized and updated
+   and sources are fetched from there.  If GNULIB_REFDIR is set (either
+   as an environment variable or via the --gnulib-refdir option) and is
+   a git repository, then it is used as a reference.
+
+ * Otherwise, if the 'gnulib' directory does not exist, Gnulib sources
+   are cloned into that directory using git from \$GNULIB_URL, defaulting
+   to $default_gnulib_url.
+   If the configuration variable GNULIB_REVISION is set in bootstrap.conf,
+   then that revision is checked out.
+
+ * Otherwise, the existing Gnulib sources in the 'gnulib' directory are
+   used.  If it is a git repository and the configuration variable
+   GNULIB_REVISION is set in bootstrap.conf, then that revision is
+   checked out.
+
+If you maintain a package and want to pin a particular revision of the
+Gnulib sources that has been tested with your package, then there are
+two possible approaches: either configure a 'gnulib' submodule with the
+appropriate revision, or set GNULIB_REVISION (and if necessary
+GNULIB_URL) in bootstrap.conf.
+
+Running without arguments will suffice in most cases.
+EOF
+}
+
+# Fetch auxiliary files that are omitted from the version control
+# repository of this package.
+autopull()
+{
+  # Ensure that CDPATH is not set.  Otherwise, the output from cd
+  # would cause trouble in at least one use below.
+  (unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+  # Parse options.
+
+  # Use git to update gnulib sources
+  use_git=true
+
+  for option
+  do
+    case $option in
+    --help)
+      autopull_usage
+      return;;
+    --version)
+      set -e
+      echo "autopull.sh $scriptversion"
+      echo "$copyright"
+      return 0
+      ;;
+    --skip-po)
+      SKIP_PO=t;;
+    --force)
+      checkout_only_file=;;
+    --bootstrap-sync)
+      bootstrap_sync=true;;
+    --no-bootstrap-sync)
+      bootstrap_sync=false;;
+    --no-git)
+      use_git=false;;
+    *)
+      bootstrap_option_hook $option || die "$option: unknown option";;
+    esac
+  done
+
+  $use_git || test -n "$GNULIB_SRCDIR" \
+    || die "Error: --no-git requires \$GNULIB_SRCDIR environment variable or --gnulib-srcdir option"
+  test -z "$GNULIB_SRCDIR" || test -d "$GNULIB_SRCDIR" \
+    || die "Error: \$GNULIB_SRCDIR environment variable or --gnulib-srcdir option is specified, but does not denote a directory"
+
+  if test -n "$checkout_only_file" && test ! -r "$checkout_only_file"; then
+    die "Running this script from a non-checked-out distribution is risky."
+  fi
+
+  check_build_prerequisites $use_git
+
+  if $use_gnulib || $bootstrap_sync; then
+    prepare_GNULIB_SRCDIR
+    if $bootstrap_sync; then
+      upgrade_bootstrap
+    fi
+  fi
+
+  # Find sha1sum, named gsha1sum on MacPorts, shasum on Mac OS X 10.6.
+  # Also find the compatible sha1 utility on the BSDs
+  if test x"$SKIP_PO" = x; then
+    find_tool SHA1SUM sha1sum gsha1sum shasum sha1
+  fi
+
+  # See if we can use gnulib's git-merge-changelog merge driver.
+  if $use_git && test -d .git && check_exists git; then
+    if git config merge.merge-changelog.driver >/dev/null ; then
+      :
+    elif check_exists git-merge-changelog; then
+      echo "$0: initializing git-merge-changelog driver"
+      git config merge.merge-changelog.name 'GNU-style ChangeLog merge driver'
+      git config merge.merge-changelog.driver 'git-merge-changelog %O %A %B'
+    else
+      echo "$0: consider installing git-merge-changelog from gnulib"
+    fi
+  fi
+
+  case $SKIP_PO in
+  '')
+    if test -d po; then
+      update_po_files po $package || return
+    fi
+
+    if test -d runtime-po; then
+      update_po_files runtime-po $package-runtime || return
+    fi;;
+  esac
+
+  # ---------------------------------------------------------------------------
+
+  bootstrap_post_pull_hook \
+    || die "bootstrap_post_pull_hook failed"
+
+  # Don't proceed if there are uninitialized submodules.  In particular,
+  # autogen.sh will remove dangling links, which might be links into
+  # uninitialized submodules.
+  # But it's OK if the 'gnulib' submodule is uninitialized, as long as
+  # GNULIB_SRCDIR is set.
+  if $use_git; then
+    # Uninitialized submodules are listed with an initial dash.
+    uninitialized=`git submodule | grep '^-' | awk '{ print $2 }'`
+    if test -n "$GNULIB_SRCDIR"; then
+      uninitialized=`echo "$uninitialized" | grep -v '^gnulib$'`
+    fi
+    if test -n "$uninitialized"; then
+      die "Some git submodules are not initialized: "`echo "$uninitialized" | tr '\n' ',' | sed -e 's|,$|.|'`" Either use option '--no-git', or run 'git submodule update --init' and bootstrap again."
+    fi
+  fi
+
+  echo "$0: done.  Now you can run './autogen.sh'."
+}
+
+# ----------------------------- Get translations. -----------------------------
+
+download_po_files() {
+  subdir=$1
+  domain=$2
+  echo "$me: getting translations into $subdir for $domain..."
+  cmd=$(printf "$po_download_command_format" "$subdir" "$domain")
+  eval "$cmd"
+}
+
+# Mirror .po files to $po_dir/.reference and copy only the new
+# or modified ones into $po_dir.  Also update $po_dir/LINGUAS.
+# Note po files that exist locally only are left in $po_dir but will
+# not be included in LINGUAS and hence will not be distributed.
+update_po_files() {
+  # Directory containing primary .po files.
+  # Overwrite them only when we're sure a .po file is new.
+  po_dir=$1
+  domain=$2
+
+  # Mirror *.po files into this dir.
+  # Usually contains *.s1 checksum files.
+  ref_po_dir="$po_dir/.reference"
+
+  test -d $ref_po_dir || mkdir $ref_po_dir || return
+  download_po_files $ref_po_dir $domain \
+    && ls "$ref_po_dir"/*.po 2>/dev/null |
+      sed 's|.*/||; s|\.po$||' > "$po_dir/LINGUAS" || return
+
+  langs=$(cd $ref_po_dir && echo *.po | sed 's/\.po//g')
+  test "$langs" = '*' && langs=x
+  for po in $langs; do
+    case $po in x) continue;; esac
+    new_po="$ref_po_dir/$po.po"
+    cksum_file="$ref_po_dir/$po.s1"
+    if ! test -f "$cksum_file" ||
+        ! test -f "$po_dir/$po.po" ||
+        ! $SHA1SUM -c "$cksum_file" < "$new_po" > /dev/null 2>&1; then
+      echo "$me: updated $po_dir/$po.po..."
+      cp "$new_po" "$po_dir/$po.po" \
+          && $SHA1SUM < "$new_po" > "$cksum_file" || return
+    fi
+  done
+}
 
 # -------- Generate files automatically from existing sources.  --------------
 
diff --git a/top/autopull.sh b/top/autopull.sh
index f3b9a3811d..6fb3c9d9d5 100755
--- a/top/autopull.sh
+++ b/top/autopull.sh
@@ -2,8 +2,6 @@
 # Convenience script for fetching auxiliary files that are omitted from
 # the version control repository of this package.
 
-scriptversion=2022-12-27.03; # UTC
-
 # Copyright (C) 2003-2022 Free Software Foundation, Inc.
 #
 # This program is free software: you can redistribute it and/or modify
@@ -36,238 +34,4 @@ medir=`dirname "$me"`
 # Read the function library and the configuration.
 . "$medir"/bootstrap-funclib.sh
 
-# Ensure that CDPATH is not set.  Otherwise, the output from cd
-# would cause trouble in at least one use below.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-usage() {
-  cat <<EOF
-Usage: $me [OPTION]...
-Bootstrap this package from the checked-out sources.
-
-Optional environment variables:
-  GNULIB_SRCDIR            Specifies the local directory where gnulib
-                           sources reside.  Use this if you already
-                           have gnulib sources on your machine, and
-                           you want to use these sources.
-  GNULIB_REFDIR            Specifies the local directory where a gnulib
-                           repository (with a .git subdirectory) resides.
-                           Use this if you already have gnulib sources
-                           and history on your machine, and do not want
-                           to waste your bandwidth downloading them again.
-  GNULIB_URL               Cloneable URL of the gnulib repository.
-
-Options:
-  --bootstrap-sync         if this bootstrap script is not identical to
-                           the version in the local gnulib sources,
-                           update this script, and then restart it with
-                           /bin/sh or the shell \$CONFIG_SHELL
-  --no-bootstrap-sync      do not check whether bootstrap is out of sync
-  --force                  attempt to bootstrap even if the sources seem
-                           not to have been checked out
-  --no-git                 do not use git to update gnulib.  Requires that
-                           \$GNULIB_SRCDIR or the --gnulib-srcdir option
-                           points to a gnulib repository with the correct
-                           revision
-  --skip-po                do not download po files
-EOF
-  bootstrap_print_option_usage_hook
-  cat <<EOF
-If the file bootstrap.conf exists in the same directory as this script, its
-contents are read as shell variables to configure the bootstrap.
-
-For build prerequisites, environment variables like \$AUTOCONF and \$AMTAR
-are honored.
-
-Gnulib sources can be fetched in various ways:
-
- * If the environment variable GNULIB_SRCDIR is set (either as an
-   environment variable or via the --gnulib-srcdir option), then sources
-   are fetched from that local directory.  If it is a git repository and
-   the configuration variable GNULIB_REVISION is set in bootstrap.conf,
-   then that revision is checked out.
-
- * Otherwise, if this package is in a git repository with a 'gnulib'
-   submodule configured, then that submodule is initialized and updated
-   and sources are fetched from there.  If GNULIB_REFDIR is set (either
-   as an environment variable or via the --gnulib-refdir option) and is
-   a git repository, then it is used as a reference.
-
- * Otherwise, if the 'gnulib' directory does not exist, Gnulib sources
-   are cloned into that directory using git from \$GNULIB_URL, defaulting
-   to $default_gnulib_url.
-   If the configuration variable GNULIB_REVISION is set in bootstrap.conf,
-   then that revision is checked out.
-
- * Otherwise, the existing Gnulib sources in the 'gnulib' directory are
-   used.  If it is a git repository and the configuration variable
-   GNULIB_REVISION is set in bootstrap.conf, then that revision is
-   checked out.
-
-If you maintain a package and want to pin a particular revision of the
-Gnulib sources that has been tested with your package, then there are
-two possible approaches: either configure a 'gnulib' submodule with the
-appropriate revision, or set GNULIB_REVISION (and if necessary
-GNULIB_URL) in bootstrap.conf.
-
-Running without arguments will suffice in most cases.
-EOF
-}
-
-# Parse options.
-
-# Use git to update gnulib sources
-use_git=true
-
-for option
-do
-  case $option in
-  --help)
-    usage
-    exit;;
-  --version)
-    set -e
-    echo "autopull.sh $scriptversion"
-    echo "$copyright"
-    exit 0
-    ;;
-  --skip-po)
-    SKIP_PO=t;;
-  --force)
-    checkout_only_file=;;
-  --bootstrap-sync)
-    bootstrap_sync=true;;
-  --no-bootstrap-sync)
-    bootstrap_sync=false;;
-  --no-git)
-    use_git=false;;
-  *)
-    bootstrap_option_hook $option || die "$option: unknown option";;
-  esac
-done
-
-$use_git || test -n "$GNULIB_SRCDIR" \
-  || die "Error: --no-git requires \$GNULIB_SRCDIR environment variable or --gnulib-srcdir option"
-test -z "$GNULIB_SRCDIR" || test -d "$GNULIB_SRCDIR" \
-  || die "Error: \$GNULIB_SRCDIR environment variable or --gnulib-srcdir option is specified, but does not denote a directory"
-
-if test -n "$checkout_only_file" && test ! -r "$checkout_only_file"; then
-  die "Running this script from a non-checked-out distribution is risky."
-fi
-
-check_build_prerequisites $use_git
-
-if $use_gnulib || $bootstrap_sync; then
-  prepare_GNULIB_SRCDIR
-  if $bootstrap_sync; then
-    upgrade_bootstrap
-  fi
-fi
-
-# Find sha1sum, named gsha1sum on MacPorts, shasum on Mac OS X 10.6.
-# Also find the compatible sha1 utility on the BSDs
-if test x"$SKIP_PO" = x; then
-  find_tool SHA1SUM sha1sum gsha1sum shasum sha1
-fi
-
-# See if we can use gnulib's git-merge-changelog merge driver.
-if $use_git && test -d .git && check_exists git; then
-  if git config merge.merge-changelog.driver >/dev/null ; then
-    :
-  elif check_exists git-merge-changelog; then
-    echo "$0: initializing git-merge-changelog driver"
-    git config merge.merge-changelog.name 'GNU-style ChangeLog merge driver'
-    git config merge.merge-changelog.driver 'git-merge-changelog %O %A %B'
-  else
-    echo "$0: consider installing git-merge-changelog from gnulib"
-  fi
-fi
-
-# ----------------------------- Get translations. -----------------------------
-
-download_po_files() {
-  subdir=$1
-  domain=$2
-  echo "$me: getting translations into $subdir for $domain..."
-  cmd=$(printf "$po_download_command_format" "$subdir" "$domain")
-  eval "$cmd"
-}
-
-# Mirror .po files to $po_dir/.reference and copy only the new
-# or modified ones into $po_dir.  Also update $po_dir/LINGUAS.
-# Note po files that exist locally only are left in $po_dir but will
-# not be included in LINGUAS and hence will not be distributed.
-update_po_files() {
-  # Directory containing primary .po files.
-  # Overwrite them only when we're sure a .po file is new.
-  po_dir=$1
-  domain=$2
-
-  # Mirror *.po files into this dir.
-  # Usually contains *.s1 checksum files.
-  ref_po_dir="$po_dir/.reference"
-
-  test -d $ref_po_dir || mkdir $ref_po_dir || return
-  download_po_files $ref_po_dir $domain \
-    && ls "$ref_po_dir"/*.po 2>/dev/null |
-      sed 's|.*/||; s|\.po$||' > "$po_dir/LINGUAS" || return
-
-  langs=$(cd $ref_po_dir && echo *.po | sed 's/\.po//g')
-  test "$langs" = '*' && langs=x
-  for po in $langs; do
-    case $po in x) continue;; esac
-    new_po="$ref_po_dir/$po.po"
-    cksum_file="$ref_po_dir/$po.s1"
-    if ! test -f "$cksum_file" ||
-        ! test -f "$po_dir/$po.po" ||
-        ! $SHA1SUM -c "$cksum_file" < "$new_po" > /dev/null 2>&1; then
-      echo "$me: updated $po_dir/$po.po..."
-      cp "$new_po" "$po_dir/$po.po" \
-          && $SHA1SUM < "$new_po" > "$cksum_file" || return
-    fi
-  done
-}
-
-case $SKIP_PO in
-'')
-  if test -d po; then
-    update_po_files po $package || exit
-  fi
-
-  if test -d runtime-po; then
-    update_po_files runtime-po $package-runtime || exit
-  fi;;
-esac
-
-# -----------------------------------------------------------------------------
-
-bootstrap_post_pull_hook \
-  || die "bootstrap_post_pull_hook failed"
-
-# Don't proceed if there are uninitialized submodules.  In particular,
-# autogen.sh will remove dangling links, which might be links into
-# uninitialized submodules.
-# But it's OK if the 'gnulib' submodule is uninitialized, as long as
-# GNULIB_SRCDIR is set.
-if $use_git; then
-  # Uninitialized submodules are listed with an initial dash.
-  uninitialized=`git submodule | grep '^-' | awk '{ print $2 }'`
-  if test -n "$GNULIB_SRCDIR"; then
-    uninitialized=`echo "$uninitialized" | grep -v '^gnulib$'`
-  fi
-  if test -n "$uninitialized"; then
-    die "Some git submodules are not initialized: "`echo "$uninitialized" | tr '\n' ',' | sed -e 's|,$|.|'`" Either use option '--no-git', or run 'git submodule update --init' and bootstrap again."
-  fi
-fi
-
-echo "$0: done.  Now you can run './autogen.sh'."
-
-# ----------------------------------------------------------------------------
-
-# Local Variables:
-# eval: (add-hook 'before-save-hook 'time-stamp)
-# time-stamp-start: "scriptversion="
-# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC0"
-# time-stamp-end: "; # UTC"
-# End:
+autopull "$@"
diff --git a/top/bootstrap-funclib.sh b/top/bootstrap-funclib.sh
index efb6a086a3..802ef2ba92 100644
--- a/top/bootstrap-funclib.sh
+++ b/top/bootstrap-funclib.sh
@@ -583,6 +583,238 @@ else
   use_gnulib=true
 fi
 
+# -------- Fetch auxiliary files from the network.  --------------------------
+
+autopull_usage() {
+  cat <<EOF
+Usage: $me [OPTION]...
+Bootstrap this package from the checked-out sources.
+
+Optional environment variables:
+  GNULIB_SRCDIR            Specifies the local directory where gnulib
+                           sources reside.  Use this if you already
+                           have gnulib sources on your machine, and
+                           you want to use these sources.
+  GNULIB_REFDIR            Specifies the local directory where a gnulib
+                           repository (with a .git subdirectory) resides.
+                           Use this if you already have gnulib sources
+                           and history on your machine, and do not want
+                           to waste your bandwidth downloading them again.
+  GNULIB_URL               Cloneable URL of the gnulib repository.
+
+Options:
+  --bootstrap-sync         if this bootstrap script is not identical to
+                           the version in the local gnulib sources,
+                           update this script, and then restart it with
+                           /bin/sh or the shell \$CONFIG_SHELL
+  --no-bootstrap-sync      do not check whether bootstrap is out of sync
+  --force                  attempt to bootstrap even if the sources seem
+                           not to have been checked out
+  --no-git                 do not use git to update gnulib.  Requires that
+                           \$GNULIB_SRCDIR or the --gnulib-srcdir option
+                           points to a gnulib repository with the correct
+                           revision
+  --skip-po                do not download po files
+EOF
+  bootstrap_print_option_usage_hook
+  cat <<EOF
+If the file bootstrap.conf exists in the same directory as this script, its
+contents are read as shell variables to configure the bootstrap.
+
+For build prerequisites, environment variables like \$AUTOCONF and \$AMTAR
+are honored.
+
+Gnulib sources can be fetched in various ways:
+
+ * If the environment variable GNULIB_SRCDIR is set (either as an
+   environment variable or via the --gnulib-srcdir option), then sources
+   are fetched from that local directory.  If it is a git repository and
+   the configuration variable GNULIB_REVISION is set in bootstrap.conf,
+   then that revision is checked out.
+
+ * Otherwise, if this package is in a git repository with a 'gnulib'
+   submodule configured, then that submodule is initialized and updated
+   and sources are fetched from there.  If GNULIB_REFDIR is set (either
+   as an environment variable or via the --gnulib-refdir option) and is
+   a git repository, then it is used as a reference.
+
+ * Otherwise, if the 'gnulib' directory does not exist, Gnulib sources
+   are cloned into that directory using git from \$GNULIB_URL, defaulting
+   to $default_gnulib_url.
+   If the configuration variable GNULIB_REVISION is set in bootstrap.conf,
+   then that revision is checked out.
+
+ * Otherwise, the existing Gnulib sources in the 'gnulib' directory are
+   used.  If it is a git repository and the configuration variable
+   GNULIB_REVISION is set in bootstrap.conf, then that revision is
+   checked out.
+
+If you maintain a package and want to pin a particular revision of the
+Gnulib sources that has been tested with your package, then there are
+two possible approaches: either configure a 'gnulib' submodule with the
+appropriate revision, or set GNULIB_REVISION (and if necessary
+GNULIB_URL) in bootstrap.conf.
+
+Running without arguments will suffice in most cases.
+EOF
+}
+
+# Fetch auxiliary files that are omitted from the version control
+# repository of this package.
+autopull()
+{
+  # Ensure that CDPATH is not set.  Otherwise, the output from cd
+  # would cause trouble in at least one use below.
+  (unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+  # Parse options.
+
+  # Use git to update gnulib sources
+  use_git=true
+
+  for option
+  do
+    case $option in
+    --help)
+      autopull_usage
+      return;;
+    --version)
+      set -e
+      echo "autopull.sh $scriptversion"
+      echo "$copyright"
+      return 0
+      ;;
+    --skip-po)
+      SKIP_PO=t;;
+    --force)
+      checkout_only_file=;;
+    --bootstrap-sync)
+      bootstrap_sync=true;;
+    --no-bootstrap-sync)
+      bootstrap_sync=false;;
+    --no-git)
+      use_git=false;;
+    *)
+      bootstrap_option_hook $option || die "$option: unknown option";;
+    esac
+  done
+
+  $use_git || test -n "$GNULIB_SRCDIR" \
+    || die "Error: --no-git requires \$GNULIB_SRCDIR environment variable or --gnulib-srcdir option"
+  test -z "$GNULIB_SRCDIR" || test -d "$GNULIB_SRCDIR" \
+    || die "Error: \$GNULIB_SRCDIR environment variable or --gnulib-srcdir option is specified, but does not denote a directory"
+
+  if test -n "$checkout_only_file" && test ! -r "$checkout_only_file"; then
+    die "Running this script from a non-checked-out distribution is risky."
+  fi
+
+  check_build_prerequisites $use_git
+
+  if $use_gnulib || $bootstrap_sync; then
+    prepare_GNULIB_SRCDIR
+    if $bootstrap_sync; then
+      upgrade_bootstrap
+    fi
+  fi
+
+  # Find sha1sum, named gsha1sum on MacPorts, shasum on Mac OS X 10.6.
+  # Also find the compatible sha1 utility on the BSDs
+  if test x"$SKIP_PO" = x; then
+    find_tool SHA1SUM sha1sum gsha1sum shasum sha1
+  fi
+
+  # See if we can use gnulib's git-merge-changelog merge driver.
+  if $use_git && test -d .git && check_exists git; then
+    if git config merge.merge-changelog.driver >/dev/null ; then
+      :
+    elif check_exists git-merge-changelog; then
+      echo "$0: initializing git-merge-changelog driver"
+      git config merge.merge-changelog.name 'GNU-style ChangeLog merge driver'
+      git config merge.merge-changelog.driver 'git-merge-changelog %O %A %B'
+    else
+      echo "$0: consider installing git-merge-changelog from gnulib"
+    fi
+  fi
+
+  case $SKIP_PO in
+  '')
+    if test -d po; then
+      update_po_files po $package || return
+    fi
+
+    if test -d runtime-po; then
+      update_po_files runtime-po $package-runtime || return
+    fi;;
+  esac
+
+  # ---------------------------------------------------------------------------
+
+  bootstrap_post_pull_hook \
+    || die "bootstrap_post_pull_hook failed"
+
+  # Don't proceed if there are uninitialized submodules.  In particular,
+  # autogen.sh will remove dangling links, which might be links into
+  # uninitialized submodules.
+  # But it's OK if the 'gnulib' submodule is uninitialized, as long as
+  # GNULIB_SRCDIR is set.
+  if $use_git; then
+    # Uninitialized submodules are listed with an initial dash.
+    uninitialized=`git submodule | grep '^-' | awk '{ print $2 }'`
+    if test -n "$GNULIB_SRCDIR"; then
+      uninitialized=`echo "$uninitialized" | grep -v '^gnulib$'`
+    fi
+    if test -n "$uninitialized"; then
+      die "Some git submodules are not initialized: "`echo "$uninitialized" | tr '\n' ',' | sed -e 's|,$|.|'`" Either use option '--no-git', or run 'git submodule update --init' and bootstrap again."
+    fi
+  fi
+
+  echo "$0: done.  Now you can run './autogen.sh'."
+}
+
+# ----------------------------- Get translations. -----------------------------
+
+download_po_files() {
+  subdir=$1
+  domain=$2
+  echo "$me: getting translations into $subdir for $domain..."
+  cmd=$(printf "$po_download_command_format" "$subdir" "$domain")
+  eval "$cmd"
+}
+
+# Mirror .po files to $po_dir/.reference and copy only the new
+# or modified ones into $po_dir.  Also update $po_dir/LINGUAS.
+# Note po files that exist locally only are left in $po_dir but will
+# not be included in LINGUAS and hence will not be distributed.
+update_po_files() {
+  # Directory containing primary .po files.
+  # Overwrite them only when we're sure a .po file is new.
+  po_dir=$1
+  domain=$2
+
+  # Mirror *.po files into this dir.
+  # Usually contains *.s1 checksum files.
+  ref_po_dir="$po_dir/.reference"
+
+  test -d $ref_po_dir || mkdir $ref_po_dir || return
+  download_po_files $ref_po_dir $domain \
+    && ls "$ref_po_dir"/*.po 2>/dev/null |
+      sed 's|.*/||; s|\.po$||' > "$po_dir/LINGUAS" || return
+
+  langs=$(cd $ref_po_dir && echo *.po | sed 's/\.po//g')
+  test "$langs" = '*' && langs=x
+  for po in $langs; do
+    case $po in x) continue;; esac
+    new_po="$ref_po_dir/$po.po"
+    cksum_file="$ref_po_dir/$po.s1"
+    if ! test -f "$cksum_file" ||
+        ! test -f "$po_dir/$po.po" ||
+        ! $SHA1SUM -c "$cksum_file" < "$new_po" > /dev/null 2>&1; then
+      echo "$me: updated $po_dir/$po.po..."
+      cp "$new_po" "$po_dir/$po.po" \
+          && $SHA1SUM < "$new_po" > "$cksum_file" || return
+    fi
+  done
+}
 
 # -------- Generate files automatically from existing sources.  --------------
 
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 4/6] Bootstrap with functions, not scripts
  2022-12-27 18:59 [PATCH 0/6] build-aux/bootstrap that doesn't need to replace itself Paul Eggert
                   ` (3 preceding siblings ...)
  2022-12-27 18:59 ` [PATCH 3/6] Make autopull " Paul Eggert
@ 2022-12-27 19:00 ` Paul Eggert
  2022-12-27 19:00 ` [PATCH 5/6] Support packages with just 'bootstrap' Paul Eggert
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Paul Eggert @ 2022-12-27 19:00 UTC (permalink / raw)
  To: bug-gnulib; +Cc: Paul Eggert

* top/bootstrap: Use autopull and autogen functions, not
shell scripts.  This lets build-aux/bootstrap become a
standalone script.  It does not change the behavior of
top/bootstrap, except for minor rewording of disagnostics.
---
 ChangeLog           |  6 ++++++
 build-aux/bootstrap | 14 ++++++--------
 top/bootstrap       | 14 ++++++--------
 3 files changed, 18 insertions(+), 16 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 21dbc68b10..53c645a55f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2022-12-27  Paul Eggert  <eggert@cs.ucla.edu>
 
+	Bootstrap with functions, not scripts
+	* top/bootstrap: Use autopull and autogen functions, not
+	shell scripts.  This lets build-aux/bootstrap become a
+	standalone script.  It does not change the behavior of
+	top/bootstrap, except for minor rewording of disagnostics.
+
 	Make autopull a shell function too
 	This does not change behavior.  It is helpful for future changes.
 	* top/autopull.sh: Call autopull to do the actual work.
diff --git a/build-aux/bootstrap b/build-aux/bootstrap
index 78e307c5ef..2c81b0f26e 100755
--- a/build-aux/bootstrap
+++ b/build-aux/bootstrap
@@ -5,7 +5,7 @@
 
 # Bootstrap this package from checked-out sources.
 
-scriptversion=2022-12-27.03; # UTC
+scriptversion=2022-12-27.04; # UTC
 
 # Copyright (C) 2003-2022 Free Software Foundation, Inc.
 #
@@ -1462,25 +1462,23 @@ fi
 
 echo "$0: Bootstrapping from checked-out $package sources..."
 
-# Pass GNULIB_SRCDIR to autopull.sh and autogen.sh.
+# Pass GNULIB_SRCDIR and GNULIB_REFDIR to any subsidiary commands that care.
 export GNULIB_SRCDIR
-
-# Pass GNULIB_REFDIR to autopull.sh.
 export GNULIB_REFDIR
 
 if $use_git || test -z "$SKIP_PO"; then
-  "$medir"/autopull.sh \
+  autopull \
       `if $bootstrap_sync; then echo ' --bootstrap-sync'; else echo ' --no-bootstrap-sync'; fi` \
       `if test -z "$checkout_only_file"; then echo ' --force'; fi` \
       `if ! $use_git; then echo ' --no-git'; fi` \
       `if test -n "$SKIP_PO"; then echo ' --skip-po'; fi` \
-    || die "autopull.sh failed."
+    || die "could not fetch auxiliary files"
 fi
 
-"$medir"/autogen.sh \
+autogen \
     `if $copy; then echo ' --copy'; fi` \
     `if test -z "$checkout_only_file"; then echo ' --force'; fi` \
-  || die "autogen.sh failed."
+  || die "could not generate auxiliary files"
 
 # ----------------------------------------------------------------------------
 
diff --git a/top/bootstrap b/top/bootstrap
index 9d31b4311c..a4246c7e80 100755
--- a/top/bootstrap
+++ b/top/bootstrap
@@ -1,7 +1,7 @@
 #! /bin/sh
 # Bootstrap this package from checked-out sources.
 
-scriptversion=2022-12-27.03; # UTC
+scriptversion=2022-12-27.04; # UTC
 
 # Copyright (C) 2003-2022 Free Software Foundation, Inc.
 #
@@ -183,25 +183,23 @@ fi
 
 echo "$0: Bootstrapping from checked-out $package sources..."
 
-# Pass GNULIB_SRCDIR to autopull.sh and autogen.sh.
+# Pass GNULIB_SRCDIR and GNULIB_REFDIR to any subsidiary commands that care.
 export GNULIB_SRCDIR
-
-# Pass GNULIB_REFDIR to autopull.sh.
 export GNULIB_REFDIR
 
 if $use_git || test -z "$SKIP_PO"; then
-  "$medir"/autopull.sh \
+  autopull \
       `if $bootstrap_sync; then echo ' --bootstrap-sync'; else echo ' --no-bootstrap-sync'; fi` \
       `if test -z "$checkout_only_file"; then echo ' --force'; fi` \
       `if ! $use_git; then echo ' --no-git'; fi` \
       `if test -n "$SKIP_PO"; then echo ' --skip-po'; fi` \
-    || die "autopull.sh failed."
+    || die "could not fetch auxiliary files"
 fi
 
-"$medir"/autogen.sh \
+autogen \
     `if $copy; then echo ' --copy'; fi` \
     `if test -z "$checkout_only_file"; then echo ' --force'; fi` \
-  || die "autogen.sh failed."
+  || die "could not generate auxiliary files"
 
 # ----------------------------------------------------------------------------
 
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 5/6] Support packages with just 'bootstrap'
  2022-12-27 18:59 [PATCH 0/6] build-aux/bootstrap that doesn't need to replace itself Paul Eggert
                   ` (4 preceding siblings ...)
  2022-12-27 19:00 ` [PATCH 4/6] Bootstrap with functions, not scripts Paul Eggert
@ 2022-12-27 19:00 ` Paul Eggert
  2022-12-27 19:00 ` [PATCH 6/6] Add --pull, --gen options to build-aux/bootstrap Paul Eggert
  2022-12-27 21:09 ` [PATCH 0/6] build-aux/bootstrap that doesn't need to replace itself Bruno Haible
  7 siblings, 0 replies; 10+ messages in thread
From: Paul Eggert @ 2022-12-27 19:00 UTC (permalink / raw)
  To: bug-gnulib; +Cc: Paul Eggert

* top/bootstrap: With --version, also output library version.
Support update of package that has only the bootstrap script,
and not the other three files.
* top/bootstrap-funclib.sh (scriptlibversion): Rename
from scriptversion.  All uses changed.  This way we
can distinguish script from script library versions.
(upgrade_bootstrap): If the package currently has only
the bootstrap script, just update that.
---
 ChangeLog                | 10 +++++++++
 build-aux/bootstrap      | 46 +++++++++++++++++++++-------------------
 top/bootstrap            | 10 ++-------
 top/bootstrap-funclib.sh | 34 ++++++++++++++++++-----------
 top/gen-bootstrap.sed    |  4 ----
 5 files changed, 58 insertions(+), 46 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 53c645a55f..331e31a68b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2022-12-27  Paul Eggert  <eggert@cs.ucla.edu>
 
+	Support packages with just 'bootstrap'
+	* top/bootstrap: With --version, also output library version.
+	Support update of package that has only the bootstrap script,
+	and not the other three files.
+	* top/bootstrap-funclib.sh (scriptlibversion): Rename
+	from scriptversion.  All uses changed.  This way we
+	can distinguish script from script library versions.
+	(upgrade_bootstrap): If the package currently has only
+	the bootstrap script, just update that.
+
 	Bootstrap with functions, not scripts
 	* top/bootstrap: Use autopull and autogen functions, not
 	shell scripts.  This lets build-aux/bootstrap become a
diff --git a/build-aux/bootstrap b/build-aux/bootstrap
index 2c81b0f26e..d40cd01162 100755
--- a/build-aux/bootstrap
+++ b/build-aux/bootstrap
@@ -1,11 +1,9 @@
 #! /bin/sh
 # DO NOT EDIT! GENERATED AUTOMATICALLY!
-# This script is only a trampoline that fetches the companion scripts
-# (bootstrap-funclib.sh, autopull.sh, autogen.sh).
 
 # Bootstrap this package from checked-out sources.
 
-scriptversion=2022-12-27.04; # UTC
+scriptversion=2022-12-27.05; # UTC
 
 # Copyright (C) 2003-2022 Free Software Foundation, Inc.
 #
@@ -39,7 +37,7 @@ medir=`dirname "$me"`
 
 # A library of shell functions for autopull.sh, autogen.sh, and bootstrap.
 
-scriptversion=2022-12-27.16; # UTC
+scriptlibversion=2022-12-27.16; # UTC
 
 # Copyright (C) 2003-2022 Free Software Foundation, Inc.
 #
@@ -77,7 +75,7 @@ PERL="${PERL-perl}"
 default_gnulib_url=https://git.savannah.gnu.org/git/gnulib.git
 
 # Copyright year, for the --version output.
-copyright_year=`echo "$scriptversion" | sed -e 's/[^0-9].*//'`
+copyright_year=`echo "$scriptlibversion" | sed -e 's/[^0-9].*//'`
 copyright="Copyright (C) ${copyright_year} Free Software Foundation, Inc.
 License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
 This is free software: you are free to change and redistribute it.
@@ -593,18 +591,28 @@ prepare_GNULIB_SRCDIR ()
 
 upgrade_bootstrap ()
 {
-  { cmp -s "$medir"/bootstrap "$GNULIB_SRCDIR/top/bootstrap" \
-    && cmp -s "$medir"/bootstrap-funclib.sh "$GNULIB_SRCDIR/top/bootstrap-funclib.sh" \
-    && cmp -s "$medir"/autopull.sh "$GNULIB_SRCDIR/top/autopull.sh" \
-    && cmp -s "$medir"/autogen.sh "$GNULIB_SRCDIR/top/autogen.sh"; \
-  } || {
-    echo "$0: updating bootstrap & companions and restarting..."
+  if test -f "$medir"/bootstrap-funclib.sh; then
+    update_lib=true
+    { cmp -s "$medir"/bootstrap "$GNULIB_SRCDIR/top/bootstrap" \
+      && cmp -s "$medir"/bootstrap-funclib.sh "$GNULIB_SRCDIR/top/bootstrap-funclib.sh" \
+      && cmp -s "$medir"/autopull.sh "$GNULIB_SRCDIR/top/autopull.sh" \
+      && cmp -s "$medir"/autogen.sh "$GNULIB_SRCDIR/top/autogen.sh"; \
+    }
+  else
+    update_lib=false
+    cmp -s "$medir"/bootstrap "$GNULIB_SRCDIR/build-aux/bootstrap"
+  fi || {
+    if $update_lib; then
+      echo "$0: updating bootstrap & companions and restarting..."
+    else
+      echo "$0: updating bootstrap and restarting..."
+    fi
     case $(sh -c 'echo "$1"' -- a) in
       a) ignored=--;;
       *) ignored=ignored;;
     esac
     exec sh -c \
-      '{ if test -f "$1"; then cp "$1" "$3"; else cp "$2" "$3"; fi; } && { if test -f "$4"; then cp "$4" "$5"; else rm -f "$5"; fi; } && { if test -f "$6"; then cp "$6" "$7"; else rm -f "$7"; fi; } && { if test -f "$8"; then cp "$8" "$9"; else rm -f "$9"; fi; } && shift && shift && shift && shift && shift && shift && shift && shift && shift && exec "${CONFIG_SHELL-/bin/sh}" "$@"' \
+      '{ if '$update_lib' && test -f "$1"; then cp "$1" "$3"; else cp "$2" "$3"; fi; } && { if '$update_lib' && test -f "$4"; then cp "$4" "$5"; else rm -f "$5"; fi; } && { if '$update_lib' && test -f "$6"; then cp "$6" "$7"; else rm -f "$7"; fi; } && { if '$update_lib' && test -f "$8"; then cp "$8" "$9"; else rm -f "$9"; fi; } && shift && shift && shift && shift && shift && shift && shift && shift && shift && exec "${CONFIG_SHELL-/bin/sh}" "$@"' \
       $ignored \
       "$GNULIB_SRCDIR/top/bootstrap" "$GNULIB_SRCDIR/build-aux/bootstrap" "$medir/bootstrap" \
       "$GNULIB_SRCDIR/top/bootstrap-funclib.sh" "$medir/bootstrap-funclib.sh" \
@@ -719,7 +727,7 @@ autopull()
       return;;
     --version)
       set -e
-      echo "autopull.sh $scriptversion"
+      echo "autopull.sh $scriptlibversion"
       echo "$copyright"
       return 0
       ;;
@@ -1051,7 +1059,7 @@ autogen()
       return;;
     --version)
       set -e
-      echo "autogen.sh $scriptversion"
+      echo "autogen.sh $scriptlibversion"
       echo "$copyright"
       return 0
       ;;
@@ -1307,7 +1315,7 @@ autogen()
 
 # Local Variables:
 # eval: (add-hook 'before-save-hook 'time-stamp)
-# time-stamp-start: "scriptversion="
+# time-stamp-start: "scriptlibversion="
 # time-stamp-format: "%:y-%02m-%02d.%02H"
 # time-stamp-time-zone: "UTC0"
 # time-stamp-end: "; # UTC"
@@ -1411,7 +1419,7 @@ do
     exit;;
   --version)
     set -e
-    echo "bootstrap $scriptversion"
+    echo "bootstrap $scriptversion lib $scriptlibversion"
     echo "$copyright"
     exit 0
     ;;
@@ -1447,12 +1455,6 @@ fi
 
 check_build_prerequisites $use_git
 
-if ! test -f "$medir"/bootstrap-funclib.sh; then
-  # We have only completed the first phase of an upgrade from a bootstrap
-  # version < 2022-07-24. Need to do the second phase now.
-  bootstrap_sync=true
-fi
-
 if $bootstrap_sync; then
   prepare_GNULIB_SRCDIR
   upgrade_bootstrap
diff --git a/top/bootstrap b/top/bootstrap
index a4246c7e80..365c378d42 100755
--- a/top/bootstrap
+++ b/top/bootstrap
@@ -1,7 +1,7 @@
 #! /bin/sh
 # Bootstrap this package from checked-out sources.
 
-scriptversion=2022-12-27.04; # UTC
+scriptversion=2022-12-27.05; # UTC
 
 # Copyright (C) 2003-2022 Free Software Foundation, Inc.
 #
@@ -132,7 +132,7 @@ do
     exit;;
   --version)
     set -e
-    echo "bootstrap $scriptversion"
+    echo "bootstrap $scriptversion lib $scriptlibversion"
     echo "$copyright"
     exit 0
     ;;
@@ -168,12 +168,6 @@ fi
 
 check_build_prerequisites $use_git
 
-if ! test -f "$medir"/bootstrap-funclib.sh; then
-  # We have only completed the first phase of an upgrade from a bootstrap
-  # version < 2022-07-24. Need to do the second phase now.
-  bootstrap_sync=true
-fi
-
 if $bootstrap_sync; then
   prepare_GNULIB_SRCDIR
   upgrade_bootstrap
diff --git a/top/bootstrap-funclib.sh b/top/bootstrap-funclib.sh
index 802ef2ba92..76e5f30b19 100644
--- a/top/bootstrap-funclib.sh
+++ b/top/bootstrap-funclib.sh
@@ -1,6 +1,6 @@
 # A library of shell functions for autopull.sh, autogen.sh, and bootstrap.
 
-scriptversion=2022-12-27.16; # UTC
+scriptlibversion=2022-12-27.16; # UTC
 
 # Copyright (C) 2003-2022 Free Software Foundation, Inc.
 #
@@ -38,7 +38,7 @@ PERL="${PERL-perl}"
 default_gnulib_url=https://git.savannah.gnu.org/git/gnulib.git
 
 # Copyright year, for the --version output.
-copyright_year=`echo "$scriptversion" | sed -e 's/[^0-9].*//'`
+copyright_year=`echo "$scriptlibversion" | sed -e 's/[^0-9].*//'`
 copyright="Copyright (C) ${copyright_year} Free Software Foundation, Inc.
 License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
 This is free software: you are free to change and redistribute it.
@@ -554,18 +554,28 @@ prepare_GNULIB_SRCDIR ()
 
 upgrade_bootstrap ()
 {
-  { cmp -s "$medir"/bootstrap "$GNULIB_SRCDIR/top/bootstrap" \
-    && cmp -s "$medir"/bootstrap-funclib.sh "$GNULIB_SRCDIR/top/bootstrap-funclib.sh" \
-    && cmp -s "$medir"/autopull.sh "$GNULIB_SRCDIR/top/autopull.sh" \
-    && cmp -s "$medir"/autogen.sh "$GNULIB_SRCDIR/top/autogen.sh"; \
-  } || {
-    echo "$0: updating bootstrap & companions and restarting..."
+  if test -f "$medir"/bootstrap-funclib.sh; then
+    update_lib=true
+    { cmp -s "$medir"/bootstrap "$GNULIB_SRCDIR/top/bootstrap" \
+      && cmp -s "$medir"/bootstrap-funclib.sh "$GNULIB_SRCDIR/top/bootstrap-funclib.sh" \
+      && cmp -s "$medir"/autopull.sh "$GNULIB_SRCDIR/top/autopull.sh" \
+      && cmp -s "$medir"/autogen.sh "$GNULIB_SRCDIR/top/autogen.sh"; \
+    }
+  else
+    update_lib=false
+    cmp -s "$medir"/bootstrap "$GNULIB_SRCDIR/build-aux/bootstrap"
+  fi || {
+    if $update_lib; then
+      echo "$0: updating bootstrap & companions and restarting..."
+    else
+      echo "$0: updating bootstrap and restarting..."
+    fi
     case $(sh -c 'echo "$1"' -- a) in
       a) ignored=--;;
       *) ignored=ignored;;
     esac
     exec sh -c \
-      '{ if test -f "$1"; then cp "$1" "$3"; else cp "$2" "$3"; fi; } && { if test -f "$4"; then cp "$4" "$5"; else rm -f "$5"; fi; } && { if test -f "$6"; then cp "$6" "$7"; else rm -f "$7"; fi; } && { if test -f "$8"; then cp "$8" "$9"; else rm -f "$9"; fi; } && shift && shift && shift && shift && shift && shift && shift && shift && shift && exec "${CONFIG_SHELL-/bin/sh}" "$@"' \
+      '{ if '$update_lib' && test -f "$1"; then cp "$1" "$3"; else cp "$2" "$3"; fi; } && { if '$update_lib' && test -f "$4"; then cp "$4" "$5"; else rm -f "$5"; fi; } && { if '$update_lib' && test -f "$6"; then cp "$6" "$7"; else rm -f "$7"; fi; } && { if '$update_lib' && test -f "$8"; then cp "$8" "$9"; else rm -f "$9"; fi; } && shift && shift && shift && shift && shift && shift && shift && shift && shift && exec "${CONFIG_SHELL-/bin/sh}" "$@"' \
       $ignored \
       "$GNULIB_SRCDIR/top/bootstrap" "$GNULIB_SRCDIR/build-aux/bootstrap" "$medir/bootstrap" \
       "$GNULIB_SRCDIR/top/bootstrap-funclib.sh" "$medir/bootstrap-funclib.sh" \
@@ -680,7 +690,7 @@ autopull()
       return;;
     --version)
       set -e
-      echo "autopull.sh $scriptversion"
+      echo "autopull.sh $scriptlibversion"
       echo "$copyright"
       return 0
       ;;
@@ -1012,7 +1022,7 @@ autogen()
       return;;
     --version)
       set -e
-      echo "autogen.sh $scriptversion"
+      echo "autogen.sh $scriptlibversion"
       echo "$copyright"
       return 0
       ;;
@@ -1268,7 +1278,7 @@ autogen()
 
 # Local Variables:
 # eval: (add-hook 'before-save-hook 'time-stamp)
-# time-stamp-start: "scriptversion="
+# time-stamp-start: "scriptlibversion="
 # time-stamp-format: "%:y-%02m-%02d.%02H"
 # time-stamp-time-zone: "UTC0"
 # time-stamp-end: "; # UTC"
diff --git a/top/gen-bootstrap.sed b/top/gen-bootstrap.sed
index c182abfa50..434e6147fa 100644
--- a/top/gen-bootstrap.sed
+++ b/top/gen-bootstrap.sed
@@ -2,10 +2,6 @@
 a\
 # DO NOT EDIT! GENERATED AUTOMATICALLY!
 a\
-# This script is only a trampoline that fetches the companion scripts
-a\
-# (bootstrap-funclib.sh, autopull.sh, autogen.sh).
-a\
 
 }
 /^[.] "[$]medir"[/]bootstrap-funclib.sh/{
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 6/6] Add --pull, --gen options to build-aux/bootstrap
  2022-12-27 18:59 [PATCH 0/6] build-aux/bootstrap that doesn't need to replace itself Paul Eggert
                   ` (5 preceding siblings ...)
  2022-12-27 19:00 ` [PATCH 5/6] Support packages with just 'bootstrap' Paul Eggert
@ 2022-12-27 19:00 ` Paul Eggert
  2022-12-27 21:09 ` [PATCH 0/6] build-aux/bootstrap that doesn't need to replace itself Bruno Haible
  7 siblings, 0 replies; 10+ messages in thread
From: Paul Eggert @ 2022-12-27 19:00 UTC (permalink / raw)
  To: bug-gnulib; +Cc: Paul Eggert

This supports a single bootstrap script with --pull and --gen
options, as an alternative to separate autogen.sh and autopull.sh
and bootstrap-funclib.sh auxiliary files.
* top/bootstrap: With --version, also output library version.
Support update of package that has only the bootstrap script,
and not the other three files.
---
 ChangeLog            |  9 +++++++++
 build-aux/bootstrap  | 26 +++++++++++++++++++++++---
 doc/gnulib-tool.texi | 13 ++++++++-----
 doc/gnulib.texi      | 23 ++++++++++++++++++-----
 top/bootstrap        | 26 +++++++++++++++++++++++---
 5 files changed, 81 insertions(+), 16 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 331e31a68b..12c14a2e7a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,9 +1,18 @@
 2022-12-27  Paul Eggert  <eggert@cs.ucla.edu>
 
+	Add --pull, --gen options to build-aux/bootstrap
+	This supports a single bootstrap script with --pull and --gen
+	options, as an alternative to separate autogen.sh and autopull.sh
+	and bootstrap-funclib.sh auxiliary files.
+	* top/bootstrap: With --version, also output library version.
+	Support update of package that has only the bootstrap script,
+	and not the other three files.
+
 	Support packages with just 'bootstrap'
 	* top/bootstrap: With --version, also output library version.
 	Support update of package that has only the bootstrap script,
 	and not the other three files.
+
 	* top/bootstrap-funclib.sh (scriptlibversion): Rename
 	from scriptversion.  All uses changed.  This way we
 	can distinguish script from script library versions.
diff --git a/build-aux/bootstrap b/build-aux/bootstrap
index d40cd01162..b1a4cc17de 100755
--- a/build-aux/bootstrap
+++ b/build-aux/bootstrap
@@ -3,7 +3,7 @@
 
 # Bootstrap this package from checked-out sources.
 
-scriptversion=2022-12-27.05; # UTC
+scriptversion=2022-12-27.07; # UTC
 
 # Copyright (C) 2003-2022 Free Software Foundation, Inc.
 #
@@ -1335,6 +1335,11 @@ Optional environment variables:
   GNULIB_URL               Cloneable URL of the gnulib repository.
 
 Options:
+
+  --pull                   Do phase 1: pull files from network
+  --gen                    Do phase 2: generate from local files.
+                           (The default is to do both phases.)
+
   --gnulib-srcdir=DIRNAME  specify the local directory where gnulib
                            sources reside.  Use this if you already
                            have gnulib sources on your machine, and
@@ -1346,11 +1351,13 @@ Options:
                            and history on your machine, and do not want
                            to waste your bandwidth downloading them again.
                            Defaults to \$GNULIB_REFDIR
+
   --bootstrap-sync         if this bootstrap script is not identical to
                            the version in the local gnulib sources,
                            update this script, and then restart it with
                            /bin/sh or the shell \$CONFIG_SHELL
   --no-bootstrap-sync      do not check whether bootstrap is out of sync
+
   --copy                   copy files instead of creating symbolic links
   --force                  attempt to bootstrap even if the sources seem
                            not to have been checked out
@@ -1405,6 +1412,10 @@ EOF
 
 # Parse options.
 
+# Whether to pull and generate.
+pull=false
+gen=false
+
 # Whether to use copies instead of symlinks.
 copy=false
 
@@ -1423,6 +1434,10 @@ do
     echo "$copyright"
     exit 0
     ;;
+  --pull)
+    pull=true;;
+  --gen)
+    gen=true;;
   --gnulib-srcdir=*)
     GNULIB_SRCDIR=${option#--gnulib-srcdir=};;
   --gnulib-refdir=*)
@@ -1444,6 +1459,9 @@ do
   esac
 done
 
+# Default is to do both.
+$pull || $gen || pull=true gen=true
+
 $use_git || test -n "$GNULIB_SRCDIR" \
   || die "Error: --no-git requires \$GNULIB_SRCDIR environment variable or --gnulib-srcdir option"
 test -z "$GNULIB_SRCDIR" || test -d "$GNULIB_SRCDIR" \
@@ -1468,7 +1486,7 @@ echo "$0: Bootstrapping from checked-out $package sources..."
 export GNULIB_SRCDIR
 export GNULIB_REFDIR
 
-if $use_git || test -z "$SKIP_PO"; then
+if $pull && { $use_git || test -z "$SKIP_PO"; }; then
   autopull \
       `if $bootstrap_sync; then echo ' --bootstrap-sync'; else echo ' --no-bootstrap-sync'; fi` \
       `if test -z "$checkout_only_file"; then echo ' --force'; fi` \
@@ -1477,10 +1495,12 @@ if $use_git || test -z "$SKIP_PO"; then
     || die "could not fetch auxiliary files"
 fi
 
-autogen \
+if $gen; then
+ autogen \
     `if $copy; then echo ' --copy'; fi` \
     `if test -z "$checkout_only_file"; then echo ' --force'; fi` \
   || die "could not generate auxiliary files"
+fi
 
 # ----------------------------------------------------------------------------
 
diff --git a/doc/gnulib-tool.texi b/doc/gnulib-tool.texi
index ba1598fd9a..808e1e8279 100644
--- a/doc/gnulib-tool.texi
+++ b/doc/gnulib-tool.texi
@@ -987,7 +987,8 @@ time, three ways of handling version control have evolved.
 
 In the cases (A) and (B), a ``git submodule'' is used to reference
 the precise commit of the gnulib repository, so that each developer
-running @file{autopull.sh} will get the same version of all gnulib-provided
+running @samp{./bootstrap --pull} or @file{autopull.sh}
+will get the same version of all gnulib-provided
 files.
 
 The alternative is to always follow the newest Gnulib automatically.
@@ -1031,10 +1032,12 @@ $ git syncsub
 @end smallexample
 
 @item (B)
-In this approach, the @code{autopull.sh} program (see @ref{Developer tools})
-is used to aid a developer in using this setup.  You copy this program and
-its companion files into your package and place them under version control.
-It can be customized using @file{bootstrap.conf} which you also put under
+In this approach, the @code{build-aux/bootstrap} or @code{autopull.sh}
+program (see @ref{Developer tools}) is used to aid a developer in
+using this setup.  You copy this program (and if it's
+@code{autopull.sh}, its companion files) into your package and place
+the copy or copies under version control.  The program can be
+customized using @file{bootstrap.conf} which you also put under
 version control.
 
 @item (C)
diff --git a/doc/gnulib.texi b/doc/gnulib.texi
index eeb9b81f8a..816bf2a3f2 100644
--- a/doc/gnulib.texi
+++ b/doc/gnulib.texi
@@ -7055,7 +7055,7 @@ otherwise have a hard time building your package.
 @node Utilities for Makefiles
 @section Utilities for Makefiles
 
-These are a couple of programs that are often useful in Makefiles.  Some
+These programs can be used in Makefiles.  Some
 of them are also described in
 @ifinfo
 @ref{Auxiliary Programs,,,automake}.
@@ -7105,7 +7105,7 @@ targets depend upon.
 @node Developer tools
 @section Programs for developing in Git checkouts
 
-These are a couple of programs that help when developing in a Git
+These programs can help when developing in a Git
 checkout.  The maintainer of the package copies these programs into the
 version control of the package, so that co-developers can use these
 tools right away.
@@ -7134,9 +7134,12 @@ omitted from version control.  Usually this means that it invokes
 @code{gnulib-tool} and @code{automake}, that generate files from other
 files.
 
-@code{bootstrap} is a wrapper around both: It invokes @code{autopull.sh}
-and then immediately @code{autogen.sh}.@*
-Note: Because this program mixes version control management and
+@code{bootstrap} is a wrapper around both:
+@code{./bootstrap --pull} is equivalent to @code{./autopull.sh},
+@code{./bootstrap --gen} is equivalent to @code{./autogen.sh}.
+Plain @code{./bootstrap} is equivalent to @code{./autopull.sh}
+immediately followed by @code{./autogen.sh}; however, because plain
+@code{./bootstrap} mixes version control management and
 generation of files in non-obvious ways, it has a number of usability
 issues for the advanced developer.
 
@@ -7146,6 +7149,16 @@ programs.  It is not meant to be used directly.
 All three programs make use of a configuration file, called
 @code{bootstrap.conf}.
 
+@item build-aux/bootstrap
+This acts like @code{top/bootstrap}, except it does not
+need the companion files @code{autogen.sh},
+@code{autopull.sh}, and @code{bootstrap-funclib.sh}
+so it avoids some clutter in your project's top level directory.
+With this approach, you update via @code{./bootstrap --pull} and
+@code{./bootstrap --gen} instead of via @code{./autopull.sh} and
+@code{./autogen.sh}.  Otherwise this approach acts similarly, and
+uses the same @code{bootstrap.conf} file.
+
 @item build-aux/bootstrap.conf
 This is the template configuration file.  After copying it into the
 top-level directory of your package, you need to customize it.
diff --git a/top/bootstrap b/top/bootstrap
index 365c378d42..f6ec8fecee 100755
--- a/top/bootstrap
+++ b/top/bootstrap
@@ -1,7 +1,7 @@
 #! /bin/sh
 # Bootstrap this package from checked-out sources.
 
-scriptversion=2022-12-27.05; # UTC
+scriptversion=2022-12-27.07; # UTC
 
 # Copyright (C) 2003-2022 Free Software Foundation, Inc.
 #
@@ -48,6 +48,11 @@ Optional environment variables:
   GNULIB_URL               Cloneable URL of the gnulib repository.
 
 Options:
+
+  --pull                   Do phase 1: pull files from network
+  --gen                    Do phase 2: generate from local files.
+                           (The default is to do both phases.)
+
   --gnulib-srcdir=DIRNAME  specify the local directory where gnulib
                            sources reside.  Use this if you already
                            have gnulib sources on your machine, and
@@ -59,11 +64,13 @@ Options:
                            and history on your machine, and do not want
                            to waste your bandwidth downloading them again.
                            Defaults to \$GNULIB_REFDIR
+
   --bootstrap-sync         if this bootstrap script is not identical to
                            the version in the local gnulib sources,
                            update this script, and then restart it with
                            /bin/sh or the shell \$CONFIG_SHELL
   --no-bootstrap-sync      do not check whether bootstrap is out of sync
+
   --copy                   copy files instead of creating symbolic links
   --force                  attempt to bootstrap even if the sources seem
                            not to have been checked out
@@ -118,6 +125,10 @@ EOF
 
 # Parse options.
 
+# Whether to pull and generate.
+pull=false
+gen=false
+
 # Whether to use copies instead of symlinks.
 copy=false
 
@@ -136,6 +147,10 @@ do
     echo "$copyright"
     exit 0
     ;;
+  --pull)
+    pull=true;;
+  --gen)
+    gen=true;;
   --gnulib-srcdir=*)
     GNULIB_SRCDIR=${option#--gnulib-srcdir=};;
   --gnulib-refdir=*)
@@ -157,6 +172,9 @@ do
   esac
 done
 
+# Default is to do both.
+$pull || $gen || pull=true gen=true
+
 $use_git || test -n "$GNULIB_SRCDIR" \
   || die "Error: --no-git requires \$GNULIB_SRCDIR environment variable or --gnulib-srcdir option"
 test -z "$GNULIB_SRCDIR" || test -d "$GNULIB_SRCDIR" \
@@ -181,7 +199,7 @@ echo "$0: Bootstrapping from checked-out $package sources..."
 export GNULIB_SRCDIR
 export GNULIB_REFDIR
 
-if $use_git || test -z "$SKIP_PO"; then
+if $pull && { $use_git || test -z "$SKIP_PO"; }; then
   autopull \
       `if $bootstrap_sync; then echo ' --bootstrap-sync'; else echo ' --no-bootstrap-sync'; fi` \
       `if test -z "$checkout_only_file"; then echo ' --force'; fi` \
@@ -190,10 +208,12 @@ if $use_git || test -z "$SKIP_PO"; then
     || die "could not fetch auxiliary files"
 fi
 
-autogen \
+if $gen; then
+ autogen \
     `if $copy; then echo ' --copy'; fi` \
     `if test -z "$checkout_only_file"; then echo ' --force'; fi` \
   || die "could not generate auxiliary files"
+fi
 
 # ----------------------------------------------------------------------------
 
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 0/6] build-aux/bootstrap that doesn't need to replace itself
  2022-12-27 18:59 [PATCH 0/6] build-aux/bootstrap that doesn't need to replace itself Paul Eggert
                   ` (6 preceding siblings ...)
  2022-12-27 19:00 ` [PATCH 6/6] Add --pull, --gen options to build-aux/bootstrap Paul Eggert
@ 2022-12-27 21:09 ` Bruno Haible
  2022-12-28  2:16   ` Paul Eggert
  7 siblings, 1 reply; 10+ messages in thread
From: Bruno Haible @ 2022-12-27 21:09 UTC (permalink / raw)
  To: bug-gnulib, Paul Eggert

Hi Paul,

You write in <https://debbugs.gnu.org/cgi/bugreport.cgi?bug=56749>:

> I put the latter script into the gzip 
> repository but did not put the auxiliary files there. I did not notice 
> the error in my testing, since the three auxiliary files were there in 
> my working copy.

I'm sorry that the mechanism that I coded in July got you into making
a mistake.

But I strongly object against the backwards move regarding the autopull.sh /
autogen.sh *concepts*.

The concepts, as I described them in
  <https://lists.gnu.org/archive/html/bug-gnulib/2022-07/msg00053.html>
  <https://lists.gnu.org/archive/html/bug-gnulib/2022-07/msg00078.html>
are that

  * There are two preparation phases for a git repo, before the user
    can run configure: './autopull.sh' then './autogen.sh'.

  * These are *interfaces* between the package's code and the developer.
    Like the *interface* behind the 'configure' script. The purpose
    is that — over time, as more and more packages adopt these two script
    names — developers can just use these two script names as part of their
    habits.

The implementation (bootstrap script, bootstrap-funclib.sh function library)
are just an implementation of these concepts. If your implementation works
better than mine (by avoiding some possible pitfalls), then that's fine.

But what I object to is that you are killing the incentive for more packages
to adopt the autopull.sh / autogen.sh separation. In particular:

  * It's better to recommend in README-hacking

        $ # 1. Fetch auxiliary files from the network.
        $ ./autopull.sh
        $
        $ # 2. Generate files locally.
        $ ./autogen.sh

    because that's the two command names that the developer should remember
    and get used to work with.

    If you write

        $ ./bootstrap --pull  # 1. Fetch some files from the network.
        $ ./bootstrap --gen   # 2. Generate other files locally.

    then we have different command names for the same thing, and it
    encourages packages to clump two different things into a single
    script.

  * I object against omitting autopull.sh and autogen.sh from what gets
    copied into the package.

  * I object against documentation such as

        running @samp{./bootstrap --pull} or @file{autopull.sh}

    because two different commands (with 'or') does not help in creating
    a habit that is easy to remember and easy to use.

Bruno





^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 0/6] build-aux/bootstrap that doesn't need to replace itself
  2022-12-27 21:09 ` [PATCH 0/6] build-aux/bootstrap that doesn't need to replace itself Bruno Haible
@ 2022-12-28  2:16   ` Paul Eggert
  0 siblings, 0 replies; 10+ messages in thread
From: Paul Eggert @ 2022-12-28  2:16 UTC (permalink / raw)
  To: Bruno Haible; +Cc: bug-gnulib

On 12/27/22 13:09, Bruno Haible wrote:
> I strongly object against the backwards move regarding the autopull.sh /
> autogen.sh *concepts*.

The concepts are still there; the only issue is the API. Whether the API 
should be './bootstrap --pull && ./bootstrap --gen' or './autopull.sh && 
./autogen.sh' is a relatively minor detail, as far as the 
pull-vs-generate concepts are concerned.

When the API was proposed I put it on my list of things to worry about, 
and unfortunately I didn't get around to thinking about it seriously 
until recently. Having done so, I took the trouble of implementing and 
suggesting a API that seems to be better for developers of gzip, tar and 
I assume other packages.

Even if we can't agree whether the newer API is better enough to 
standardize on, that should be OK. People doing software imports already 
have to deal with dozens of such APIs, and whether there's one vs two 
more APIs won't make much difference. That being said, if it matters to 
have just one API for Gnulib-using apps, I can volunteer to help migrate 
any packages already using the autogen.sh/autopull.sh API; it shouldn't 
be that hard, and these packages can even continue to support both APIs 
if that is needed for some reason.

>      it encourages packages to clump two different things into a single
>      script.

That shouldn't be much of a problem, any more that it's much of a 
problem that "git fetch" and "git diff" are in a single "git" command.

The current implementation is not cast in stone, and we can to work to 
make it better, more flexible, improve the documentation, etc.

PS. I got one private email from someone else in response to the recent 
patches, in that they didn't like the name "autogen". Not sure what name 
they'd prefer or why, but have asked.



^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2022-12-28  2:16 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-12-27 18:59 [PATCH 0/6] build-aux/bootstrap that doesn't need to replace itself Paul Eggert
2022-12-27 18:59 ` [PATCH 1/6] Move scriptversion= lines up in scripts Paul Eggert
2022-12-27 18:59 ` [PATCH] stdnoreturn: deprecate Paul Eggert
2022-12-27 18:59 ` [PATCH 2/6] Make autogen a shell function too Paul Eggert
2022-12-27 18:59 ` [PATCH 3/6] Make autopull " Paul Eggert
2022-12-27 19:00 ` [PATCH 4/6] Bootstrap with functions, not scripts Paul Eggert
2022-12-27 19:00 ` [PATCH 5/6] Support packages with just 'bootstrap' Paul Eggert
2022-12-27 19:00 ` [PATCH 6/6] Add --pull, --gen options to build-aux/bootstrap Paul Eggert
2022-12-27 21:09 ` [PATCH 0/6] build-aux/bootstrap that doesn't need to replace itself Bruno Haible
2022-12-28  2:16   ` Paul Eggert

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).