Hi all, So far, gnulib-tool has no support for files outside modules, such as config.guess, maint.mk, or doc/INSTALL.UTF-8.
There are two ways to invoke gnulib-tool: with a full pathname or through a symbolic link. In the first case, the absolute filename of a file outside a module can be inferred from the full pathname of the gnulib checkout. But in the second case, it becomes quite tedious. I'm therefore adding an option --copy-file. It's indented to be used in the autogen.sh script of packages, in the same vein as "gnulib-tool --import" or "automake -a -c". Bruno 2009-04-05 Bruno Haible <br...@clisp.org> * gnulib-tool: New option --copy-file. (func_usage): Document it. (func_dest_tmpfilename): Moved out of func_import. (func_add_file, func_update_file): New functions, extracted from func_import. (func_import): Update. *** gnulib-tool.orig 2009-04-05 21:47:45.000000000 +0200 --- gnulib-tool 2009-04-05 21:47:11.000000000 +0200 *************** *** 124,129 **** --- 124,130 ---- gnulib-tool --extract-license module gnulib-tool --extract-maintainer module gnulib-tool --extract-tests-module module + gnulib-tool --copy-file file [destination] Operation modes: --list print the available module names *************** *** 152,157 **** --- 153,159 ---- under lib/ --extract-maintainer report the maintainer(s) inside gnulib --extract-tests-module report the unit test module, if it exists + --copy-file copy a file that is not part of any module General options: --dir=DIRECTORY Specify the target directory. *************** *** 897,902 **** --- 899,907 ---- --extract-* ) mode=`echo "X$1" | sed -e 's/^X--//'` shift ;; + --copy-file | --copy-fil | --copy-fi | --copy-f | --copy- | --copy | --cop | --co ) + mode=copy-file + shift ;; --dir ) shift if test $# = 0; then *************** *** 1795,1800 **** --- 1800,1907 ---- fi } + # func_dest_tmpfilename file + # determines the name of a temporary file (file is relative to destdir). + # Input: + # - destdir target directory + # - doit : if actions shall be executed, false if only to be printed + # - tmp pathname of a temporary directory + # Sets variable: + # - tmpfile absolute filename of the temporary file + func_dest_tmpfilename () + { + if $doit; then + # Put the new contents of $file in a file in the same directory (needed + # to guarantee that an 'mv' to "$destdir/$file" works). + tmpfile="$destdir/$1.tmp" + else + # Put the new contents of $file in a file in a temporary directory + # (because the directory of "$file" might not exist). + tmpfile="$tmp"/`basename "$1"`.tmp + fi + } + + # func_add_file + # copies a file from gnulib into the destination directory. The destination + # is known to not exist. + # Input: + # - destdir target directory + # - local_gnulib_dir from --local-dir + # - f the original file name + # - lookedup_file name of the merged (combined) file + # - lookedup_tmp true if it is located in the tmp directory, blank otherwise + # - g the rewritten file name + # - tmpfile absolute filename of the temporary file + # - doit : if actions shall be executed, false if only to be printed + # - symbolic true if files should be symlinked, copied otherwise + # - lsymbolic true if files from local_gnulib_dir should be symlinked, + # copied otherwise + func_add_file () + { + if $doit; then + echo "Copying file $g" + if { test -n "$symbolic" \ + || { test -n "$lsymbolic" \ + && test "$lookedup_file" = "$local_gnulib_dir/$f"; }; } \ + && test -z "$lookedup_tmp" \ + && cmp "$lookedup_file" "$tmpfile" > /dev/null; then + func_ln_if_changed "$lookedup_file" "$destdir/$g" + else + mv -f "$tmpfile" "$destdir/${g}" || func_fatal_error "failed" + fi + else + echo "Copy file $g" + fi + } + + # func_update_file + # copies a file from gnulib into the destination directory. The destination + # is known to exist. + # Input: + # - destdir target directory + # - local_gnulib_dir from --local-dir + # - f the original file name + # - lookedup_file name of the merged (combined) file + # - lookedup_tmp true if it is located in the tmp directory, blank otherwise + # - g the rewritten file name + # - tmpfile absolute filename of the temporary file + # - doit : if actions shall be executed, false if only to be printed + # - symbolic true if files should be symlinked, copied otherwise + # - lsymbolic true if files from local_gnulib_dir should be symlinked, + # copied otherwise + # - already_present nonempty if the file should already exist, empty otherwise + func_update_file () + { + if cmp "$destdir/$g" "$tmpfile" > /dev/null; then + : # The file has not changed. + else + # Replace the file. + if $doit; then + if test -n "$already_present"; then + echo "Updating file $g (backup in ${g}~)" + else + echo "Replacing file $g (non-gnulib code backed up in ${g}~) !!" + fi + mv -f "$destdir/$g" "$destdir/${g}~" || func_fatal_error "failed" + if { test -n "$symbolic" \ + || { test -n "$lsymbolic" \ + && test "$lookedup_file" = "$local_gnulib_dir/$f"; }; } \ + && test -z "$lookedup_tmp" \ + && cmp "$lookedup_file" "$tmpfile" > /dev/null; then + func_ln_if_changed "$lookedup_file" "$destdir/$g" + else + mv -f "$tmpfile" "$destdir/${g}" || func_fatal_error "failed" + fi + else + if test -n "$already_present"; then + echo "Update file $g (backup in ${g}~)" + else + echo "Replace file $g (non-gnulib code backed up in ${g}~) !!" + fi + fi + fi + } + # func_emit_lib_Makefile_am # emits the contents of library makefile to standard output. # Input: *************** *** 2850,2872 **** exec 0<&5 5<&- } - # func_dest_tmpfilename file - # determines the name of a temporary file (file is relative to destdir). - # Sets variable: - # - tmpfile absolute filename of the temporary file - func_dest_tmpfilename () - { - if $doit; then - # Put the new contents of $file in a file in the same directory (needed - # to guarantee that an 'mv' to "$destdir/$file" works). - tmpfile="$destdir/$1.tmp" - else - # Put the new contents of $file in a file in a temporary directory - # (because the directory of "$file" might not exist). - tmpfile="$tmp"/`basename "$1"`.tmp - fi - } - # Copy files or make symbolic links. Remove obsolete files. added_files='' removed_files='' --- 2957,2962 ---- *************** *** 2901,2907 **** # Uses parameters # - f the original file name # - g the rewritten file name ! # - already_present nonempty if the file already exists, empty otherwise func_add_or_update () { of="$f" --- 2991,2998 ---- # Uses parameters # - f the original file name # - g the rewritten file name ! # - already_present nonempty if the file should already exist, empty ! # otherwise func_add_or_update () { of="$f" *************** *** 2929,2980 **** fi if test -f "$destdir/$g"; then # The file already exists. ! if cmp "$destdir/$g" "$tmpfile" > /dev/null; then ! : # The file has not changed. ! else ! # Replace the file. ! if $doit; then ! if test -n "$already_present"; then ! echo "Updating file $g (backup in ${g}~)" ! else ! echo "Replacing file $g (non-gnulib code backed up in ${g}~) !!" ! fi ! mv -f "$destdir/$g" "$destdir/${g}~" || func_fatal_error "failed" ! if { test -n "$symbolic" \ ! || { test -n "$lsymbolic" \ ! && test "$lookedup_file" = "$local_gnulib_dir/$f"; }; } \ ! && test -z "$lookedup_tmp" \ ! && cmp "$lookedup_file" "$tmpfile" > /dev/null; then ! func_ln_if_changed "$lookedup_file" "$destdir/$g" ! else ! mv -f "$tmpfile" "$destdir/${g}" || func_fatal_error "failed" ! fi ! else ! if test -n "$already_present"; then ! echo "Update file $g (backup in ${g}~)" ! else ! echo "Replace file $g (non-gnulib code backed up in ${g}~) !!" ! fi ! fi ! fi else # Install the file. # Don't protest if the file should be there but isn't: it happens # frequently that developers don't put autogenerated files into CVS. ! if $doit; then ! echo "Copying file $g" ! if { test -n "$symbolic" \ ! || { test -n "$lsymbolic" \ ! && test "$lookedup_file" = "$local_gnulib_dir/$f"; }; } \ ! && test -z "$lookedup_tmp" \ ! && cmp "$lookedup_file" "$tmpfile" > /dev/null; then ! func_ln_if_changed "$lookedup_file" "$destdir/$g" ! else ! mv -f "$tmpfile" "$destdir/${g}" || func_fatal_error "failed" ! fi ! else ! echo "Copy file $g" ! fi func_append added_files "$g$nl" fi rm -f "$tmpfile" --- 3020,3031 ---- fi if test -f "$destdir/$g"; then # The file already exists. ! func_update_file else # Install the file. # Don't protest if the file should be there but isn't: it happens # frequently that developers don't put autogenerated files into CVS. ! func_add_file func_append added_files "$g$nl" fi rm -f "$tmpfile" *************** *** 4634,4639 **** --- 4685,4748 ---- done ;; + copy-file ) + # Verify the number of arguments. + if test $# -lt 1 || test $# -gt 2; then + func_fatal_error "invalid number of arguments for --$mode" + fi + + # The first argument is the file to be copied. + f="$1" + # Verify the file exists. + func_lookup_file "$f" + + # The second argument is the destination; either a directory ot a file. + # It defaults to the current directory. + dest="$2" + test -n "$dest" || dest='.' + test -n "$sourcebase" || sourcebase="lib" + test -n "$m4base" || m4base="m4" + test -n "$docbase" || docbase="doc" + test -n "$testsbase" || testsbase="tests" + test -n "$auxdir" || auxdir="build-aux" + sed_rewrite_files="\ + s,^build-aux/,$auxdir/, + s,^doc/,$docbase/, + s,^lib/,$sourcebase/, + s,^m4/,$m4base/, + s,^tests/,$testsbase/, + s,^top/,," + if test -d "$dest"; then + destdir="$dest" + g=`echo "$f" | sed -e "$sed_rewrite_files"` + else + destdir=`dirname "$dest"` + g=`basename "$dest"` + fi + + # Create the directory for destfile. + d=`dirname "$destdir/$g"` + if $doit; then + if test -n "$d" && test ! -d "$d"; then + mkdir -p "$d" || func_fatal_error "failed" + fi + fi + # Copy the file. + func_dest_tmpfilename "$g" + cp "$lookedup_file" "$tmpfile" || func_fatal_error "failed" + already_present=true + if test -f "$destdir/$g"; then + # The file already exists. + func_update_file + else + # Install the file. + # Don't protest if the file should be there but isn't: it happens + # frequently that developers don't put autogenerated files into CVS. + func_add_file + fi + rm -f "$tmpfile" + ;; + * ) func_fatal_error "unknown operation mode --$mode" ;; esac