summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rw-r--r--doc/Makefile.am75
-rw-r--r--doc/Makefile.in2170
-rw-r--r--doc/fdl.texi505
-rw-r--r--doc/find-maint.info1585
-rw-r--r--doc/find-maint.texi1141
-rw-r--r--doc/find.info186
-rw-r--r--doc/find.info-17261
-rw-r--r--doc/find.info-2bin0 -> 11618 bytes
-rw-r--r--doc/find.texi5712
-rwxr-xr-xdoc/mdate-sh224
-rw-r--r--doc/parse-datetime.texi594
-rw-r--r--doc/perm.texi508
-rw-r--r--doc/regexprops.texi592
-rw-r--r--doc/stamp-14
-rw-r--r--doc/stamp-vti4
-rw-r--r--doc/texinfo.tex10174
-rw-r--r--doc/version.texi4
-rw-r--r--doc/versionmaint.texi4
18 files changed, 30743 insertions, 0 deletions
diff --git a/doc/Makefile.am b/doc/Makefile.am
new file mode 100644
index 0000000..f6f7443
--- /dev/null
+++ b/doc/Makefile.am
@@ -0,0 +1,75 @@
+# Copyright (C) 1996,1999,2000,2001,2003-2015 Free Software Foundation, Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+AM_CFLAGS = $(WARN_CFLAGS)
+
+info_TEXINFOS = find.texi find-maint.texi
+find_TEXINFOS = perm.texi parse-datetime.texi regexprops.texi fdl.texi
+BUILT_SOURCES = dblocation.texi
+nodist_find_TEXINFOS = dblocation.texi
+find_maint_TEXINFOS = fdl.texi
+MOSTLYCLEANFILES = find.cps
+CLEANFILES = find.txt find_mono.html findutils.texi_html_node.tar.gz dblocation.texi
+
+MAKEINFOTXT = $(MAKEINFO) --plaintext
+
+find.txt: find.texi $(srcdir)/version.texi $(find_TEXINFOS)
+
+# find.txt is a file which we need to know how to build
+# because it gets put on the www.gnu.org website.
+# This rule is derived from the .texi.html rule.
+.texi.txt:
+ rm -rf $(@:.txt=.tmp)
+ if $(MAKEINFOTXT) $(AM_MAKEINFOTXTFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
+ -o $(@:.txt=.tmp) $<; \
+ then \
+ rm -rf $@; \
+ if test ! -d $(@:.txt=.tmp) && test -d $(@:.txt=); then \
+ mv $(@:.txt=) $@; else mv $(@:.txt=.tmp) $@; fi; \
+ else \
+ if test ! -d $(@:.txt=.tmp) && test -d $(@:.txt=); then \
+ rm -rf $(@:.txt=); else rm -Rf $(@:.txt=.tmp) $@; fi; \
+ exit 1; \
+ fi
+
+
+# find_mono.html is a file which we need to know how to build
+# because it gets put on the www.gnu.org website.
+# This rule is derived from the generic .texi.html rule.
+find_mono.html: find.texi
+ rm -rf $(@:.html=.htp)
+ if $(MAKEINFOHTML) --no-split $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
+ -o $(@:.html=.htp) $<; \
+ then \
+ rm -rf $@; \
+ if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \
+ mv $(@:.html=) $@; else mv $(@:.html=.htp) $@; fi; \
+ else \
+ if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \
+ rm -rf $(@:.html=); else rm -Rf $(@:.html=.htp) $@; fi; \
+ exit 1; \
+ fi
+
+
+# findutils.texi_html_node.tar.gz is a file which we need to know
+# how to build because it gets put on the www.gnu.org website.
+# This rule depends on GNU tar, but it's principally used
+# by the maintainer, and we don't need to build the file
+# for "make all" or "make install" (or even "make check").
+findutils.texi_html_node.tar.gz: find.html
+ tar zcf $@ $<
+
+
+dblocation.texi: ../locate/dblocation.texi
+ $(LN_S) ../locate/dblocation.texi $@
diff --git a/doc/Makefile.in b/doc/Makefile.in
new file mode 100644
index 0000000..54d4e4e
--- /dev/null
+++ b/doc/Makefile.in
@@ -0,0 +1,2170 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = doc
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/build-aux/mkinstalldirs $(find_TEXINFOS) \
+ $(top_srcdir)/build-aux/mdate-sh $(srcdir)/version.texi \
+ $(srcdir)/stamp-vti $(find_maint_TEXINFOS) \
+ $(srcdir)/versionmaint.texi $(srcdir)/stamp-1 \
+ $(top_srcdir)/build-aux/texinfo.tex mdate-sh texinfo.tex
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/findlib.m4 \
+ $(top_srcdir)/m4/mkinstalldirs.m4 $(top_srcdir)/m4/noreturn.m4 \
+ $(top_srcdir)/m4/nullsort.m4 $(top_srcdir)/m4/withfts.m4 \
+ $(top_srcdir)/gl/m4/00gnulib.m4 \
+ $(top_srcdir)/gl/m4/absolute-header.m4 \
+ $(top_srcdir)/gl/m4/alloca.m4 \
+ $(top_srcdir)/gl/m4/arpa_inet_h.m4 \
+ $(top_srcdir)/gl/m4/assert.m4 $(top_srcdir)/gl/m4/bison.m4 \
+ $(top_srcdir)/gl/m4/btowc.m4 $(top_srcdir)/gl/m4/byteswap.m4 \
+ $(top_srcdir)/gl/m4/canonicalize.m4 \
+ $(top_srcdir)/gl/m4/chdir-long.m4 \
+ $(top_srcdir)/gl/m4/check-math-lib.m4 \
+ $(top_srcdir)/gl/m4/clock_time.m4 \
+ $(top_srcdir)/gl/m4/close-stream.m4 \
+ $(top_srcdir)/gl/m4/close.m4 $(top_srcdir)/gl/m4/closedir.m4 \
+ $(top_srcdir)/gl/m4/closein.m4 $(top_srcdir)/gl/m4/closeout.m4 \
+ $(top_srcdir)/gl/m4/codeset.m4 \
+ $(top_srcdir)/gl/m4/configmake.m4 $(top_srcdir)/gl/m4/ctype.m4 \
+ $(top_srcdir)/gl/m4/cycle-check.m4 \
+ $(top_srcdir)/gl/m4/d-ino.m4 $(top_srcdir)/gl/m4/d-type.m4 \
+ $(top_srcdir)/gl/m4/dirent-safer.m4 \
+ $(top_srcdir)/gl/m4/dirent_h.m4 $(top_srcdir)/gl/m4/dirfd.m4 \
+ $(top_srcdir)/gl/m4/dirname.m4 \
+ $(top_srcdir)/gl/m4/double-slash-root.m4 \
+ $(top_srcdir)/gl/m4/dup.m4 $(top_srcdir)/gl/m4/dup2.m4 \
+ $(top_srcdir)/gl/m4/eealloc.m4 $(top_srcdir)/gl/m4/environ.m4 \
+ $(top_srcdir)/gl/m4/errno_h.m4 $(top_srcdir)/gl/m4/error.m4 \
+ $(top_srcdir)/gl/m4/euidaccess.m4 \
+ $(top_srcdir)/gl/m4/exponentd.m4 \
+ $(top_srcdir)/gl/m4/exponentf.m4 \
+ $(top_srcdir)/gl/m4/exponentl.m4 \
+ $(top_srcdir)/gl/m4/extensions.m4 \
+ $(top_srcdir)/gl/m4/extern-inline.m4 \
+ $(top_srcdir)/gl/m4/faccessat.m4 $(top_srcdir)/gl/m4/fchdir.m4 \
+ $(top_srcdir)/gl/m4/fcntl-o.m4 \
+ $(top_srcdir)/gl/m4/fcntl-safer.m4 \
+ $(top_srcdir)/gl/m4/fcntl.m4 $(top_srcdir)/gl/m4/fcntl_h.m4 \
+ $(top_srcdir)/gl/m4/fdopen.m4 $(top_srcdir)/gl/m4/fdopendir.m4 \
+ $(top_srcdir)/gl/m4/fflush.m4 \
+ $(top_srcdir)/gl/m4/fileblocks.m4 \
+ $(top_srcdir)/gl/m4/filemode.m4 \
+ $(top_srcdir)/gl/m4/filenamecat.m4 \
+ $(top_srcdir)/gl/m4/flexmember.m4 \
+ $(top_srcdir)/gl/m4/float_h.m4 $(top_srcdir)/gl/m4/fnmatch.m4 \
+ $(top_srcdir)/gl/m4/fopen.m4 $(top_srcdir)/gl/m4/fpending.m4 \
+ $(top_srcdir)/gl/m4/fpieee.m4 $(top_srcdir)/gl/m4/fpurge.m4 \
+ $(top_srcdir)/gl/m4/freadahead.m4 \
+ $(top_srcdir)/gl/m4/freading.m4 $(top_srcdir)/gl/m4/fseek.m4 \
+ $(top_srcdir)/gl/m4/fseeko.m4 $(top_srcdir)/gl/m4/fstat.m4 \
+ $(top_srcdir)/gl/m4/fstatat.m4 \
+ $(top_srcdir)/gl/m4/fstypename.m4 $(top_srcdir)/gl/m4/ftell.m4 \
+ $(top_srcdir)/gl/m4/ftello.m4 $(top_srcdir)/gl/m4/ftruncate.m4 \
+ $(top_srcdir)/gl/m4/fts.m4 \
+ $(top_srcdir)/gl/m4/getcwd-abort-bug.m4 \
+ $(top_srcdir)/gl/m4/getcwd-path-max.m4 \
+ $(top_srcdir)/gl/m4/getcwd.m4 $(top_srcdir)/gl/m4/getdelim.m4 \
+ $(top_srcdir)/gl/m4/getdtablesize.m4 \
+ $(top_srcdir)/gl/m4/getgroups.m4 \
+ $(top_srcdir)/gl/m4/gethostname.m4 \
+ $(top_srcdir)/gl/m4/getline.m4 $(top_srcdir)/gl/m4/getopt.m4 \
+ $(top_srcdir)/gl/m4/getpagesize.m4 \
+ $(top_srcdir)/gl/m4/gettext.m4 $(top_srcdir)/gl/m4/gettime.m4 \
+ $(top_srcdir)/gl/m4/gettimeofday.m4 \
+ $(top_srcdir)/gl/m4/glibc21.m4 \
+ $(top_srcdir)/gl/m4/gnulib-common.m4 \
+ $(top_srcdir)/gl/m4/gnulib-comp.m4 \
+ $(top_srcdir)/gl/m4/group-member.m4 \
+ $(top_srcdir)/gl/m4/human.m4 $(top_srcdir)/gl/m4/i-ring.m4 \
+ $(top_srcdir)/gl/m4/iconv.m4 $(top_srcdir)/gl/m4/idcache.m4 \
+ $(top_srcdir)/gl/m4/include_next.m4 \
+ $(top_srcdir)/gl/m4/inet_pton.m4 $(top_srcdir)/gl/m4/inline.m4 \
+ $(top_srcdir)/gl/m4/intlmacosx.m4 \
+ $(top_srcdir)/gl/m4/intmax_t.m4 \
+ $(top_srcdir)/gl/m4/inttostr.m4 \
+ $(top_srcdir)/gl/m4/inttypes-pri.m4 \
+ $(top_srcdir)/gl/m4/inttypes.m4 \
+ $(top_srcdir)/gl/m4/inttypes_h.m4 $(top_srcdir)/gl/m4/ioctl.m4 \
+ $(top_srcdir)/gl/m4/isblank.m4 $(top_srcdir)/gl/m4/isfinite.m4 \
+ $(top_srcdir)/gl/m4/isinf.m4 $(top_srcdir)/gl/m4/isnand.m4 \
+ $(top_srcdir)/gl/m4/isnanf.m4 $(top_srcdir)/gl/m4/isnanl.m4 \
+ $(top_srcdir)/gl/m4/iswblank.m4 \
+ $(top_srcdir)/gl/m4/langinfo_h.m4 \
+ $(top_srcdir)/gl/m4/largefile.m4 \
+ $(top_srcdir)/gl/m4/lcmessage.m4 $(top_srcdir)/gl/m4/lib-ld.m4 \
+ $(top_srcdir)/gl/m4/lib-link.m4 \
+ $(top_srcdir)/gl/m4/lib-prefix.m4 \
+ $(top_srcdir)/gl/m4/libunistring-base.m4 \
+ $(top_srcdir)/gl/m4/localcharset.m4 \
+ $(top_srcdir)/gl/m4/locale-fr.m4 \
+ $(top_srcdir)/gl/m4/locale-ja.m4 \
+ $(top_srcdir)/gl/m4/locale-tr.m4 \
+ $(top_srcdir)/gl/m4/locale-zh.m4 \
+ $(top_srcdir)/gl/m4/locale_h.m4 \
+ $(top_srcdir)/gl/m4/localeconv.m4 \
+ $(top_srcdir)/gl/m4/localename.m4 $(top_srcdir)/gl/m4/lock.m4 \
+ $(top_srcdir)/gl/m4/longlong.m4 \
+ $(top_srcdir)/gl/m4/ls-mntd-fs.m4 $(top_srcdir)/gl/m4/lseek.m4 \
+ $(top_srcdir)/gl/m4/lstat.m4 $(top_srcdir)/gl/m4/malloc.m4 \
+ $(top_srcdir)/gl/m4/malloca.m4 \
+ $(top_srcdir)/gl/m4/manywarnings.m4 \
+ $(top_srcdir)/gl/m4/math_h.m4 $(top_srcdir)/gl/m4/mathfunc.m4 \
+ $(top_srcdir)/gl/m4/mbchar.m4 $(top_srcdir)/gl/m4/mbiter.m4 \
+ $(top_srcdir)/gl/m4/mbrtowc.m4 $(top_srcdir)/gl/m4/mbsinit.m4 \
+ $(top_srcdir)/gl/m4/mbslen.m4 $(top_srcdir)/gl/m4/mbsrtowcs.m4 \
+ $(top_srcdir)/gl/m4/mbstate_t.m4 \
+ $(top_srcdir)/gl/m4/mbswidth.m4 $(top_srcdir)/gl/m4/mbtowc.m4 \
+ $(top_srcdir)/gl/m4/memchr.m4 $(top_srcdir)/gl/m4/mempcpy.m4 \
+ $(top_srcdir)/gl/m4/memrchr.m4 $(top_srcdir)/gl/m4/mktime.m4 \
+ $(top_srcdir)/gl/m4/mmap-anon.m4 $(top_srcdir)/gl/m4/mode_t.m4 \
+ $(top_srcdir)/gl/m4/modechange.m4 $(top_srcdir)/gl/m4/modf.m4 \
+ $(top_srcdir)/gl/m4/mountlist.m4 \
+ $(top_srcdir)/gl/m4/msvc-inval.m4 \
+ $(top_srcdir)/gl/m4/msvc-nothrow.m4 \
+ $(top_srcdir)/gl/m4/multiarch.m4 \
+ $(top_srcdir)/gl/m4/nanosleep.m4 \
+ $(top_srcdir)/gl/m4/netinet_in_h.m4 \
+ $(top_srcdir)/gl/m4/nl_langinfo.m4 $(top_srcdir)/gl/m4/nls.m4 \
+ $(top_srcdir)/gl/m4/nocrash.m4 $(top_srcdir)/gl/m4/off_t.m4 \
+ $(top_srcdir)/gl/m4/onceonly.m4 $(top_srcdir)/gl/m4/open.m4 \
+ $(top_srcdir)/gl/m4/openat.m4 $(top_srcdir)/gl/m4/opendir.m4 \
+ $(top_srcdir)/gl/m4/parse-datetime.m4 \
+ $(top_srcdir)/gl/m4/pathmax.m4 $(top_srcdir)/gl/m4/perror.m4 \
+ $(top_srcdir)/gl/m4/pipe.m4 $(top_srcdir)/gl/m4/po.m4 \
+ $(top_srcdir)/gl/m4/printf.m4 $(top_srcdir)/gl/m4/priv-set.m4 \
+ $(top_srcdir)/gl/m4/progtest.m4 $(top_srcdir)/gl/m4/putenv.m4 \
+ $(top_srcdir)/gl/m4/quote.m4 $(top_srcdir)/gl/m4/quotearg.m4 \
+ $(top_srcdir)/gl/m4/raise.m4 $(top_srcdir)/gl/m4/read.m4 \
+ $(top_srcdir)/gl/m4/readdir.m4 $(top_srcdir)/gl/m4/readlink.m4 \
+ $(top_srcdir)/gl/m4/readlinkat.m4 \
+ $(top_srcdir)/gl/m4/realloc.m4 $(top_srcdir)/gl/m4/regex.m4 \
+ $(top_srcdir)/gl/m4/rewinddir.m4 $(top_srcdir)/gl/m4/rmdir.m4 \
+ $(top_srcdir)/gl/m4/rpmatch.m4 \
+ $(top_srcdir)/gl/m4/safe-read.m4 $(top_srcdir)/gl/m4/same.m4 \
+ $(top_srcdir)/gl/m4/save-cwd.m4 $(top_srcdir)/gl/m4/savedir.m4 \
+ $(top_srcdir)/gl/m4/select.m4 \
+ $(top_srcdir)/gl/m4/selinux-context-h.m4 \
+ $(top_srcdir)/gl/m4/selinux-selinux-h.m4 \
+ $(top_srcdir)/gl/m4/setenv.m4 $(top_srcdir)/gl/m4/setlocale.m4 \
+ $(top_srcdir)/gl/m4/sigaction.m4 \
+ $(top_srcdir)/gl/m4/signal_h.m4 \
+ $(top_srcdir)/gl/m4/signalblocking.m4 \
+ $(top_srcdir)/gl/m4/size_max.m4 $(top_srcdir)/gl/m4/sleep.m4 \
+ $(top_srcdir)/gl/m4/snprintf.m4 \
+ $(top_srcdir)/gl/m4/socketlib.m4 \
+ $(top_srcdir)/gl/m4/sockets.m4 $(top_srcdir)/gl/m4/socklen.m4 \
+ $(top_srcdir)/gl/m4/sockpfaf.m4 $(top_srcdir)/gl/m4/ssize_t.m4 \
+ $(top_srcdir)/gl/m4/st_dm_mode.m4 \
+ $(top_srcdir)/gl/m4/stat-size.m4 \
+ $(top_srcdir)/gl/m4/stat-time.m4 $(top_srcdir)/gl/m4/stat.m4 \
+ $(top_srcdir)/gl/m4/stdalign.m4 $(top_srcdir)/gl/m4/stdarg.m4 \
+ $(top_srcdir)/gl/m4/stdbool.m4 $(top_srcdir)/gl/m4/stddef_h.m4 \
+ $(top_srcdir)/gl/m4/stdint.m4 $(top_srcdir)/gl/m4/stdint_h.m4 \
+ $(top_srcdir)/gl/m4/stdio_h.m4 $(top_srcdir)/gl/m4/stdlib_h.m4 \
+ $(top_srcdir)/gl/m4/stpcpy.m4 $(top_srcdir)/gl/m4/strcase.m4 \
+ $(top_srcdir)/gl/m4/strcasestr.m4 \
+ $(top_srcdir)/gl/m4/strdup.m4 $(top_srcdir)/gl/m4/strerror.m4 \
+ $(top_srcdir)/gl/m4/strerror_r.m4 \
+ $(top_srcdir)/gl/m4/strftime.m4 \
+ $(top_srcdir)/gl/m4/string_h.m4 \
+ $(top_srcdir)/gl/m4/strings_h.m4 \
+ $(top_srcdir)/gl/m4/strndup.m4 $(top_srcdir)/gl/m4/strnlen.m4 \
+ $(top_srcdir)/gl/m4/strstr.m4 $(top_srcdir)/gl/m4/strtoull.m4 \
+ $(top_srcdir)/gl/m4/strtoumax.m4 \
+ $(top_srcdir)/gl/m4/symlink.m4 \
+ $(top_srcdir)/gl/m4/symlinkat.m4 \
+ $(top_srcdir)/gl/m4/sys_ioctl_h.m4 \
+ $(top_srcdir)/gl/m4/sys_select_h.m4 \
+ $(top_srcdir)/gl/m4/sys_socket_h.m4 \
+ $(top_srcdir)/gl/m4/sys_stat_h.m4 \
+ $(top_srcdir)/gl/m4/sys_time_h.m4 \
+ $(top_srcdir)/gl/m4/sys_types_h.m4 \
+ $(top_srcdir)/gl/m4/sys_uio_h.m4 \
+ $(top_srcdir)/gl/m4/sys_utsname_h.m4 \
+ $(top_srcdir)/gl/m4/sys_wait_h.m4 \
+ $(top_srcdir)/gl/m4/thread.m4 $(top_srcdir)/gl/m4/threadlib.m4 \
+ $(top_srcdir)/gl/m4/time_h.m4 $(top_srcdir)/gl/m4/time_r.m4 \
+ $(top_srcdir)/gl/m4/time_rz.m4 $(top_srcdir)/gl/m4/timegm.m4 \
+ $(top_srcdir)/gl/m4/timespec.m4 \
+ $(top_srcdir)/gl/m4/tm_gmtoff.m4 $(top_srcdir)/gl/m4/trunc.m4 \
+ $(top_srcdir)/gl/m4/uname.m4 $(top_srcdir)/gl/m4/ungetc.m4 \
+ $(top_srcdir)/gl/m4/unistd-safer.m4 \
+ $(top_srcdir)/gl/m4/unistd_h.m4 $(top_srcdir)/gl/m4/unlink.m4 \
+ $(top_srcdir)/gl/m4/unlinkat.m4 \
+ $(top_srcdir)/gl/m4/unlinkdir.m4 \
+ $(top_srcdir)/gl/m4/vasnprintf.m4 \
+ $(top_srcdir)/gl/m4/version-etc.m4 \
+ $(top_srcdir)/gl/m4/warn-on-use.m4 \
+ $(top_srcdir)/gl/m4/warnings.m4 $(top_srcdir)/gl/m4/wchar_h.m4 \
+ $(top_srcdir)/gl/m4/wchar_t.m4 $(top_srcdir)/gl/m4/wcrtomb.m4 \
+ $(top_srcdir)/gl/m4/wctob.m4 $(top_srcdir)/gl/m4/wctomb.m4 \
+ $(top_srcdir)/gl/m4/wctype_h.m4 $(top_srcdir)/gl/m4/wcwidth.m4 \
+ $(top_srcdir)/gl/m4/wint_t.m4 $(top_srcdir)/gl/m4/xalloc.m4 \
+ $(top_srcdir)/gl/m4/xgetcwd.m4 $(top_srcdir)/gl/m4/xsize.m4 \
+ $(top_srcdir)/gl/m4/xstrndup.m4 $(top_srcdir)/gl/m4/xstrtod.m4 \
+ $(top_srcdir)/gl/m4/xstrtol.m4 $(top_srcdir)/gl/m4/yesno.m4 \
+ $(top_srcdir)/gl/m4/yield.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/build-aux/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+AM_V_DVIPS = $(am__v_DVIPS_@AM_V@)
+am__v_DVIPS_ = $(am__v_DVIPS_@AM_DEFAULT_V@)
+am__v_DVIPS_0 = @echo " DVIPS " $@;
+am__v_DVIPS_1 =
+AM_V_MAKEINFO = $(am__v_MAKEINFO_@AM_V@)
+am__v_MAKEINFO_ = $(am__v_MAKEINFO_@AM_DEFAULT_V@)
+am__v_MAKEINFO_0 = @echo " MAKEINFO" $@;
+am__v_MAKEINFO_1 =
+AM_V_INFOHTML = $(am__v_INFOHTML_@AM_V@)
+am__v_INFOHTML_ = $(am__v_INFOHTML_@AM_DEFAULT_V@)
+am__v_INFOHTML_0 = @echo " INFOHTML" $@;
+am__v_INFOHTML_1 =
+AM_V_TEXI2DVI = $(am__v_TEXI2DVI_@AM_V@)
+am__v_TEXI2DVI_ = $(am__v_TEXI2DVI_@AM_DEFAULT_V@)
+am__v_TEXI2DVI_0 = @echo " TEXI2DVI" $@;
+am__v_TEXI2DVI_1 =
+AM_V_TEXI2PDF = $(am__v_TEXI2PDF_@AM_V@)
+am__v_TEXI2PDF_ = $(am__v_TEXI2PDF_@AM_DEFAULT_V@)
+am__v_TEXI2PDF_0 = @echo " TEXI2PDF" $@;
+am__v_TEXI2PDF_1 =
+AM_V_texinfo = $(am__v_texinfo_@AM_V@)
+am__v_texinfo_ = $(am__v_texinfo_@AM_DEFAULT_V@)
+am__v_texinfo_0 = -q
+am__v_texinfo_1 =
+AM_V_texidevnull = $(am__v_texidevnull_@AM_V@)
+am__v_texidevnull_ = $(am__v_texidevnull_@AM_DEFAULT_V@)
+am__v_texidevnull_0 = > /dev/null
+am__v_texidevnull_1 =
+INFO_DEPS = $(srcdir)/find.info $(srcdir)/find-maint.info
+TEXINFO_TEX = $(top_srcdir)/build-aux/texinfo.tex
+am__TEXINFO_TEX_DIR = $(top_srcdir)/build-aux
+DVIS = find.dvi find-maint.dvi
+PDFS = find.pdf find-maint.pdf
+PSS = find.ps find-maint.ps
+HTMLS = find.html find-maint.html
+TEXINFOS = find.texi find-maint.texi
+TEXI2DVI = texi2dvi
+TEXI2PDF = $(TEXI2DVI) --pdf --batch
+MAKEINFOHTML = $(MAKEINFO) --html
+AM_MAKEINFOHTMLFLAGS = $(AM_MAKEINFOFLAGS)
+DVIPS = dvips
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__installdirs = "$(DESTDIR)$(infodir)"
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+pkglibexecdir = @pkglibexecdir@
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+ALLOCA_H = @ALLOCA_H@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+APPLE_UNIVERSAL_BUILD = @APPLE_UNIVERSAL_BUILD@
+AR = @AR@
+ARFLAGS = @ARFLAGS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AUXDIR = @AUXDIR@
+AWK = @AWK@
+BITSIZEOF_PTRDIFF_T = @BITSIZEOF_PTRDIFF_T@
+BITSIZEOF_SIG_ATOMIC_T = @BITSIZEOF_SIG_ATOMIC_T@
+BITSIZEOF_SIZE_T = @BITSIZEOF_SIZE_T@
+BITSIZEOF_WCHAR_T = @BITSIZEOF_WCHAR_T@
+BITSIZEOF_WINT_T = @BITSIZEOF_WINT_T@
+BYTESWAP_H = @BYTESWAP_H@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CONFIG_INCLUDE = @CONFIG_INCLUDE@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFAULT_ARG_SIZE = @DEFAULT_ARG_SIZE@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EMULTIHOP_HIDDEN = @EMULTIHOP_HIDDEN@
+EMULTIHOP_VALUE = @EMULTIHOP_VALUE@
+ENOLINK_HIDDEN = @ENOLINK_HIDDEN@
+ENOLINK_VALUE = @ENOLINK_VALUE@
+EOVERFLOW_HIDDEN = @EOVERFLOW_HIDDEN@
+EOVERFLOW_VALUE = @EOVERFLOW_VALUE@
+ERRNO_H = @ERRNO_H@
+EXEEXT = @EXEEXT@
+FAKETIME = @FAKETIME@
+FINDLIBOBJS = @FINDLIBOBJS@
+FINDLIBS = @FINDLIBS@
+FLOAT_H = @FLOAT_H@
+FNMATCH_H = @FNMATCH_H@
+GETHOSTNAME_LIB = @GETHOSTNAME_LIB@
+GETOPT_H = @GETOPT_H@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GLIBC21 = @GLIBC21@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GNULIB_ACCEPT = @GNULIB_ACCEPT@
+GNULIB_ACCEPT4 = @GNULIB_ACCEPT4@
+GNULIB_ACOSF = @GNULIB_ACOSF@
+GNULIB_ACOSL = @GNULIB_ACOSL@
+GNULIB_ALPHASORT = @GNULIB_ALPHASORT@
+GNULIB_ASINF = @GNULIB_ASINF@
+GNULIB_ASINL = @GNULIB_ASINL@
+GNULIB_ATAN2F = @GNULIB_ATAN2F@
+GNULIB_ATANF = @GNULIB_ATANF@
+GNULIB_ATANL = @GNULIB_ATANL@
+GNULIB_ATOLL = @GNULIB_ATOLL@
+GNULIB_BIND = @GNULIB_BIND@
+GNULIB_BTOWC = @GNULIB_BTOWC@
+GNULIB_CALLOC_POSIX = @GNULIB_CALLOC_POSIX@
+GNULIB_CANONICALIZE_FILE_NAME = @GNULIB_CANONICALIZE_FILE_NAME@
+GNULIB_CBRT = @GNULIB_CBRT@
+GNULIB_CBRTF = @GNULIB_CBRTF@
+GNULIB_CBRTL = @GNULIB_CBRTL@
+GNULIB_CEIL = @GNULIB_CEIL@
+GNULIB_CEILF = @GNULIB_CEILF@
+GNULIB_CEILL = @GNULIB_CEILL@
+GNULIB_CHDIR = @GNULIB_CHDIR@
+GNULIB_CHOWN = @GNULIB_CHOWN@
+GNULIB_CLOSE = @GNULIB_CLOSE@
+GNULIB_CLOSEDIR = @GNULIB_CLOSEDIR@
+GNULIB_CONNECT = @GNULIB_CONNECT@
+GNULIB_COPYSIGN = @GNULIB_COPYSIGN@
+GNULIB_COPYSIGNF = @GNULIB_COPYSIGNF@
+GNULIB_COPYSIGNL = @GNULIB_COPYSIGNL@
+GNULIB_COSF = @GNULIB_COSF@
+GNULIB_COSHF = @GNULIB_COSHF@
+GNULIB_COSL = @GNULIB_COSL@
+GNULIB_DIRFD = @GNULIB_DIRFD@
+GNULIB_DPRINTF = @GNULIB_DPRINTF@
+GNULIB_DUP = @GNULIB_DUP@
+GNULIB_DUP2 = @GNULIB_DUP2@
+GNULIB_DUP3 = @GNULIB_DUP3@
+GNULIB_DUPLOCALE = @GNULIB_DUPLOCALE@
+GNULIB_ENVIRON = @GNULIB_ENVIRON@
+GNULIB_EUIDACCESS = @GNULIB_EUIDACCESS@
+GNULIB_EXP2 = @GNULIB_EXP2@
+GNULIB_EXP2F = @GNULIB_EXP2F@
+GNULIB_EXP2L = @GNULIB_EXP2L@
+GNULIB_EXPF = @GNULIB_EXPF@
+GNULIB_EXPL = @GNULIB_EXPL@
+GNULIB_EXPM1 = @GNULIB_EXPM1@
+GNULIB_EXPM1F = @GNULIB_EXPM1F@
+GNULIB_EXPM1L = @GNULIB_EXPM1L@
+GNULIB_FABSF = @GNULIB_FABSF@
+GNULIB_FABSL = @GNULIB_FABSL@
+GNULIB_FACCESSAT = @GNULIB_FACCESSAT@
+GNULIB_FCHDIR = @GNULIB_FCHDIR@
+GNULIB_FCHMODAT = @GNULIB_FCHMODAT@
+GNULIB_FCHOWNAT = @GNULIB_FCHOWNAT@
+GNULIB_FCLOSE = @GNULIB_FCLOSE@
+GNULIB_FCNTL = @GNULIB_FCNTL@
+GNULIB_FDATASYNC = @GNULIB_FDATASYNC@
+GNULIB_FDOPEN = @GNULIB_FDOPEN@
+GNULIB_FDOPENDIR = @GNULIB_FDOPENDIR@
+GNULIB_FFLUSH = @GNULIB_FFLUSH@
+GNULIB_FFS = @GNULIB_FFS@
+GNULIB_FFSL = @GNULIB_FFSL@
+GNULIB_FFSLL = @GNULIB_FFSLL@
+GNULIB_FGETC = @GNULIB_FGETC@
+GNULIB_FGETS = @GNULIB_FGETS@
+GNULIB_FLOOR = @GNULIB_FLOOR@
+GNULIB_FLOORF = @GNULIB_FLOORF@
+GNULIB_FLOORL = @GNULIB_FLOORL@
+GNULIB_FMA = @GNULIB_FMA@
+GNULIB_FMAF = @GNULIB_FMAF@
+GNULIB_FMAL = @GNULIB_FMAL@
+GNULIB_FMOD = @GNULIB_FMOD@
+GNULIB_FMODF = @GNULIB_FMODF@
+GNULIB_FMODL = @GNULIB_FMODL@
+GNULIB_FOPEN = @GNULIB_FOPEN@
+GNULIB_FPRINTF = @GNULIB_FPRINTF@
+GNULIB_FPRINTF_POSIX = @GNULIB_FPRINTF_POSIX@
+GNULIB_FPURGE = @GNULIB_FPURGE@
+GNULIB_FPUTC = @GNULIB_FPUTC@
+GNULIB_FPUTS = @GNULIB_FPUTS@
+GNULIB_FREAD = @GNULIB_FREAD@
+GNULIB_FREOPEN = @GNULIB_FREOPEN@
+GNULIB_FREXP = @GNULIB_FREXP@
+GNULIB_FREXPF = @GNULIB_FREXPF@
+GNULIB_FREXPL = @GNULIB_FREXPL@
+GNULIB_FSCANF = @GNULIB_FSCANF@
+GNULIB_FSEEK = @GNULIB_FSEEK@
+GNULIB_FSEEKO = @GNULIB_FSEEKO@
+GNULIB_FSTAT = @GNULIB_FSTAT@
+GNULIB_FSTATAT = @GNULIB_FSTATAT@
+GNULIB_FSYNC = @GNULIB_FSYNC@
+GNULIB_FTELL = @GNULIB_FTELL@
+GNULIB_FTELLO = @GNULIB_FTELLO@
+GNULIB_FTRUNCATE = @GNULIB_FTRUNCATE@
+GNULIB_FUTIMENS = @GNULIB_FUTIMENS@
+GNULIB_FWRITE = @GNULIB_FWRITE@
+GNULIB_GETC = @GNULIB_GETC@
+GNULIB_GETCHAR = @GNULIB_GETCHAR@
+GNULIB_GETCWD = @GNULIB_GETCWD@
+GNULIB_GETDELIM = @GNULIB_GETDELIM@
+GNULIB_GETDOMAINNAME = @GNULIB_GETDOMAINNAME@
+GNULIB_GETDTABLESIZE = @GNULIB_GETDTABLESIZE@
+GNULIB_GETGROUPS = @GNULIB_GETGROUPS@
+GNULIB_GETHOSTNAME = @GNULIB_GETHOSTNAME@
+GNULIB_GETLINE = @GNULIB_GETLINE@
+GNULIB_GETLOADAVG = @GNULIB_GETLOADAVG@
+GNULIB_GETLOGIN = @GNULIB_GETLOGIN@
+GNULIB_GETLOGIN_R = @GNULIB_GETLOGIN_R@
+GNULIB_GETPAGESIZE = @GNULIB_GETPAGESIZE@
+GNULIB_GETPEERNAME = @GNULIB_GETPEERNAME@
+GNULIB_GETSOCKNAME = @GNULIB_GETSOCKNAME@
+GNULIB_GETSOCKOPT = @GNULIB_GETSOCKOPT@
+GNULIB_GETSUBOPT = @GNULIB_GETSUBOPT@
+GNULIB_GETTIMEOFDAY = @GNULIB_GETTIMEOFDAY@
+GNULIB_GETUSERSHELL = @GNULIB_GETUSERSHELL@
+GNULIB_GL_UNISTD_H_GETOPT = @GNULIB_GL_UNISTD_H_GETOPT@
+GNULIB_GRANTPT = @GNULIB_GRANTPT@
+GNULIB_GROUP_MEMBER = @GNULIB_GROUP_MEMBER@
+GNULIB_HYPOT = @GNULIB_HYPOT@
+GNULIB_HYPOTF = @GNULIB_HYPOTF@
+GNULIB_HYPOTL = @GNULIB_HYPOTL@
+GNULIB_ILOGB = @GNULIB_ILOGB@
+GNULIB_ILOGBF = @GNULIB_ILOGBF@
+GNULIB_ILOGBL = @GNULIB_ILOGBL@
+GNULIB_IMAXABS = @GNULIB_IMAXABS@
+GNULIB_IMAXDIV = @GNULIB_IMAXDIV@
+GNULIB_INET_NTOP = @GNULIB_INET_NTOP@
+GNULIB_INET_PTON = @GNULIB_INET_PTON@
+GNULIB_IOCTL = @GNULIB_IOCTL@
+GNULIB_ISATTY = @GNULIB_ISATTY@
+GNULIB_ISBLANK = @GNULIB_ISBLANK@
+GNULIB_ISFINITE = @GNULIB_ISFINITE@
+GNULIB_ISINF = @GNULIB_ISINF@
+GNULIB_ISNAN = @GNULIB_ISNAN@
+GNULIB_ISNAND = @GNULIB_ISNAND@
+GNULIB_ISNANF = @GNULIB_ISNANF@
+GNULIB_ISNANL = @GNULIB_ISNANL@
+GNULIB_ISWBLANK = @GNULIB_ISWBLANK@
+GNULIB_ISWCTYPE = @GNULIB_ISWCTYPE@
+GNULIB_LCHMOD = @GNULIB_LCHMOD@
+GNULIB_LCHOWN = @GNULIB_LCHOWN@
+GNULIB_LDEXPF = @GNULIB_LDEXPF@
+GNULIB_LDEXPL = @GNULIB_LDEXPL@
+GNULIB_LINK = @GNULIB_LINK@
+GNULIB_LINKAT = @GNULIB_LINKAT@
+GNULIB_LISTEN = @GNULIB_LISTEN@
+GNULIB_LOCALECONV = @GNULIB_LOCALECONV@
+GNULIB_LOG = @GNULIB_LOG@
+GNULIB_LOG10 = @GNULIB_LOG10@
+GNULIB_LOG10F = @GNULIB_LOG10F@
+GNULIB_LOG10L = @GNULIB_LOG10L@
+GNULIB_LOG1P = @GNULIB_LOG1P@
+GNULIB_LOG1PF = @GNULIB_LOG1PF@
+GNULIB_LOG1PL = @GNULIB_LOG1PL@
+GNULIB_LOG2 = @GNULIB_LOG2@
+GNULIB_LOG2F = @GNULIB_LOG2F@
+GNULIB_LOG2L = @GNULIB_LOG2L@
+GNULIB_LOGB = @GNULIB_LOGB@
+GNULIB_LOGBF = @GNULIB_LOGBF@
+GNULIB_LOGBL = @GNULIB_LOGBL@
+GNULIB_LOGF = @GNULIB_LOGF@
+GNULIB_LOGL = @GNULIB_LOGL@
+GNULIB_LSEEK = @GNULIB_LSEEK@
+GNULIB_LSTAT = @GNULIB_LSTAT@
+GNULIB_MALLOC_POSIX = @GNULIB_MALLOC_POSIX@
+GNULIB_MBRLEN = @GNULIB_MBRLEN@
+GNULIB_MBRTOWC = @GNULIB_MBRTOWC@
+GNULIB_MBSCASECMP = @GNULIB_MBSCASECMP@
+GNULIB_MBSCASESTR = @GNULIB_MBSCASESTR@
+GNULIB_MBSCHR = @GNULIB_MBSCHR@
+GNULIB_MBSCSPN = @GNULIB_MBSCSPN@
+GNULIB_MBSINIT = @GNULIB_MBSINIT@
+GNULIB_MBSLEN = @GNULIB_MBSLEN@
+GNULIB_MBSNCASECMP = @GNULIB_MBSNCASECMP@
+GNULIB_MBSNLEN = @GNULIB_MBSNLEN@
+GNULIB_MBSNRTOWCS = @GNULIB_MBSNRTOWCS@
+GNULIB_MBSPBRK = @GNULIB_MBSPBRK@
+GNULIB_MBSPCASECMP = @GNULIB_MBSPCASECMP@
+GNULIB_MBSRCHR = @GNULIB_MBSRCHR@
+GNULIB_MBSRTOWCS = @GNULIB_MBSRTOWCS@
+GNULIB_MBSSEP = @GNULIB_MBSSEP@
+GNULIB_MBSSPN = @GNULIB_MBSSPN@
+GNULIB_MBSSTR = @GNULIB_MBSSTR@
+GNULIB_MBSTOK_R = @GNULIB_MBSTOK_R@
+GNULIB_MBTOWC = @GNULIB_MBTOWC@
+GNULIB_MEMCHR = @GNULIB_MEMCHR@
+GNULIB_MEMMEM = @GNULIB_MEMMEM@
+GNULIB_MEMPCPY = @GNULIB_MEMPCPY@
+GNULIB_MEMRCHR = @GNULIB_MEMRCHR@
+GNULIB_MKDIRAT = @GNULIB_MKDIRAT@
+GNULIB_MKDTEMP = @GNULIB_MKDTEMP@
+GNULIB_MKFIFO = @GNULIB_MKFIFO@
+GNULIB_MKFIFOAT = @GNULIB_MKFIFOAT@
+GNULIB_MKNOD = @GNULIB_MKNOD@
+GNULIB_MKNODAT = @GNULIB_MKNODAT@
+GNULIB_MKOSTEMP = @GNULIB_MKOSTEMP@
+GNULIB_MKOSTEMPS = @GNULIB_MKOSTEMPS@
+GNULIB_MKSTEMP = @GNULIB_MKSTEMP@
+GNULIB_MKSTEMPS = @GNULIB_MKSTEMPS@
+GNULIB_MKTIME = @GNULIB_MKTIME@
+GNULIB_MODF = @GNULIB_MODF@
+GNULIB_MODFF = @GNULIB_MODFF@
+GNULIB_MODFL = @GNULIB_MODFL@
+GNULIB_NANOSLEEP = @GNULIB_NANOSLEEP@
+GNULIB_NL_LANGINFO = @GNULIB_NL_LANGINFO@
+GNULIB_NONBLOCKING = @GNULIB_NONBLOCKING@
+GNULIB_OBSTACK_PRINTF = @GNULIB_OBSTACK_PRINTF@
+GNULIB_OBSTACK_PRINTF_POSIX = @GNULIB_OBSTACK_PRINTF_POSIX@
+GNULIB_OPEN = @GNULIB_OPEN@
+GNULIB_OPENAT = @GNULIB_OPENAT@
+GNULIB_OPENDIR = @GNULIB_OPENDIR@
+GNULIB_PCLOSE = @GNULIB_PCLOSE@
+GNULIB_PERROR = @GNULIB_PERROR@
+GNULIB_PIPE = @GNULIB_PIPE@
+GNULIB_PIPE2 = @GNULIB_PIPE2@
+GNULIB_POPEN = @GNULIB_POPEN@
+GNULIB_POSIX_OPENPT = @GNULIB_POSIX_OPENPT@
+GNULIB_POWF = @GNULIB_POWF@
+GNULIB_PREAD = @GNULIB_PREAD@
+GNULIB_PRINTF = @GNULIB_PRINTF@
+GNULIB_PRINTF_POSIX = @GNULIB_PRINTF_POSIX@
+GNULIB_PSELECT = @GNULIB_PSELECT@
+GNULIB_PTHREAD_SIGMASK = @GNULIB_PTHREAD_SIGMASK@
+GNULIB_PTSNAME = @GNULIB_PTSNAME@
+GNULIB_PTSNAME_R = @GNULIB_PTSNAME_R@
+GNULIB_PUTC = @GNULIB_PUTC@
+GNULIB_PUTCHAR = @GNULIB_PUTCHAR@
+GNULIB_PUTENV = @GNULIB_PUTENV@
+GNULIB_PUTS = @GNULIB_PUTS@
+GNULIB_PWRITE = @GNULIB_PWRITE@
+GNULIB_QSORT_R = @GNULIB_QSORT_R@
+GNULIB_RAISE = @GNULIB_RAISE@
+GNULIB_RANDOM = @GNULIB_RANDOM@
+GNULIB_RANDOM_R = @GNULIB_RANDOM_R@
+GNULIB_RAWMEMCHR = @GNULIB_RAWMEMCHR@
+GNULIB_READ = @GNULIB_READ@
+GNULIB_READDIR = @GNULIB_READDIR@
+GNULIB_READLINK = @GNULIB_READLINK@
+GNULIB_READLINKAT = @GNULIB_READLINKAT@
+GNULIB_REALLOC_POSIX = @GNULIB_REALLOC_POSIX@
+GNULIB_REALPATH = @GNULIB_REALPATH@
+GNULIB_RECV = @GNULIB_RECV@
+GNULIB_RECVFROM = @GNULIB_RECVFROM@
+GNULIB_REMAINDER = @GNULIB_REMAINDER@
+GNULIB_REMAINDERF = @GNULIB_REMAINDERF@
+GNULIB_REMAINDERL = @GNULIB_REMAINDERL@
+GNULIB_REMOVE = @GNULIB_REMOVE@
+GNULIB_RENAME = @GNULIB_RENAME@
+GNULIB_RENAMEAT = @GNULIB_RENAMEAT@
+GNULIB_REWINDDIR = @GNULIB_REWINDDIR@
+GNULIB_RINT = @GNULIB_RINT@
+GNULIB_RINTF = @GNULIB_RINTF@
+GNULIB_RINTL = @GNULIB_RINTL@
+GNULIB_RMDIR = @GNULIB_RMDIR@
+GNULIB_ROUND = @GNULIB_ROUND@
+GNULIB_ROUNDF = @GNULIB_ROUNDF@
+GNULIB_ROUNDL = @GNULIB_ROUNDL@
+GNULIB_RPMATCH = @GNULIB_RPMATCH@
+GNULIB_SCANDIR = @GNULIB_SCANDIR@
+GNULIB_SCANF = @GNULIB_SCANF@
+GNULIB_SECURE_GETENV = @GNULIB_SECURE_GETENV@
+GNULIB_SELECT = @GNULIB_SELECT@
+GNULIB_SEND = @GNULIB_SEND@
+GNULIB_SENDTO = @GNULIB_SENDTO@
+GNULIB_SETENV = @GNULIB_SETENV@
+GNULIB_SETHOSTNAME = @GNULIB_SETHOSTNAME@
+GNULIB_SETLOCALE = @GNULIB_SETLOCALE@
+GNULIB_SETSOCKOPT = @GNULIB_SETSOCKOPT@
+GNULIB_SHUTDOWN = @GNULIB_SHUTDOWN@
+GNULIB_SIGACTION = @GNULIB_SIGACTION@
+GNULIB_SIGNAL_H_SIGPIPE = @GNULIB_SIGNAL_H_SIGPIPE@
+GNULIB_SIGNBIT = @GNULIB_SIGNBIT@
+GNULIB_SIGPROCMASK = @GNULIB_SIGPROCMASK@
+GNULIB_SINF = @GNULIB_SINF@
+GNULIB_SINHF = @GNULIB_SINHF@
+GNULIB_SINL = @GNULIB_SINL@
+GNULIB_SLEEP = @GNULIB_SLEEP@
+GNULIB_SNPRINTF = @GNULIB_SNPRINTF@
+GNULIB_SOCKET = @GNULIB_SOCKET@
+GNULIB_SPRINTF_POSIX = @GNULIB_SPRINTF_POSIX@
+GNULIB_SQRTF = @GNULIB_SQRTF@
+GNULIB_SQRTL = @GNULIB_SQRTL@
+GNULIB_STAT = @GNULIB_STAT@
+GNULIB_STDIO_H_NONBLOCKING = @GNULIB_STDIO_H_NONBLOCKING@
+GNULIB_STDIO_H_SIGPIPE = @GNULIB_STDIO_H_SIGPIPE@
+GNULIB_STPCPY = @GNULIB_STPCPY@
+GNULIB_STPNCPY = @GNULIB_STPNCPY@
+GNULIB_STRCASESTR = @GNULIB_STRCASESTR@
+GNULIB_STRCHRNUL = @GNULIB_STRCHRNUL@
+GNULIB_STRDUP = @GNULIB_STRDUP@
+GNULIB_STRERROR = @GNULIB_STRERROR@
+GNULIB_STRERROR_R = @GNULIB_STRERROR_R@
+GNULIB_STRNCAT = @GNULIB_STRNCAT@
+GNULIB_STRNDUP = @GNULIB_STRNDUP@
+GNULIB_STRNLEN = @GNULIB_STRNLEN@
+GNULIB_STRPBRK = @GNULIB_STRPBRK@
+GNULIB_STRPTIME = @GNULIB_STRPTIME@
+GNULIB_STRSEP = @GNULIB_STRSEP@
+GNULIB_STRSIGNAL = @GNULIB_STRSIGNAL@
+GNULIB_STRSTR = @GNULIB_STRSTR@
+GNULIB_STRTOD = @GNULIB_STRTOD@
+GNULIB_STRTOIMAX = @GNULIB_STRTOIMAX@
+GNULIB_STRTOK_R = @GNULIB_STRTOK_R@
+GNULIB_STRTOLL = @GNULIB_STRTOLL@
+GNULIB_STRTOULL = @GNULIB_STRTOULL@
+GNULIB_STRTOUMAX = @GNULIB_STRTOUMAX@
+GNULIB_STRVERSCMP = @GNULIB_STRVERSCMP@
+GNULIB_SYMLINK = @GNULIB_SYMLINK@
+GNULIB_SYMLINKAT = @GNULIB_SYMLINKAT@
+GNULIB_SYSTEM_POSIX = @GNULIB_SYSTEM_POSIX@
+GNULIB_TANF = @GNULIB_TANF@
+GNULIB_TANHF = @GNULIB_TANHF@
+GNULIB_TANL = @GNULIB_TANL@
+GNULIB_TIMEGM = @GNULIB_TIMEGM@
+GNULIB_TIME_R = @GNULIB_TIME_R@
+GNULIB_TIME_RZ = @GNULIB_TIME_RZ@
+GNULIB_TMPFILE = @GNULIB_TMPFILE@
+GNULIB_TOWCTRANS = @GNULIB_TOWCTRANS@
+GNULIB_TRUNC = @GNULIB_TRUNC@
+GNULIB_TRUNCF = @GNULIB_TRUNCF@
+GNULIB_TRUNCL = @GNULIB_TRUNCL@
+GNULIB_TTYNAME_R = @GNULIB_TTYNAME_R@
+GNULIB_UNAME = @GNULIB_UNAME@
+GNULIB_UNISTD_H_NONBLOCKING = @GNULIB_UNISTD_H_NONBLOCKING@
+GNULIB_UNISTD_H_SIGPIPE = @GNULIB_UNISTD_H_SIGPIPE@
+GNULIB_UNLINK = @GNULIB_UNLINK@
+GNULIB_UNLINKAT = @GNULIB_UNLINKAT@
+GNULIB_UNLOCKPT = @GNULIB_UNLOCKPT@
+GNULIB_UNSETENV = @GNULIB_UNSETENV@
+GNULIB_USLEEP = @GNULIB_USLEEP@
+GNULIB_UTIMENSAT = @GNULIB_UTIMENSAT@
+GNULIB_VASPRINTF = @GNULIB_VASPRINTF@
+GNULIB_VDPRINTF = @GNULIB_VDPRINTF@
+GNULIB_VFPRINTF = @GNULIB_VFPRINTF@
+GNULIB_VFPRINTF_POSIX = @GNULIB_VFPRINTF_POSIX@
+GNULIB_VFSCANF = @GNULIB_VFSCANF@
+GNULIB_VPRINTF = @GNULIB_VPRINTF@
+GNULIB_VPRINTF_POSIX = @GNULIB_VPRINTF_POSIX@
+GNULIB_VSCANF = @GNULIB_VSCANF@
+GNULIB_VSNPRINTF = @GNULIB_VSNPRINTF@
+GNULIB_VSPRINTF_POSIX = @GNULIB_VSPRINTF_POSIX@
+GNULIB_WAITPID = @GNULIB_WAITPID@
+GNULIB_WCPCPY = @GNULIB_WCPCPY@
+GNULIB_WCPNCPY = @GNULIB_WCPNCPY@
+GNULIB_WCRTOMB = @GNULIB_WCRTOMB@
+GNULIB_WCSCASECMP = @GNULIB_WCSCASECMP@
+GNULIB_WCSCAT = @GNULIB_WCSCAT@
+GNULIB_WCSCHR = @GNULIB_WCSCHR@
+GNULIB_WCSCMP = @GNULIB_WCSCMP@
+GNULIB_WCSCOLL = @GNULIB_WCSCOLL@
+GNULIB_WCSCPY = @GNULIB_WCSCPY@
+GNULIB_WCSCSPN = @GNULIB_WCSCSPN@
+GNULIB_WCSDUP = @GNULIB_WCSDUP@
+GNULIB_WCSLEN = @GNULIB_WCSLEN@
+GNULIB_WCSNCASECMP = @GNULIB_WCSNCASECMP@
+GNULIB_WCSNCAT = @GNULIB_WCSNCAT@
+GNULIB_WCSNCMP = @GNULIB_WCSNCMP@
+GNULIB_WCSNCPY = @GNULIB_WCSNCPY@
+GNULIB_WCSNLEN = @GNULIB_WCSNLEN@
+GNULIB_WCSNRTOMBS = @GNULIB_WCSNRTOMBS@
+GNULIB_WCSPBRK = @GNULIB_WCSPBRK@
+GNULIB_WCSRCHR = @GNULIB_WCSRCHR@
+GNULIB_WCSRTOMBS = @GNULIB_WCSRTOMBS@
+GNULIB_WCSSPN = @GNULIB_WCSSPN@
+GNULIB_WCSSTR = @GNULIB_WCSSTR@
+GNULIB_WCSTOK = @GNULIB_WCSTOK@
+GNULIB_WCSWIDTH = @GNULIB_WCSWIDTH@
+GNULIB_WCSXFRM = @GNULIB_WCSXFRM@
+GNULIB_WCTOB = @GNULIB_WCTOB@
+GNULIB_WCTOMB = @GNULIB_WCTOMB@
+GNULIB_WCTRANS = @GNULIB_WCTRANS@
+GNULIB_WCTYPE = @GNULIB_WCTYPE@
+GNULIB_WCWIDTH = @GNULIB_WCWIDTH@
+GNULIB_WMEMCHR = @GNULIB_WMEMCHR@
+GNULIB_WMEMCMP = @GNULIB_WMEMCMP@
+GNULIB_WMEMCPY = @GNULIB_WMEMCPY@
+GNULIB_WMEMMOVE = @GNULIB_WMEMMOVE@
+GNULIB_WMEMSET = @GNULIB_WMEMSET@
+GNULIB_WRITE = @GNULIB_WRITE@
+GNULIB__EXIT = @GNULIB__EXIT@
+GREP = @GREP@
+HAVE_ACCEPT4 = @HAVE_ACCEPT4@
+HAVE_ACOSF = @HAVE_ACOSF@
+HAVE_ACOSL = @HAVE_ACOSL@
+HAVE_ALPHASORT = @HAVE_ALPHASORT@
+HAVE_ARPA_INET_H = @HAVE_ARPA_INET_H@
+HAVE_ASINF = @HAVE_ASINF@
+HAVE_ASINL = @HAVE_ASINL@
+HAVE_ATAN2F = @HAVE_ATAN2F@
+HAVE_ATANF = @HAVE_ATANF@
+HAVE_ATANL = @HAVE_ATANL@
+HAVE_ATOLL = @HAVE_ATOLL@
+HAVE_ATTRIBUTE_NORETURN = @HAVE_ATTRIBUTE_NORETURN@
+HAVE_BTOWC = @HAVE_BTOWC@
+HAVE_CANONICALIZE_FILE_NAME = @HAVE_CANONICALIZE_FILE_NAME@
+HAVE_CBRT = @HAVE_CBRT@
+HAVE_CBRTF = @HAVE_CBRTF@
+HAVE_CBRTL = @HAVE_CBRTL@
+HAVE_CHOWN = @HAVE_CHOWN@
+HAVE_CLOSEDIR = @HAVE_CLOSEDIR@
+HAVE_COPYSIGN = @HAVE_COPYSIGN@
+HAVE_COPYSIGNL = @HAVE_COPYSIGNL@
+HAVE_COSF = @HAVE_COSF@
+HAVE_COSHF = @HAVE_COSHF@
+HAVE_COSL = @HAVE_COSL@
+HAVE_DECL_ACOSL = @HAVE_DECL_ACOSL@
+HAVE_DECL_ASINL = @HAVE_DECL_ASINL@
+HAVE_DECL_ATANL = @HAVE_DECL_ATANL@
+HAVE_DECL_CBRTF = @HAVE_DECL_CBRTF@
+HAVE_DECL_CBRTL = @HAVE_DECL_CBRTL@
+HAVE_DECL_CEILF = @HAVE_DECL_CEILF@
+HAVE_DECL_CEILL = @HAVE_DECL_CEILL@
+HAVE_DECL_COPYSIGNF = @HAVE_DECL_COPYSIGNF@
+HAVE_DECL_COSL = @HAVE_DECL_COSL@
+HAVE_DECL_DIRFD = @HAVE_DECL_DIRFD@
+HAVE_DECL_ENVIRON = @HAVE_DECL_ENVIRON@
+HAVE_DECL_EXP2 = @HAVE_DECL_EXP2@
+HAVE_DECL_EXP2F = @HAVE_DECL_EXP2F@
+HAVE_DECL_EXP2L = @HAVE_DECL_EXP2L@
+HAVE_DECL_EXPL = @HAVE_DECL_EXPL@
+HAVE_DECL_EXPM1L = @HAVE_DECL_EXPM1L@
+HAVE_DECL_FCHDIR = @HAVE_DECL_FCHDIR@
+HAVE_DECL_FDATASYNC = @HAVE_DECL_FDATASYNC@
+HAVE_DECL_FDOPENDIR = @HAVE_DECL_FDOPENDIR@
+HAVE_DECL_FLOORF = @HAVE_DECL_FLOORF@
+HAVE_DECL_FLOORL = @HAVE_DECL_FLOORL@
+HAVE_DECL_FPURGE = @HAVE_DECL_FPURGE@
+HAVE_DECL_FREXPL = @HAVE_DECL_FREXPL@
+HAVE_DECL_FSEEKO = @HAVE_DECL_FSEEKO@
+HAVE_DECL_FTELLO = @HAVE_DECL_FTELLO@
+HAVE_DECL_GETDELIM = @HAVE_DECL_GETDELIM@
+HAVE_DECL_GETDOMAINNAME = @HAVE_DECL_GETDOMAINNAME@
+HAVE_DECL_GETLINE = @HAVE_DECL_GETLINE@
+HAVE_DECL_GETLOADAVG = @HAVE_DECL_GETLOADAVG@
+HAVE_DECL_GETLOGIN_R = @HAVE_DECL_GETLOGIN_R@
+HAVE_DECL_GETPAGESIZE = @HAVE_DECL_GETPAGESIZE@
+HAVE_DECL_GETUSERSHELL = @HAVE_DECL_GETUSERSHELL@
+HAVE_DECL_IMAXABS = @HAVE_DECL_IMAXABS@
+HAVE_DECL_IMAXDIV = @HAVE_DECL_IMAXDIV@
+HAVE_DECL_INET_NTOP = @HAVE_DECL_INET_NTOP@
+HAVE_DECL_INET_PTON = @HAVE_DECL_INET_PTON@
+HAVE_DECL_LDEXPL = @HAVE_DECL_LDEXPL@
+HAVE_DECL_LOCALTIME_R = @HAVE_DECL_LOCALTIME_R@
+HAVE_DECL_LOG10L = @HAVE_DECL_LOG10L@
+HAVE_DECL_LOG2 = @HAVE_DECL_LOG2@
+HAVE_DECL_LOG2F = @HAVE_DECL_LOG2F@
+HAVE_DECL_LOG2L = @HAVE_DECL_LOG2L@
+HAVE_DECL_LOGB = @HAVE_DECL_LOGB@
+HAVE_DECL_LOGL = @HAVE_DECL_LOGL@
+HAVE_DECL_MEMMEM = @HAVE_DECL_MEMMEM@
+HAVE_DECL_MEMRCHR = @HAVE_DECL_MEMRCHR@
+HAVE_DECL_OBSTACK_PRINTF = @HAVE_DECL_OBSTACK_PRINTF@
+HAVE_DECL_REMAINDER = @HAVE_DECL_REMAINDER@
+HAVE_DECL_REMAINDERL = @HAVE_DECL_REMAINDERL@
+HAVE_DECL_RINTF = @HAVE_DECL_RINTF@
+HAVE_DECL_ROUND = @HAVE_DECL_ROUND@
+HAVE_DECL_ROUNDF = @HAVE_DECL_ROUNDF@
+HAVE_DECL_ROUNDL = @HAVE_DECL_ROUNDL@
+HAVE_DECL_SETENV = @HAVE_DECL_SETENV@
+HAVE_DECL_SETHOSTNAME = @HAVE_DECL_SETHOSTNAME@
+HAVE_DECL_SINL = @HAVE_DECL_SINL@
+HAVE_DECL_SNPRINTF = @HAVE_DECL_SNPRINTF@
+HAVE_DECL_SQRTL = @HAVE_DECL_SQRTL@
+HAVE_DECL_STRDUP = @HAVE_DECL_STRDUP@
+HAVE_DECL_STRERROR_R = @HAVE_DECL_STRERROR_R@
+HAVE_DECL_STRNCASECMP = @HAVE_DECL_STRNCASECMP@
+HAVE_DECL_STRNDUP = @HAVE_DECL_STRNDUP@
+HAVE_DECL_STRNLEN = @HAVE_DECL_STRNLEN@
+HAVE_DECL_STRSIGNAL = @HAVE_DECL_STRSIGNAL@
+HAVE_DECL_STRTOIMAX = @HAVE_DECL_STRTOIMAX@
+HAVE_DECL_STRTOK_R = @HAVE_DECL_STRTOK_R@
+HAVE_DECL_STRTOUMAX = @HAVE_DECL_STRTOUMAX@
+HAVE_DECL_TANL = @HAVE_DECL_TANL@
+HAVE_DECL_TRUNC = @HAVE_DECL_TRUNC@
+HAVE_DECL_TRUNCF = @HAVE_DECL_TRUNCF@
+HAVE_DECL_TRUNCL = @HAVE_DECL_TRUNCL@
+HAVE_DECL_TTYNAME_R = @HAVE_DECL_TTYNAME_R@
+HAVE_DECL_UNSETENV = @HAVE_DECL_UNSETENV@
+HAVE_DECL_VSNPRINTF = @HAVE_DECL_VSNPRINTF@
+HAVE_DECL_WCTOB = @HAVE_DECL_WCTOB@
+HAVE_DECL_WCWIDTH = @HAVE_DECL_WCWIDTH@
+HAVE_DIRENT_H = @HAVE_DIRENT_H@
+HAVE_DPRINTF = @HAVE_DPRINTF@
+HAVE_DUP2 = @HAVE_DUP2@
+HAVE_DUP3 = @HAVE_DUP3@
+HAVE_DUPLOCALE = @HAVE_DUPLOCALE@
+HAVE_EUIDACCESS = @HAVE_EUIDACCESS@
+HAVE_EXPF = @HAVE_EXPF@
+HAVE_EXPL = @HAVE_EXPL@
+HAVE_EXPM1 = @HAVE_EXPM1@
+HAVE_EXPM1F = @HAVE_EXPM1F@
+HAVE_FABSF = @HAVE_FABSF@
+HAVE_FABSL = @HAVE_FABSL@
+HAVE_FACCESSAT = @HAVE_FACCESSAT@
+HAVE_FCHDIR = @HAVE_FCHDIR@
+HAVE_FCHMODAT = @HAVE_FCHMODAT@
+HAVE_FCHOWNAT = @HAVE_FCHOWNAT@
+HAVE_FCNTL = @HAVE_FCNTL@
+HAVE_FDATASYNC = @HAVE_FDATASYNC@
+HAVE_FDOPENDIR = @HAVE_FDOPENDIR@
+HAVE_FEATURES_H = @HAVE_FEATURES_H@
+HAVE_FFS = @HAVE_FFS@
+HAVE_FFSL = @HAVE_FFSL@
+HAVE_FFSLL = @HAVE_FFSLL@
+HAVE_FMA = @HAVE_FMA@
+HAVE_FMAF = @HAVE_FMAF@
+HAVE_FMAL = @HAVE_FMAL@
+HAVE_FMODF = @HAVE_FMODF@
+HAVE_FMODL = @HAVE_FMODL@
+HAVE_FREXPF = @HAVE_FREXPF@
+HAVE_FSEEKO = @HAVE_FSEEKO@
+HAVE_FSTATAT = @HAVE_FSTATAT@
+HAVE_FSYNC = @HAVE_FSYNC@
+HAVE_FTELLO = @HAVE_FTELLO@
+HAVE_FTRUNCATE = @HAVE_FTRUNCATE@
+HAVE_FUTIMENS = @HAVE_FUTIMENS@
+HAVE_GETDTABLESIZE = @HAVE_GETDTABLESIZE@
+HAVE_GETGROUPS = @HAVE_GETGROUPS@
+HAVE_GETHOSTNAME = @HAVE_GETHOSTNAME@
+HAVE_GETLOGIN = @HAVE_GETLOGIN@
+HAVE_GETOPT_H = @HAVE_GETOPT_H@
+HAVE_GETPAGESIZE = @HAVE_GETPAGESIZE@
+HAVE_GETSUBOPT = @HAVE_GETSUBOPT@
+HAVE_GETTIMEOFDAY = @HAVE_GETTIMEOFDAY@
+HAVE_GRANTPT = @HAVE_GRANTPT@
+HAVE_GROUP_MEMBER = @HAVE_GROUP_MEMBER@
+HAVE_HYPOTF = @HAVE_HYPOTF@
+HAVE_HYPOTL = @HAVE_HYPOTL@
+HAVE_ILOGB = @HAVE_ILOGB@
+HAVE_ILOGBF = @HAVE_ILOGBF@
+HAVE_ILOGBL = @HAVE_ILOGBL@
+HAVE_INTTYPES_H = @HAVE_INTTYPES_H@
+HAVE_ISBLANK = @HAVE_ISBLANK@
+HAVE_ISNAND = @HAVE_ISNAND@
+HAVE_ISNANF = @HAVE_ISNANF@
+HAVE_ISNANL = @HAVE_ISNANL@
+HAVE_ISWBLANK = @HAVE_ISWBLANK@
+HAVE_ISWCNTRL = @HAVE_ISWCNTRL@
+HAVE_LANGINFO_CODESET = @HAVE_LANGINFO_CODESET@
+HAVE_LANGINFO_ERA = @HAVE_LANGINFO_ERA@
+HAVE_LANGINFO_H = @HAVE_LANGINFO_H@
+HAVE_LANGINFO_T_FMT_AMPM = @HAVE_LANGINFO_T_FMT_AMPM@
+HAVE_LANGINFO_YESEXPR = @HAVE_LANGINFO_YESEXPR@
+HAVE_LCHMOD = @HAVE_LCHMOD@
+HAVE_LCHOWN = @HAVE_LCHOWN@
+HAVE_LDEXPF = @HAVE_LDEXPF@
+HAVE_LINK = @HAVE_LINK@
+HAVE_LINKAT = @HAVE_LINKAT@
+HAVE_LOG10F = @HAVE_LOG10F@
+HAVE_LOG10L = @HAVE_LOG10L@
+HAVE_LOG1P = @HAVE_LOG1P@
+HAVE_LOG1PF = @HAVE_LOG1PF@
+HAVE_LOG1PL = @HAVE_LOG1PL@
+HAVE_LOGBF = @HAVE_LOGBF@
+HAVE_LOGBL = @HAVE_LOGBL@
+HAVE_LOGF = @HAVE_LOGF@
+HAVE_LOGL = @HAVE_LOGL@
+HAVE_LONG_LONG_INT = @HAVE_LONG_LONG_INT@
+HAVE_LSTAT = @HAVE_LSTAT@
+HAVE_MAX_ALIGN_T = @HAVE_MAX_ALIGN_T@
+HAVE_MBRLEN = @HAVE_MBRLEN@
+HAVE_MBRTOWC = @HAVE_MBRTOWC@
+HAVE_MBSINIT = @HAVE_MBSINIT@
+HAVE_MBSLEN = @HAVE_MBSLEN@
+HAVE_MBSNRTOWCS = @HAVE_MBSNRTOWCS@
+HAVE_MBSRTOWCS = @HAVE_MBSRTOWCS@
+HAVE_MEMCHR = @HAVE_MEMCHR@
+HAVE_MEMPCPY = @HAVE_MEMPCPY@
+HAVE_MKDIRAT = @HAVE_MKDIRAT@
+HAVE_MKDTEMP = @HAVE_MKDTEMP@
+HAVE_MKFIFO = @HAVE_MKFIFO@
+HAVE_MKFIFOAT = @HAVE_MKFIFOAT@
+HAVE_MKNOD = @HAVE_MKNOD@
+HAVE_MKNODAT = @HAVE_MKNODAT@
+HAVE_MKOSTEMP = @HAVE_MKOSTEMP@
+HAVE_MKOSTEMPS = @HAVE_MKOSTEMPS@
+HAVE_MKSTEMP = @HAVE_MKSTEMP@
+HAVE_MKSTEMPS = @HAVE_MKSTEMPS@
+HAVE_MODFF = @HAVE_MODFF@
+HAVE_MODFL = @HAVE_MODFL@
+HAVE_MSVC_INVALID_PARAMETER_HANDLER = @HAVE_MSVC_INVALID_PARAMETER_HANDLER@
+HAVE_NANOSLEEP = @HAVE_NANOSLEEP@
+HAVE_NETINET_IN_H = @HAVE_NETINET_IN_H@
+HAVE_NL_LANGINFO = @HAVE_NL_LANGINFO@
+HAVE_OPENAT = @HAVE_OPENAT@
+HAVE_OPENDIR = @HAVE_OPENDIR@
+HAVE_OS_H = @HAVE_OS_H@
+HAVE_PCLOSE = @HAVE_PCLOSE@
+HAVE_PIPE = @HAVE_PIPE@
+HAVE_PIPE2 = @HAVE_PIPE2@
+HAVE_POPEN = @HAVE_POPEN@
+HAVE_POSIX_OPENPT = @HAVE_POSIX_OPENPT@
+HAVE_POSIX_SIGNALBLOCKING = @HAVE_POSIX_SIGNALBLOCKING@
+HAVE_POWF = @HAVE_POWF@
+HAVE_PREAD = @HAVE_PREAD@
+HAVE_PSELECT = @HAVE_PSELECT@
+HAVE_PTHREAD_SIGMASK = @HAVE_PTHREAD_SIGMASK@
+HAVE_PTSNAME = @HAVE_PTSNAME@
+HAVE_PTSNAME_R = @HAVE_PTSNAME_R@
+HAVE_PWRITE = @HAVE_PWRITE@
+HAVE_RAISE = @HAVE_RAISE@
+HAVE_RANDOM = @HAVE_RANDOM@
+HAVE_RANDOM_H = @HAVE_RANDOM_H@
+HAVE_RANDOM_R = @HAVE_RANDOM_R@
+HAVE_RAWMEMCHR = @HAVE_RAWMEMCHR@
+HAVE_READDIR = @HAVE_READDIR@
+HAVE_READLINK = @HAVE_READLINK@
+HAVE_READLINKAT = @HAVE_READLINKAT@
+HAVE_REALPATH = @HAVE_REALPATH@
+HAVE_REMAINDER = @HAVE_REMAINDER@
+HAVE_REMAINDERF = @HAVE_REMAINDERF@
+HAVE_RENAMEAT = @HAVE_RENAMEAT@
+HAVE_REWINDDIR = @HAVE_REWINDDIR@
+HAVE_RINT = @HAVE_RINT@
+HAVE_RINTL = @HAVE_RINTL@
+HAVE_RPMATCH = @HAVE_RPMATCH@
+HAVE_SAME_LONG_DOUBLE_AS_DOUBLE = @HAVE_SAME_LONG_DOUBLE_AS_DOUBLE@
+HAVE_SA_FAMILY_T = @HAVE_SA_FAMILY_T@
+HAVE_SCANDIR = @HAVE_SCANDIR@
+HAVE_SECURE_GETENV = @HAVE_SECURE_GETENV@
+HAVE_SETENV = @HAVE_SETENV@
+HAVE_SETHOSTNAME = @HAVE_SETHOSTNAME@
+HAVE_SIGACTION = @HAVE_SIGACTION@
+HAVE_SIGHANDLER_T = @HAVE_SIGHANDLER_T@
+HAVE_SIGINFO_T = @HAVE_SIGINFO_T@
+HAVE_SIGNED_SIG_ATOMIC_T = @HAVE_SIGNED_SIG_ATOMIC_T@
+HAVE_SIGNED_WCHAR_T = @HAVE_SIGNED_WCHAR_T@
+HAVE_SIGNED_WINT_T = @HAVE_SIGNED_WINT_T@
+HAVE_SIGSET_T = @HAVE_SIGSET_T@
+HAVE_SINF = @HAVE_SINF@
+HAVE_SINHF = @HAVE_SINHF@
+HAVE_SINL = @HAVE_SINL@
+HAVE_SLEEP = @HAVE_SLEEP@
+HAVE_SQRTF = @HAVE_SQRTF@
+HAVE_SQRTL = @HAVE_SQRTL@
+HAVE_STDINT_H = @HAVE_STDINT_H@
+HAVE_STPCPY = @HAVE_STPCPY@
+HAVE_STPNCPY = @HAVE_STPNCPY@
+HAVE_STRCASECMP = @HAVE_STRCASECMP@
+HAVE_STRCASESTR = @HAVE_STRCASESTR@
+HAVE_STRCHRNUL = @HAVE_STRCHRNUL@
+HAVE_STRINGS_H = @HAVE_STRINGS_H@
+HAVE_STRPBRK = @HAVE_STRPBRK@
+HAVE_STRPTIME = @HAVE_STRPTIME@
+HAVE_STRSEP = @HAVE_STRSEP@
+HAVE_STRTOD = @HAVE_STRTOD@
+HAVE_STRTOLL = @HAVE_STRTOLL@
+HAVE_STRTOULL = @HAVE_STRTOULL@
+HAVE_STRUCT_RANDOM_DATA = @HAVE_STRUCT_RANDOM_DATA@
+HAVE_STRUCT_SIGACTION_SA_SIGACTION = @HAVE_STRUCT_SIGACTION_SA_SIGACTION@
+HAVE_STRUCT_SOCKADDR_STORAGE = @HAVE_STRUCT_SOCKADDR_STORAGE@
+HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY = @HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY@
+HAVE_STRUCT_TIMEVAL = @HAVE_STRUCT_TIMEVAL@
+HAVE_STRUCT_UTSNAME = @HAVE_STRUCT_UTSNAME@
+HAVE_STRVERSCMP = @HAVE_STRVERSCMP@
+HAVE_SYMLINK = @HAVE_SYMLINK@
+HAVE_SYMLINKAT = @HAVE_SYMLINKAT@
+HAVE_SYS_BITYPES_H = @HAVE_SYS_BITYPES_H@
+HAVE_SYS_INTTYPES_H = @HAVE_SYS_INTTYPES_H@
+HAVE_SYS_IOCTL_H = @HAVE_SYS_IOCTL_H@
+HAVE_SYS_LOADAVG_H = @HAVE_SYS_LOADAVG_H@
+HAVE_SYS_PARAM_H = @HAVE_SYS_PARAM_H@
+HAVE_SYS_SELECT_H = @HAVE_SYS_SELECT_H@
+HAVE_SYS_SOCKET_H = @HAVE_SYS_SOCKET_H@
+HAVE_SYS_TIME_H = @HAVE_SYS_TIME_H@
+HAVE_SYS_TYPES_H = @HAVE_SYS_TYPES_H@
+HAVE_SYS_UIO_H = @HAVE_SYS_UIO_H@
+HAVE_SYS_UTSNAME_H = @HAVE_SYS_UTSNAME_H@
+HAVE_TANF = @HAVE_TANF@
+HAVE_TANHF = @HAVE_TANHF@
+HAVE_TANL = @HAVE_TANL@
+HAVE_TIMEGM = @HAVE_TIMEGM@
+HAVE_TIMEZONE_T = @HAVE_TIMEZONE_T@
+HAVE_TYPE_VOLATILE_SIG_ATOMIC_T = @HAVE_TYPE_VOLATILE_SIG_ATOMIC_T@
+HAVE_UNAME = @HAVE_UNAME@
+HAVE_UNISTD_H = @HAVE_UNISTD_H@
+HAVE_UNLINKAT = @HAVE_UNLINKAT@
+HAVE_UNLOCKPT = @HAVE_UNLOCKPT@
+HAVE_UNSIGNED_LONG_LONG_INT = @HAVE_UNSIGNED_LONG_LONG_INT@
+HAVE_USLEEP = @HAVE_USLEEP@
+HAVE_UTIMENSAT = @HAVE_UTIMENSAT@
+HAVE_VASPRINTF = @HAVE_VASPRINTF@
+HAVE_VDPRINTF = @HAVE_VDPRINTF@
+HAVE_WCHAR_H = @HAVE_WCHAR_H@
+HAVE_WCHAR_T = @HAVE_WCHAR_T@
+HAVE_WCPCPY = @HAVE_WCPCPY@
+HAVE_WCPNCPY = @HAVE_WCPNCPY@
+HAVE_WCRTOMB = @HAVE_WCRTOMB@
+HAVE_WCSCASECMP = @HAVE_WCSCASECMP@
+HAVE_WCSCAT = @HAVE_WCSCAT@
+HAVE_WCSCHR = @HAVE_WCSCHR@
+HAVE_WCSCMP = @HAVE_WCSCMP@
+HAVE_WCSCOLL = @HAVE_WCSCOLL@
+HAVE_WCSCPY = @HAVE_WCSCPY@
+HAVE_WCSCSPN = @HAVE_WCSCSPN@
+HAVE_WCSDUP = @HAVE_WCSDUP@
+HAVE_WCSLEN = @HAVE_WCSLEN@
+HAVE_WCSNCASECMP = @HAVE_WCSNCASECMP@
+HAVE_WCSNCAT = @HAVE_WCSNCAT@
+HAVE_WCSNCMP = @HAVE_WCSNCMP@
+HAVE_WCSNCPY = @HAVE_WCSNCPY@
+HAVE_WCSNLEN = @HAVE_WCSNLEN@
+HAVE_WCSNRTOMBS = @HAVE_WCSNRTOMBS@
+HAVE_WCSPBRK = @HAVE_WCSPBRK@
+HAVE_WCSRCHR = @HAVE_WCSRCHR@
+HAVE_WCSRTOMBS = @HAVE_WCSRTOMBS@
+HAVE_WCSSPN = @HAVE_WCSSPN@
+HAVE_WCSSTR = @HAVE_WCSSTR@
+HAVE_WCSTOK = @HAVE_WCSTOK@
+HAVE_WCSWIDTH = @HAVE_WCSWIDTH@
+HAVE_WCSXFRM = @HAVE_WCSXFRM@
+HAVE_WCTRANS_T = @HAVE_WCTRANS_T@
+HAVE_WCTYPE_H = @HAVE_WCTYPE_H@
+HAVE_WCTYPE_T = @HAVE_WCTYPE_T@
+HAVE_WINSOCK2_H = @HAVE_WINSOCK2_H@
+HAVE_WINT_T = @HAVE_WINT_T@
+HAVE_WMEMCHR = @HAVE_WMEMCHR@
+HAVE_WMEMCMP = @HAVE_WMEMCMP@
+HAVE_WMEMCPY = @HAVE_WMEMCPY@
+HAVE_WMEMMOVE = @HAVE_WMEMMOVE@
+HAVE_WMEMSET = @HAVE_WMEMSET@
+HAVE_WS2TCPIP_H = @HAVE_WS2TCPIP_H@
+HAVE_XLOCALE_H = @HAVE_XLOCALE_H@
+HAVE__BOOL = @HAVE__BOOL@
+HAVE__EXIT = @HAVE__EXIT@
+INCLUDE_NEXT = @INCLUDE_NEXT@
+INCLUDE_NEXT_AS_FIRST_DIRECTIVE = @INCLUDE_NEXT_AS_FIRST_DIRECTIVE@
+INET_PTON_LIB = @INET_PTON_LIB@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INT32_MAX_LT_INTMAX_MAX = @INT32_MAX_LT_INTMAX_MAX@
+INT64_MAX_EQ_LONG_MAX = @INT64_MAX_EQ_LONG_MAX@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+ISFINITE_LIBM = @ISFINITE_LIBM@
+ISINF_LIBM = @ISINF_LIBM@
+LDFLAGS = @LDFLAGS@
+LIBGNULIB_LIBDEPS = @LIBGNULIB_LIBDEPS@
+LIBGNULIB_LTLIBDEPS = @LIBGNULIB_LTLIBDEPS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBMULTITHREAD = @LIBMULTITHREAD@
+LIBOBJS = @LIBOBJS@
+LIBPTH = @LIBPTH@
+LIBPTH_PREFIX = @LIBPTH_PREFIX@
+LIBS = @LIBS@
+LIBSOCKET = @LIBSOCKET@
+LIBTESTS_LIBDEPS = @LIBTESTS_LIBDEPS@
+LIBTHREAD = @LIBTHREAD@
+LIBUNISTRING_UNITYPES_H = @LIBUNISTRING_UNITYPES_H@
+LIBUNISTRING_UNIWIDTH_H = @LIBUNISTRING_UNIWIDTH_H@
+LIB_CLOCK_GETTIME = @LIB_CLOCK_GETTIME@
+LIB_EACCESS = @LIB_EACCESS@
+LIB_NANOSLEEP = @LIB_NANOSLEEP@
+LIB_SELECT = @LIB_SELECT@
+LIB_SELINUX = @LIB_SELINUX@
+LN_S = @LN_S@
+LOCALCHARSET_TESTS_ENVIRONMENT = @LOCALCHARSET_TESTS_ENVIRONMENT@
+LOCALE_FR = @LOCALE_FR@
+LOCALE_FR_UTF8 = @LOCALE_FR_UTF8@
+LOCALE_JA = @LOCALE_JA@
+LOCALE_TR_UTF8 = @LOCALE_TR_UTF8@
+LOCALE_ZH_CN = @LOCALE_ZH_CN@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBMULTITHREAD = @LTLIBMULTITHREAD@
+LTLIBOBJS = @LTLIBOBJS@
+LTLIBPTH = @LTLIBPTH@
+LTLIBTHREAD = @LTLIBTHREAD@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MODF_LIBM = @MODF_LIBM@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NETINET_IN_H = @NETINET_IN_H@
+NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@
+NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@
+NEXT_AS_FIRST_DIRECTIVE_CTYPE_H = @NEXT_AS_FIRST_DIRECTIVE_CTYPE_H@
+NEXT_AS_FIRST_DIRECTIVE_DIRENT_H = @NEXT_AS_FIRST_DIRECTIVE_DIRENT_H@
+NEXT_AS_FIRST_DIRECTIVE_ERRNO_H = @NEXT_AS_FIRST_DIRECTIVE_ERRNO_H@
+NEXT_AS_FIRST_DIRECTIVE_FCNTL_H = @NEXT_AS_FIRST_DIRECTIVE_FCNTL_H@
+NEXT_AS_FIRST_DIRECTIVE_FLOAT_H = @NEXT_AS_FIRST_DIRECTIVE_FLOAT_H@
+NEXT_AS_FIRST_DIRECTIVE_GETOPT_H = @NEXT_AS_FIRST_DIRECTIVE_GETOPT_H@
+NEXT_AS_FIRST_DIRECTIVE_INTTYPES_H = @NEXT_AS_FIRST_DIRECTIVE_INTTYPES_H@
+NEXT_AS_FIRST_DIRECTIVE_LANGINFO_H = @NEXT_AS_FIRST_DIRECTIVE_LANGINFO_H@
+NEXT_AS_FIRST_DIRECTIVE_LOCALE_H = @NEXT_AS_FIRST_DIRECTIVE_LOCALE_H@
+NEXT_AS_FIRST_DIRECTIVE_MATH_H = @NEXT_AS_FIRST_DIRECTIVE_MATH_H@
+NEXT_AS_FIRST_DIRECTIVE_NETINET_IN_H = @NEXT_AS_FIRST_DIRECTIVE_NETINET_IN_H@
+NEXT_AS_FIRST_DIRECTIVE_SELINUX_SELINUX_H = @NEXT_AS_FIRST_DIRECTIVE_SELINUX_SELINUX_H@
+NEXT_AS_FIRST_DIRECTIVE_SIGNAL_H = @NEXT_AS_FIRST_DIRECTIVE_SIGNAL_H@
+NEXT_AS_FIRST_DIRECTIVE_STDARG_H = @NEXT_AS_FIRST_DIRECTIVE_STDARG_H@
+NEXT_AS_FIRST_DIRECTIVE_STDDEF_H = @NEXT_AS_FIRST_DIRECTIVE_STDDEF_H@
+NEXT_AS_FIRST_DIRECTIVE_STDINT_H = @NEXT_AS_FIRST_DIRECTIVE_STDINT_H@
+NEXT_AS_FIRST_DIRECTIVE_STDIO_H = @NEXT_AS_FIRST_DIRECTIVE_STDIO_H@
+NEXT_AS_FIRST_DIRECTIVE_STDLIB_H = @NEXT_AS_FIRST_DIRECTIVE_STDLIB_H@
+NEXT_AS_FIRST_DIRECTIVE_STRINGS_H = @NEXT_AS_FIRST_DIRECTIVE_STRINGS_H@
+NEXT_AS_FIRST_DIRECTIVE_STRING_H = @NEXT_AS_FIRST_DIRECTIVE_STRING_H@
+NEXT_AS_FIRST_DIRECTIVE_SYS_IOCTL_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_IOCTL_H@
+NEXT_AS_FIRST_DIRECTIVE_SYS_SELECT_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_SELECT_H@
+NEXT_AS_FIRST_DIRECTIVE_SYS_SOCKET_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_SOCKET_H@
+NEXT_AS_FIRST_DIRECTIVE_SYS_STAT_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_STAT_H@
+NEXT_AS_FIRST_DIRECTIVE_SYS_TIME_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_TIME_H@
+NEXT_AS_FIRST_DIRECTIVE_SYS_TYPES_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_TYPES_H@
+NEXT_AS_FIRST_DIRECTIVE_SYS_UIO_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_UIO_H@
+NEXT_AS_FIRST_DIRECTIVE_SYS_UTSNAME_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_UTSNAME_H@
+NEXT_AS_FIRST_DIRECTIVE_SYS_WAIT_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_WAIT_H@
+NEXT_AS_FIRST_DIRECTIVE_TIME_H = @NEXT_AS_FIRST_DIRECTIVE_TIME_H@
+NEXT_AS_FIRST_DIRECTIVE_UNISTD_H = @NEXT_AS_FIRST_DIRECTIVE_UNISTD_H@
+NEXT_AS_FIRST_DIRECTIVE_WCHAR_H = @NEXT_AS_FIRST_DIRECTIVE_WCHAR_H@
+NEXT_AS_FIRST_DIRECTIVE_WCTYPE_H = @NEXT_AS_FIRST_DIRECTIVE_WCTYPE_H@
+NEXT_CTYPE_H = @NEXT_CTYPE_H@
+NEXT_DIRENT_H = @NEXT_DIRENT_H@
+NEXT_ERRNO_H = @NEXT_ERRNO_H@
+NEXT_FCNTL_H = @NEXT_FCNTL_H@
+NEXT_FLOAT_H = @NEXT_FLOAT_H@
+NEXT_GETOPT_H = @NEXT_GETOPT_H@
+NEXT_INTTYPES_H = @NEXT_INTTYPES_H@
+NEXT_LANGINFO_H = @NEXT_LANGINFO_H@
+NEXT_LOCALE_H = @NEXT_LOCALE_H@
+NEXT_MATH_H = @NEXT_MATH_H@
+NEXT_NETINET_IN_H = @NEXT_NETINET_IN_H@
+NEXT_SELINUX_SELINUX_H = @NEXT_SELINUX_SELINUX_H@
+NEXT_SIGNAL_H = @NEXT_SIGNAL_H@
+NEXT_STDARG_H = @NEXT_STDARG_H@
+NEXT_STDDEF_H = @NEXT_STDDEF_H@
+NEXT_STDINT_H = @NEXT_STDINT_H@
+NEXT_STDIO_H = @NEXT_STDIO_H@
+NEXT_STDLIB_H = @NEXT_STDLIB_H@
+NEXT_STRINGS_H = @NEXT_STRINGS_H@
+NEXT_STRING_H = @NEXT_STRING_H@
+NEXT_SYS_IOCTL_H = @NEXT_SYS_IOCTL_H@
+NEXT_SYS_SELECT_H = @NEXT_SYS_SELECT_H@
+NEXT_SYS_SOCKET_H = @NEXT_SYS_SOCKET_H@
+NEXT_SYS_STAT_H = @NEXT_SYS_STAT_H@
+NEXT_SYS_TIME_H = @NEXT_SYS_TIME_H@
+NEXT_SYS_TYPES_H = @NEXT_SYS_TYPES_H@
+NEXT_SYS_UIO_H = @NEXT_SYS_UIO_H@
+NEXT_SYS_UTSNAME_H = @NEXT_SYS_UTSNAME_H@
+NEXT_SYS_WAIT_H = @NEXT_SYS_WAIT_H@
+NEXT_TIME_H = @NEXT_TIME_H@
+NEXT_UNISTD_H = @NEXT_UNISTD_H@
+NEXT_WCHAR_H = @NEXT_WCHAR_H@
+NEXT_WCTYPE_H = @NEXT_WCTYPE_H@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+POSUB = @POSUB@
+PRAGMA_COLUMNS = @PRAGMA_COLUMNS@
+PRAGMA_SYSTEM_HEADER = @PRAGMA_SYSTEM_HEADER@
+PRIPTR_PREFIX = @PRIPTR_PREFIX@
+PRI_MACROS_BROKEN = @PRI_MACROS_BROKEN@
+PTHREAD_H_DEFINES_STRUCT_TIMESPEC = @PTHREAD_H_DEFINES_STRUCT_TIMESPEC@
+PTRDIFF_T_SUFFIX = @PTRDIFF_T_SUFFIX@
+PYTHON = @PYTHON@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+RANLIB = @RANLIB@
+REPLACE_BTOWC = @REPLACE_BTOWC@
+REPLACE_CALLOC = @REPLACE_CALLOC@
+REPLACE_CANONICALIZE_FILE_NAME = @REPLACE_CANONICALIZE_FILE_NAME@
+REPLACE_CBRTF = @REPLACE_CBRTF@
+REPLACE_CBRTL = @REPLACE_CBRTL@
+REPLACE_CEIL = @REPLACE_CEIL@
+REPLACE_CEILF = @REPLACE_CEILF@
+REPLACE_CEILL = @REPLACE_CEILL@
+REPLACE_CHOWN = @REPLACE_CHOWN@
+REPLACE_CLOSE = @REPLACE_CLOSE@
+REPLACE_CLOSEDIR = @REPLACE_CLOSEDIR@
+REPLACE_DIRFD = @REPLACE_DIRFD@
+REPLACE_DPRINTF = @REPLACE_DPRINTF@
+REPLACE_DUP = @REPLACE_DUP@
+REPLACE_DUP2 = @REPLACE_DUP2@
+REPLACE_DUPLOCALE = @REPLACE_DUPLOCALE@
+REPLACE_EXP2 = @REPLACE_EXP2@
+REPLACE_EXP2L = @REPLACE_EXP2L@
+REPLACE_EXPM1 = @REPLACE_EXPM1@
+REPLACE_EXPM1F = @REPLACE_EXPM1F@
+REPLACE_FABSL = @REPLACE_FABSL@
+REPLACE_FCHOWNAT = @REPLACE_FCHOWNAT@
+REPLACE_FCLOSE = @REPLACE_FCLOSE@
+REPLACE_FCNTL = @REPLACE_FCNTL@
+REPLACE_FDOPEN = @REPLACE_FDOPEN@
+REPLACE_FDOPENDIR = @REPLACE_FDOPENDIR@
+REPLACE_FFLUSH = @REPLACE_FFLUSH@
+REPLACE_FLOOR = @REPLACE_FLOOR@
+REPLACE_FLOORF = @REPLACE_FLOORF@
+REPLACE_FLOORL = @REPLACE_FLOORL@
+REPLACE_FMA = @REPLACE_FMA@
+REPLACE_FMAF = @REPLACE_FMAF@
+REPLACE_FMAL = @REPLACE_FMAL@
+REPLACE_FMOD = @REPLACE_FMOD@
+REPLACE_FMODF = @REPLACE_FMODF@
+REPLACE_FMODL = @REPLACE_FMODL@
+REPLACE_FOPEN = @REPLACE_FOPEN@
+REPLACE_FPRINTF = @REPLACE_FPRINTF@
+REPLACE_FPURGE = @REPLACE_FPURGE@
+REPLACE_FREOPEN = @REPLACE_FREOPEN@
+REPLACE_FREXP = @REPLACE_FREXP@
+REPLACE_FREXPF = @REPLACE_FREXPF@
+REPLACE_FREXPL = @REPLACE_FREXPL@
+REPLACE_FSEEK = @REPLACE_FSEEK@
+REPLACE_FSEEKO = @REPLACE_FSEEKO@
+REPLACE_FSTAT = @REPLACE_FSTAT@
+REPLACE_FSTATAT = @REPLACE_FSTATAT@
+REPLACE_FTELL = @REPLACE_FTELL@
+REPLACE_FTELLO = @REPLACE_FTELLO@
+REPLACE_FTRUNCATE = @REPLACE_FTRUNCATE@
+REPLACE_FUTIMENS = @REPLACE_FUTIMENS@
+REPLACE_GETCWD = @REPLACE_GETCWD@
+REPLACE_GETDELIM = @REPLACE_GETDELIM@
+REPLACE_GETDOMAINNAME = @REPLACE_GETDOMAINNAME@
+REPLACE_GETDTABLESIZE = @REPLACE_GETDTABLESIZE@
+REPLACE_GETGROUPS = @REPLACE_GETGROUPS@
+REPLACE_GETLINE = @REPLACE_GETLINE@
+REPLACE_GETLOGIN_R = @REPLACE_GETLOGIN_R@
+REPLACE_GETPAGESIZE = @REPLACE_GETPAGESIZE@
+REPLACE_GETTIMEOFDAY = @REPLACE_GETTIMEOFDAY@
+REPLACE_GMTIME = @REPLACE_GMTIME@
+REPLACE_HUGE_VAL = @REPLACE_HUGE_VAL@
+REPLACE_HYPOT = @REPLACE_HYPOT@
+REPLACE_HYPOTF = @REPLACE_HYPOTF@
+REPLACE_HYPOTL = @REPLACE_HYPOTL@
+REPLACE_ILOGB = @REPLACE_ILOGB@
+REPLACE_ILOGBF = @REPLACE_ILOGBF@
+REPLACE_INET_NTOP = @REPLACE_INET_NTOP@
+REPLACE_INET_PTON = @REPLACE_INET_PTON@
+REPLACE_IOCTL = @REPLACE_IOCTL@
+REPLACE_ISATTY = @REPLACE_ISATTY@
+REPLACE_ISFINITE = @REPLACE_ISFINITE@
+REPLACE_ISINF = @REPLACE_ISINF@
+REPLACE_ISNAN = @REPLACE_ISNAN@
+REPLACE_ISWBLANK = @REPLACE_ISWBLANK@
+REPLACE_ISWCNTRL = @REPLACE_ISWCNTRL@
+REPLACE_ITOLD = @REPLACE_ITOLD@
+REPLACE_LCHOWN = @REPLACE_LCHOWN@
+REPLACE_LDEXPL = @REPLACE_LDEXPL@
+REPLACE_LINK = @REPLACE_LINK@
+REPLACE_LINKAT = @REPLACE_LINKAT@
+REPLACE_LOCALECONV = @REPLACE_LOCALECONV@
+REPLACE_LOCALTIME = @REPLACE_LOCALTIME@
+REPLACE_LOCALTIME_R = @REPLACE_LOCALTIME_R@
+REPLACE_LOG = @REPLACE_LOG@
+REPLACE_LOG10 = @REPLACE_LOG10@
+REPLACE_LOG10F = @REPLACE_LOG10F@
+REPLACE_LOG10L = @REPLACE_LOG10L@
+REPLACE_LOG1P = @REPLACE_LOG1P@
+REPLACE_LOG1PF = @REPLACE_LOG1PF@
+REPLACE_LOG1PL = @REPLACE_LOG1PL@
+REPLACE_LOG2 = @REPLACE_LOG2@
+REPLACE_LOG2F = @REPLACE_LOG2F@
+REPLACE_LOG2L = @REPLACE_LOG2L@
+REPLACE_LOGB = @REPLACE_LOGB@
+REPLACE_LOGBF = @REPLACE_LOGBF@
+REPLACE_LOGBL = @REPLACE_LOGBL@
+REPLACE_LOGF = @REPLACE_LOGF@
+REPLACE_LOGL = @REPLACE_LOGL@
+REPLACE_LSEEK = @REPLACE_LSEEK@
+REPLACE_LSTAT = @REPLACE_LSTAT@
+REPLACE_MALLOC = @REPLACE_MALLOC@
+REPLACE_MBRLEN = @REPLACE_MBRLEN@
+REPLACE_MBRTOWC = @REPLACE_MBRTOWC@
+REPLACE_MBSINIT = @REPLACE_MBSINIT@
+REPLACE_MBSNRTOWCS = @REPLACE_MBSNRTOWCS@
+REPLACE_MBSRTOWCS = @REPLACE_MBSRTOWCS@
+REPLACE_MBSTATE_T = @REPLACE_MBSTATE_T@
+REPLACE_MBTOWC = @REPLACE_MBTOWC@
+REPLACE_MEMCHR = @REPLACE_MEMCHR@
+REPLACE_MEMMEM = @REPLACE_MEMMEM@
+REPLACE_MKDIR = @REPLACE_MKDIR@
+REPLACE_MKFIFO = @REPLACE_MKFIFO@
+REPLACE_MKNOD = @REPLACE_MKNOD@
+REPLACE_MKSTEMP = @REPLACE_MKSTEMP@
+REPLACE_MKTIME = @REPLACE_MKTIME@
+REPLACE_MODF = @REPLACE_MODF@
+REPLACE_MODFF = @REPLACE_MODFF@
+REPLACE_MODFL = @REPLACE_MODFL@
+REPLACE_NAN = @REPLACE_NAN@
+REPLACE_NANOSLEEP = @REPLACE_NANOSLEEP@
+REPLACE_NL_LANGINFO = @REPLACE_NL_LANGINFO@
+REPLACE_NULL = @REPLACE_NULL@
+REPLACE_OBSTACK_PRINTF = @REPLACE_OBSTACK_PRINTF@
+REPLACE_OPEN = @REPLACE_OPEN@
+REPLACE_OPENAT = @REPLACE_OPENAT@
+REPLACE_OPENDIR = @REPLACE_OPENDIR@
+REPLACE_PERROR = @REPLACE_PERROR@
+REPLACE_POPEN = @REPLACE_POPEN@
+REPLACE_PREAD = @REPLACE_PREAD@
+REPLACE_PRINTF = @REPLACE_PRINTF@
+REPLACE_PSELECT = @REPLACE_PSELECT@
+REPLACE_PTHREAD_SIGMASK = @REPLACE_PTHREAD_SIGMASK@
+REPLACE_PTSNAME = @REPLACE_PTSNAME@
+REPLACE_PTSNAME_R = @REPLACE_PTSNAME_R@
+REPLACE_PUTENV = @REPLACE_PUTENV@
+REPLACE_PWRITE = @REPLACE_PWRITE@
+REPLACE_QSORT_R = @REPLACE_QSORT_R@
+REPLACE_RAISE = @REPLACE_RAISE@
+REPLACE_RANDOM_R = @REPLACE_RANDOM_R@
+REPLACE_READ = @REPLACE_READ@
+REPLACE_READLINK = @REPLACE_READLINK@
+REPLACE_READLINKAT = @REPLACE_READLINKAT@
+REPLACE_REALLOC = @REPLACE_REALLOC@
+REPLACE_REALPATH = @REPLACE_REALPATH@
+REPLACE_REMAINDER = @REPLACE_REMAINDER@
+REPLACE_REMAINDERF = @REPLACE_REMAINDERF@
+REPLACE_REMAINDERL = @REPLACE_REMAINDERL@
+REPLACE_REMOVE = @REPLACE_REMOVE@
+REPLACE_RENAME = @REPLACE_RENAME@
+REPLACE_RENAMEAT = @REPLACE_RENAMEAT@
+REPLACE_RMDIR = @REPLACE_RMDIR@
+REPLACE_ROUND = @REPLACE_ROUND@
+REPLACE_ROUNDF = @REPLACE_ROUNDF@
+REPLACE_ROUNDL = @REPLACE_ROUNDL@
+REPLACE_SELECT = @REPLACE_SELECT@
+REPLACE_SETENV = @REPLACE_SETENV@
+REPLACE_SETLOCALE = @REPLACE_SETLOCALE@
+REPLACE_SIGNBIT = @REPLACE_SIGNBIT@
+REPLACE_SIGNBIT_USING_GCC = @REPLACE_SIGNBIT_USING_GCC@
+REPLACE_SLEEP = @REPLACE_SLEEP@
+REPLACE_SNPRINTF = @REPLACE_SNPRINTF@
+REPLACE_SPRINTF = @REPLACE_SPRINTF@
+REPLACE_SQRTL = @REPLACE_SQRTL@
+REPLACE_STAT = @REPLACE_STAT@
+REPLACE_STDIO_READ_FUNCS = @REPLACE_STDIO_READ_FUNCS@
+REPLACE_STDIO_WRITE_FUNCS = @REPLACE_STDIO_WRITE_FUNCS@
+REPLACE_STPNCPY = @REPLACE_STPNCPY@
+REPLACE_STRCASESTR = @REPLACE_STRCASESTR@
+REPLACE_STRCHRNUL = @REPLACE_STRCHRNUL@
+REPLACE_STRDUP = @REPLACE_STRDUP@
+REPLACE_STRERROR = @REPLACE_STRERROR@
+REPLACE_STRERROR_R = @REPLACE_STRERROR_R@
+REPLACE_STRNCAT = @REPLACE_STRNCAT@
+REPLACE_STRNDUP = @REPLACE_STRNDUP@
+REPLACE_STRNLEN = @REPLACE_STRNLEN@
+REPLACE_STRSIGNAL = @REPLACE_STRSIGNAL@
+REPLACE_STRSTR = @REPLACE_STRSTR@
+REPLACE_STRTOD = @REPLACE_STRTOD@
+REPLACE_STRTOIMAX = @REPLACE_STRTOIMAX@
+REPLACE_STRTOK_R = @REPLACE_STRTOK_R@
+REPLACE_STRTOUMAX = @REPLACE_STRTOUMAX@
+REPLACE_STRUCT_LCONV = @REPLACE_STRUCT_LCONV@
+REPLACE_STRUCT_TIMEVAL = @REPLACE_STRUCT_TIMEVAL@
+REPLACE_SYMLINK = @REPLACE_SYMLINK@
+REPLACE_SYMLINKAT = @REPLACE_SYMLINKAT@
+REPLACE_TIMEGM = @REPLACE_TIMEGM@
+REPLACE_TMPFILE = @REPLACE_TMPFILE@
+REPLACE_TOWLOWER = @REPLACE_TOWLOWER@
+REPLACE_TRUNC = @REPLACE_TRUNC@
+REPLACE_TRUNCF = @REPLACE_TRUNCF@
+REPLACE_TRUNCL = @REPLACE_TRUNCL@
+REPLACE_TTYNAME_R = @REPLACE_TTYNAME_R@
+REPLACE_UNLINK = @REPLACE_UNLINK@
+REPLACE_UNLINKAT = @REPLACE_UNLINKAT@
+REPLACE_UNSETENV = @REPLACE_UNSETENV@
+REPLACE_USLEEP = @REPLACE_USLEEP@
+REPLACE_UTIMENSAT = @REPLACE_UTIMENSAT@
+REPLACE_VASPRINTF = @REPLACE_VASPRINTF@
+REPLACE_VDPRINTF = @REPLACE_VDPRINTF@
+REPLACE_VFPRINTF = @REPLACE_VFPRINTF@
+REPLACE_VPRINTF = @REPLACE_VPRINTF@
+REPLACE_VSNPRINTF = @REPLACE_VSNPRINTF@
+REPLACE_VSPRINTF = @REPLACE_VSPRINTF@
+REPLACE_WCRTOMB = @REPLACE_WCRTOMB@
+REPLACE_WCSNRTOMBS = @REPLACE_WCSNRTOMBS@
+REPLACE_WCSRTOMBS = @REPLACE_WCSRTOMBS@
+REPLACE_WCSWIDTH = @REPLACE_WCSWIDTH@
+REPLACE_WCTOB = @REPLACE_WCTOB@
+REPLACE_WCTOMB = @REPLACE_WCTOMB@
+REPLACE_WCWIDTH = @REPLACE_WCWIDTH@
+REPLACE_WRITE = @REPLACE_WRITE@
+SED = @SED@
+SELINUX_CONTEXT_H = @SELINUX_CONTEXT_H@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SIG_ATOMIC_T_SUFFIX = @SIG_ATOMIC_T_SUFFIX@
+SIZE_T_SUFFIX = @SIZE_T_SUFFIX@
+SORT = @SORT@
+SORT_SUPPORTS_Z = @SORT_SUPPORTS_Z@
+STDALIGN_H = @STDALIGN_H@
+STDARG_H = @STDARG_H@
+STDBOOL_H = @STDBOOL_H@
+STDDEF_H = @STDDEF_H@
+STDINT_H = @STDINT_H@
+STRIP = @STRIP@
+SYS_IOCTL_H_HAVE_WINSOCK2_H = @SYS_IOCTL_H_HAVE_WINSOCK2_H@
+SYS_IOCTL_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS = @SYS_IOCTL_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS@
+SYS_TIME_H_DEFINES_STRUCT_TIMESPEC = @SYS_TIME_H_DEFINES_STRUCT_TIMESPEC@
+TIME_H_DEFINES_STRUCT_TIMESPEC = @TIME_H_DEFINES_STRUCT_TIMESPEC@
+TRUNC_LIBM = @TRUNC_LIBM@
+UINT32_MAX_LT_UINTMAX_MAX = @UINT32_MAX_LT_UINTMAX_MAX@
+UINT64_MAX_EQ_ULONG_MAX = @UINT64_MAX_EQ_ULONG_MAX@
+UNDEFINE_STRTOK_R = @UNDEFINE_STRTOK_R@
+UNISTD_H_DEFINES_STRUCT_TIMESPEC = @UNISTD_H_DEFINES_STRUCT_TIMESPEC@
+UNISTD_H_HAVE_WINSOCK2_H = @UNISTD_H_HAVE_WINSOCK2_H@
+UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS = @UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+WCHAR_T_SUFFIX = @WCHAR_T_SUFFIX@
+WINDOWS_64_BIT_OFF_T = @WINDOWS_64_BIT_OFF_T@
+WINDOWS_64_BIT_ST_SIZE = @WINDOWS_64_BIT_ST_SIZE@
+WINT_T_SUFFIX = @WINT_T_SUFFIX@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+YIELD_LIB = @YIELD_LIB@
+abs_aux_dir = @abs_aux_dir@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gl_LIBOBJS = @gl_LIBOBJS@
+gl_LTLIBOBJS = @gl_LTLIBOBJS@
+gltests_LIBOBJS = @gltests_LIBOBJS@
+gltests_LTLIBOBJS = @gltests_LTLIBOBJS@
+gltests_WITNESS = @gltests_WITNESS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+lispdir = @lispdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+
+# Copyright (C) 1996,1999,2000,2001,2003-2015 Free Software Foundation, Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+AM_CFLAGS = $(WARN_CFLAGS)
+info_TEXINFOS = find.texi find-maint.texi
+find_TEXINFOS = perm.texi parse-datetime.texi regexprops.texi fdl.texi
+BUILT_SOURCES = dblocation.texi
+nodist_find_TEXINFOS = dblocation.texi
+find_maint_TEXINFOS = fdl.texi
+MOSTLYCLEANFILES = find.cps
+CLEANFILES = find.txt find_mono.html findutils.texi_html_node.tar.gz dblocation.texi
+MAKEINFOTXT = $(MAKEINFO) --plaintext
+all: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) all-am
+
+.SUFFIXES:
+.SUFFIXES: .dvi .html .info .pdf .ps .texi .txt
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnits doc/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnits doc/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+.texi.info:
+ $(AM_V_MAKEINFO)restore=: && backupdir="$(am__leading_dot)am$$$$" && \
+ am__cwd=`pwd` && $(am__cd) $(srcdir) && \
+ rm -rf $$backupdir && mkdir $$backupdir && \
+ if ($(MAKEINFO) --version) >/dev/null 2>&1; then \
+ for f in $@ $@-[0-9] $@-[0-9][0-9] $(@:.info=).i[0-9] $(@:.info=).i[0-9][0-9]; do \
+ if test -f $$f; then mv $$f $$backupdir; restore=mv; else :; fi; \
+ done; \
+ else :; fi && \
+ cd "$$am__cwd"; \
+ if $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
+ -o $@ $<; \
+ then \
+ rc=0; \
+ $(am__cd) $(srcdir); \
+ else \
+ rc=$$?; \
+ $(am__cd) $(srcdir) && \
+ $$restore $$backupdir/* `echo "./$@" | sed 's|[^/]*$$||'`; \
+ fi; \
+ rm -rf $$backupdir; exit $$rc
+
+.texi.dvi:
+ $(AM_V_TEXI2DVI)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+ MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
+ $(TEXI2DVI) $(AM_V_texinfo) --build-dir=$(@:.dvi=.t2d) -o $@ $(AM_V_texidevnull) \
+ $<
+
+.texi.pdf:
+ $(AM_V_TEXI2PDF)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+ MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
+ $(TEXI2PDF) $(AM_V_texinfo) --build-dir=$(@:.pdf=.t2p) -o $@ $(AM_V_texidevnull) \
+ $<
+
+.texi.html:
+ $(AM_V_MAKEINFO)rm -rf $(@:.html=.htp)
+ $(AM_V_at)if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
+ -o $(@:.html=.htp) $<; \
+ then \
+ rm -rf $@ && mv $(@:.html=.htp) $@; \
+ else \
+ rm -rf $(@:.html=.htp); exit 1; \
+ fi
+$(srcdir)/find.info: find.texi $(srcdir)/version.texi $(find_TEXINFOS)
+find.dvi: find.texi $(srcdir)/version.texi $(find_TEXINFOS)
+find.pdf: find.texi $(srcdir)/version.texi $(find_TEXINFOS)
+find.html: find.texi $(srcdir)/version.texi $(find_TEXINFOS)
+$(srcdir)/version.texi: $(srcdir)/stamp-vti
+$(srcdir)/stamp-vti: find.texi $(top_srcdir)/configure
+ @(dir=.; test -f ./find.texi || dir=$(srcdir); \
+ set `$(SHELL) $(top_srcdir)/build-aux/mdate-sh $$dir/find.texi`; \
+ echo "@set UPDATED $$1 $$2 $$3"; \
+ echo "@set UPDATED-MONTH $$2 $$3"; \
+ echo "@set EDITION $(VERSION)"; \
+ echo "@set VERSION $(VERSION)") > vti.tmp
+ @cmp -s vti.tmp $(srcdir)/version.texi \
+ || (echo "Updating $(srcdir)/version.texi"; \
+ cp vti.tmp $(srcdir)/version.texi)
+ -@rm -f vti.tmp
+ @cp $(srcdir)/version.texi $@
+
+mostlyclean-vti:
+ -rm -f vti.tmp
+
+maintainer-clean-vti:
+ -rm -f $(srcdir)/stamp-vti $(srcdir)/version.texi
+$(srcdir)/find-maint.info: find-maint.texi $(srcdir)/versionmaint.texi $(find_maint_TEXINFOS)
+find-maint.dvi: find-maint.texi $(srcdir)/versionmaint.texi $(find_maint_TEXINFOS)
+find-maint.pdf: find-maint.texi $(srcdir)/versionmaint.texi $(find_maint_TEXINFOS)
+find-maint.html: find-maint.texi $(srcdir)/versionmaint.texi $(find_maint_TEXINFOS)
+$(srcdir)/versionmaint.texi: $(srcdir)/stamp-1
+$(srcdir)/stamp-1: find-maint.texi $(top_srcdir)/configure
+ @(dir=.; test -f ./find-maint.texi || dir=$(srcdir); \
+ set `$(SHELL) $(top_srcdir)/build-aux/mdate-sh $$dir/find-maint.texi`; \
+ echo "@set UPDATED $$1 $$2 $$3"; \
+ echo "@set UPDATED-MONTH $$2 $$3"; \
+ echo "@set EDITION $(VERSION)"; \
+ echo "@set VERSION $(VERSION)") > 1.tmp
+ @cmp -s 1.tmp $(srcdir)/versionmaint.texi \
+ || (echo "Updating $(srcdir)/versionmaint.texi"; \
+ cp 1.tmp $(srcdir)/versionmaint.texi)
+ -@rm -f 1.tmp
+ @cp $(srcdir)/versionmaint.texi $@
+
+mostlyclean-1:
+ -rm -f 1.tmp
+
+maintainer-clean-1:
+ -rm -f $(srcdir)/stamp-1 $(srcdir)/versionmaint.texi
+.dvi.ps:
+ $(AM_V_DVIPS)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+ $(DVIPS) $(AM_V_texinfo) -o $@ $<
+
+uninstall-dvi-am:
+ @$(NORMAL_UNINSTALL)
+ @list='$(DVIS)'; test -n "$(dvidir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(dvidir)/$$f'"; \
+ rm -f "$(DESTDIR)$(dvidir)/$$f"; \
+ done
+
+uninstall-html-am:
+ @$(NORMAL_UNINSTALL)
+ @list='$(HTMLS)'; test -n "$(htmldir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " rm -rf '$(DESTDIR)$(htmldir)/$$f'"; \
+ rm -rf "$(DESTDIR)$(htmldir)/$$f"; \
+ done
+
+uninstall-info-am:
+ @$(PRE_UNINSTALL)
+ @if test -d '$(DESTDIR)$(infodir)' && $(am__can_run_installinfo); then \
+ list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ relfile=`echo "$$file" | sed 's|^.*/||'`; \
+ echo " install-info --info-dir='$(DESTDIR)$(infodir)' --remove '$(DESTDIR)$(infodir)/$$relfile'"; \
+ if install-info --info-dir="$(DESTDIR)$(infodir)" --remove "$(DESTDIR)$(infodir)/$$relfile"; \
+ then :; else test ! -f "$(DESTDIR)$(infodir)/$$relfile" || exit 1; fi; \
+ done; \
+ else :; fi
+ @$(NORMAL_UNINSTALL)
+ @list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ relfile=`echo "$$file" | sed 's|^.*/||'`; \
+ relfile_i=`echo "$$relfile" | sed 's|\.info$$||;s|$$|.i|'`; \
+ (if test -d "$(DESTDIR)$(infodir)" && cd "$(DESTDIR)$(infodir)"; then \
+ echo " cd '$(DESTDIR)$(infodir)' && rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]"; \
+ rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]; \
+ else :; fi); \
+ done
+
+uninstall-pdf-am:
+ @$(NORMAL_UNINSTALL)
+ @list='$(PDFS)'; test -n "$(pdfdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(pdfdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(pdfdir)/$$f"; \
+ done
+
+uninstall-ps-am:
+ @$(NORMAL_UNINSTALL)
+ @list='$(PSS)'; test -n "$(psdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(psdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(psdir)/$$f"; \
+ done
+
+dist-info: $(INFO_DEPS)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ list='$(INFO_DEPS)'; \
+ for base in $$list; do \
+ case $$base in \
+ $(srcdir)/*) base=`echo "$$base" | sed "s|^$$srcdirstrip/||"`;; \
+ esac; \
+ if test -f $$base; then d=.; else d=$(srcdir); fi; \
+ base_i=`echo "$$base" | sed 's|\.info$$||;s|$$|.i|'`; \
+ for file in $$d/$$base $$d/$$base-[0-9] $$d/$$base-[0-9][0-9] $$d/$$base_i[0-9] $$d/$$base_i[0-9][0-9]; do \
+ if test -f $$file; then \
+ relfile=`expr "$$file" : "$$d/\(.*\)"`; \
+ test -f "$(distdir)/$$relfile" || \
+ cp -p $$file "$(distdir)/$$relfile"; \
+ else :; fi; \
+ done; \
+ done
+
+mostlyclean-aminfo:
+ -rm -rf find.t2d find.t2p find-maint.t2d find-maint.t2p
+
+clean-aminfo:
+ -test -z "find.dvi find.pdf find.ps find.html find-maint.dvi find-maint.pdf \
+ find-maint.ps find-maint.html" \
+ || rm -rf find.dvi find.pdf find.ps find.html find-maint.dvi find-maint.pdf \
+ find-maint.ps find-maint.html
+
+maintainer-clean-aminfo:
+ @list='$(INFO_DEPS)'; for i in $$list; do \
+ i_i=`echo "$$i" | sed 's|\.info$$||;s|$$|.i|'`; \
+ echo " rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]"; \
+ rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]; \
+ done
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$(top_distdir)" distdir="$(distdir)" \
+ dist-info
+check-am: all-am
+check: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) check-am
+all-am: Makefile $(INFO_DEPS)
+installdirs:
+ for dir in "$(DESTDIR)$(infodir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+clean: clean-am
+
+clean-am: clean-aminfo clean-generic mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am: $(DVIS)
+
+html: html-am
+
+html-am: $(HTMLS)
+
+info: info-am
+
+info-am: $(INFO_DEPS)
+
+install-data-am: install-info-am
+
+install-dvi: install-dvi-am
+
+install-dvi-am: $(DVIS)
+ @$(NORMAL_INSTALL)
+ @list='$(DVIS)'; test -n "$(dvidir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(dvidir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(dvidir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(dvidir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(dvidir)" || exit $$?; \
+ done
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am: $(HTMLS)
+ @$(NORMAL_INSTALL)
+ @list='$(HTMLS)'; list2=; test -n "$(htmldir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(htmldir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p" || test -d "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ $(am__strip_dir) \
+ d2=$$d$$p; \
+ if test -d "$$d2"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)/$$f'"; \
+ $(MKDIR_P) "$(DESTDIR)$(htmldir)/$$f" || exit 1; \
+ echo " $(INSTALL_DATA) '$$d2'/* '$(DESTDIR)$(htmldir)/$$f'"; \
+ $(INSTALL_DATA) "$$d2"/* "$(DESTDIR)$(htmldir)/$$f" || exit $$?; \
+ else \
+ list2="$$list2 $$d2"; \
+ fi; \
+ done; \
+ test -z "$$list2" || { echo "$$list2" | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(htmldir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(htmldir)" || exit $$?; \
+ done; }
+install-info: install-info-am
+
+install-info-am: $(INFO_DEPS)
+ @$(NORMAL_INSTALL)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(infodir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(infodir)" || exit 1; \
+ fi; \
+ for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ esac; \
+ if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ file_i=`echo "$$file" | sed 's|\.info$$||;s|$$|.i|'`; \
+ for ifile in $$d/$$file $$d/$$file-[0-9] $$d/$$file-[0-9][0-9] \
+ $$d/$$file_i[0-9] $$d/$$file_i[0-9][0-9] ; do \
+ if test -f $$ifile; then \
+ echo "$$ifile"; \
+ else : ; fi; \
+ done; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(infodir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(infodir)" || exit $$?; done
+ @$(POST_INSTALL)
+ @if $(am__can_run_installinfo); then \
+ list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \
+ for file in $$list; do \
+ relfile=`echo "$$file" | sed 's|^.*/||'`; \
+ echo " install-info --info-dir='$(DESTDIR)$(infodir)' '$(DESTDIR)$(infodir)/$$relfile'";\
+ install-info --info-dir="$(DESTDIR)$(infodir)" "$(DESTDIR)$(infodir)/$$relfile" || :;\
+ done; \
+ else : ; fi
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am: $(PDFS)
+ @$(NORMAL_INSTALL)
+ @list='$(PDFS)'; test -n "$(pdfdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pdfdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pdfdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pdfdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(pdfdir)" || exit $$?; done
+install-ps: install-ps-am
+
+install-ps-am: $(PSS)
+ @$(NORMAL_INSTALL)
+ @list='$(PSS)'; test -n "$(psdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(psdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(psdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(psdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(psdir)" || exit $$?; done
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-1 \
+ maintainer-clean-aminfo maintainer-clean-generic \
+ maintainer-clean-vti
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-1 mostlyclean-aminfo mostlyclean-generic \
+ mostlyclean-vti
+
+pdf: pdf-am
+
+pdf-am: $(PDFS)
+
+ps: ps-am
+
+ps-am: $(PSS)
+
+uninstall-am: uninstall-dvi-am uninstall-html-am uninstall-info-am \
+ uninstall-pdf-am uninstall-ps-am
+
+.MAKE: all check install install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-aminfo clean-generic \
+ cscopelist-am ctags-am dist-info distclean distclean-generic \
+ distdir dvi dvi-am html html-am info info-am install \
+ install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-1 maintainer-clean-aminfo \
+ maintainer-clean-generic maintainer-clean-vti mostlyclean \
+ mostlyclean-1 mostlyclean-aminfo mostlyclean-generic \
+ mostlyclean-vti pdf pdf-am ps ps-am tags-am uninstall \
+ uninstall-am uninstall-dvi-am uninstall-html-am \
+ uninstall-info-am uninstall-pdf-am uninstall-ps-am
+
+
+find.txt: find.texi $(srcdir)/version.texi $(find_TEXINFOS)
+
+# find.txt is a file which we need to know how to build
+# because it gets put on the www.gnu.org website.
+# This rule is derived from the .texi.html rule.
+.texi.txt:
+ rm -rf $(@:.txt=.tmp)
+ if $(MAKEINFOTXT) $(AM_MAKEINFOTXTFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
+ -o $(@:.txt=.tmp) $<; \
+ then \
+ rm -rf $@; \
+ if test ! -d $(@:.txt=.tmp) && test -d $(@:.txt=); then \
+ mv $(@:.txt=) $@; else mv $(@:.txt=.tmp) $@; fi; \
+ else \
+ if test ! -d $(@:.txt=.tmp) && test -d $(@:.txt=); then \
+ rm -rf $(@:.txt=); else rm -Rf $(@:.txt=.tmp) $@; fi; \
+ exit 1; \
+ fi
+
+# find_mono.html is a file which we need to know how to build
+# because it gets put on the www.gnu.org website.
+# This rule is derived from the generic .texi.html rule.
+find_mono.html: find.texi
+ rm -rf $(@:.html=.htp)
+ if $(MAKEINFOHTML) --no-split $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
+ -o $(@:.html=.htp) $<; \
+ then \
+ rm -rf $@; \
+ if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \
+ mv $(@:.html=) $@; else mv $(@:.html=.htp) $@; fi; \
+ else \
+ if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \
+ rm -rf $(@:.html=); else rm -Rf $(@:.html=.htp) $@; fi; \
+ exit 1; \
+ fi
+
+# findutils.texi_html_node.tar.gz is a file which we need to know
+# how to build because it gets put on the www.gnu.org website.
+# This rule depends on GNU tar, but it's principally used
+# by the maintainer, and we don't need to build the file
+# for "make all" or "make install" (or even "make check").
+findutils.texi_html_node.tar.gz: find.html
+ tar zcf $@ $<
+
+dblocation.texi: ../locate/dblocation.texi
+ $(LN_S) ../locate/dblocation.texi $@
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/doc/fdl.texi b/doc/fdl.texi
new file mode 100644
index 0000000..9c3bbe5
--- /dev/null
+++ b/doc/fdl.texi
@@ -0,0 +1,505 @@
+@c The GNU Free Documentation License.
+@center Version 1.3, 3 November 2008
+
+@c This file is intended to be included within another document,
+@c hence no sectioning command or @node.
+
+@display
+Copyright @copyright{} 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
+@uref{http://fsf.org/}
+
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+@end display
+
+@enumerate 0
+@item
+PREAMBLE
+
+The purpose of this License is to make a manual, textbook, or other
+functional and useful document @dfn{free} in the sense of freedom: to
+assure everyone the effective freedom to copy and redistribute it,
+with or without modifying it, either commercially or noncommercially.
+Secondarily, this License preserves for the author and publisher a way
+to get credit for their work, while not being considered responsible
+for modifications made by others.
+
+This License is a kind of ``copyleft'', which means that derivative
+works of the document must themselves be free in the same sense. It
+complements the GNU General Public License, which is a copyleft
+license designed for free software.
+
+We have designed this License in order to use it for manuals for free
+software, because free software needs free documentation: a free
+program should come with manuals providing the same freedoms that the
+software does. But this License is not limited to software manuals;
+it can be used for any textual work, regardless of subject matter or
+whether it is published as a printed book. We recommend this License
+principally for works whose purpose is instruction or reference.
+
+@item
+APPLICABILITY AND DEFINITIONS
+
+This License applies to any manual or other work, in any medium, that
+contains a notice placed by the copyright holder saying it can be
+distributed under the terms of this License. Such a notice grants a
+world-wide, royalty-free license, unlimited in duration, to use that
+work under the conditions stated herein. The ``Document'', below,
+refers to any such manual or work. Any member of the public is a
+licensee, and is addressed as ``you''. You accept the license if you
+copy, modify or distribute the work in a way requiring permission
+under copyright law.
+
+A ``Modified Version'' of the Document means any work containing the
+Document or a portion of it, either copied verbatim, or with
+modifications and/or translated into another language.
+
+A ``Secondary Section'' is a named appendix or a front-matter section
+of the Document that deals exclusively with the relationship of the
+publishers or authors of the Document to the Document's overall
+subject (or to related matters) and contains nothing that could fall
+directly within that overall subject. (Thus, if the Document is in
+part a textbook of mathematics, a Secondary Section may not explain
+any mathematics.) The relationship could be a matter of historical
+connection with the subject or with related matters, or of legal,
+commercial, philosophical, ethical or political position regarding
+them.
+
+The ``Invariant Sections'' are certain Secondary Sections whose titles
+are designated, as being those of Invariant Sections, in the notice
+that says that the Document is released under this License. If a
+section does not fit the above definition of Secondary then it is not
+allowed to be designated as Invariant. The Document may contain zero
+Invariant Sections. If the Document does not identify any Invariant
+Sections then there are none.
+
+The ``Cover Texts'' are certain short passages of text that are listed,
+as Front-Cover Texts or Back-Cover Texts, in the notice that says that
+the Document is released under this License. A Front-Cover Text may
+be at most 5 words, and a Back-Cover Text may be at most 25 words.
+
+A ``Transparent'' copy of the Document means a machine-readable copy,
+represented in a format whose specification is available to the
+general public, that is suitable for revising the document
+straightforwardly with generic text editors or (for images composed of
+pixels) generic paint programs or (for drawings) some widely available
+drawing editor, and that is suitable for input to text formatters or
+for automatic translation to a variety of formats suitable for input
+to text formatters. A copy made in an otherwise Transparent file
+format whose markup, or absence of markup, has been arranged to thwart
+or discourage subsequent modification by readers is not Transparent.
+An image format is not Transparent if used for any substantial amount
+of text. A copy that is not ``Transparent'' is called ``Opaque''.
+
+Examples of suitable formats for Transparent copies include plain
+ASCII without markup, Texinfo input format, La@TeX{} input
+format, SGML or XML using a publicly available
+DTD, and standard-conforming simple HTML,
+PostScript or PDF designed for human modification. Examples
+of transparent image formats include PNG, XCF and
+JPG@. Opaque formats include proprietary formats that can be
+read and edited only by proprietary word processors, SGML or
+XML for which the DTD and/or processing tools are
+not generally available, and the machine-generated HTML,
+PostScript or PDF produced by some word processors for
+output purposes only.
+
+The ``Title Page'' means, for a printed book, the title page itself,
+plus such following pages as are needed to hold, legibly, the material
+this License requires to appear in the title page. For works in
+formats which do not have any title page as such, ``Title Page'' means
+the text near the most prominent appearance of the work's title,
+preceding the beginning of the body of the text.
+
+The ``publisher'' means any person or entity that distributes copies
+of the Document to the public.
+
+A section ``Entitled XYZ'' means a named subunit of the Document whose
+title either is precisely XYZ or contains XYZ in parentheses following
+text that translates XYZ in another language. (Here XYZ stands for a
+specific section name mentioned below, such as ``Acknowledgements'',
+``Dedications'', ``Endorsements'', or ``History''.) To ``Preserve the Title''
+of such a section when you modify the Document means that it remains a
+section ``Entitled XYZ'' according to this definition.
+
+The Document may include Warranty Disclaimers next to the notice which
+states that this License applies to the Document. These Warranty
+Disclaimers are considered to be included by reference in this
+License, but only as regards disclaiming warranties: any other
+implication that these Warranty Disclaimers may have is void and has
+no effect on the meaning of this License.
+
+@item
+VERBATIM COPYING
+
+You may copy and distribute the Document in any medium, either
+commercially or noncommercially, provided that this License, the
+copyright notices, and the license notice saying this License applies
+to the Document are reproduced in all copies, and that you add no other
+conditions whatsoever to those of this License. You may not use
+technical measures to obstruct or control the reading or further
+copying of the copies you make or distribute. However, you may accept
+compensation in exchange for copies. If you distribute a large enough
+number of copies you must also follow the conditions in section 3.
+
+You may also lend copies, under the same conditions stated above, and
+you may publicly display copies.
+
+@item
+COPYING IN QUANTITY
+
+If you publish printed copies (or copies in media that commonly have
+printed covers) of the Document, numbering more than 100, and the
+Document's license notice requires Cover Texts, you must enclose the
+copies in covers that carry, clearly and legibly, all these Cover
+Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
+the back cover. Both covers must also clearly and legibly identify
+you as the publisher of these copies. The front cover must present
+the full title with all words of the title equally prominent and
+visible. You may add other material on the covers in addition.
+Copying with changes limited to the covers, as long as they preserve
+the title of the Document and satisfy these conditions, can be treated
+as verbatim copying in other respects.
+
+If the required texts for either cover are too voluminous to fit
+legibly, you should put the first ones listed (as many as fit
+reasonably) on the actual cover, and continue the rest onto adjacent
+pages.
+
+If you publish or distribute Opaque copies of the Document numbering
+more than 100, you must either include a machine-readable Transparent
+copy along with each Opaque copy, or state in or with each Opaque copy
+a computer-network location from which the general network-using
+public has access to download using public-standard network protocols
+a complete Transparent copy of the Document, free of added material.
+If you use the latter option, you must take reasonably prudent steps,
+when you begin distribution of Opaque copies in quantity, to ensure
+that this Transparent copy will remain thus accessible at the stated
+location until at least one year after the last time you distribute an
+Opaque copy (directly or through your agents or retailers) of that
+edition to the public.
+
+It is requested, but not required, that you contact the authors of the
+Document well before redistributing any large number of copies, to give
+them a chance to provide you with an updated version of the Document.
+
+@item
+MODIFICATIONS
+
+You may copy and distribute a Modified Version of the Document under
+the conditions of sections 2 and 3 above, provided that you release
+the Modified Version under precisely this License, with the Modified
+Version filling the role of the Document, thus licensing distribution
+and modification of the Modified Version to whoever possesses a copy
+of it. In addition, you must do these things in the Modified Version:
+
+@enumerate A
+@item
+Use in the Title Page (and on the covers, if any) a title distinct
+from that of the Document, and from those of previous versions
+(which should, if there were any, be listed in the History section
+of the Document). You may use the same title as a previous version
+if the original publisher of that version gives permission.
+
+@item
+List on the Title Page, as authors, one or more persons or entities
+responsible for authorship of the modifications in the Modified
+Version, together with at least five of the principal authors of the
+Document (all of its principal authors, if it has fewer than five),
+unless they release you from this requirement.
+
+@item
+State on the Title page the name of the publisher of the
+Modified Version, as the publisher.
+
+@item
+Preserve all the copyright notices of the Document.
+
+@item
+Add an appropriate copyright notice for your modifications
+adjacent to the other copyright notices.
+
+@item
+Include, immediately after the copyright notices, a license notice
+giving the public permission to use the Modified Version under the
+terms of this License, in the form shown in the Addendum below.
+
+@item
+Preserve in that license notice the full lists of Invariant Sections
+and required Cover Texts given in the Document's license notice.
+
+@item
+Include an unaltered copy of this License.
+
+@item
+Preserve the section Entitled ``History'', Preserve its Title, and add
+to it an item stating at least the title, year, new authors, and
+publisher of the Modified Version as given on the Title Page. If
+there is no section Entitled ``History'' in the Document, create one
+stating the title, year, authors, and publisher of the Document as
+given on its Title Page, then add an item describing the Modified
+Version as stated in the previous sentence.
+
+@item
+Preserve the network location, if any, given in the Document for
+public access to a Transparent copy of the Document, and likewise
+the network locations given in the Document for previous versions
+it was based on. These may be placed in the ``History'' section.
+You may omit a network location for a work that was published at
+least four years before the Document itself, or if the original
+publisher of the version it refers to gives permission.
+
+@item
+For any section Entitled ``Acknowledgements'' or ``Dedications'', Preserve
+the Title of the section, and preserve in the section all the
+substance and tone of each of the contributor acknowledgements and/or
+dedications given therein.
+
+@item
+Preserve all the Invariant Sections of the Document,
+unaltered in their text and in their titles. Section numbers
+or the equivalent are not considered part of the section titles.
+
+@item
+Delete any section Entitled ``Endorsements''. Such a section
+may not be included in the Modified Version.
+
+@item
+Do not retitle any existing section to be Entitled ``Endorsements'' or
+to conflict in title with any Invariant Section.
+
+@item
+Preserve any Warranty Disclaimers.
+@end enumerate
+
+If the Modified Version includes new front-matter sections or
+appendices that qualify as Secondary Sections and contain no material
+copied from the Document, you may at your option designate some or all
+of these sections as invariant. To do this, add their titles to the
+list of Invariant Sections in the Modified Version's license notice.
+These titles must be distinct from any other section titles.
+
+You may add a section Entitled ``Endorsements'', provided it contains
+nothing but endorsements of your Modified Version by various
+parties---for example, statements of peer review or that the text has
+been approved by an organization as the authoritative definition of a
+standard.
+
+You may add a passage of up to five words as a Front-Cover Text, and a
+passage of up to 25 words as a Back-Cover Text, to the end of the list
+of Cover Texts in the Modified Version. Only one passage of
+Front-Cover Text and one of Back-Cover Text may be added by (or
+through arrangements made by) any one entity. If the Document already
+includes a cover text for the same cover, previously added by you or
+by arrangement made by the same entity you are acting on behalf of,
+you may not add another; but you may replace the old one, on explicit
+permission from the previous publisher that added the old one.
+
+The author(s) and publisher(s) of the Document do not by this License
+give permission to use their names for publicity for or to assert or
+imply endorsement of any Modified Version.
+
+@item
+COMBINING DOCUMENTS
+
+You may combine the Document with other documents released under this
+License, under the terms defined in section 4 above for modified
+versions, provided that you include in the combination all of the
+Invariant Sections of all of the original documents, unmodified, and
+list them all as Invariant Sections of your combined work in its
+license notice, and that you preserve all their Warranty Disclaimers.
+
+The combined work need only contain one copy of this License, and
+multiple identical Invariant Sections may be replaced with a single
+copy. If there are multiple Invariant Sections with the same name but
+different contents, make the title of each such section unique by
+adding at the end of it, in parentheses, the name of the original
+author or publisher of that section if known, or else a unique number.
+Make the same adjustment to the section titles in the list of
+Invariant Sections in the license notice of the combined work.
+
+In the combination, you must combine any sections Entitled ``History''
+in the various original documents, forming one section Entitled
+``History''; likewise combine any sections Entitled ``Acknowledgements'',
+and any sections Entitled ``Dedications''. You must delete all
+sections Entitled ``Endorsements.''
+
+@item
+COLLECTIONS OF DOCUMENTS
+
+You may make a collection consisting of the Document and other documents
+released under this License, and replace the individual copies of this
+License in the various documents with a single copy that is included in
+the collection, provided that you follow the rules of this License for
+verbatim copying of each of the documents in all other respects.
+
+You may extract a single document from such a collection, and distribute
+it individually under this License, provided you insert a copy of this
+License into the extracted document, and follow this License in all
+other respects regarding verbatim copying of that document.
+
+@item
+AGGREGATION WITH INDEPENDENT WORKS
+
+A compilation of the Document or its derivatives with other separate
+and independent documents or works, in or on a volume of a storage or
+distribution medium, is called an ``aggregate'' if the copyright
+resulting from the compilation is not used to limit the legal rights
+of the compilation's users beyond what the individual works permit.
+When the Document is included in an aggregate, this License does not
+apply to the other works in the aggregate which are not themselves
+derivative works of the Document.
+
+If the Cover Text requirement of section 3 is applicable to these
+copies of the Document, then if the Document is less than one half of
+the entire aggregate, the Document's Cover Texts may be placed on
+covers that bracket the Document within the aggregate, or the
+electronic equivalent of covers if the Document is in electronic form.
+Otherwise they must appear on printed covers that bracket the whole
+aggregate.
+
+@item
+TRANSLATION
+
+Translation is considered a kind of modification, so you may
+distribute translations of the Document under the terms of section 4.
+Replacing Invariant Sections with translations requires special
+permission from their copyright holders, but you may include
+translations of some or all Invariant Sections in addition to the
+original versions of these Invariant Sections. You may include a
+translation of this License, and all the license notices in the
+Document, and any Warranty Disclaimers, provided that you also include
+the original English version of this License and the original versions
+of those notices and disclaimers. In case of a disagreement between
+the translation and the original version of this License or a notice
+or disclaimer, the original version will prevail.
+
+If a section in the Document is Entitled ``Acknowledgements'',
+``Dedications'', or ``History'', the requirement (section 4) to Preserve
+its Title (section 1) will typically require changing the actual
+title.
+
+@item
+TERMINATION
+
+You may not copy, modify, sublicense, or distribute the Document
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense, or distribute it is void, and
+will automatically terminate your rights under this License.
+
+However, if you cease all violation of this License, then your license
+from a particular copyright holder is reinstated (a) provisionally,
+unless and until the copyright holder explicitly and finally
+terminates your license, and (b) permanently, if the copyright holder
+fails to notify you of the violation by some reasonable means prior to
+60 days after the cessation.
+
+Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, receipt of a copy of some or all of the same material does
+not give you any rights to use it.
+
+@item
+FUTURE REVISIONS OF THIS LICENSE
+
+The Free Software Foundation may publish new, revised versions
+of the GNU Free Documentation License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns. See
+@uref{http://www.gnu.org/copyleft/}.
+
+Each version of the License is given a distinguishing version number.
+If the Document specifies that a particular numbered version of this
+License ``or any later version'' applies to it, you have the option of
+following the terms and conditions either of that specified version or
+of any later version that has been published (not as a draft) by the
+Free Software Foundation. If the Document does not specify a version
+number of this License, you may choose any version ever published (not
+as a draft) by the Free Software Foundation. If the Document
+specifies that a proxy can decide which future versions of this
+License can be used, that proxy's public statement of acceptance of a
+version permanently authorizes you to choose that version for the
+Document.
+
+@item
+RELICENSING
+
+``Massive Multiauthor Collaboration Site'' (or ``MMC Site'') means any
+World Wide Web server that publishes copyrightable works and also
+provides prominent facilities for anybody to edit those works. A
+public wiki that anybody can edit is an example of such a server. A
+``Massive Multiauthor Collaboration'' (or ``MMC'') contained in the
+site means any set of copyrightable works thus published on the MMC
+site.
+
+``CC-BY-SA'' means the Creative Commons Attribution-Share Alike 3.0
+license published by Creative Commons Corporation, a not-for-profit
+corporation with a principal place of business in San Francisco,
+California, as well as future copyleft versions of that license
+published by that same organization.
+
+``Incorporate'' means to publish or republish a Document, in whole or
+in part, as part of another Document.
+
+An MMC is ``eligible for relicensing'' if it is licensed under this
+License, and if all works that were first published under this License
+somewhere other than this MMC, and subsequently incorporated in whole
+or in part into the MMC, (1) had no cover texts or invariant sections,
+and (2) were thus incorporated prior to November 1, 2008.
+
+The operator of an MMC Site may republish an MMC contained in the site
+under CC-BY-SA on the same site at any time before August 1, 2009,
+provided the MMC is eligible for relicensing.
+
+@end enumerate
+
+@page
+@heading ADDENDUM: How to use this License for your documents
+
+To use this License in a document you have written, include a copy of
+the License in the document and put the following copyright and
+license notices just after the title page:
+
+@smallexample
+@group
+ Copyright (C) @var{year} @var{your name}.
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.3
+ or any later version published by the Free Software Foundation;
+ with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
+ Texts. A copy of the license is included in the section entitled ``GNU
+ Free Documentation License''.
+@end group
+@end smallexample
+
+If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
+replace the ``with@dots{}Texts.''@: line with this:
+
+@smallexample
+@group
+ with the Invariant Sections being @var{list their titles}, with
+ the Front-Cover Texts being @var{list}, and with the Back-Cover Texts
+ being @var{list}.
+@end group
+@end smallexample
+
+If you have Invariant Sections without Cover Texts, or some other
+combination of the three, merge those two alternatives to suit the
+situation.
+
+If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of
+free software license, such as the GNU General Public License,
+to permit their use in free software.
+
+@c Local Variables:
+@c ispell-local-pdict: "ispell-dict"
+@c End:
diff --git a/doc/find-maint.info b/doc/find-maint.info
new file mode 100644
index 0000000..2052013
--- /dev/null
+++ b/doc/find-maint.info
@@ -0,0 +1,1585 @@
+This is find-maint.info, produced by makeinfo version 5.2 from
+find-maint.texi.
+
+This manual explains how GNU findutils is maintained, how changes should
+be made and tested, and what resources exist to help developers.
+
+ This is edition 4.6.0, for findutils version 4.6.0.
+
+ Copyright (C) 2007, 2008, 2010-2015 Free Software Foundation, Inc.
+
+ Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.3 or
+any later version published by the Free Software Foundation; with no
+Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A
+copy of the license is included in the section entitled "GNU Free
+Documentation License".
+INFO-DIR-SECTION GNU organization
+START-INFO-DIR-ENTRY
+* Maintaining Findutils: (find-maint). Maintaining GNU findutils
+END-INFO-DIR-ENTRY
+
+
+File: find-maint.info, Node: Top, Next: Introduction, Prev: (dir), Up: (dir)
+
+Maintaining GNU Findutils
+*************************
+
+This manual explains how GNU findutils is maintained, how changes should
+be made and tested, and what resources exist to help developers.
+
+ This is edition 4.6.0, for findutils version 4.6.0.
+
+ Copyright (C) 2007, 2008, 2010-2015 Free Software Foundation, Inc.
+
+ Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.3 or
+any later version published by the Free Software Foundation; with no
+Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A
+copy of the license is included in the section entitled "GNU Free
+Documentation License".
+
+* Menu:
+
+* Introduction::
+* Maintaining GNU Programs::
+* Design Issues::
+* Coding Conventions::
+* Tools::
+* Using the GNU Portability Library::
+* Documentation::
+* Testing::
+* Bugs::
+* Distributions::
+* Internationalisation::
+* Security::
+* Making Releases::
+* GNU Free Documentation License::
+
+
+File: find-maint.info, Node: Introduction, Next: Maintaining GNU Programs, Up: Top
+
+1 Introduction
+**************
+
+This document explains how to contribute to and maintain GNU Findutils.
+It concentrates on developer-specific issues. For information about how
+to use the software please refer to *Note Introduction:
+(find)Introduction.
+
+ This manual aims to be useful without necessarily being verbose.
+It's also a recent document, so there will be a many areas in which
+improvements can be made. If you find that the document misses out
+important information or any part of the document is be so terse as to
+be unuseful, please ask for help on the <bug-findutils@gnu.org> mailing
+list. We'll try to improve this document too.
+
+
+File: find-maint.info, Node: Maintaining GNU Programs, Next: Design Issues, Prev: Introduction, Up: Top
+
+2 Maintaining GNU Programs
+**************************
+
+GNU Findutils is part of the GNU Project and so there are a number of
+documents which set out standards for the maintenance of GNU software.
+
+'standards.texi'
+ GNU Project Coding Standards. All changes to findutils should
+ comply with these standards. In some areas we go somewhat beyond
+ the requirements of the standards, but these cases are explained in
+ this manual.
+'maintain.texi'
+ Information for Maintainers of GNU Software. This document
+ provides guidance for GNU maintainers. Everybody with commit
+ access should read this document. Everybody else is welcome to do
+ so too, of course.
+
+
+File: find-maint.info, Node: Design Issues, Next: Coding Conventions, Prev: Maintaining GNU Programs, Up: Top
+
+3 Design Issues
+***************
+
+The findutils package is installed on many many systems, usually as a
+fundamental component. The programs in the package are often used in
+order to successfully boot or fix the system.
+
+ This fact means that for findutils we bear in mind considerations
+that may not apply so much as for other packages. For example, the fact
+that findutils is often a base component motivates us to
+ * Limit dependencies on libraries
+ * Avoid dependencies on other large packages (for example,
+ interpreters)
+ * Be conservative when making changes to the 'stable' release branch
+
+ All those considerations come before functionality. Functional
+enhancements are still made to findutils, but these are almost
+exclusively introduced in the 'development' release branch, to allow
+extensive testing and proving.
+
+ Sometimes it is useful to have a priority list to provide guidance
+when making design trade-offs. For findutils, that priority list is:
+
+ 1. Correctness
+ 2. Standards compliance
+ 3. Security
+ 4. Backward compatibility
+ 5. Performance
+ 6. Functionality
+
+ For example, we support the '-exec' action because POSIX compliance
+requires this, even though there are security problems with it and we
+would otherwise prefer people to use '-execdir'. There are also cases
+where some performance is sacrificed in the name of security. For
+example, the sanity checks that 'find' performs while traversing a
+directory tree may slow it down. We adopt functional changes, and
+functional changes are allowed to make 'find' slower, but only if there
+is no detectable impact on users who don't use the feature.
+
+ Backward-incompatible changes do get made in order to comply with
+standards (for example the behaviour of '-perm -...' changed in order to
+comply with POSIX). However, they don't get made in order to provide
+better ease of use; for example the semantics of '-size -2G' are almost
+always unexpected by users, but we retain the current behaviour because
+of backward compatibility and for its similarity to the block-rounding
+behaviour of '-size -30'. We might introduce a change which does not
+have the unfortunate rounding behaviour, but we would choose another
+syntax (for example '-size '<2G'') for this.
+
+ In a general sense, we try to do test-driven development of the
+findutils code; that is, we try to implement test cases for new features
+and bug fixes before modifying the code to make the test pass. Some
+features of the code are tested well, but the test coverage for other
+features is less good. If you are about to modify the code for a
+predicate and aren't sure about the test coverage, use 'grep' on the
+test directories and measure the coverage with 'lcov' or another test
+coverage tool.
+
+ You should be able to use the 'coverage' Makefile target (it's
+defined in 'maint.mk' to generate a test coverage report for findutils.
+Due to limitations in 'lcov', this only works if your build directory is
+the same asthe source directory (that is, you're not using a VPATH build
+configuration).
+
+ Lastly, we try not to depend on having a "working system". The
+findutils suite is used for diagnosis of problems, and this applies
+especially to 'find'. We should ensure that 'find' still works on
+relatively broken systems, for example systems with damaged
+'/etc/passwd' or '/etc/fstab' files. Another interesting example is the
+case where a system is a client of one or more unresponsive NFS servers.
+On such a system, if you try to stat all mount points, your program will
+hang indefinitely, waiting for the remote NFS server to respond.
+
+ Another interesting but unusual case is broken NFS servers and
+corrupt filesystems; sometimes they return 'impossible' file modes.
+It's important that find does not entirely fail when encountering such a
+file.
+
+
+File: find-maint.info, Node: Coding Conventions, Next: Tools, Prev: Design Issues, Up: Top
+
+4 Coding Conventions
+********************
+
+Coding style documents which set out to establish a uniform look and
+feel to source code have worthy goals, for example greater ease of
+maintenance and readability. However, I do not believe that in general
+coding style guide authors can envisage every situation, and it is
+always possible that it might on occasion be necessary to break the
+letter of the style guide in order to honour its spirit, or to better
+achieve the style guide's goals.
+
+ I've certainly seen many style guides outside the free software world
+which make bald statements such as "functions shall have exactly one
+return statement". The desire to ensure consistency and obviousness of
+control flow is laudable, but it is all too common for such bald
+requirements to be followed unthinkingly. Certainly I've seen such
+coding standards result in unmaintainable code with terrible
+infelicities such as functions containing 'if' statements nested nine
+levels deep. I suppose such coding standards don't survive in free
+software projects because they tend to drive away potential contributors
+or tend to generate heated discussions on mailing lists. Equally, a
+nine-level-deep function in a free software program would quickly get
+refactored, assuming it is obvious what the function is supposed to
+do...
+
+ Be that as it may, the approach I will take for this document is to
+explain some idioms and practices in use in the findutils source code,
+and leave it up to the reader's engineering judgement to decide which
+considerations apply to the code they are working on, and whether or not
+there is sufficient reason to ignore the guidance in current
+circumstances.
+
+* Menu:
+
+* Make the Compiler Find the Bugs::
+* Factor Out Repeated Code::
+* Debugging is For Users Too::
+* Don't Trust the File System Contents::
+* The File System Is Being Modified::
+
+
+File: find-maint.info, Node: Make the Compiler Find the Bugs, Next: Factor Out Repeated Code, Up: Coding Conventions
+
+4.1 Make the Compiler Find the Bugs
+===================================
+
+Finding bugs is tedious. If I have a filesystem containing two million
+files, and a find command line should print one million of them, but in
+fact it misses out 1%, you can tell the program is printing the wrong
+result only if you know the right answer for that filesystem at that
+time. If you don't know this, you may just not find out about that bug.
+For this reason it is important to have a comprehensive test suite.
+
+ The test suite is of course not the only way to find the bugs. The
+findutils source code makes liberal use of the assert macro. While on
+the one hand these might be a performance drain, the performance impact
+of most of these is negligible compared to the time taken to fetch even
+one sector from a disk drive.
+
+ Assertions should not be used to check the results of operations
+which may be affected by the program's external environment. For
+example, never assert that a file could be opened successfully. Errors
+relating to problems with the program's execution environment should be
+diagnosed with a user-oriented error message. An assertion failure
+should always denote a bug in the program.
+
+ Don't use 'assert' to catch not-fuly-implemented features of your
+code. Finish the implementation, disable the code, or leave the
+unfinished version on a local branch.
+
+ Several programs in the findutils suite perform self-checks. See for
+example the function 'pred_sanity_check' in 'find/pred.c'. This is
+generally desirable.
+
+ There are also a number of small ways in which we can help the
+compiler to find the bugs for us.
+
+4.1.1 Constants in Equality Testing
+-----------------------------------
+
+It's a common error to write '=' when '==' is meant. Sometimes this
+happens in new code and is simply due to finger trouble. Sometimes it
+is the result of the inadvertent deletion of a character. In any case,
+there is a subset of cases where we can persuade the compiler to
+generate an error message when we make this mistake; this is where the
+equality test is with a constant.
+
+ This is an example of a vulnerable piece of code.
+
+ if (x == 2)
+ ...
+
+ A simple typo converts the above into
+
+ if (x = 2)
+ ...
+
+ We've introduced a bug; the condition is always true, and the value
+of 'x' has been changed. However, a simple change to our practice would
+have made us immune to this problem:
+
+ if (2 == x)
+ ...
+
+ Usually, the Emacs keystroke 'M-t' can be used to swap the operands.
+
+4.1.2 Spelling of ASCII NUL
+---------------------------
+
+Strings in C are just sequences of characters terminated by a NUL. The
+ASCII NUL character has the numerical value zero. It is normally
+represented in C code as '\0'. Here is a typical piece of C code:
+
+ *p = '\0';
+
+ Consider what happens if there is an unfortunate typo:
+
+ *p = '0';
+
+ We have changed the meaning of our program and the compiler cannot
+diagnose this as an error. Our string is no longer terminated. Bad
+things will probably happen. It would be better if the compiler could
+help us diagnose this problem.
+
+ In C, the type of ''\0'' is in fact int, not char. This provides us
+with a simple way to avoid this error. The constant '0' has the same
+value and type as the constant ''\0''. However, it is not as vulnerable
+to typos. For this reason I normally prefer to use this code:
+
+ *p = 0;
+
+
+File: find-maint.info, Node: Factor Out Repeated Code, Next: Debugging is For Users Too, Prev: Make the Compiler Find the Bugs, Up: Coding Conventions
+
+4.2 Factor Out Repeated Code
+============================
+
+Repeated code imposes a greater maintenance burden and increases the
+exposure to bugs. For example, if you discover that something you want
+to implement has some similarity with an existing piece of code, don't
+cut and paste it. Instead, factor the code out. The risk of cutting
+and pasting the code, particularly if you do this several times, is that
+you end up with several copies of the same code.
+
+ If the original code had a bug, you now have N places where this
+needs to be fixed. It's all to easy to miss some out when trying to fix
+the bug. Equally, it's quite possible that when pasting the code into
+some function, the pasted code was not quite adapted correctly to its
+new environment. To pick a contrived example, perhaps it modifies a
+global variable which it that code shouldn't be touching in its new
+home. Worse, perhaps it makes some unstated assumption about the nature
+of the input arguments which is in fact not true for the context of the
+now duplicated code.
+
+ A good example of the use of refactoring in findutils is the
+'collect_arg' function in 'find/parser.c'. A less clear-cut but larger
+example is the factoring out of code which would otherwise have been
+duplicated between 'find/oldfind.c' and 'find/ftsfind.c'.
+
+ The findutils test suite is comprehensive enough that refactoring
+code should not generally be a daunting prospect from a testing point of
+view. Nevertheless there are some areas which are only lightly-tested:
+
+ 1. Tests on the ages of files
+ 2. Code which deals with the values returned by operating system calls
+ (for example handling of ENOENT)
+ 3. Code dealing with OS limits (for example, limits on path length or
+ exec arguments)
+ 4. Code relating to features not all systems have (for example Solaris
+ Doors)
+
+ Please exercise caution when working in those areas.
+
+
+File: find-maint.info, Node: Debugging is For Users Too, Next: Don't Trust the File System Contents, Prev: Factor Out Repeated Code, Up: Coding Conventions
+
+4.3 Debugging is For Users Too
+==============================
+
+Debug and diagnostic code is often used to verify that a program is
+working in the way its author thinks it should be. But users are often
+uncertain about what a program is doing, too. Exposing them a little
+more diagnostic information can help. Much of the diagnostic code in
+'find', for example, is controlled by the '-D' flag, as opposed to C
+preprocessor directives.
+
+ Making diagnostic messages available to users also means that the
+phrasing of the diagnostic messages becomes important, too.
+
+
+File: find-maint.info, Node: Don't Trust the File System Contents, Next: The File System Is Being Modified, Prev: Debugging is For Users Too, Up: Coding Conventions
+
+4.4 Don't Trust the File System Contents
+========================================
+
+People use 'find' to search in directories created by other people.
+Sometimes they do this to check to suspicious activity (for example to
+look for new setuid binaries). This means that it would be bad if
+'find' were vulnerable to, say, a security problem exploitable by
+constructing a specially-crafted filename. The same consideration would
+apply to 'locate' and 'updatedb'.
+
+ Henry Spencer said this well in his fifth commandment:
+ Thou shalt check the array bounds of all strings (indeed, all
+ arrays), for surely where thou typest 'foo' someone someday shall
+ type 'supercalifragilisticexpialidocious'.
+
+ Symbolic links can often be a problem. If 'find' calls 'lstat' on
+something and discovers that it is a directory, it's normal for 'find'
+to recurse into it. Even if the 'chdir' system call is used
+immediately, there is still a window of opportunity between the 'lstat'
+and the 'chdir' in which a malicious person could rename the directory
+and substitute a symbolic link to some other directory.
+
+
+File: find-maint.info, Node: The File System Is Being Modified, Prev: Don't Trust the File System Contents, Up: Coding Conventions
+
+4.5 The File System Is Being Modified
+=====================================
+
+The filesystem gets modified while you are traversing it. For, example,
+it's normal for files to get deleted while 'find' is traversing a
+directory. Issuing an error message seems helpful when a file is
+deleted from the one directory you are interested in, but if 'find' is
+searching 15000 directories, such a message becomes less helpful.
+
+ Bear in mind also that it is possible for the directory 'find' is
+currently searching could be moved to another point in the filesystem,
+and that the directory in which 'find' was started could be deleted.
+
+ Henry Spencer's sixth commandment is also apposite here:
+ If a function be advertised to return an error code in the event of
+ difficulties, thou shalt check for that code, yea, even though the
+ checks triple the size of thy code and produce aches in thy typing
+ fingers, for if thou thinkest "it cannot happen to me", the gods
+ shall surely punish thee for thy arrogance.
+
+ There are a lot of files out there. They come in all dates and
+sizes. There is a condition out there in the real world to exercise
+every bit of the code base. So we try to test that code base before
+someone falls over a bug.
+
+
+File: find-maint.info, Node: Tools, Next: Using the GNU Portability Library, Prev: Coding Conventions, Up: Top
+
+5 Tools
+*******
+
+Most of the tools required to build findutils are mentioned in the file
+'README-hacking'. We also use some other tools:
+
+System call traces
+ Much of the execution time of find is spent waiting for filesystem
+ operations. A system call trace (for example, that provided by
+ 'strace') shows what system calls are being made. Using this
+ information we can work to remove unnecessary file system
+ operations.
+
+Valgrind
+ Valgrind is a tool which dynamically verifies the memory accesses a
+ program makes to ensure that they are valid (for example, that the
+ behaviour of the program does not in any way depend on the contents
+ of uninitialized memory).
+
+DejaGnu
+ DejaGnu is the test framework used to run the findutils test suite
+ (the 'runtest' program is part of DejaGnu). It would be ideal if
+ everybody building 'findutils' also ran the test suite, but many
+ people don't have DejaGnu installed. When changes are made to
+ findutils, DejaGnu is invoked a lot. *Note Testing::, for more
+ information.
+
+
+File: find-maint.info, Node: Using the GNU Portability Library, Next: Documentation, Prev: Tools, Up: Top
+
+6 Using the GNU Portability Library
+***********************************
+
+The Gnulib library (<http://www.gnu.org/software/gnulib/>) makes a
+variety of systems look more like a GNU/Linux system and also applies a
+bunch of automatic bug fixes and workarounds. Some of these also apply
+to GNU/Linux systems too. For example, the Gnulib regex implementation
+is used when we determine that we are building on a GNU libc system with
+a bug in the regex implementation.
+
+6.1 How and Why we Import the Gnulib Code
+=========================================
+
+Gnulib does not have a release process which results in a source tarball
+you can download. Instead, the code is simply made available by GIT, so
+we import gnulib via the submodule feature. The bootstrap script
+performs the necessary steps.
+
+ Findutils does not use all the Gnulib code. The modules we need are
+listed in the file 'bootstrap.conf'.
+
+ The upshot of all this is that we can use the findutils git
+repository to track which version of Gnulib every findutils release
+uses.
+
+ A small number of files are installed by automake and will therefore
+vary according to which version of automake was used to generate a
+release. This includes for example boiler-plate GNU files such as
+'ABOUT-NLS', 'INSTALL' and 'COPYING'.
+
+6.2 How We Fix Gnulib Bugs
+==========================
+
+Gnulib is used by quite a number of GNU projects, and this means that it
+gets plenty of testing. Therefore there are relatively few bugs in the
+Gnulib code, but it does happen from time to time.
+
+ However, since there is no waiting around for a Gnulib source release
+tarball, Gnulib bugs are generally fixed quickly. Here is an outline of
+the way we would contribute a fix to Gnulib (assuming you know it is not
+already fixed in the current Gnulib git tree):
+
+Check you already completed a copyright assignment for Gnulib
+Begin with a vanilla git tree
+ Download the Findutils source code from git (or use the tree you
+ have already)
+Run the bootstrap script
+Run configure
+Build findutils
+ Build findutils and run the test suite, which should pass. In our
+ example we assume you have just noticed a bug in Gnulib, not that
+ recent Gnulib changes broke the findutils regression tests.
+Write a test case
+ If in fact Gnulib did break the findutils regression tests, you can
+ probably skip this step, since you already have a test case
+ demonstrating the problem. Otherwise, write a findutils test case
+ for the bug and/or a Gnulib test case.
+Fix the Gnulib bug
+ Make sure your editor follows symbolic links so that your changes
+ to 'gnulib/...' actually affect the files in the git working
+ directory you checked out earlier. Observe that your test now
+ passes.
+Prepare a Gnulib patch
+ In the gnulib subdirectory, use 'git format-patch' to prepare the
+ patch. Follow the normal usage for checkin comments (take a look
+ at the output of 'git log'). Check that the patch conforms with
+ the GNU coding standards, and email it to the Gnulib mailing list.
+Wait for the patch to be applied
+ Once your bug fix has been applied, you can update your gnulib
+ directory from git, and then check in the change to the submodule
+ as normal (you can check 'git help submodule' for details).
+
+ There is an alternative to the method above; it is possible to store
+local diffs to be patched into gnulib beneath the 'gnulib-local'.
+Normally however, there is no need for this, since gnulib updates are
+very prompt.
+
+
+File: find-maint.info, Node: Documentation, Next: Testing, Prev: Using the GNU Portability Library, Up: Top
+
+7 Documentation
+***************
+
+The findutils git tree includes several different types of
+documentation.
+
+7.1 git change log
+==================
+
+The git change log for the source tree contains check-in messages which
+describe each check-in. These have a standard format:
+
+ Summary of the change.
+
+ (ChangeLog-style detail)
+
+ Here, the format of the detail part follows the standard GNU
+ChangeLog style, but without whitespace in the left margin and without
+author/date headers. Take a look at the output of 'git log' to see some
+examples. The README-hacking file also contains an example with an
+explanation.
+
+7.2 User Documentation
+======================
+
+User-oriented documentation is provided as manual pages and in Texinfo.
+See *note Introduction: (find)Introduction.
+
+ Please make sure both sets of documentation are updated if you make a
+change to the code. The GNU coding standards do not normally call for
+maintaining manual pages on the grounds of effort duplication. However,
+the manual page format is more convenient for quick reference, and so
+it's worth maintaining both types of documentation. However, the manual
+pages are normally rather more terse than the Texinfo documentation.
+The manual pages are suitable for reference use, but the Texinfo manual
+should also include introductory and tutorial material.
+
+7.3 Build Guidance
+==================
+
+'ABOUT-NLS'
+ Describes the Free Translation Project, the translation status of
+ various GNU projects, and how to participate by translating an
+ application.
+'AUTHORS'
+ Lists the authors of findutils.
+'COPYING'
+ The copyright license covering findutils; currently, the GNU GPL,
+ version 3.
+'INSTALL'
+ Generic installation instructions for installing GNU programs.
+'README'
+ Information about how to compile findutils in particular
+'README-alpha'
+ A README file which is included with testing releases of findutils.
+'README-hacking'
+ Describes how to build findutils from the code in git.
+'THANKS'
+ Thanks for people who contributed to findutils. Generally, if
+ someone's contribution was significant enough to need a copyright
+ assignment, their name should go in here.
+'TODO'
+ Mainly obsolete. Please add bugs to the Savannah bug tracker
+ instead of adding entries to this file.
+
+7.4 Release Information
+=======================
+
+'NEWS'
+ Enumerates the user-visible change in each release. Typical
+ changes are fixed bugs, functionality changes and documentation
+ changes. Include the date when a release is made.
+'ChangeLog'
+ This file enumerates all changes to the findutils source code (with
+ the possible exception of '.cvsignore' and '.gitignore' changes).
+ The level of detail used for this file should be sufficient to
+ answer the questions "what changed?" and "why was it changed?".
+ The file is generated from the git commit messages during 'make
+ dist'. If a change fixes a bug, always give the bug reference
+ number in the 'NEWS' file and of course also in the checkin
+ message. In general, it should be possible to enumerate all
+ material changes to a function by searching for its name in
+ 'ChangeLog'. Mention when each release is made.
+
+
+File: find-maint.info, Node: Testing, Next: Bugs, Prev: Documentation, Up: Top
+
+8 Testing
+*********
+
+This chapter will explain the general procedures for adding tests to the
+test suite, and the functions defined in the findutils-specific DejaGnu
+configuration. Where appropriate references will be made to the DejaGnu
+documentation.
+
+
+File: find-maint.info, Node: Bugs, Next: Distributions, Prev: Testing, Up: Top
+
+9 Bugs
+******
+
+Bugs are logged in the Savannah bug tracker
+<http://savannah.gnu.org/bugs/?group=findutils>. The tracker offers
+several fields but their use is largely obvious. The life-cycle of a
+bug is like this:
+
+Open
+ Someone, usually a maintainer, a distribution maintainer or a user,
+ creates a bug by filling in the form. They fill in field values as
+ they see fit. This will generate an email to
+ <bug-findutils@gnu.org>.
+
+Triage
+ The bug hangs around with 'Status=None' until someone begins to
+ work on it. At that point they set the "Assigned To" field and
+ will sometimes set the status to 'In Progress', especially if the
+ bug will take a while to fix.
+
+Non-bugs
+ Quite a lot of reports are not actually bugs; for these the usual
+ procedure is to explain why the problem is not a bug, set the
+ status to 'Invalid' and close the bug. Make sure you set the
+ 'Assigned to' field to yourself before closing the bug.
+
+Fixing
+ When you commit a bug fix into git (or in the case of a contributed
+ patch, commit the change), mark the bug as 'Fixed'. Make sure you
+ include a new test case where this is relevant. If you can figure
+ out which releases are affected, please also set the 'Release'
+ field to the earliest release which is affected by the bug.
+ Indicate which source branch the fix is included in (for example,
+ 4.2.x or 4.3.x). Don't close the bug yet.
+
+Release
+ When a release is made which includes the bug fix, make sure the
+ bug is listed in the NEWS file. Once the release is made, fill in
+ the 'Fixed Release' field and close the bug.
+
+
+File: find-maint.info, Node: Distributions, Next: Internationalisation, Prev: Bugs, Up: Top
+
+10 Distributions
+****************
+
+Almost all GNU/Linux distributions include findutils, but only some of
+them have a package maintainer who is a member of the mailing list.
+Distributions don't often feed back patches to the
+<bug-findutils@gnu.org> list, but on the other hand many of their
+patches relate only to standards for file locations and so forth, and
+are therefore distribution specific. On an irregular basis I check the
+current patches being used by one or two distributions, but the total
+number of GNU/Linux distributions is large enough that we could not hope
+to cover them all.
+
+ Often, bugs are raised against a distribution's bug tracker instead
+of GNU's. Periodically (about every six months) I take a look at some
+of the more accessible bug trackers to indicate which bugs have been
+fixed upstream.
+
+ Many distributions include both findutils and the slocate package,
+which provides a replacement 'locate'.
+
+
+File: find-maint.info, Node: Internationalisation, Next: Security, Prev: Distributions, Up: Top
+
+11 Internationalisation
+***********************
+
+Translation is essentially automated from the maintainer's point of
+view. The TP mails the maintainer when a new PO file is available, and
+we just download it and check it in. We copy the '.po' files into the
+git repository. For more information, please see
+<http://translationproject.org/domain/findutils.html>.
+
+
+File: find-maint.info, Node: Security, Next: Making Releases, Prev: Internationalisation, Up: Top
+
+12 Security
+***********
+
+See *note Security Considerations: (find)Security Considerations, for a
+full description of the findutils approach to security considerations
+and discussion of particular tools.
+
+ If someone reports a security bug publicly, we should fix this as
+rapidly as possible. If necessary, this can mean issuing a fixed
+release containing just the one bug fix. We try to avoid issuing
+releases which include both significant security fixes and functional
+changes.
+
+ Where someone reports a security problem privately, we generally try
+to construct and test a patch without pushing the intermediate code to
+the public repository.
+
+ Once everything has been tested, this allows us to make a release and
+push the patch. The advantage of doing things this way is that we avoid
+situations where people watching for git commits can figure out and
+exploit a security problem before a fixed release is available.
+
+ It's important that security problems be fixed promptly, but don't
+rush so much that things go wrong. Make sure the new release really
+fixes the problem. It's usually best not to include functional changes
+in your security-fix release.
+
+ If the security problem is serious, send an alert to
+<vendor-sec@lst.de>. The members of the list include most GNU/Linux
+distributions. The point of doing this is to allow them to prepare to
+release your security fix to their customers, once the fix becomes
+available. Here is an example alert:-
+
+ GNU findutils heap buffer overrun (potential privilege escalation)
+
+
+
+ I. BACKGROUND
+ =============
+
+ GNU findutils is a set of programs which search for files on Unix-like
+ systems. It is maintained by the GNU Project of the Free Software
+ Foundation. For more information, see
+ <http://www.gnu.org/software/findutils>.
+
+
+ II. DESCRIPTION
+ ===============
+
+ When GNU locate reads filenames from an old-format locate database,
+ they are read into a fixed-length buffer allocated on the heap.
+ Filenames longer than the 1026-byte buffer can cause a buffer overrun.
+ The overrunning data can be chosen by any person able to control the
+ names of filenames created on the local system. This will normally
+ include all local users, but in many cases also remote users (for
+ example in the case of FTP servers allowing uploads).
+
+ III. ANALYSIS
+ =============
+
+ Findutils supports three different formats of locate database, its
+ native format "LOCATE02", the slocate variant of LOCATE02, and a
+ traditional ("old") format that locate uses on other Unix systems.
+
+ When locate reads filenames from a LOCATE02 database (the default
+ format), the buffer into which data is read is automatically extended
+ to accommodate the length of the filenames.
+
+ This automatic buffer extension does not happen for old-format
+ databases. Instead a 1026-byte buffer is used. When a longer
+ pathname appears in the locate database, the end of this buffer is
+ overrun. The buffer is allocated on the heap (not the stack).
+
+ If the locate database is in the default LOCATE02 format, the locate
+ program does perform automatic buffer extension, and the program is
+ not vulnerable to this problem. The software used to build the
+ old-format locate database is not itself vulnerable to the same
+ attack.
+
+ Most installations of GNU findutils do not use the old database
+ format, and so will not be vulnerable.
+
+
+ IV. DETECTION
+ =============
+
+ Software
+ --------
+ All existing releases of findutils are affected.
+
+
+ Installations
+ -------------
+
+ To discover the longest path name on a given system, you can use the
+ following command (requires GNU findutils and GNU coreutils):
+
+ find / -print0 | tr -c '\0' 'x' | tr '\0' '\n' | wc -L
+
+ V. EXAMPLE
+ ==========
+
+ This section includes a shell script which determines which of a list
+ of locate binaries is vulnerable to the problem. The shell script has
+ been tested only on glibc based systems having a mktemp binary.
+
+ NOTE: This script deliberately overruns the buffer in order to
+ determine if a binary is affected. Therefore running it on your
+ system may have undesirable effects. We recommend that you read the
+ script before running it.
+
+ #! /bin/sh
+ set +m
+ if vanilla_db="$(mktemp nicedb.XXXXXX)" ; then
+ if updatedb --prunepaths="" --old-format --localpaths="/tmp" \
+ --output="$@{vanilla_db@}" ; then
+ true
+ else
+ rm -f "$@{vanilla_db@}"
+ vanilla_db=""
+ echo "Failed to create old-format locate database; skipping the sanity checks" >&2
+ fi
+ fi
+
+ make_overrun_db() @{
+ # Start with a valid database
+ cat "$@{vanilla_db@}"
+ # Make the final entry really long
+ dd if=/dev/zero bs=1 count=1500 2>/dev/null | tr '\000' 'x'
+ @}
+
+
+
+ ulimit -c 0
+
+ usage() @{ echo "usage: $0 binary [binary...]" >&2; exit $1; @}
+ [ $# -eq 0 ] && usage 1
+
+ bad=""
+ good=""
+ ugly=""
+ if dbfile="$(mktemp nasty.XXXXXX)"
+ then
+ make_overrun_db > "$dbfile"
+ for locate ; do
+ ver="$locate = $("$locate" --version | head -1)"
+ if [ -z "$vanilla_db" ] || "$locate" -d "$vanilla_db" "" >/dev/null ; then
+ "$locate" -d "$dbfile" "" >/dev/null
+ if [ $? -gt 128 ] ; then
+ bad="$bad
+ vulnerable: $ver"
+ else
+ good="$good
+ good: $ver"
+ fi
+ else
+ # the regular locate failed
+ ugly="$ugly
+ buggy, may or may not be vulnerable: $ver"
+ fi
+ done
+ rm -f "$@{dbfile@}" "$@{vanilla_db@}"
+ # good: unaffected. bad: affected (vulnerable).
+ # ugly: doesn't even work for a normal old-format database.
+ echo "$good"
+ echo "$bad"
+ echo "$ugly"
+ else
+ exit 1
+ fi
+
+
+
+
+ VI. VENDOR RESPONSE
+ ===================
+
+ The GNU project discovered the problem while 'locate' was being worked
+ on; this is the first public announcement of the problem.
+
+ The GNU findutils mantainer has issued a patch as p[art of this
+ announcement. The patch appears below.
+
+ A source release of findutils-4.2.31 will be issued on 2007-05-30.
+ That release will of course include the patch. The patch will be
+ committed to the public CVS repository at the same time. Public
+ announcements of the release, including a description of the bug, will
+ be made at the same time as the release.
+
+ A release of findutils-4.3.x will follow and will also include the
+ patch.
+
+
+ VII. PATCH
+ ==========
+
+ This patch should apply to findutils-4.2.23 and later.
+ Findutils-4.2.23 was released almost two years ago.
+ Index: locate/locate.c
+ ===================================================================
+ RCS file: /cvsroot/findutils/findutils/locate/locate.c,v
+ retrieving revision 1.58.2.2
+ diff -u -p -r1.58.2.2 locate.c
+ --- locate/locate.c 22 Apr 2007 16:57:42 -0000 1.58.2.2
+ +++ locate/locate.c 28 May 2007 10:18:16 -0000
+ @@@@ -124,9 +124,9 @@@@ extern int errno;
+
+ #include "locatedb.h"
+ #include <getline.h>
+ -#include "../gnulib/lib/xalloc.h"
+ -#include "../gnulib/lib/error.h"
+ -#include "../gnulib/lib/human.h"
+ +#include "xalloc.h"
+ +#include "error.h"
+ +#include "human.h"
+ #include "dirname.h"
+ #include "closeout.h"
+ #include "nextelem.h"
+ @@@@ -468,10 +468,36 @@@@ visit_justprint_unquoted(struct process_
+ return VISIT_CONTINUE;
+ @}
+
+ +static void
+ +toolong (struct process_data *procdata)
+ +@{
+ + error (EXIT_FAILURE, 0,
+ + _("locate database %s contains a "
+ + "filename longer than locate can handle"),
+ + procdata->dbfile);
+ +@}
+ +
+ +static void
+ +extend (struct process_data *procdata, size_t siz1, size_t siz2)
+ +@{
+ + /* Figure out if the addition operation is safe before performing it. */
+ + if (SIZE_MAX - siz1 < siz2)
+ + @{
+ + toolong (procdata);
+ + @}
+ + else if (procdata->pathsize < (siz1+siz2))
+ + @{
+ + procdata->pathsize = siz1+siz2;
+ + procdata->original_filename = x2nrealloc (procdata->original_filename,
+ + &procdata->pathsize,
+ + 1);
+ + @}
+ +@}
+ +
+ static int
+ visit_old_format(struct process_data *procdata, void *context)
+ @{
+ - register char *s;
+ + register size_t i;
+ (void) context;
+
+ /* Get the offset in the path where this path info starts. */
+ @@@@ -479,20 +505,35 @@@@ visit_old_format(struct process_data *pr
+ procdata->count += getw (procdata->fp) - LOCATEDB_OLD_OFFSET;
+ else
+ procdata->count += procdata->c - LOCATEDB_OLD_OFFSET;
+ + assert(procdata->count > 0);
+
+ - /* Overlay the old path with the remainder of the new. */
+ - for (s = procdata->original_filename + procdata->count;
+ + /* Overlay the old path with the remainder of the new. Read
+ + * more data until we get to the next filename.
+ + */
+ + for (i=procdata->count;
+ (procdata->c = getc (procdata->fp)) > LOCATEDB_OLD_ESCAPE;)
+ - if (procdata->c < 0200)
+ - *s++ = procdata->c; /* An ordinary character. */
+ - else
+ - @{
+ - /* Bigram markers have the high bit set. */
+ - procdata->c &= 0177;
+ - *s++ = procdata->bigram1[procdata->c];
+ - *s++ = procdata->bigram2[procdata->c];
+ - @}
+ - *s-- = '\0';
+ + @{
+ + if (procdata->c < 0200)
+ + @{
+ + /* An ordinary character. */
+ + extend (procdata, i, 1u);
+ + procdata->original_filename[i++] = procdata->c;
+ + @}
+ + else
+ + @{
+ + /* Bigram markers have the high bit set. */
+ + extend (procdata, i, 2u);
+ + procdata->c &= 0177;
+ + procdata->original_filename[i++] = procdata->bigram1[procdata->c];
+ + procdata->original_filename[i++] = procdata->bigram2[procdata->c];
+ + @}
+ + @}
+ +
+ + /* Consider the case where we executed the loop body zero times; we
+ + * still need space for the terminating null byte.
+ + */
+ + extend (procdata, i, 1u);
+ + procdata->original_filename[i] = 0;
+
+ procdata->munged_filename = procdata->original_filename;
+
+
+ VIII. THANKS
+ ============
+
+ Thanks to Rob Holland <rob@inversepath.com> and Tavis Ormandy.
+
+
+ VIII. CVE INFORMATION
+ =====================
+
+ No CVE candidate number has yet been assigned for this vulnerability.
+ If someone provides one, I will include it in the public announcement
+ and change logs.
+
+ The original announcement above was sent out with a cleartext PGP
+signature, of course, but that has been omitted from the example.
+
+ Once a fixed release is available, announce the new release using the
+normal channels. Any CVE number assigned for the problem should be
+included in the 'ChangeLog' and 'NEWS' entries. See
+<http://cve.mitre.org/> for an explanation of CVE numbers.
+
+
+File: find-maint.info, Node: Making Releases, Next: GNU Free Documentation License, Prev: Security, Up: Top
+
+13 Making Releases
+******************
+
+This section will explain how to make a findutils release. For the time
+being here is a terse description of the main steps:
+
+ 1. Commit changes; make sure your working directory has no uncommitted
+ changes.
+ 2. Test; make sure that all changes you have made have tests, and that
+ the tests pass. Verify this with 'make distcheck'.
+ 3. Bugs; make sure all Savannah bug entries fixed in this release are
+ fixed.
+ 4. NEWS; make sure that the NEWS and configure.in file are updated
+ with the new release number (and checked in).
+ 5. Build the release tarball; do this with 'make distcheck'. Copy the
+ tarball somewhere safe.
+ 6. Tag the release; findutils releases are tagged like this for
+ example: v4.5.5. Previously a different format was in use:
+ FINDUTILS_4_3_8-1. You can create a tag with the a command like
+ this: 'git tag -s -m "Findutils release v4.5.7" v4.5.7'.
+ 7. Prepare the upload and upload it. *Note Automated FTP Uploads:
+ (maintain)Automated FTP Uploads, for detailed upload instructions.
+ 8. Make a release announcement; include an extract from the NEWS file
+ which explains what's changed. Announcements for test releases
+ should just go to <bug-findutils@gnu.org>. Announcements for
+ stable releases should go to <info-gnu@gnu.org> as well.
+ 9. Bump the release numbers in git; edit the 'configure.in' and 'NEWS'
+ files to advance the release numbers. For example, if you have
+ just released '4.6.2', bump the release number to '4.6.3-git'. The
+ point of the '-git' suffix here is that a findutils binary built
+ from git will bear a release number indicating it's not built from
+ the "official" source release.
+ 10. Close bugs; any bugs recorded on Savannah which were fixed in this
+ release should now be marked as closed. Update the 'Fixed Release'
+ field of these bugs appropriately and make sure the 'Assigned to'
+ field is populated.
+
+
+File: find-maint.info, Node: GNU Free Documentation License, Prev: Making Releases, Up: Top
+
+Appendix A GNU Free Documentation License
+*****************************************
+
+ Version 1.3, 3 November 2008
+
+ Copyright (C) 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
+ <http://fsf.org/>
+
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ 0. PREAMBLE
+
+ The purpose of this License is to make a manual, textbook, or other
+ functional and useful document "free" in the sense of freedom: to
+ assure everyone the effective freedom to copy and redistribute it,
+ with or without modifying it, either commercially or
+ noncommercially. Secondarily, this License preserves for the
+ author and publisher a way to get credit for their work, while not
+ being considered responsible for modifications made by others.
+
+ This License is a kind of "copyleft", which means that derivative
+ works of the document must themselves be free in the same sense.
+ It complements the GNU General Public License, which is a copyleft
+ license designed for free software.
+
+ We have designed this License in order to use it for manuals for
+ free software, because free software needs free documentation: a
+ free program should come with manuals providing the same freedoms
+ that the software does. But this License is not limited to
+ software manuals; it can be used for any textual work, regardless
+ of subject matter or whether it is published as a printed book. We
+ recommend this License principally for works whose purpose is
+ instruction or reference.
+
+ 1. APPLICABILITY AND DEFINITIONS
+
+ This License applies to any manual or other work, in any medium,
+ that contains a notice placed by the copyright holder saying it can
+ be distributed under the terms of this License. Such a notice
+ grants a world-wide, royalty-free license, unlimited in duration,
+ to use that work under the conditions stated herein. The
+ "Document", below, refers to any such manual or work. Any member
+ of the public is a licensee, and is addressed as "you". You accept
+ the license if you copy, modify or distribute the work in a way
+ requiring permission under copyright law.
+
+ A "Modified Version" of the Document means any work containing the
+ Document or a portion of it, either copied verbatim, or with
+ modifications and/or translated into another language.
+
+ A "Secondary Section" is a named appendix or a front-matter section
+ of the Document that deals exclusively with the relationship of the
+ publishers or authors of the Document to the Document's overall
+ subject (or to related matters) and contains nothing that could
+ fall directly within that overall subject. (Thus, if the Document
+ is in part a textbook of mathematics, a Secondary Section may not
+ explain any mathematics.) The relationship could be a matter of
+ historical connection with the subject or with related matters, or
+ of legal, commercial, philosophical, ethical or political position
+ regarding them.
+
+ The "Invariant Sections" are certain Secondary Sections whose
+ titles are designated, as being those of Invariant Sections, in the
+ notice that says that the Document is released under this License.
+ If a section does not fit the above definition of Secondary then it
+ is not allowed to be designated as Invariant. The Document may
+ contain zero Invariant Sections. If the Document does not identify
+ any Invariant Sections then there are none.
+
+ The "Cover Texts" are certain short passages of text that are
+ listed, as Front-Cover Texts or Back-Cover Texts, in the notice
+ that says that the Document is released under this License. A
+ Front-Cover Text may be at most 5 words, and a Back-Cover Text may
+ be at most 25 words.
+
+ A "Transparent" copy of the Document means a machine-readable copy,
+ represented in a format whose specification is available to the
+ general public, that is suitable for revising the document
+ straightforwardly with generic text editors or (for images composed
+ of pixels) generic paint programs or (for drawings) some widely
+ available drawing editor, and that is suitable for input to text
+ formatters or for automatic translation to a variety of formats
+ suitable for input to text formatters. A copy made in an otherwise
+ Transparent file format whose markup, or absence of markup, has
+ been arranged to thwart or discourage subsequent modification by
+ readers is not Transparent. An image format is not Transparent if
+ used for any substantial amount of text. A copy that is not
+ "Transparent" is called "Opaque".
+
+ Examples of suitable formats for Transparent copies include plain
+ ASCII without markup, Texinfo input format, LaTeX input format,
+ SGML or XML using a publicly available DTD, and standard-conforming
+ simple HTML, PostScript or PDF designed for human modification.
+ Examples of transparent image formats include PNG, XCF and JPG.
+ Opaque formats include proprietary formats that can be read and
+ edited only by proprietary word processors, SGML or XML for which
+ the DTD and/or processing tools are not generally available, and
+ the machine-generated HTML, PostScript or PDF produced by some word
+ processors for output purposes only.
+
+ The "Title Page" means, for a printed book, the title page itself,
+ plus such following pages as are needed to hold, legibly, the
+ material this License requires to appear in the title page. For
+ works in formats which do not have any title page as such, "Title
+ Page" means the text near the most prominent appearance of the
+ work's title, preceding the beginning of the body of the text.
+
+ The "publisher" means any person or entity that distributes copies
+ of the Document to the public.
+
+ A section "Entitled XYZ" means a named subunit of the Document
+ whose title either is precisely XYZ or contains XYZ in parentheses
+ following text that translates XYZ in another language. (Here XYZ
+ stands for a specific section name mentioned below, such as
+ "Acknowledgements", "Dedications", "Endorsements", or "History".)
+ To "Preserve the Title" of such a section when you modify the
+ Document means that it remains a section "Entitled XYZ" according
+ to this definition.
+
+ The Document may include Warranty Disclaimers next to the notice
+ which states that this License applies to the Document. These
+ Warranty Disclaimers are considered to be included by reference in
+ this License, but only as regards disclaiming warranties: any other
+ implication that these Warranty Disclaimers may have is void and
+ has no effect on the meaning of this License.
+
+ 2. VERBATIM COPYING
+
+ You may copy and distribute the Document in any medium, either
+ commercially or noncommercially, provided that this License, the
+ copyright notices, and the license notice saying this License
+ applies to the Document are reproduced in all copies, and that you
+ add no other conditions whatsoever to those of this License. You
+ may not use technical measures to obstruct or control the reading
+ or further copying of the copies you make or distribute. However,
+ you may accept compensation in exchange for copies. If you
+ distribute a large enough number of copies you must also follow the
+ conditions in section 3.
+
+ You may also lend copies, under the same conditions stated above,
+ and you may publicly display copies.
+
+ 3. COPYING IN QUANTITY
+
+ If you publish printed copies (or copies in media that commonly
+ have printed covers) of the Document, numbering more than 100, and
+ the Document's license notice requires Cover Texts, you must
+ enclose the copies in covers that carry, clearly and legibly, all
+ these Cover Texts: Front-Cover Texts on the front cover, and
+ Back-Cover Texts on the back cover. Both covers must also clearly
+ and legibly identify you as the publisher of these copies. The
+ front cover must present the full title with all words of the title
+ equally prominent and visible. You may add other material on the
+ covers in addition. Copying with changes limited to the covers, as
+ long as they preserve the title of the Document and satisfy these
+ conditions, can be treated as verbatim copying in other respects.
+
+ If the required texts for either cover are too voluminous to fit
+ legibly, you should put the first ones listed (as many as fit
+ reasonably) on the actual cover, and continue the rest onto
+ adjacent pages.
+
+ If you publish or distribute Opaque copies of the Document
+ numbering more than 100, you must either include a machine-readable
+ Transparent copy along with each Opaque copy, or state in or with
+ each Opaque copy a computer-network location from which the general
+ network-using public has access to download using public-standard
+ network protocols a complete Transparent copy of the Document, free
+ of added material. If you use the latter option, you must take
+ reasonably prudent steps, when you begin distribution of Opaque
+ copies in quantity, to ensure that this Transparent copy will
+ remain thus accessible at the stated location until at least one
+ year after the last time you distribute an Opaque copy (directly or
+ through your agents or retailers) of that edition to the public.
+
+ It is requested, but not required, that you contact the authors of
+ the Document well before redistributing any large number of copies,
+ to give them a chance to provide you with an updated version of the
+ Document.
+
+ 4. MODIFICATIONS
+
+ You may copy and distribute a Modified Version of the Document
+ under the conditions of sections 2 and 3 above, provided that you
+ release the Modified Version under precisely this License, with the
+ Modified Version filling the role of the Document, thus licensing
+ distribution and modification of the Modified Version to whoever
+ possesses a copy of it. In addition, you must do these things in
+ the Modified Version:
+
+ A. Use in the Title Page (and on the covers, if any) a title
+ distinct from that of the Document, and from those of previous
+ versions (which should, if there were any, be listed in the
+ History section of the Document). You may use the same title
+ as a previous version if the original publisher of that
+ version gives permission.
+
+ B. List on the Title Page, as authors, one or more persons or
+ entities responsible for authorship of the modifications in
+ the Modified Version, together with at least five of the
+ principal authors of the Document (all of its principal
+ authors, if it has fewer than five), unless they release you
+ from this requirement.
+
+ C. State on the Title page the name of the publisher of the
+ Modified Version, as the publisher.
+
+ D. Preserve all the copyright notices of the Document.
+
+ E. Add an appropriate copyright notice for your modifications
+ adjacent to the other copyright notices.
+
+ F. Include, immediately after the copyright notices, a license
+ notice giving the public permission to use the Modified
+ Version under the terms of this License, in the form shown in
+ the Addendum below.
+
+ G. Preserve in that license notice the full lists of Invariant
+ Sections and required Cover Texts given in the Document's
+ license notice.
+
+ H. Include an unaltered copy of this License.
+
+ I. Preserve the section Entitled "History", Preserve its Title,
+ and add to it an item stating at least the title, year, new
+ authors, and publisher of the Modified Version as given on the
+ Title Page. If there is no section Entitled "History" in the
+ Document, create one stating the title, year, authors, and
+ publisher of the Document as given on its Title Page, then add
+ an item describing the Modified Version as stated in the
+ previous sentence.
+
+ J. Preserve the network location, if any, given in the Document
+ for public access to a Transparent copy of the Document, and
+ likewise the network locations given in the Document for
+ previous versions it was based on. These may be placed in the
+ "History" section. You may omit a network location for a work
+ that was published at least four years before the Document
+ itself, or if the original publisher of the version it refers
+ to gives permission.
+
+ K. For any section Entitled "Acknowledgements" or "Dedications",
+ Preserve the Title of the section, and preserve in the section
+ all the substance and tone of each of the contributor
+ acknowledgements and/or dedications given therein.
+
+ L. Preserve all the Invariant Sections of the Document, unaltered
+ in their text and in their titles. Section numbers or the
+ equivalent are not considered part of the section titles.
+
+ M. Delete any section Entitled "Endorsements". Such a section
+ may not be included in the Modified Version.
+
+ N. Do not retitle any existing section to be Entitled
+ "Endorsements" or to conflict in title with any Invariant
+ Section.
+
+ O. Preserve any Warranty Disclaimers.
+
+ If the Modified Version includes new front-matter sections or
+ appendices that qualify as Secondary Sections and contain no
+ material copied from the Document, you may at your option designate
+ some or all of these sections as invariant. To do this, add their
+ titles to the list of Invariant Sections in the Modified Version's
+ license notice. These titles must be distinct from any other
+ section titles.
+
+ You may add a section Entitled "Endorsements", provided it contains
+ nothing but endorsements of your Modified Version by various
+ parties--for example, statements of peer review or that the text
+ has been approved by an organization as the authoritative
+ definition of a standard.
+
+ You may add a passage of up to five words as a Front-Cover Text,
+ and a passage of up to 25 words as a Back-Cover Text, to the end of
+ the list of Cover Texts in the Modified Version. Only one passage
+ of Front-Cover Text and one of Back-Cover Text may be added by (or
+ through arrangements made by) any one entity. If the Document
+ already includes a cover text for the same cover, previously added
+ by you or by arrangement made by the same entity you are acting on
+ behalf of, you may not add another; but you may replace the old
+ one, on explicit permission from the previous publisher that added
+ the old one.
+
+ The author(s) and publisher(s) of the Document do not by this
+ License give permission to use their names for publicity for or to
+ assert or imply endorsement of any Modified Version.
+
+ 5. COMBINING DOCUMENTS
+
+ You may combine the Document with other documents released under
+ this License, under the terms defined in section 4 above for
+ modified versions, provided that you include in the combination all
+ of the Invariant Sections of all of the original documents,
+ unmodified, and list them all as Invariant Sections of your
+ combined work in its license notice, and that you preserve all
+ their Warranty Disclaimers.
+
+ The combined work need only contain one copy of this License, and
+ multiple identical Invariant Sections may be replaced with a single
+ copy. If there are multiple Invariant Sections with the same name
+ but different contents, make the title of each such section unique
+ by adding at the end of it, in parentheses, the name of the
+ original author or publisher of that section if known, or else a
+ unique number. Make the same adjustment to the section titles in
+ the list of Invariant Sections in the license notice of the
+ combined work.
+
+ In the combination, you must combine any sections Entitled
+ "History" in the various original documents, forming one section
+ Entitled "History"; likewise combine any sections Entitled
+ "Acknowledgements", and any sections Entitled "Dedications". You
+ must delete all sections Entitled "Endorsements."
+
+ 6. COLLECTIONS OF DOCUMENTS
+
+ You may make a collection consisting of the Document and other
+ documents released under this License, and replace the individual
+ copies of this License in the various documents with a single copy
+ that is included in the collection, provided that you follow the
+ rules of this License for verbatim copying of each of the documents
+ in all other respects.
+
+ You may extract a single document from such a collection, and
+ distribute it individually under this License, provided you insert
+ a copy of this License into the extracted document, and follow this
+ License in all other respects regarding verbatim copying of that
+ document.
+
+ 7. AGGREGATION WITH INDEPENDENT WORKS
+
+ A compilation of the Document or its derivatives with other
+ separate and independent documents or works, in or on a volume of a
+ storage or distribution medium, is called an "aggregate" if the
+ copyright resulting from the compilation is not used to limit the
+ legal rights of the compilation's users beyond what the individual
+ works permit. When the Document is included in an aggregate, this
+ License does not apply to the other works in the aggregate which
+ are not themselves derivative works of the Document.
+
+ If the Cover Text requirement of section 3 is applicable to these
+ copies of the Document, then if the Document is less than one half
+ of the entire aggregate, the Document's Cover Texts may be placed
+ on covers that bracket the Document within the aggregate, or the
+ electronic equivalent of covers if the Document is in electronic
+ form. Otherwise they must appear on printed covers that bracket
+ the whole aggregate.
+
+ 8. TRANSLATION
+
+ Translation is considered a kind of modification, so you may
+ distribute translations of the Document under the terms of section
+ 4. Replacing Invariant Sections with translations requires special
+ permission from their copyright holders, but you may include
+ translations of some or all Invariant Sections in addition to the
+ original versions of these Invariant Sections. You may include a
+ translation of this License, and all the license notices in the
+ Document, and any Warranty Disclaimers, provided that you also
+ include the original English version of this License and the
+ original versions of those notices and disclaimers. In case of a
+ disagreement between the translation and the original version of
+ this License or a notice or disclaimer, the original version will
+ prevail.
+
+ If a section in the Document is Entitled "Acknowledgements",
+ "Dedications", or "History", the requirement (section 4) to
+ Preserve its Title (section 1) will typically require changing the
+ actual title.
+
+ 9. TERMINATION
+
+ You may not copy, modify, sublicense, or distribute the Document
+ except as expressly provided under this License. Any attempt
+ otherwise to copy, modify, sublicense, or distribute it is void,
+ and will automatically terminate your rights under this License.
+
+ However, if you cease all violation of this License, then your
+ license from a particular copyright holder is reinstated (a)
+ provisionally, unless and until the copyright holder explicitly and
+ finally terminates your license, and (b) permanently, if the
+ copyright holder fails to notify you of the violation by some
+ reasonable means prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+ reinstated permanently if the copyright holder notifies you of the
+ violation by some reasonable means, this is the first time you have
+ received notice of violation of this License (for any work) from
+ that copyright holder, and you cure the violation prior to 30 days
+ after your receipt of the notice.
+
+ Termination of your rights under this section does not terminate
+ the licenses of parties who have received copies or rights from you
+ under this License. If your rights have been terminated and not
+ permanently reinstated, receipt of a copy of some or all of the
+ same material does not give you any rights to use it.
+
+ 10. FUTURE REVISIONS OF THIS LICENSE
+
+ The Free Software Foundation may publish new, revised versions of
+ the GNU Free Documentation License from time to time. Such new
+ versions will be similar in spirit to the present version, but may
+ differ in detail to address new problems or concerns. See
+ <http://www.gnu.org/copyleft/>.
+
+ Each version of the License is given a distinguishing version
+ number. If the Document specifies that a particular numbered
+ version of this License "or any later version" applies to it, you
+ have the option of following the terms and conditions either of
+ that specified version or of any later version that has been
+ published (not as a draft) by the Free Software Foundation. If the
+ Document does not specify a version number of this License, you may
+ choose any version ever published (not as a draft) by the Free
+ Software Foundation. If the Document specifies that a proxy can
+ decide which future versions of this License can be used, that
+ proxy's public statement of acceptance of a version permanently
+ authorizes you to choose that version for the Document.
+
+ 11. RELICENSING
+
+ "Massive Multiauthor Collaboration Site" (or "MMC Site") means any
+ World Wide Web server that publishes copyrightable works and also
+ provides prominent facilities for anybody to edit those works. A
+ public wiki that anybody can edit is an example of such a server.
+ A "Massive Multiauthor Collaboration" (or "MMC") contained in the
+ site means any set of copyrightable works thus published on the MMC
+ site.
+
+ "CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0
+ license published by Creative Commons Corporation, a not-for-profit
+ corporation with a principal place of business in San Francisco,
+ California, as well as future copyleft versions of that license
+ published by that same organization.
+
+ "Incorporate" means to publish or republish a Document, in whole or
+ in part, as part of another Document.
+
+ An MMC is "eligible for relicensing" if it is licensed under this
+ License, and if all works that were first published under this
+ License somewhere other than this MMC, and subsequently
+ incorporated in whole or in part into the MMC, (1) had no cover
+ texts or invariant sections, and (2) were thus incorporated prior
+ to November 1, 2008.
+
+ The operator of an MMC Site may republish an MMC contained in the
+ site under CC-BY-SA on the same site at any time before August 1,
+ 2009, provided the MMC is eligible for relicensing.
+
+ADDENDUM: How to use this License for your documents
+====================================================
+
+To use this License in a document you have written, include a copy of
+the License in the document and put the following copyright and license
+notices just after the title page:
+
+ Copyright (C) YEAR YOUR NAME.
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.3
+ or any later version published by the Free Software Foundation;
+ with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
+ Texts. A copy of the license is included in the section entitled ``GNU
+ Free Documentation License''.
+
+ If you have Invariant Sections, Front-Cover Texts and Back-Cover
+Texts, replace the "with...Texts." line with this:
+
+ with the Invariant Sections being LIST THEIR TITLES, with
+ the Front-Cover Texts being LIST, and with the Back-Cover Texts
+ being LIST.
+
+ If you have Invariant Sections without Cover Texts, or some other
+combination of the three, merge those two alternatives to suit the
+situation.
+
+ If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of free
+software license, such as the GNU General Public License, to permit
+their use in free software.
+
+
+
+Tag Table:
+Node: Top866
+Node: Introduction1937
+Node: Maintaining GNU Programs2674
+Node: Design Issues3474
+Node: Coding Conventions7414
+Node: Make the Compiler Find the Bugs9382
+Node: Factor Out Repeated Code12926
+Node: Debugging is For Users Too14992
+Node: Don't Trust the File System Contents15723
+Node: The File System Is Being Modified17005
+Node: Tools18401
+Node: Using the GNU Portability Library19602
+Node: Documentation23240
+Node: Testing26612
+Node: Bugs26953
+Node: Distributions28695
+Node: Internationalisation29728
+Node: Security30197
+Node: Making Releases41557
+Node: GNU Free Documentation License43671
+
+End Tag Table
diff --git a/doc/find-maint.texi b/doc/find-maint.texi
new file mode 100644
index 0000000..a6c65b8
--- /dev/null
+++ b/doc/find-maint.texi
@@ -0,0 +1,1141 @@
+\input texinfo @c -*-texinfo-*-
+@c %**start of header
+@setfilename find-maint.info
+@settitle Maintaining Findutils
+@c For double-sided printing, uncomment:
+@c @setchapternewpage odd
+@c %**end of header
+
+@include versionmaint.texi
+
+@iftex
+@finalout
+@end iftex
+
+@dircategory GNU organization
+@direntry
+* Maintaining Findutils: (find-maint). Maintaining GNU findutils
+@end direntry
+
+@copying
+This manual explains how GNU findutils is maintained, how changes should
+be made and tested, and what resources exist to help developers.
+
+This is edition @value{EDITION}, for findutils version @value{VERSION}.
+
+Copyright @copyright{} 2007, 2008, 2010-2015 Free Software Foundation,
+Inc.
+
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.3
+or any later version published by the Free Software Foundation;
+with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
+Texts.
+A copy of the license is included in the section entitled ``GNU
+Free Documentation License''.
+@end copying
+
+@titlepage
+@title Maintaining Findutils
+@subtitle Edition @value{EDITION}, for GNU findutils version @value{VERSION}
+@subtitle @value{UPDATED}
+@author by James Youngman
+
+@page
+@vskip 0pt plus 1filll
+@insertcopying
+@end titlepage
+
+@contents
+
+@ifnottex
+@node Top, Introduction, (dir), (dir)
+@top Maintaining GNU Findutils
+
+@insertcopying
+@end ifnottex
+
+@menu
+* Introduction::
+* Maintaining GNU Programs::
+* Design Issues::
+* Coding Conventions::
+* Tools::
+* Using the GNU Portability Library::
+* Documentation::
+* Testing::
+* Bugs::
+* Distributions::
+* Internationalisation::
+* Security::
+* Making Releases::
+* GNU Free Documentation License::
+@end menu
+
+
+
+
+
+@node Introduction
+@chapter Introduction
+
+This document explains how to contribute to and maintain GNU
+Findutils. It concentrates on developer-specific issues. For
+information about how to use the software please refer to
+@xref{Introduction, ,Introduction,find,The Findutils manual}.
+
+This manual aims to be useful without necessarily being verbose. It's
+also a recent document, so there will be a many areas in which
+improvements can be made. If you find that the document misses out
+important information or any part of the document is be so terse as to
+be unuseful, please ask for help on the @email{bug-findutils@@gnu.org}
+mailing list. We'll try to improve this document too.
+
+
+@node Maintaining GNU Programs
+@chapter Maintaining GNU Programs
+
+GNU Findutils is part of the GNU Project and so there are a number of
+documents which set out standards for the maintenance of GNU
+software.
+
+@table @file
+@item standards.texi
+GNU Project Coding Standards. All changes to findutils should comply
+with these standards. In some areas we go somewhat beyond the
+requirements of the standards, but these cases are explained in this
+manual.
+@item maintain.texi
+Information for Maintainers of GNU Software. This document provides
+guidance for GNU maintainers. Everybody with commit access should
+read this document. Everybody else is welcome to do so too, of
+course.
+@end table
+
+
+
+@node Design Issues
+@chapter Design Issues
+
+The findutils package is installed on many many systems, usually as a
+fundamental component. The programs in the package are often used in
+order to successfully boot or fix the system.
+
+This fact means that for findutils we bear in mind considerations that
+may not apply so much as for other packages. For example, the fact
+that findutils is often a base component motivates us to
+@itemize
+@item Limit dependencies on libraries
+@item Avoid dependencies on other large packages (for example, interpreters)
+@item Be conservative when making changes to the 'stable' release branch
+@end itemize
+
+All those considerations come before functionality. Functional
+enhancements are still made to findutils, but these are almost
+exclusively introduced in the 'development' release branch, to allow
+extensive testing and proving.
+
+Sometimes it is useful to have a priority list to provide guidance
+when making design trade-offs. For findutils, that priority list is:
+
+@enumerate
+@item Correctness
+@item Standards compliance
+@item Security
+@item Backward compatibility
+@item Performance
+@item Functionality
+@end enumerate
+
+For example, we support the @code{-exec} action because POSIX
+compliance requires this, even though there are security problems with
+it and we would otherwise prefer people to use @code{-execdir}. There
+are also cases where some performance is sacrificed in the name of
+security. For example, the sanity checks that @code{find} performs
+while traversing a directory tree may slow it down. We adopt
+functional changes, and functional changes are allowed to make
+@code{find} slower, but only if there is no detectable impact on users
+who don't use the feature.
+
+Backward-incompatible changes do get made in order to comply with
+standards (for example the behaviour of @code{-perm -...} changed in
+order to comply with POSIX). However, they don't get made in order to
+provide better ease of use; for example the semantics of @code{-size
+-2G} are almost always unexpected by users, but we retain the current
+behaviour because of backward compatibility and for its similarity to
+the block-rounding behaviour of @code{-size -30}. We might introduce
+a change which does not have the unfortunate rounding behaviour, but
+we would choose another syntax (for example @code{-size '<2G'}) for
+this.
+
+In a general sense, we try to do test-driven development of the
+findutils code; that is, we try to implement test cases for new
+features and bug fixes before modifying the code to make the test
+pass. Some features of the code are tested well, but the test
+coverage for other features is less good. If you are about to modify
+the code for a predicate and aren't sure about the test coverage, use
+@code{grep} on the test directories and measure the coverage with
+@code{lcov} or another test coverage tool.
+
+You should be able to use the @code{coverage} Makefile target (it's
+defined in @code{maint.mk} to generate a test coverage report for
+findutils. Due to limitations in @code{lcov}, this only works if
+your build directory is the same asthe source directory (that is,
+you're not using a VPATH build configuration).
+
+Lastly, we try not to depend on having a ``working system''. The
+findutils suite is used for diagnosis of problems, and this applies
+especially to @code{find}. We should ensure that @code{find} still
+works on relatively broken systems, for example systems with damaged
+@file{/etc/passwd} or @code{/etc/fstab} files. Another interesting
+example is the case where a system is a client of one or more
+unresponsive NFS servers. On such a system, if you try to stat all
+mount points, your program will hang indefinitely, waiting for the
+remote NFS server to respond.
+
+Another interesting but unusual case is broken NFS servers and corrupt
+filesystems; sometimes they return `impossible' file modes. It's
+important that find does not entirely fail when encountering such a
+file.
+
+
+@node Coding Conventions
+@chapter Coding Conventions
+
+Coding style documents which set out to establish a uniform look and
+feel to source code have worthy goals, for example greater ease of
+maintenance and readability. However, I do not believe that in
+general coding style guide authors can envisage every situation, and
+it is always possible that it might on occasion be necessary to break
+the letter of the style guide in order to honour its spirit, or to
+better achieve the style guide's goals.
+
+I've certainly seen many style guides outside the free software world
+which make bald statements such as ``functions shall have exactly one
+return statement''. The desire to ensure consistency and obviousness
+of control flow is laudable, but it is all too common for such bald
+requirements to be followed unthinkingly. Certainly I've seen such
+coding standards result in unmaintainable code with terrible
+infelicities such as functions containing @code{if} statements nested
+nine levels deep. I suppose such coding standards don't survive in
+free software projects because they tend to drive away potential
+contributors or tend to generate heated discussions on mailing lists.
+Equally, a nine-level-deep function in a free software program would
+quickly get refactored, assuming it is obvious what the function is
+supposed to do...
+
+Be that as it may, the approach I will take for this document is to
+explain some idioms and practices in use in the findutils source code,
+and leave it up to the reader's engineering judgement to decide which
+considerations apply to the code they are working on, and whether or
+not there is sufficient reason to ignore the guidance in current
+circumstances.
+
+
+@menu
+* Make the Compiler Find the Bugs::
+* Factor Out Repeated Code::
+* Debugging is For Users Too::
+* Don't Trust the File System Contents::
+* The File System Is Being Modified::
+@end menu
+
+@node Make the Compiler Find the Bugs
+@section Make the Compiler Find the Bugs
+
+Finding bugs is tedious. If I have a filesystem containing two
+million files, and a find command line should print one million of
+them, but in fact it misses out 1%, you can tell the program is
+printing the wrong result only if you know the right answer for that
+filesystem at that time. If you don't know this, you may just not
+find out about that bug. For this reason it is important to have a
+comprehensive test suite.
+
+The test suite is of course not the only way to find the bugs. The
+findutils source code makes liberal use of the assert macro. While on
+the one hand these might be a performance drain, the performance
+impact of most of these is negligible compared to the time taken to
+fetch even one sector from a disk drive.
+
+Assertions should not be used to check the results of operations which
+may be affected by the program's external environment. For example,
+never assert that a file could be opened successfully. Errors
+relating to problems with the program's execution environment should
+be diagnosed with a user-oriented error message. An assertion failure
+should always denote a bug in the program.
+
+Don't use @code{assert} to catch not-fuly-implemented features of your
+code. Finish the implementation, disable the code, or leave the
+unfinished version on a local branch.
+
+Several programs in the findutils suite perform self-checks. See for
+example the function @code{pred_sanity_check} in @file{find/pred.c}.
+This is generally desirable.
+
+There are also a number of small ways in which we can help the
+compiler to find the bugs for us.
+
+@subsection Constants in Equality Testing
+
+It's a common error to write @code{=} when @code{==} is meant.
+Sometimes this happens in new code and is simply due to finger
+trouble. Sometimes it is the result of the inadvertent deletion of a
+character. In any case, there is a subset of cases where we can
+persuade the compiler to generate an error message when we make this
+mistake; this is where the equality test is with a constant.
+
+This is an example of a vulnerable piece of code.
+
+@example
+if (x == 2)
+ ...
+@end example
+
+A simple typo converts the above into
+
+@example
+if (x = 2)
+ ...
+@end example
+
+We've introduced a bug; the condition is always true, and the value of
+@code{x} has been changed. However, a simple change to our practice
+would have made us immune to this problem:
+
+@example
+if (2 == x)
+ ...
+@end example
+
+Usually, the Emacs keystroke @kbd{M-t} can be used to swap the operands.
+
+
+@subsection Spelling of ASCII NUL
+
+Strings in C are just sequences of characters terminated by a NUL.
+The ASCII NUL character has the numerical value zero. It is normally
+represented in C code as @samp{\0}. Here is a typical piece of C
+code:
+
+@example
+*p = '\0';
+@end example
+
+Consider what happens if there is an unfortunate typo:
+
+@example
+*p = '0';
+@end example
+
+We have changed the meaning of our program and the compiler cannot
+diagnose this as an error. Our string is no longer terminated. Bad
+things will probably happen. It would be better if the compiler could
+help us diagnose this problem.
+
+In C, the type of @code{'\0'} is in fact int, not char. This provides
+us with a simple way to avoid this error. The constant @code{0} has
+the same value and type as the constant @code{'\0'}. However, it is
+not as vulnerable to typos. For this reason I normally prefer to
+use this code:
+
+@example
+*p = 0;
+@end example
+
+
+@node Factor Out Repeated Code
+@section Factor Out Repeated Code
+
+Repeated code imposes a greater maintenance burden and increases the
+exposure to bugs. For example, if you discover that something you
+want to implement has some similarity with an existing piece of code,
+don't cut and paste it. Instead, factor the code out. The risk of
+cutting and pasting the code, particularly if you do this several
+times, is that you end up with several copies of the same code.
+
+If the original code had a bug, you now have N places where this needs
+to be fixed. It's all to easy to miss some out when trying to fix the
+bug. Equally, it's quite possible that when pasting the code into
+some function, the pasted code was not quite adapted correctly to its
+new environment. To pick a contrived example, perhaps it modifies a
+global variable which it that code shouldn't be touching in its new
+home. Worse, perhaps it makes some unstated assumption about the
+nature of the input arguments which is in fact not true for the
+context of the now duplicated code.
+
+A good example of the use of refactoring in findutils is the
+@code{collect_arg} function in @file{find/parser.c}. A less clear-cut
+but larger example is the factoring out of code which would otherwise
+have been duplicated between @file{find/oldfind.c} and
+@code{find/ftsfind.c}.
+
+The findutils test suite is comprehensive enough that refactoring code
+should not generally be a daunting prospect from a testing point of
+view. Nevertheless there are some areas which are only
+lightly-tested:
+
+@enumerate
+@item Tests on the ages of files
+@item Code which deals with the values returned by operating system calls (for example handling of ENOENT)
+@item Code dealing with OS limits (for example, limits on path length
+or exec arguments)
+@item Code relating to features not all systems have (for example
+Solaris Doors)
+@end enumerate
+
+Please exercise caution when working in those areas.
+
+
+@node Debugging is For Users Too
+@section Debugging is For Users Too
+
+Debug and diagnostic code is often used to verify that a program is
+working in the way its author thinks it should be. But users are
+often uncertain about what a program is doing, too. Exposing them a
+little more diagnostic information can help. Much of the diagnostic
+code in @code{find}, for example, is controlled by the @samp{-D} flag,
+as opposed to C preprocessor directives.
+
+Making diagnostic messages available to users also means that the
+phrasing of the diagnostic messages becomes important, too.
+
+
+@node Don't Trust the File System Contents
+@section Don't Trust the File System Contents
+
+People use @code{find} to search in directories created by other
+people. Sometimes they do this to check to suspicious activity (for
+example to look for new setuid binaries). This means that it would be
+bad if @code{find} were vulnerable to, say, a security problem
+exploitable by constructing a specially-crafted filename. The same
+consideration would apply to @code{locate} and @code{updatedb}.
+
+Henry Spencer said this well in his fifth commandment:
+@quotation
+Thou shalt check the array bounds of all strings (indeed, all arrays),
+for surely where thou typest @samp{foo} someone someday shall type
+@samp{supercalifragilisticexpialidocious}.
+@end quotation
+
+Symbolic links can often be a problem. If @code{find} calls
+@code{lstat} on something and discovers that it is a directory, it's
+normal for @code{find} to recurse into it. Even if the @code{chdir}
+system call is used immediately, there is still a window of
+opportunity between the @code{lstat} and the @code{chdir} in which a
+malicious person could rename the directory and substitute a symbolic
+link to some other directory.
+
+@node The File System Is Being Modified
+@section The File System Is Being Modified
+
+The filesystem gets modified while you are traversing it. For,
+example, it's normal for files to get deleted while @code{find} is
+traversing a directory. Issuing an error message seems helpful when a
+file is deleted from the one directory you are interested in, but if
+@code{find} is searching 15000 directories, such a message becomes
+less helpful.
+
+Bear in mind also that it is possible for the directory @code{find} is
+currently searching could be moved to another point in the filesystem,
+and that the directory in which @code{find} was started could be
+deleted.
+
+Henry Spencer's sixth commandment is also apposite here:
+@quotation
+If a function be advertised to return an error code in the event of
+difficulties, thou shalt check for that code, yea, even though the
+checks triple the size of thy code and produce aches in thy typing
+fingers, for if thou thinkest ``it cannot happen to me'', the gods
+shall surely punish thee for thy arrogance.
+@end quotation
+
+There are a lot of files out there. They come in all dates and
+sizes. There is a condition out there in the real world to exercise
+every bit of the code base. So we try to test that code base before
+someone falls over a bug.
+
+
+@node Tools
+@chapter Tools
+Most of the tools required to build findutils are mentioned in the
+file @file{README-hacking}. We also use some other tools:
+
+@table @asis
+@item System call traces
+Much of the execution time of find is spent waiting for filesystem
+operations. A system call trace (for example, that provided by
+@code{strace}) shows what system calls are being made. Using this
+information we can work to remove unnecessary file system operations.
+
+@item Valgrind
+Valgrind is a tool which dynamically verifies the memory accesses a
+program makes to ensure that they are valid (for example, that the
+behaviour of the program does not in any way depend on the contents of
+uninitialized memory).
+
+@item DejaGnu
+DejaGnu is the test framework used to run the findutils test suite
+(the @code{runtest} program is part of DejaGnu). It would be ideal if
+everybody building @code{findutils} also ran the test suite, but many
+people don't have DejaGnu installed. When changes are made to
+findutils, DejaGnu is invoked a lot. @xref{Testing}, for more
+information.
+@end table
+
+@node Using the GNU Portability Library
+@chapter Using the GNU Portability Library
+The Gnulib library (@url{http://www.gnu.org/software/gnulib/}) makes a
+variety of systems look more like a GNU/Linux system and also applies
+a bunch of automatic bug fixes and workarounds. Some of these also
+apply to GNU/Linux systems too. For example, the Gnulib regex
+implementation is used when we determine that we are building on a
+GNU libc system with a bug in the regex implementation.
+
+
+@section How and Why we Import the Gnulib Code
+Gnulib does not have a release process which results in a source
+tarball you can download. Instead, the code is simply made available
+by GIT, so we import gnulib via the submodule feature. The bootstrap
+script performs the necessary steps.
+
+Findutils does not use all the Gnulib code. The modules we need are
+listed in the file @file{bootstrap.conf}.
+
+The upshot of all this is that we can use the findutils git repository
+to track which version of Gnulib every findutils release uses.
+
+A small number of files are installed by automake and will therefore
+vary according to which version of automake was used to generate a
+release. This includes for example boiler-plate GNU files such as
+@file{ABOUT-NLS}, @file{INSTALL} and @file{COPYING}.
+
+
+@section How We Fix Gnulib Bugs
+Gnulib is used by quite a number of GNU projects, and this means that
+it gets plenty of testing. Therefore there are relatively few bugs in
+the Gnulib code, but it does happen from time to time.
+
+However, since there is no waiting around for a Gnulib source release
+tarball, Gnulib bugs are generally fixed quickly. Here is an outline
+of the way we would contribute a fix to Gnulib (assuming you know it
+is not already fixed in the current Gnulib git tree):
+
+@table @asis
+@item Check you already completed a copyright assignment for Gnulib
+@item Begin with a vanilla git tree
+Download the Findutils source code from git (or use the tree you have
+already)
+@item Run the bootstrap script
+@item Run configure
+@item Build findutils
+Build findutils and run the test suite, which should pass. In our
+example we assume you have just noticed a bug in Gnulib, not that
+recent Gnulib changes broke the findutils regression tests.
+@item Write a test case
+If in fact Gnulib did break the findutils regression tests, you can probably
+skip this step, since you already have a test case demonstrating the problem.
+Otherwise, write a findutils test case for the bug and/or a Gnulib test case.
+@item Fix the Gnulib bug
+Make sure your editor follows symbolic links so that your changes to
+@file{gnulib/...} actually affect the files in the git working
+directory you checked out earlier. Observe that your test now passes.
+@item Prepare a Gnulib patch
+In the gnulib subdirectory, use @code{git format-patch} to prepare the
+patch. Follow the normal usage for checkin comments (take a look at
+the output of @code{git log}). Check that the patch conforms with the
+GNU coding standards, and email it to the Gnulib mailing list.
+@item Wait for the patch to be applied
+Once your bug fix has been applied, you can update your gnulib
+directory from git, and then check in the change to the submodule as
+normal (you can check @code{git help submodule} for details).
+@end table
+
+There is an alternative to the method above; it is possible to store
+local diffs to be patched into gnulib beneath the
+@file{gnulib-local}. Normally however, there is no need for this,
+since gnulib updates are very prompt.
+
+
+@node Documentation
+@chapter Documentation
+
+The findutils git tree includes several different types of
+documentation.
+
+@section git change log
+The git change log for the source tree contains check-in messages
+which describe each check-in. These have a standard format:
+
+@smallexample
+Summary of the change.
+
+(ChangeLog-style detail)
+@end smallexample
+
+Here, the format of the detail part follows the standard GNU ChangeLog
+style, but without whitespace in the left margin and without
+author/date headers. Take a look at the output of @code{git log} to
+see some examples. The README-hacking file also contains an example
+with an explanation.
+
+@section User Documentation
+User-oriented documentation is provided as manual pages and in
+Texinfo. See
+@ref{Introduction,,Introduction,find,The Findutils manual}.
+
+Please make sure both sets of documentation are updated if you make a
+change to the code. The GNU coding standards do not normally call for
+maintaining manual pages on the grounds of effort duplication.
+However, the manual page format is more convenient for quick
+reference, and so it's worth maintaining both types of documentation.
+However, the manual pages are normally rather more terse than the
+Texinfo documentation. The manual pages are suitable for reference
+use, but the Texinfo manual should also include introductory and
+tutorial material.
+
+
+@section Build Guidance
+
+@table @file
+@item ABOUT-NLS
+Describes the Free Translation Project, the translation status of
+various GNU projects, and how to participate by translating an
+application.
+@item AUTHORS
+Lists the authors of findutils.
+@item COPYING
+The copyright license covering findutils; currently, the GNU GPL,
+version 3.
+@item INSTALL
+Generic installation instructions for installing GNU programs.
+@item README
+Information about how to compile findutils in particular
+@item README-alpha
+A README file which is included with testing releases of findutils.
+@item README-hacking
+Describes how to build findutils from the code in git.
+@item THANKS
+Thanks for people who contributed to findutils. Generally, if
+someone's contribution was significant enough to need a copyright
+assignment, their name should go in here.
+@item TODO
+Mainly obsolete. Please add bugs to the Savannah bug tracker instead
+of adding entries to this file.
+@end table
+
+
+@section Release Information
+@table @file
+@item NEWS
+Enumerates the user-visible change in each release. Typical changes
+are fixed bugs, functionality changes and documentation changes.
+Include the date when a release is made.
+@item ChangeLog
+This file enumerates all changes to the findutils source code (with
+the possible exception of @file{.cvsignore} and @code{.gitignore}
+changes). The level of detail used for this file should be sufficient
+to answer the questions ``what changed?'' and ``why was it changed?''.
+The file is generated from the git commit messages during @code{make dist}.
+If a change fixes a bug, always give the bug reference number in the
+@file{NEWS} file and of course also in the checkin message.
+In general, it should be possible to enumerate all
+material changes to a function by searching for its name in
+@file{ChangeLog}. Mention when each release is made.
+@end table
+
+@node Testing
+@chapter Testing
+This chapter will explain the general procedures for adding tests to
+the test suite, and the functions defined in the findutils-specific
+DejaGnu configuration. Where appropriate references will be made to
+the DejaGnu documentation.
+
+@node Bugs
+@chapter Bugs
+
+Bugs are logged in the Savannah bug tracker
+@url{http://savannah.gnu.org/bugs/?group=findutils}. The tracker
+offers several fields but their use is largely obvious. The
+life-cycle of a bug is like this:
+
+
+@table @asis
+@item Open
+Someone, usually a maintainer, a distribution maintainer or a user,
+creates a bug by filling in the form. They fill in field values as
+they see fit. This will generate an email to
+@email{bug-findutils@@gnu.org}.
+
+@item Triage
+The bug hangs around with @samp{Status=None} until someone begins to
+work on it. At that point they set the ``Assigned To'' field and will
+sometimes set the status to @samp{In Progress}, especially if the bug
+will take a while to fix.
+
+@item Non-bugs
+Quite a lot of reports are not actually bugs; for these the usual
+procedure is to explain why the problem is not a bug, set the status
+to @samp{Invalid} and close the bug. Make sure you set the
+@samp{Assigned to} field to yourself before closing the bug.
+
+@item Fixing
+When you commit a bug fix into git (or in the case of a contributed
+patch, commit the change), mark the bug as @samp{Fixed}. Make sure
+you include a new test case where this is relevant. If you can figure
+out which releases are affected, please also set the @samp{Release}
+field to the earliest release which is affected by the bug.
+Indicate which source branch the fix is included in (for example,
+4.2.x or 4.3.x). Don't close the bug yet.
+
+@item Release
+When a release is made which includes the bug fix, make sure the bug
+is listed in the NEWS file. Once the release is made, fill in the
+@samp{Fixed Release} field and close the bug.
+@end table
+
+
+@node Distributions
+@chapter Distributions
+Almost all GNU/Linux distributions include findutils, but only some of
+them have a package maintainer who is a member of the mailing list.
+Distributions don't often feed back patches to the
+@email{bug-findutils@@gnu.org} list, but on the other hand many of
+their patches relate only to standards for file locations and so
+forth, and are therefore distribution specific. On an irregular basis
+I check the current patches being used by one or two distributions,
+but the total number of GNU/Linux distributions is large enough that
+we could not hope to cover them all.
+
+Often, bugs are raised against a distribution's bug tracker instead of
+GNU's. Periodically (about every six months) I take a look at some
+of the more accessible bug trackers to indicate which bugs have been
+fixed upstream.
+
+Many distributions include both findutils and the slocate package,
+which provides a replacement @code{locate}.
+
+
+@node Internationalisation
+@chapter Internationalisation
+Translation is essentially automated from the maintainer's point of
+view. The TP mails the maintainer when a new PO file is available,
+and we just download it and check it in. We copy the @file{.po} files
+into the git repository. For more information, please see
+@url{http://translationproject.org/domain/findutils.html}.
+
+
+@node Security
+@chapter Security
+
+See @ref{Security Considerations, ,Security Considerations,find,The
+Findutils manual}, for a full description of the findutils approach to
+security considerations and discussion of particular tools.
+
+If someone reports a security bug publicly, we should fix this as
+rapidly as possible. If necessary, this can mean issuing a fixed
+release containing just the one bug fix. We try to avoid issuing
+releases which include both significant security fixes and functional
+changes.
+
+Where someone reports a security problem privately, we generally try
+to construct and test a patch without pushing the intermediate code to
+the public repository.
+
+Once everything has been tested, this allows us to make a release and
+push the patch. The advantage of doing things this way is that we
+avoid situations where people watching for git commits can figure out
+and exploit a security problem before a fixed release is available.
+
+It's important that security problems be fixed promptly, but don't
+rush so much that things go wrong. Make sure the new release really
+fixes the problem. It's usually best not to include functional
+changes in your security-fix release.
+
+If the security problem is serious, send an alert to
+@email{vendor-sec@@lst.de}. The members of the list include most
+GNU/Linux distributions. The point of doing this is to allow them to
+prepare to release your security fix to their customers, once the fix
+becomes available. Here is an example alert:-
+
+@smallexample
+GNU findutils heap buffer overrun (potential privilege escalation)
+
+
+
+I. BACKGROUND
+=============
+
+GNU findutils is a set of programs which search for files on Unix-like
+systems. It is maintained by the GNU Project of the Free Software
+Foundation. For more information, see
+@url{http://www.gnu.org/software/findutils}.
+
+
+II. DESCRIPTION
+===============
+
+When GNU locate reads filenames from an old-format locate database,
+they are read into a fixed-length buffer allocated on the heap.
+Filenames longer than the 1026-byte buffer can cause a buffer overrun.
+The overrunning data can be chosen by any person able to control the
+names of filenames created on the local system. This will normally
+include all local users, but in many cases also remote users (for
+example in the case of FTP servers allowing uploads).
+
+III. ANALYSIS
+=============
+
+Findutils supports three different formats of locate database, its
+native format "LOCATE02", the slocate variant of LOCATE02, and a
+traditional ("old") format that locate uses on other Unix systems.
+
+When locate reads filenames from a LOCATE02 database (the default
+format), the buffer into which data is read is automatically extended
+to accommodate the length of the filenames.
+
+This automatic buffer extension does not happen for old-format
+databases. Instead a 1026-byte buffer is used. When a longer
+pathname appears in the locate database, the end of this buffer is
+overrun. The buffer is allocated on the heap (not the stack).
+
+If the locate database is in the default LOCATE02 format, the locate
+program does perform automatic buffer extension, and the program is
+not vulnerable to this problem. The software used to build the
+old-format locate database is not itself vulnerable to the same
+attack.
+
+Most installations of GNU findutils do not use the old database
+format, and so will not be vulnerable.
+
+
+IV. DETECTION
+=============
+
+Software
+--------
+All existing releases of findutils are affected.
+
+
+Installations
+-------------
+
+To discover the longest path name on a given system, you can use the
+following command (requires GNU findutils and GNU coreutils):
+
+@verbatim
+find / -print0 | tr -c '\0' 'x' | tr '\0' '\n' | wc -L
+@end verbatim
+
+V. EXAMPLE
+==========
+
+This section includes a shell script which determines which of a list
+of locate binaries is vulnerable to the problem. The shell script has
+been tested only on glibc based systems having a mktemp binary.
+
+NOTE: This script deliberately overruns the buffer in order to
+determine if a binary is affected. Therefore running it on your
+system may have undesirable effects. We recommend that you read the
+script before running it.
+
+@verbatim
+#! /bin/sh
+set +m
+if vanilla_db="$(mktemp nicedb.XXXXXX)" ; then
+ if updatedb --prunepaths="" --old-format --localpaths="/tmp" \
+ --output="$@{vanilla_db@}" ; then
+ true
+ else
+ rm -f "$@{vanilla_db@}"
+ vanilla_db=""
+ echo "Failed to create old-format locate database; skipping the sanity checks" >&2
+ fi
+fi
+
+make_overrun_db() @{
+ # Start with a valid database
+ cat "$@{vanilla_db@}"
+ # Make the final entry really long
+ dd if=/dev/zero bs=1 count=1500 2>/dev/null | tr '\000' 'x'
+@}
+
+
+
+ulimit -c 0
+
+usage() @{ echo "usage: $0 binary [binary...]" >&2; exit $1; @}
+[ $# -eq 0 ] && usage 1
+
+bad=""
+good=""
+ugly=""
+if dbfile="$(mktemp nasty.XXXXXX)"
+then
+ make_overrun_db > "$dbfile"
+ for locate ; do
+ ver="$locate = $("$locate" --version | head -1)"
+ if [ -z "$vanilla_db" ] || "$locate" -d "$vanilla_db" "" >/dev/null ; then
+ "$locate" -d "$dbfile" "" >/dev/null
+ if [ $? -gt 128 ] ; then
+ bad="$bad
+vulnerable: $ver"
+ else
+ good="$good
+good: $ver"
+ fi
+ else
+ # the regular locate failed
+ ugly="$ugly
+buggy, may or may not be vulnerable: $ver"
+ fi
+ done
+ rm -f "$@{dbfile@}" "$@{vanilla_db@}"
+ # good: unaffected. bad: affected (vulnerable).
+ # ugly: doesn't even work for a normal old-format database.
+ echo "$good"
+ echo "$bad"
+ echo "$ugly"
+else
+ exit 1
+fi
+@end verbatim
+
+
+
+
+VI. VENDOR RESPONSE
+===================
+
+The GNU project discovered the problem while 'locate' was being worked
+on; this is the first public announcement of the problem.
+
+The GNU findutils mantainer has issued a patch as p[art of this
+announcement. The patch appears below.
+
+A source release of findutils-4.2.31 will be issued on 2007-05-30.
+That release will of course include the patch. The patch will be
+committed to the public CVS repository at the same time. Public
+announcements of the release, including a description of the bug, will
+be made at the same time as the release.
+
+A release of findutils-4.3.x will follow and will also include the
+patch.
+
+
+VII. PATCH
+==========
+
+This patch should apply to findutils-4.2.23 and later.
+Findutils-4.2.23 was released almost two years ago.
+@verbatim
+Index: locate/locate.c
+===================================================================
+RCS file: /cvsroot/findutils/findutils/locate/locate.c,v
+retrieving revision 1.58.2.2
+diff -u -p -r1.58.2.2 locate.c
+--- locate/locate.c 22 Apr 2007 16:57:42 -0000 1.58.2.2
++++ locate/locate.c 28 May 2007 10:18:16 -0000
+@@@@ -124,9 +124,9 @@@@ extern int errno;
+
+ #include "locatedb.h"
+ #include <getline.h>
+-#include "../gnulib/lib/xalloc.h"
+-#include "../gnulib/lib/error.h"
+-#include "../gnulib/lib/human.h"
++#include "xalloc.h"
++#include "error.h"
++#include "human.h"
+ #include "dirname.h"
+ #include "closeout.h"
+ #include "nextelem.h"
+@@@@ -468,10 +468,36 @@@@ visit_justprint_unquoted(struct process_
+ return VISIT_CONTINUE;
+ @}
+
++static void
++toolong (struct process_data *procdata)
++@{
++ error (EXIT_FAILURE, 0,
++ _("locate database %s contains a "
++ "filename longer than locate can handle"),
++ procdata->dbfile);
++@}
++
++static void
++extend (struct process_data *procdata, size_t siz1, size_t siz2)
++@{
++ /* Figure out if the addition operation is safe before performing it. */
++ if (SIZE_MAX - siz1 < siz2)
++ @{
++ toolong (procdata);
++ @}
++ else if (procdata->pathsize < (siz1+siz2))
++ @{
++ procdata->pathsize = siz1+siz2;
++ procdata->original_filename = x2nrealloc (procdata->original_filename,
++ &procdata->pathsize,
++ 1);
++ @}
++@}
++
+ static int
+ visit_old_format(struct process_data *procdata, void *context)
+ @{
+- register char *s;
++ register size_t i;
+ (void) context;
+
+ /* Get the offset in the path where this path info starts. */
+@@@@ -479,20 +505,35 @@@@ visit_old_format(struct process_data *pr
+ procdata->count += getw (procdata->fp) - LOCATEDB_OLD_OFFSET;
+ else
+ procdata->count += procdata->c - LOCATEDB_OLD_OFFSET;
++ assert(procdata->count > 0);
+
+- /* Overlay the old path with the remainder of the new. */
+- for (s = procdata->original_filename + procdata->count;
++ /* Overlay the old path with the remainder of the new. Read
++ * more data until we get to the next filename.
++ */
++ for (i=procdata->count;
+ (procdata->c = getc (procdata->fp)) > LOCATEDB_OLD_ESCAPE;)
+- if (procdata->c < 0200)
+- *s++ = procdata->c; /* An ordinary character. */
+- else
+- @{
+- /* Bigram markers have the high bit set. */
+- procdata->c &= 0177;
+- *s++ = procdata->bigram1[procdata->c];
+- *s++ = procdata->bigram2[procdata->c];
+- @}
+- *s-- = '\0';
++ @{
++ if (procdata->c < 0200)
++ @{
++ /* An ordinary character. */
++ extend (procdata, i, 1u);
++ procdata->original_filename[i++] = procdata->c;
++ @}
++ else
++ @{
++ /* Bigram markers have the high bit set. */
++ extend (procdata, i, 2u);
++ procdata->c &= 0177;
++ procdata->original_filename[i++] = procdata->bigram1[procdata->c];
++ procdata->original_filename[i++] = procdata->bigram2[procdata->c];
++ @}
++ @}
++
++ /* Consider the case where we executed the loop body zero times; we
++ * still need space for the terminating null byte.
++ */
++ extend (procdata, i, 1u);
++ procdata->original_filename[i] = 0;
+
+ procdata->munged_filename = procdata->original_filename;
+@end verbatim
+
+
+VIII. THANKS
+============
+
+Thanks to Rob Holland <rob@@inversepath.com> and Tavis Ormandy.
+
+
+VIII. CVE INFORMATION
+=====================
+
+No CVE candidate number has yet been assigned for this vulnerability.
+If someone provides one, I will include it in the public announcement
+and change logs.
+@end smallexample
+
+The original announcement above was sent out with a cleartext PGP
+signature, of course, but that has been omitted from the example.
+
+Once a fixed release is available, announce the new release using the
+normal channels. Any CVE number assigned for the problem should be
+included in the @file{ChangeLog} and @file{NEWS} entries. See
+@url{http://cve.mitre.org/} for an explanation of CVE numbers.
+
+
+
+@node Making Releases
+@chapter Making Releases
+This section will explain how to make a findutils release. For the
+time being here is a terse description of the main steps:
+
+@enumerate
+@item Commit changes; make sure your working directory has no
+uncommitted changes.
+@item Test; make sure that all changes you have made have tests, and
+that the tests pass. Verify this with @code{make distcheck}.
+@item Bugs; make sure all Savannah bug entries fixed in this release
+are fixed.
+@item NEWS; make sure that the NEWS and configure.in file are updated
+with the new release number (and checked in).
+@item Build the release tarball; do this with @code{make distcheck}.
+Copy the tarball somewhere safe.
+@item Tag the release; findutils releases are tagged like this for
+example: v4.5.5. Previously a different format was in use:
+FINDUTILS_4_3_8-1. You can create a tag with the a command like this:
+@code{git tag -s -m "Findutils release v4.5.7" v4.5.7}.
+@item Prepare the upload and upload it.
+@xref{Automated FTP Uploads, ,Automated FTP
+Uploads, maintain, Information for Maintainers of GNU Software},
+for detailed upload instructions.
+@item Make a release announcement; include an extract from the NEWS
+file which explains what's changed. Announcements for test releases
+should just go to @email{bug-findutils@@gnu.org}. Announcements for
+stable releases should go to @email{info-gnu@@gnu.org} as well.
+@item Bump the release numbers in git; edit the @file{configure.in}
+and @file{NEWS} files to advance the release numbers. For example,
+if you have just released @samp{4.6.2}, bump the release number to
+@samp{4.6.3-git}. The point of the @samp{-git} suffix here is that a
+findutils binary built from git will bear a release number indicating
+it's not built from the ``official'' source release.
+@item Close bugs; any bugs recorded on Savannah which were fixed in this
+release should now be marked as closed. Update the @samp{Fixed
+Release} field of these bugs appropriately and make sure the
+@samp{Assigned to} field is populated.
+@end enumerate
+
+
+@node GNU Free Documentation License
+@appendix GNU Free Documentation License
+@include fdl.texi
+
+@bye
+
+@comment texi related words used by Emacs' spell checker ispell.el
+
+@comment LocalWords: texinfo setfilename settitle setchapternewpage
+@comment LocalWords: iftex finalout ifinfo DIR titlepage vskip pt
+@comment LocalWords: filll dir samp dfn noindent xref pxref
+@comment LocalWords: var deffn texi deffnx itemx emph asis
+@comment LocalWords: findex smallexample subsubsection cindex
+@comment LocalWords: dircategory direntry itemize
+
+@comment other words used by Emacs' spell checker ispell.el
+@comment LocalWords: README fred updatedb xargs Plett Rendell akefile
+@comment LocalWords: args grep Filesystems fo foo fOo wildcards iname
+@comment LocalWords: ipath regex iregex expr fubar regexps
+@comment LocalWords: metacharacters macs sr sc inode lname ilname
+@comment LocalWords: sysdep noleaf ls inum xdev filesystems usr atime
+@comment LocalWords: ctime mtime amin cmin mmin al daystart Sladkey rm
+@comment LocalWords: anewer cnewer bckw rf xtype uname gname uid gid
+@comment LocalWords: nouser nogroup chown chgrp perm ch maxdepth
+@comment LocalWords: mindepth cpio src CD AFS statted stat fstype ufs
+@comment LocalWords: nfs tmp mfs printf fprint dils rw djm Nov lwall
+@comment LocalWords: POSIXLY fls fprintf strftime locale's EDT GMT AP
+@comment LocalWords: EST diff perl backquotes sprintf Falstad Oct cron
+@comment LocalWords: eg vmunix mkdir afs allexec allwrite ARG bigram
+@comment LocalWords: bigrams cd chmod comp crc CVS dbfile eof
+@comment LocalWords: fileserver filesystem fn frcode Ghazi Hnewc iXX
+@comment LocalWords: joeuser Kaveh localpaths localuser LOGNAME
+@comment LocalWords: Meyering mv netpaths netuser nonblank nonblanks
+@comment LocalWords: ois ok Pinard printindex proc procs prunefs
+@comment LocalWords: prunepaths pwd RFS rmadillo rmdir rsh sbins str
+@comment LocalWords: su Timar ubins ug unstripped vf VM Weitzel
+@comment LocalWords: wildcard zlogout basename execdir wholename iwholename
+@comment LocalWords: timestamp timestamps Solaris FreeBSD OpenBSD POSIX
diff --git a/doc/find.info b/doc/find.info
new file mode 100644
index 0000000..4741b71
--- /dev/null
+++ b/doc/find.info
@@ -0,0 +1,186 @@
+This is find.info, produced by makeinfo version 5.2 from find.texi.
+
+This file documents the GNU utilities for finding files that match
+certain criteria and performing various operations on them.
+
+ Copyright (C) 1994, 1996, 1998, 2000, 2001, 2003-2015 Free Software
+Foundation, Inc.
+
+ Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.3 or
+any later version published by the Free Software Foundation; with no
+Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A
+copy of the license is included in the section entitled "GNU Free
+Documentation License".
+INFO-DIR-SECTION Basics
+START-INFO-DIR-ENTRY
+* Finding files: (find). Operating on files matching certain criteria.
+END-INFO-DIR-ENTRY
+
+INFO-DIR-SECTION Individual utilities
+START-INFO-DIR-ENTRY
+* find: (find)Invoking find. Finding and acting on files.
+* locate: (find)Invoking locate. Finding files in a database.
+* updatedb: (find)Invoking updatedb. Building the locate database.
+* xargs: (find)Invoking xargs. Operating on many files.
+END-INFO-DIR-ENTRY
+
+
+Indirect:
+find.info-1: 1185
+find.info-2: 302079
+
+Tag Table:
+(Indirect)
+Node: Top1185
+Node: Introduction3046
+Node: Scope5969
+Node: Overview7902
+Node: find Expressions9772
+Node: Finding Files11599
+Node: Name12064
+Node: Base Name Patterns12692
+Ref: Base Name Patterns-Footnote-114021
+Node: Full Name Patterns14233
+Node: Fast Full Name Search18236
+Node: Shell Pattern Matching21285
+Node: Links23374
+Node: Symbolic Links23809
+Node: Hard Links28865
+Node: Time31420
+Node: Age Ranges32395
+Node: Comparing Timestamps34079
+Node: Size36940
+Node: Type38785
+Node: Owner40455
+Node: Mode Bits41274
+Node: Contents46631
+Node: Directories47802
+Node: Filesystems53077
+Node: Combining Primaries With Operators54428
+Node: Actions56046
+Node: Print File Name56606
+Node: Print File Information57624
+Node: Escapes61570
+Node: Format Directives62311
+Node: Name Directives63557
+Node: Ownership Directives64539
+Node: Size Directives65543
+Node: Location Directives66912
+Node: Time Directives68023
+Node: Other Directives68921
+Node: Reserved and Unknown Directives69196
+Node: Time Formats70064
+Node: Time Components70525
+Node: Date Components71484
+Node: Combined Time Formats72296
+Node: Formatting Flags73175
+Node: Run Commands73785
+Node: Single File74143
+Node: Multiple Files76810
+Node: Unsafe File Name Handling81562
+Node: Safe File Name Handling83275
+Node: Unusual Characters in File Names84851
+Node: Limiting Command Size88013
+Node: Controlling Parallelism90449
+Node: Interspersing File Names96301
+Node: Querying98756
+Node: Delete Files101013
+Node: Adding Tests101660
+Node: Databases104299
+Node: Database Locations105016
+Node: Database Formats106463
+Node: LOCATE02 Database Format107571
+Node: Sample LOCATE02 Database109263
+Node: slocate Database Format109947
+Node: Old Database Format110955
+Node: Newline Handling114142
+Node: File Permissions115587
+Node: Mode Structure116165
+Node: Symbolic Modes119300
+Node: Setting Permissions120397
+Node: Copying Permissions122938
+Node: Changing Special Permissions123751
+Node: Conditional Executability125295
+Node: Multiple Changes125827
+Node: Umask and Protection127484
+Node: Numeric Modes128582
+Node: Date input formats130273
+Node: General date syntax132684
+Node: Calendar date items135662
+Node: Time of day items137660
+Node: Time zone items139857
+Node: Combined date and time of day items141109
+Node: Day of week items141965
+Node: Relative items in date strings142974
+Node: Pure numbers in date strings145777
+Node: Seconds since the Epoch146759
+Node: Specifying time zone rules148382
+Node: Authors of parse_datetime150756
+Ref: Authors of get_date150936
+Node: Configuration151899
+Node: Leaf Optimisation152680
+Node: d_type Optimisation153792
+Node: fts154094
+Node: Reference154698
+Node: Invoking find155043
+Node: Filesystem Traversal Options156525
+Node: Warning Messages157616
+Node: Optimisation Options159674
+Node: Debug Options161619
+Node: Find Expressions162669
+Node: Invoking locate163035
+Node: Invoking updatedb169222
+Node: Invoking xargs172884
+Node: xargs options173604
+Node: Invoking the shell from xargs178852
+Node: Regular Expressions182652
+Node: findutils-default regular expression syntax184131
+Node: awk regular expression syntax186632
+Node: egrep regular expression syntax188499
+Node: emacs regular expression syntax190802
+Node: gnu-awk regular expression syntax193326
+Node: grep regular expression syntax195789
+Node: posix-awk regular expression syntax198440
+Node: posix-basic regular expression syntax200738
+Node: posix-egrep regular expression syntax201039
+Node: posix-extended regular expression syntax201348
+Node: Environment Variables203819
+Node: Common Tasks206787
+Node: Viewing And Editing207212
+Node: Archiving208931
+Node: Cleaning Up210564
+Node: Strange File Names213452
+Node: Fixing Permissions215101
+Node: Classifying Files215665
+Node: Worked Examples216383
+Node: Deleting Files217088
+Node: Copying A Subset of Files230123
+Node: Updating A Timestamp File232142
+Node: Finding the Shallowest Instance238129
+Node: Security Considerations240065
+Node: Levels of Risk241632
+Ref: Levels of Risk-Footnote-1244430
+Node: Security Considerations for find244609
+Ref: Security Considerations for find-Footnote-1246933
+Node: Problems with -exec and filenames247006
+Node: Changing the Current Working Directory248640
+Node: O_NOFOLLOW250411
+Ref: O_NOFOLLOW-Footnote-1252465
+Node: Systems without O_NOFOLLOW252567
+Ref: Systems without O_NOFOLLOW-Footnote-1254720
+Node: Race Conditions with -exec254782
+Node: Race Conditions with -print and -print0257699
+Node: Security Considerations for xargs258628
+Node: Security Considerations for locate261130
+Node: Security Summary263511
+Node: Further Reading on Security264306
+Node: Error Messages265485
+Node: Error Messages From find266514
+Node: Error Messages From xargs271637
+Node: Error Messages From locate274101
+Node: Error Messages From updatedb275333
+Node: GNU Free Documentation License275740
+Node: Primary Index302079
+
+End Tag Table
diff --git a/doc/find.info-1 b/doc/find.info-1
new file mode 100644
index 0000000..fff2111
--- /dev/null
+++ b/doc/find.info-1
@@ -0,0 +1,7261 @@
+This is find.info, produced by makeinfo version 5.2 from find.texi.
+
+This file documents the GNU utilities for finding files that match
+certain criteria and performing various operations on them.
+
+ Copyright (C) 1994, 1996, 1998, 2000, 2001, 2003-2015 Free Software
+Foundation, Inc.
+
+ Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.3 or
+any later version published by the Free Software Foundation; with no
+Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A
+copy of the license is included in the section entitled "GNU Free
+Documentation License".
+INFO-DIR-SECTION Basics
+START-INFO-DIR-ENTRY
+* Finding files: (find). Operating on files matching certain criteria.
+END-INFO-DIR-ENTRY
+
+INFO-DIR-SECTION Individual utilities
+START-INFO-DIR-ENTRY
+* find: (find)Invoking find. Finding and acting on files.
+* locate: (find)Invoking locate. Finding files in a database.
+* updatedb: (find)Invoking updatedb. Building the locate database.
+* xargs: (find)Invoking xargs. Operating on many files.
+END-INFO-DIR-ENTRY
+
+
+File: find.info, Node: Top, Next: Introduction, Up: (dir)
+
+GNU Findutils
+*************
+
+This file documents the GNU utilities for finding files that match
+certain criteria and performing various operations on them.
+
+ Copyright (C) 1994, 1996, 1998, 2000, 2001, 2003-2015 Free Software
+Foundation, Inc.
+
+ Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.3 or
+any later version published by the Free Software Foundation; with no
+Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A
+copy of the license is included in the section entitled "GNU Free
+Documentation License".
+
+ This file documents the GNU utilities for finding files that match
+certain criteria and performing various actions on them.
+
+ This is edition 4.6.0, for 'find' version 4.6.0.
+
+* Menu:
+
+* Introduction:: Summary of the tasks this manual describes.
+* Finding Files:: Finding files that match certain criteria.
+* Actions:: Doing things to files you have found.
+* Databases:: Maintaining file name databases.
+* File Permissions:: How to control access to files.
+* Date input formats:: Specifying literal times.
+* Configuration:: Options you can select at compile time.
+* Reference:: Summary of how to invoke the programs.
+* Common Tasks:: Solutions to common real-world problems.
+* Worked Examples:: Examples demonstrating more complex points.
+* Security Considerations:: Security issues relating to findutils.
+* Error Messages:: Explanations of some messages you might see.
+* GNU Free Documentation License:: Copying and sharing this manual.
+* Primary Index:: The components of 'find' expressions.
+
+
+File: find.info, Node: Introduction, Next: Finding Files, Prev: Top, Up: Top
+
+1 Introduction
+**************
+
+This manual shows how to find files that meet criteria you specify, and
+how to perform various actions on the files that you find. The
+principal programs that you use to perform these tasks are 'find',
+'locate', and 'xargs'. Some of the examples in this manual use
+capabilities specific to the GNU versions of those programs.
+
+ GNU 'find' was originally written by Eric Decker, with enhancements
+by David MacKenzie, Jay Plett, and Tim Wood. GNU 'xargs' was originally
+written by Mike Rendell, with enhancements by David MacKenzie. GNU
+'locate' and its associated utilities were originally written by James
+Woods, with enhancements by David MacKenzie. The idea for 'find
+-print0' and 'xargs -0' came from Dan Bernstein. The current maintainer
+of GNU findutils (and this manual) is James Youngman. Many other people
+have contributed bug fixes, small improvements, and helpful suggestions.
+Thanks!
+
+ To report a bug in GNU findutils, please use the form on the Savannah
+web site at 'http://savannah.gnu.org/bugs/?group=findutils'. Reporting
+bugs this way means that you will then be able to track progress in
+fixing the problem.
+
+ If you don't have web access, you can also just send mail to the
+mailing list. The mailing list <bug-findutils@gnu.org> carries
+discussion of bugs in findutils, questions and answers about the
+software and discussion of the development of the programs. To join the
+list, send email to <bug-findutils-request@gnu.org>.
+
+ Please read any relevant sections of this manual before asking for
+help on the mailing list. You may also find it helpful to read the
+NON-BUGS section of the 'find' manual page.
+
+ If you ask for help on the mailing list, people will be able to help
+you much more effectively if you include the following things:
+
+ * The version of the software you are running. You can find this out
+ by running 'locate --version'.
+ * What you were trying to do
+ * The _exact_ command line you used
+ * The _exact_ output you got (if this is very long, try to find a
+ smaller example which exhibits the same problem)
+ * The output you expected to get
+
+ It may also be the case that the bug you are describing has already
+been fixed, if it is a bug. Please check the most recent findutils
+releases at <ftp://ftp.gnu.org/gnu/findutils> and, if possible, the
+development branch at <ftp://alpha.gnu.org/gnu/findutils>. If you take
+the time to check that your bug still exists in current releases, this
+will greatly help people who want to help you solve your problem.
+Please also be aware that if you obtained findutils as part of the
+GNU/Linux 'distribution', the distributions often lag seriously behind
+findutils releases, even the stable release. Please check the GNU FTP
+site.
+
+* Menu:
+
+* Scope::
+* Overview::
+* find Expressions::
+
+
+File: find.info, Node: Scope, Next: Overview, Up: Introduction
+
+1.1 Scope
+=========
+
+For brevity, the word "file" in this manual means a regular file, a
+directory, a symbolic link, or any other kind of node that has a
+directory entry. A directory entry is also called a "file name". A
+file name may contain some, all, or none of the directories in a path
+that leads to the file. These are all examples of what this manual
+calls "file names":
+
+ parser.c
+ README
+ ./budget/may-94.sc
+ fred/.cshrc
+ /usr/local/include/termcap.h
+
+ A "directory tree" is a directory and the files it contains, all of
+its subdirectories and the files they contain, etc. It can also be a
+single non-directory file.
+
+ These programs enable you to find the files in one or more directory
+trees that:
+
+ * have names that contain certain text or match a certain pattern;
+ * are links to certain files;
+ * were last used during a certain period of time;
+ * are within a certain size range;
+ * are of a certain type (regular file, directory, symbolic link,
+ etc.);
+ * are owned by a certain user or group;
+ * have certain access permissions or special mode bits;
+ * contain text that matches a certain pattern;
+ * are within a certain depth in the directory tree;
+ * or some combination of the above.
+
+ Once you have found the files you're looking for (or files that are
+potentially the ones you're looking for), you can do more to them than
+simply list their names. You can get any combination of the files'
+attributes, or process the files in many ways, either individually or in
+groups of various sizes. Actions that you might want to perform on the
+files you have found include, but are not limited to:
+
+ * view or edit
+ * store in an archive
+ * remove or rename
+ * change access permissions
+ * classify into groups
+
+ This manual describes how to perform each of those tasks, and more.
+
+
+File: find.info, Node: Overview, Next: find Expressions, Prev: Scope, Up: Introduction
+
+1.2 Overview
+============
+
+The principal programs used for making lists of files that match given
+criteria and running commands on them are 'find', 'locate', and 'xargs'.
+An additional command, 'updatedb', is used by system administrators to
+create databases for 'locate' to use.
+
+ 'find' searches for files in a directory hierarchy and prints
+information about the files it found. It is run like this:
+
+ find [FILE...] [EXPRESSION]
+
+Here is a typical use of 'find'. This example prints the names of all
+files in the directory tree rooted in '/usr/src' whose name ends with
+'.c' and that are larger than 100 Kilobytes.
+ find /usr/src -name '*.c' -size +100k -print
+
+ Notice that the wildcard must be enclosed in quotes in order to
+protect it from expansion by the shell.
+
+ 'locate' searches special file name databases for file names that
+match patterns. The system administrator runs the 'updatedb' program to
+create the databases. 'locate' is run like this:
+
+ locate [OPTION...] PATTERN...
+
+This example prints the names of all files in the default file name
+database whose name ends with 'Makefile' or 'makefile'. Which file
+names are stored in the database depends on how the system administrator
+ran 'updatedb'.
+ locate '*[Mm]akefile'
+
+ The name 'xargs', pronounced EX-args, means "combine arguments."
+'xargs' builds and executes command lines by gathering together
+arguments it reads on the standard input. Most often, these arguments
+are lists of file names generated by 'find'. 'xargs' is run like this:
+
+ xargs [OPTION...] [COMMAND [INITIAL-ARGUMENTS]]
+
+The following command searches the files listed in the file 'file-list'
+and prints all of the lines in them that contain the word 'typedef'.
+ xargs grep typedef < file-list
+
+
+File: find.info, Node: find Expressions, Prev: Overview, Up: Introduction
+
+1.3 'find' Expressions
+======================
+
+The expression that 'find' uses to select files consists of one or more
+"primaries", each of which is a separate command line argument to
+'find'. 'find' evaluates the expression each time it processes a file.
+An expression can contain any of the following types of primaries:
+
+"options"
+ affect overall operation rather than the processing of a specific
+ file;
+"tests"
+ return a true or false value, depending on the file's attributes;
+"actions"
+ have side effects and return a true or false value; and
+"operators"
+ connect the other arguments and affect when and whether they are
+ evaluated.
+
+ You can omit the operator between two primaries; it defaults to
+'-and'. *Note Combining Primaries With Operators::, for ways to connect
+primaries into more complex expressions. If the expression contains no
+actions other than '-prune', '-print' is performed on all files for
+which the entire expression is true (*note Print File Name::).
+
+ Options take effect immediately, rather than being evaluated for each
+file when their place in the expression is reached. Therefore, for
+clarity, it is best to place them at the beginning of the expression.
+There are two exceptions to this; '-daystart' and '-follow' have
+different effects depending on where in the command line they appear.
+This can be confusing, so it's best to keep them at the beginning, too.
+
+ Many of the primaries take arguments, which immediately follow them
+in the next command line argument to 'find'. Some arguments are file
+names, patterns, or other strings; others are numbers. Numeric
+arguments can be specified as
+
+'+N'
+ for greater than N,
+'-N'
+ for less than N,
+'N'
+ for exactly N.
+
+
+File: find.info, Node: Finding Files, Next: Actions, Prev: Introduction, Up: Top
+
+2 Finding Files
+***************
+
+By default, 'find' prints to the standard output the names of the files
+that match the given criteria. *Note Actions::, for how to get more
+information about the matching files.
+
+* Menu:
+
+* Name::
+* Links::
+* Time::
+* Size::
+* Type::
+* Owner::
+* Mode Bits::
+* Contents::
+* Directories::
+* Filesystems::
+* Combining Primaries With Operators::
+
+
+File: find.info, Node: Name, Next: Links, Up: Finding Files
+
+2.1 Name
+========
+
+Here are ways to search for files whose name matches a certain pattern.
+*Note Shell Pattern Matching::, for a description of the PATTERN
+arguments to these tests.
+
+ Each of these tests has a case-sensitive version and a
+case-insensitive version, whose name begins with 'i'. In a
+case-insensitive comparison, the patterns 'fo*' and 'F??' match the file
+names 'Foo', 'FOO', 'foo', 'fOo', etc.
+
+* Menu:
+
+* Base Name Patterns::
+* Full Name Patterns::
+* Fast Full Name Search::
+* Shell Pattern Matching:: Wildcards used by these programs.
+
+
+File: find.info, Node: Base Name Patterns, Next: Full Name Patterns, Up: Name
+
+2.1.1 Base Name Patterns
+------------------------
+
+ -- Test: -name pattern
+ -- Test: -iname pattern
+ True if the base of the file name (the path with the leading
+ directories removed) matches shell pattern PATTERN. For '-iname',
+ the match is case-insensitive.(1) To ignore a whole directory
+ tree, use '-prune' (*note Directories::). As an example, to find
+ Texinfo source files in '/usr/local/doc':
+
+ find /usr/local/doc -name '*.texi'
+
+ Notice that the wildcard must be enclosed in quotes in order to
+ protect it from expansion by the shell.
+
+ As of findutils version 4.2.2, patterns for '-name' and '-iname'
+ will match a file name with a leading '.'. For example the command
+ 'find /tmp -name \*bar' will match the file '/tmp/.foobar'. Braces
+ within the pattern ('{}') are not considered to be special (that
+ is, 'find . -name 'foo{1,2}'' matches a file named 'foo{1,2}', not
+ the files 'foo1' and 'foo2'.
+
+ Because the leading directories are removed, the file names
+ considered for a match with '-name' will never include a slash, so
+ '-name a/b' will never match anything (you probably need to use
+ '-path' instead).
+
+ ---------- Footnotes ----------
+
+ (1) Because we need to perform case-insensitive matching, the GNU
+fnmatch implementation is always used; if the C library includes the GNU
+implementation, we use that and otherwise we use the one from gnulib
+
+
+File: find.info, Node: Full Name Patterns, Next: Fast Full Name Search, Prev: Base Name Patterns, Up: Name
+
+2.1.2 Full Name Patterns
+------------------------
+
+ -- Test: -path pattern
+ -- Test: -wholename pattern
+ True if the entire file name, starting with the command line
+ argument under which the file was found, matches shell pattern
+ PATTERN. To ignore a whole directory tree, use '-prune' rather
+ than checking every file in the tree (*note Directories::). The
+ "entire file name" as used by 'find' starts with the starting-point
+ specified on the command line, and is not converted to an absolute
+ pathname, so for example 'cd /; find tmp -wholename /tmp' will
+ never match anything.
+
+ Find compares the '-path' argument with the concatenation of a
+ directory name and the base name of the file it's considering.
+ Since the concatenation will never end with a slash, '-path'
+ arguments ending in '/' will match nothing (except perhaps a start
+ point specified on the command line).
+
+ The name '-wholename' is GNU-specific, but '-path' is more
+ portable; it is supported by HP-UX 'find' and is part of the POSIX
+ 2008 standard.
+
+ -- Test: -ipath pattern
+ -- Test: -iwholename pattern
+ These tests are like '-wholename' and '-path', but the match is
+ case-insensitive.
+
+ In the context of the tests '-path', '-wholename', '-ipath' and
+'-wholename', a "full path" is the name of all the directories traversed
+from 'find''s start point to the file being tested, followed by the base
+name of the file itself. These paths are often not absolute paths; for
+example
+
+ $ cd /tmp
+ $ mkdir -p foo/bar/baz
+ $ find foo -path foo/bar -print
+ foo/bar
+ $ find foo -path /tmp/foo/bar -print
+ $ find /tmp/foo -path /tmp/foo/bar -print
+ /tmp/foo/bar
+
+ Notice that the second 'find' command prints nothing, even though
+'/tmp/foo/bar' exists and was examined by 'find'.
+
+ Unlike file name expansion on the command line, a '*' in the pattern
+will match both '/' and leading dots in file names:
+
+ $ find . -path '*f'
+ ./quux/bar/baz/f
+ $ find . -path '*/*config'
+ ./quux/bar/baz/.config
+
+ -- Test: -regex expr
+ -- Test: -iregex expr
+ True if the entire file name matches regular expression EXPR. This
+ is a match on the whole path, not a search. For example, to match
+ a file named './fubar3', you can use the regular expression
+ '.*bar.' or '.*b.*3', but not 'f.*r3'. *Note Syntax of Regular
+ Expressions: (emacs)Regexps, for a description of the syntax of
+ regular expressions. For '-iregex', the match is case-insensitive.
+
+ As for '-path', the candidate file name never ends with a slash, so
+ regular expressions which only match something that ends in slash
+ will always fail.
+
+ There are several varieties of regular expressions; by default this
+ test uses POSIX basic regular expressions, but this can be changed
+ with the option '-regextype'.
+
+ -- Option: -regextype name
+ This option controls the variety of regular expression syntax
+ understood by the '-regex' and '-iregex' tests. This option is
+ positional; that is, it only affects regular expressions which
+ occur later in the command line. If this option is not given, GNU
+ Emacs regular expressions are assumed. Currently-implemented types
+ are
+
+ 'emacs'
+ Regular expressions compatible with GNU Emacs; this is also
+ the default behaviour if this option is not used.
+ 'posix-awk'
+ Regular expressions compatible with the POSIX awk command (not
+ GNU awk)
+ 'posix-basic'
+ POSIX Basic Regular Expressions.
+ 'posix-egrep'
+ Regular expressions compatible with the POSIX egrep command
+ 'posix-extended'
+ POSIX Extended Regular Expressions
+
+ *note Regular Expressions:: for more information on the regular
+ expression dialects understood by GNU findutils.
+
+
+File: find.info, Node: Fast Full Name Search, Next: Shell Pattern Matching, Prev: Full Name Patterns, Up: Name
+
+2.1.3 Fast Full Name Search
+---------------------------
+
+To search for files by name without having to actually scan the
+directories on the disk (which can be slow), you can use the 'locate'
+program. For each shell pattern you give it, 'locate' searches one or
+more databases of file names and displays the file names that contain
+the pattern. *Note Shell Pattern Matching::, for details about shell
+patterns.
+
+ If a pattern is a plain string - it contains no metacharacters -
+'locate' displays all file names in the database that contain that
+string. If a pattern contains metacharacters, 'locate' only displays
+file names that match the pattern exactly. As a result, patterns that
+contain metacharacters should usually begin with a '*', and will most
+often end with one as well. The exceptions are patterns that are
+intended to explicitly match the beginning or end of a file name.
+
+ If you only want 'locate' to match against the last component of the
+file names (the "base name" of the files) you can use the '--basename'
+option. The opposite behaviour is the default, but can be selected
+explicitly by using the option '--wholename'.
+
+ The command
+ locate PATTERN
+
+ is almost equivalent to
+ find DIRECTORIES -name PATTERN
+
+ where DIRECTORIES are the directories for which the file name
+databases contain information. The differences are that the 'locate'
+information might be out of date, and that 'locate' handles wildcards in
+the pattern slightly differently than 'find' (*note Shell Pattern
+Matching::).
+
+ The file name databases contain lists of files that were on the
+system when the databases were last updated. The system administrator
+can choose the file name of the default database, the frequency with
+which the databases are updated, and the directories for which they
+contain entries.
+
+ Here is how to select which file name databases 'locate' searches.
+The default is system-dependent. At the time this document was
+generated, the default was '/usr/local/var/locatedb'.
+
+'--database=PATH'
+'-d PATH'
+ Instead of searching the default file name database, search the
+ file name databases in PATH, which is a colon-separated list of
+ database file names. You can also use the environment variable
+ 'LOCATE_PATH' to set the list of database files to search. The
+ option overrides the environment variable if both are used.
+
+ GNU 'locate' can read file name databases generated by the 'slocate'
+package. However, these generally contain a list of all the files on
+the system, and so when using this database, 'locate' will produce
+output only for files which are accessible to you. *Note Invoking
+locate::, for a description of the '--existing' option which is used to
+do this.
+
+ The 'updatedb' program can also generate database in a format
+compatible with 'slocate'. *Note Invoking updatedb::, for a description
+of its '--dbformat' and '--output' options.
+
+
+File: find.info, Node: Shell Pattern Matching, Prev: Fast Full Name Search, Up: Name
+
+2.1.4 Shell Pattern Matching
+----------------------------
+
+'find' and 'locate' can compare file names, or parts of file names, to
+shell patterns. A "shell pattern" is a string that may contain the
+following special characters, which are known as "wildcards" or
+"metacharacters".
+
+ You must quote patterns that contain metacharacters to prevent the
+shell from expanding them itself. Double and single quotes both work;
+so does escaping with a backslash.
+
+'*'
+ Matches any zero or more characters.
+
+'?'
+ Matches any one character.
+
+'[STRING]'
+ Matches exactly one character that is a member of the string
+ STRING. This is called a "character class". As a shorthand,
+ STRING may contain ranges, which consist of two characters with a
+ dash between them. For example, the class '[a-z0-9_]' matches a
+ lowercase letter, a number, or an underscore. You can negate a
+ class by placing a '!' or '^' immediately after the opening
+ bracket. Thus, '[^A-Z@]' matches any character except an uppercase
+ letter or an at sign.
+
+'\'
+ Removes the special meaning of the character that follows it. This
+ works even in character classes.
+
+ In the 'find' tests that do shell pattern matching ('-name',
+'-wholename', etc.), wildcards in the pattern will match a '.' at the
+beginning of a file name. This is also the case for 'locate'. Thus,
+'find -name '*macs'' will match a file named '.emacs', as will 'locate
+'*macs''.
+
+ Slash characters have no special significance in the shell pattern
+matching that 'find' and 'locate' do, unlike in the shell, in which
+wildcards do not match them. Therefore, a pattern 'foo*bar' can match a
+file name 'foo3/bar', and a pattern './sr*sc' can match a file name
+'./src/misc'.
+
+ If you want to locate some files with the 'locate' command but don't
+need to see the full list you can use the '--limit' option to see just a
+small number of results, or the '--count' option to display only the
+total number of matches.
+
+
+File: find.info, Node: Links, Next: Time, Prev: Name, Up: Finding Files
+
+2.2 Links
+=========
+
+There are two ways that files can be linked together. "Symbolic links"
+are a special type of file whose contents are a portion of the name of
+another file. "Hard links" are multiple directory entries for one file;
+the file names all have the same index node ("inode") number on the
+disk.
+
+* Menu:
+
+* Symbolic Links::
+* Hard Links::
+
+
+File: find.info, Node: Symbolic Links, Next: Hard Links, Up: Links
+
+2.2.1 Symbolic Links
+--------------------
+
+Symbolic links are names that reference other files. GNU 'find' will
+handle symbolic links in one of two ways; firstly, it can dereference
+the links for you - this means that if it comes across a symbolic link,
+it examines the file that the link points to, in order to see if it
+matches the criteria you have specified. Secondly, it can check the
+link itself in case you might be looking for the actual link. If the
+file that the symbolic link points to is also within the directory
+hierarchy you are searching with the 'find' command, you may not see a
+great deal of difference between these two alternatives.
+
+ By default, 'find' examines symbolic links themselves when it finds
+them (and, if it later comes across the linked-to file, it will examine
+that, too). If you would prefer 'find' to dereference the links and
+examine the file that each link points to, specify the '-L' option to
+'find'. You can explicitly specify the default behaviour by using the
+'-P' option. The '-H' option is a half-way-between option which ensures
+that any symbolic links listed on the command line are dereferenced, but
+other symbolic links are not.
+
+ Symbolic links are different from "hard links" in the sense that you
+need permission to search the directories in the linked-to file name to
+dereference the link. This can mean that even if you specify the '-L'
+option, 'find' may not be able to determine the properties of the file
+that the link points to (because you don't have sufficient permission).
+In this situation, 'find' uses the properties of the link itself. This
+also occurs if a symbolic link exists but points to a file that is
+missing.
+
+ The options controlling the behaviour of 'find' with respect to links
+are as follows:
+
+'-P'
+ 'find' does not dereference symbolic links at all. This is the
+ default behaviour. This option must be specified before any of the
+ file names on the command line.
+'-H'
+ 'find' does not dereference symbolic links (except in the case of
+ file names on the command line, which are dereferenced). If a
+ symbolic link cannot be dereferenced, the information for the
+ symbolic link itself is used. This option must be specified before
+ any of the file names on the command line.
+'-L'
+ 'find' dereferences symbolic links where possible, and where this
+ is not possible it uses the properties of the symbolic link itself.
+ This option must be specified before any of the file names on the
+ command line. Use of this option also implies the same behaviour
+ as the '-noleaf' option. If you later use the '-H' or '-P'
+ options, this does not turn off '-noleaf'.
+
+ Actions that can cause symbolic links to become broken while 'find'
+ is executing (for example '-delete') can give rise to confusing
+ behaviour. Take for example the command line 'find -L . -type d
+ -delete'. This will delete empty directories. If a subtree
+ includes only directories and symbolic links to directoires, this
+ command may still not successfully delete it, since deletion of the
+ target of the symbolic link will cause the symbolic link to become
+ broken and '-type d' is false for broken symbolic links.
+
+'-follow'
+ This option forms part of the "expression" and must be specified
+ after the file names, but it is otherwise equivalent to '-L'. The
+ '-follow' option affects only those tests which appear after it on
+ the command line. This option is deprecated. Where possible, you
+ should use '-L' instead.
+
+ The following differences in behaviour occur when the '-L' option is
+used:
+
+ * 'find' follows symbolic links to directories when searching
+ directory trees.
+ * '-lname' and '-ilname' always return false (unless they happen to
+ match broken symbolic links).
+ * '-type' reports the types of the files that symbolic links point
+ to. This means that in combination with '-L', '-type l' will be
+ true only for broken symbolic links. To check for symbolic links
+ when '-L' has been specified, use '-xtype l'.
+ * Implies '-noleaf' (*note Directories::).
+
+ If the '-L' option or the '-H' option is used, the file names used as
+arguments to '-newer', '-anewer', and '-cnewer' are dereferenced and the
+timestamp from the pointed-to file is used instead (if possible -
+otherwise the timestamp from the symbolic link is used).
+
+ -- Test: -lname pattern
+ -- Test: -ilname pattern
+ True if the file is a symbolic link whose contents match shell
+ pattern PATTERN. For '-ilname', the match is case-insensitive.
+ *Note Shell Pattern Matching::, for details about the PATTERN
+ argument. If the '-L' option is in effect, this test will always
+ return false for symbolic links unless they are broken. So, to
+ list any symbolic links to 'sysdep.c' in the current directory and
+ its subdirectories, you can do:
+
+ find . -lname '*sysdep.c'
+
+
+File: find.info, Node: Hard Links, Prev: Symbolic Links, Up: Links
+
+2.2.2 Hard Links
+----------------
+
+Hard links allow more than one name to refer to the same file. To find
+all the names which refer to the same file as NAME, use '-samefile
+NAME'. If you are not using the '-L' option, you can confine your
+search to one filesystem using the '-xdev' option. This is useful
+because hard links cannot point outside a single filesystem, so this can
+cut down on needless searching.
+
+ If the '-L' option is in effect, and NAME is in fact a symbolic link,
+the symbolic link will be dereferenced. Hence you are searching for
+other links (hard or symbolic) to the file pointed to by NAME. If '-L'
+is in effect but NAME is not itself a symbolic link, other symbolic
+links to the file NAME will be matched.
+
+ You can also search for files by inode number. This can occasionally
+be useful in diagnosing problems with filesystems for example, because
+'fsck' tends to print inode numbers. Inode numbers also occasionally
+turn up in log messages for some types of software, and are used to
+support the 'ftok()' library function.
+
+ You can learn a file's inode number and the number of links to it by
+running 'ls -li' or 'find -ls'.
+
+ You can search for hard links to inode number NUM by using '-inum
+NUM'. If there are any filesystem mount points below the directory
+where you are starting the search, use the '-xdev' option unless you are
+also using the '-L' option. Using '-xdev' this saves needless
+searching, since hard links to a file must be on the same filesystem.
+*Note Filesystems::.
+
+ -- Test: -samefile NAME
+ File is a hard link to the same inode as NAME. If the '-L' option
+ is in effect, symbolic links to the same file as NAME points to are
+ also matched.
+
+ -- Test: -inum n
+ File has inode number N. The '+' and '-' qualifiers also work,
+ though these are rarely useful. Much of the time it is easier to
+ use '-samefile' rather than this option.
+
+ You can also search for files that have a certain number of links,
+with '-links'. Directories normally have at least two hard links; their
+'.' entry is the second one. If they have subdirectories, each of those
+also has a hard link called '..' to its parent directory. The '.' and
+'..' directory entries are not normally searched unless they are
+mentioned on the 'find' command line.
+
+ -- Test: -links n
+ File has N hard links.
+
+ -- Test: -links +n
+ File has more than N hard links.
+
+ -- Test: -links -n
+ File has fewer than N hard links.
+
+
+File: find.info, Node: Time, Next: Size, Prev: Links, Up: Finding Files
+
+2.3 Time
+========
+
+Each file has three time stamps, which record the last time that certain
+operations were performed on the file:
+
+ 1. access (read the file's contents)
+ 2. change the status (modify the file or its attributes)
+ 3. modify (change the file's contents)
+
+ Some systems also provide a timestamp that indicates when a file was
+_created_. For example, the UFS2 filesystem under NetBSD-3.1 records
+the _birth time_ of each file. This information is also available under
+other versions of BSD and some versions of Cygwin. However, even on
+systems which support file birth time, files may exist for which this
+information was not recorded (for example, UFS1 file systems simply do
+not contain this information).
+
+ You can search for files whose time stamps are within a certain age
+range, or compare them to other time stamps.
+
+* Menu:
+
+* Age Ranges::
+* Comparing Timestamps::
+
+
+File: find.info, Node: Age Ranges, Next: Comparing Timestamps, Up: Time
+
+2.3.1 Age Ranges
+----------------
+
+These tests are mainly useful with ranges ('+N' and '-N').
+
+ -- Test: -atime n
+ -- Test: -ctime n
+ -- Test: -mtime n
+ True if the file was last accessed (or its status changed, or it
+ was modified) N*24 hours ago. The number of 24-hour periods since
+ the file's timestamp is always rounded down; therefore 0 means
+ "less than 24 hours ago", 1 means "between 24 and 48 hours ago",
+ and so forth. Fractional values are supported but this only really
+ makes sense for the case where ranges ('+N' and '-N') are used.
+
+ -- Test: -amin n
+ -- Test: -cmin n
+ -- Test: -mmin n
+ True if the file was last accessed (or its status changed, or it
+ was modified) N minutes ago. These tests provide finer granularity
+ of measurement than '-atime' et al., but rounding is done in a
+ similar way (again, fractions are supported). For example, to list
+ files in '/u/bill' that were last read from 2 to 6 minutes ago:
+
+ find /u/bill -amin +2 -amin -6
+
+ -- Option: -daystart
+ Measure times from the beginning of today rather than from 24 hours
+ ago. So, to list the regular files in your home directory that
+ were modified yesterday, do
+
+ find ~/ -daystart -type f -mtime 1
+
+ The '-daystart' option is unlike most other options in that it has
+ an effect on the way that other tests are performed. The affected
+ tests are '-amin', '-cmin', '-mmin', '-atime', '-ctime' and
+ '-mtime'. The '-daystart' option only affects the behaviour of any
+ tests which appear after it on the command line.
+
+
+File: find.info, Node: Comparing Timestamps, Prev: Age Ranges, Up: Time
+
+2.3.2 Comparing Timestamps
+--------------------------
+
+ -- Test: -newerXY reference
+ Succeeds if timestamp 'X' of the file being considered is newer
+ than timestamp 'Y' of the file 'reference'. The letters 'X' and
+ 'Y' can be any of the following letters:
+
+ 'a'
+ Last-access time of 'reference'
+ 'B'
+ Birth time of 'reference' (when this is not known, the test
+ cannot succeed)
+ 'c'
+ Last-change time of 'reference'
+ 'm'
+ Last-modification time of 'reference'
+ 't'
+ The 'reference' argument is interpreted as a literal time,
+ rather than the name of a file. *Note Date input formats::,
+ for a description of how the timestamp is understood. Tests
+ of the form '-newerXt' are valid but tests of the form
+ '-newertY' are not.
+
+ For example the test '-newerac /tmp/foo' succeeds for all files
+ which have been accessed more recently than '/tmp/foo' was changed.
+ Here 'X' is 'a' and 'Y' is 'c'.
+
+ Not all files have a known birth time. If 'Y' is 'b' and the birth
+ time of 'reference' is not available, 'find' exits with an
+ explanatory error message. If 'X' is 'b' and we do not know the
+ birth time the file currently being considered, the test simply
+ fails (that is, it behaves like '-false' does).
+
+ Some operating systems (for example, most implementations of Unix)
+ do not support file birth times. Some others, for example
+ NetBSD-3.1, do. Even on operating systems which support file birth
+ times, the information may not be available for specific files.
+ For example, under NetBSD, file birth times are supported on UFS2
+ file systems, but not UFS1 file systems.
+
+ There are two ways to list files in '/usr' modified after February 1
+of the current year. One uses '-newermt':
+
+ find /usr -newermt "Feb 1"
+
+ The other way of doing this works on the versions of find before
+4.3.3:
+
+ touch -t 02010000 /tmp/stamp$$
+ find /usr -newer /tmp/stamp$$
+ rm -f /tmp/stamp$$
+
+ -- Test: -anewer file
+ -- Test: -cnewer file
+ -- Test: -newer file
+ True if the file was last accessed (or its status changed, or it
+ was modified) more recently than FILE was modified. These tests
+ are affected by '-follow' only if '-follow' comes before them on
+ the command line. *Note Symbolic Links::, for more information on
+ '-follow'. As an example, to list any files modified since
+ '/bin/sh' was last modified:
+
+ find . -newer /bin/sh
+
+ -- Test: -used n
+ True if the file was last accessed N days after its status was last
+ changed. Useful for finding files that are not being used, and
+ could perhaps be archived or removed to save disk space.
+
+
+File: find.info, Node: Size, Next: Type, Prev: Time, Up: Finding Files
+
+2.4 Size
+========
+
+ -- Test: -size n[bckwMG]
+ True if the file uses N units of space, rounding up. The units are
+ 512-byte blocks by default, but they can be changed by adding a
+ one-character suffix to N:
+
+ 'b'
+ 512-byte blocks (never 1024)
+ 'c'
+ bytes
+ 'k'
+ kilobytes (1024 bytes)
+ 'w'
+ 2-byte words
+ 'M'
+ Megabytes (units of 1048576 bytes)
+ 'G'
+ Gigabytes (units of 1073741824 bytes)
+
+ The 'b' suffix always considers blocks to be 512 bytes. This is
+ not affected by the setting (or non-setting) of the
+ 'POSIXLY_CORRECT' environment variable. This behaviour is
+ different from the behaviour of the '-ls' action). If you want to
+ use 1024-byte units, use the 'k' suffix instead.
+
+ The number can be prefixed with a '+' or a '-'. A plus sign
+ indicates that the test should succeed if the file uses at least N
+ units of storage (a common use of this test) and a minus sign
+ indicates that the test should succeed if the file uses less than N
+ units of storage. There is no '=' prefix, because that's the
+ default anyway.
+
+ The size does not count indirect blocks, but it does count blocks
+ in sparse files that are not actually allocated. In other words,
+ it's consistent with the result you get for 'ls -l' or 'wc -c'.
+ This handling of sparse files differs from the output of the '%k'
+ and '%b' format specifiers for the '-printf' predicate.
+
+ -- Test: -empty
+ True if the file is empty and is either a regular file or a
+ directory. This might help determine good candidates for deletion.
+ This test is useful with '-depth' (*note Directories::) and
+ '-delete' (*note Single File::).
+
+
+File: find.info, Node: Type, Next: Owner, Prev: Size, Up: Finding Files
+
+2.5 Type
+========
+
+ -- Test: -type c
+ True if the file is of type C:
+
+ 'b'
+ block (buffered) special
+ 'c'
+ character (unbuffered) special
+ 'd'
+ directory
+ 'p'
+ named pipe (FIFO)
+ 'f'
+ regular file
+ 'l'
+ symbolic link; if '-L' is in effect, this is true only for
+ broken symbolic links. If you want to search for symbolic
+ links when '-L' is in effect, use '-xtype' instead of '-type'.
+ 's'
+ socket
+ 'D'
+ door (Solaris)
+
+ -- Test: -xtype c
+ This test behaves the same as '-type' unless the file is a symbolic
+ link. If the file is a symbolic link, the result is as follows (in
+ the table below, 'X' should be understood to represent any letter
+ except 'l'):
+
+ ''-P -xtype l''
+ True if the symbolic link is broken
+ ''-P -xtype X''
+ True if the (ultimate) target file is of type 'X'.
+ ''-L -xtype l''
+ Always true
+ ''-L -xtype X''
+ False unless the symbolic link is broken
+
+ In other words, for symbolic links, '-xtype' checks the type of the
+ file that '-type' does not check.
+
+ The '-H' option also affects the behaviour of '-xtype'. When '-H'
+ is in effect, '-xtype' behaves as if '-L' had been specified when
+ examining files listed on the command line, and as if '-P' had been
+ specified otherwise. If neither '-H' nor '-L' was specified,
+ '-xtype' behaves as if '-P' had been specified.
+
+ *Note Symbolic Links::, for more information on '-follow' and '-L'.
+
+
+File: find.info, Node: Owner, Next: Mode Bits, Prev: Type, Up: Finding Files
+
+2.6 Owner
+=========
+
+ -- Test: -user uname
+ -- Test: -group gname
+ True if the file is owned by user UNAME (belongs to group GNAME).
+ A numeric ID is allowed.
+
+ -- Test: -uid n
+ -- Test: -gid n
+ True if the file's numeric user ID (group ID) is N. These tests
+ support ranges ('+N' and '-N'), unlike '-user' and '-group'.
+
+ -- Test: -nouser
+ -- Test: -nogroup
+ True if no user corresponds to the file's numeric user ID (no group
+ corresponds to the numeric group ID). These cases usually mean that
+ the files belonged to users who have since been removed from the
+ system. You probably should change the ownership of such files to
+ an existing user or group, using the 'chown' or 'chgrp' program.
+
+
+File: find.info, Node: Mode Bits, Next: Contents, Prev: Owner, Up: Finding Files
+
+2.7 File Mode Bits
+==================
+
+*Note File Permissions::, for information on how file mode bits are
+structured and how to specify them.
+
+ Four tests determine what users can do with files. These are
+'-readable', '-writable', '-executable' and '-perm'. The first three
+tests ask the operating system if the current user can perform the
+relevant operation on a file, while '-perm' just examines the file's
+mode. The file mode may give a misleading impression of what the user
+can actually do, because the file may have an access control list, or
+exist on a read-only filesystem, for example. Of these four tests
+though, only '-perm' is specified by the POSIX standard.
+
+ The '-readable', '-writable' and '-executable' tests are implemented
+via the 'access' system call. This is implemented within the operating
+system itself. If the file being considered is on an NFS filesystem,
+the remote system may allow or forbid read or write operations for
+reasons of which the NFS client cannot take account. This includes
+user-ID mapping, either in the general sense or the more restricted
+sense in which remote superusers are treated by the NFS server as if
+they are the local user 'nobody' on the NFS server.
+
+ None of the tests in this section should be used to verify that a
+user is authorised to perform any operation (on the file being tested or
+any other file) because of the possibility of a race condition. That
+is, the situation may change between the test and an action being taken
+on the basis of the result of that test.
+
+ -- Test: -readable
+ True if the file can be read by the invoking user.
+
+ -- Test: -writable
+ True if the file can be written by the invoking user. This is an
+ in-principle check, and other things may prevent a successful write
+ operation; for example, the filesystem might be full.
+
+ -- Test: -executable
+ True if the file can be executed/searched by the invoking user.
+
+ -- Test: -perm pmode
+
+ True if the file's mode bits match PMODE, which can be either a
+ symbolic or numeric MODE (*note File Permissions::) optionally
+ prefixed by '-' or '/'.
+
+ A PMODE that starts with neither '-' nor '/' matches if MODE
+ exactly matches the file mode bits. (To avoid confusion with an
+ obsolete GNU extension, MODE must not start with a '+' immediately
+ followed by an octal digit.)
+
+ A PMODE that starts with '-' matches if _all_ the file mode bits
+ set in MODE are set for the file; bits not set in MODE are ignored.
+
+ A PMODE that starts with '/' matches if _any_ of the file mode bits
+ set in MODE are set for the file; bits not set in MODE are ignored.
+ This is a GNU extension.
+
+ If you don't use the '/' or '-' form with a symbolic mode string,
+ you may have to specify a rather complex mode string. For example
+ '-perm g=w' will only match files that have mode 0020 (that is,
+ ones for which group write permission is the only file mode bit
+ set). It is more likely that you will want to use the '/' or '-'
+ forms, for example '-perm -g=w', which matches any file with group
+ write permission.
+
+ '-perm 664'
+ Match files that have read and write permission for their
+ owner, and group, but that the rest of the world can read but
+ not write to. Do not match files that meet these criteria but
+ have other file mode bits set (for example if someone can
+ execute/search the file).
+
+ '-perm -664'
+ Match files that have read and write permission for their
+ owner, and group, but that the rest of the world can read but
+ not write to, without regard to the presence of any extra file
+ mode bits (for example the executable bit). This matches a
+ file with mode 0777, for example.
+
+ '-perm /222'
+ Match files that are writable by somebody (their owner, or
+ their group, or anybody else).
+
+ '-perm /022'
+ Match files that are writable by either their owner or their
+ group. The files don't have to be writable by both the owner
+ and group to be matched; either will do.
+
+ '-perm /g+w,o+w'
+ As above.
+
+ '-perm /g=w,o=w'
+ As above.
+
+ '-perm -022'
+ Match files that are writable by both their owner and their
+ group.
+
+ '-perm -444 -perm /222 ! -perm /111'
+ Match files that are readable for everybody, have at least one
+ write bit set (i.e., somebody can write to them), but that
+ cannot be executed/searched by anybody. Note that in some
+ shells the '!' must be escaped;.
+
+ '-perm -a+r -perm /a+w ! -perm /a+x'
+ As above.
+
+ '-perm -g+w,o+w'
+ As above.
+
+ Warning: If you specify '-perm /000' or '-perm /mode' where
+ the symbolic mode 'mode' has no bits set, the test matches all
+ files. Versions of GNU 'find' prior to 4.3.3 matched no files
+ in this situation.
+
+ -- Test: -context pattern
+ True if file's SELinux context matches the pattern PATTERN. The
+ pattern uses shell glob matching.
+
+ This predicate is supported only on 'find' versions compiled with
+ SELinux support and only when SELinux is enabled.
+
+
+File: find.info, Node: Contents, Next: Directories, Prev: Mode Bits, Up: Finding Files
+
+2.8 Contents
+============
+
+To search for files based on their contents, you can use the 'grep'
+program. For example, to find out which C source files in the current
+directory contain the string 'thing', you can do:
+
+ grep -l thing *.[ch]
+
+ If you also want to search for the string in files in subdirectories,
+you can combine 'grep' with 'find' and 'xargs', like this:
+
+ find . -name '*.[ch]' | xargs grep -l thing
+
+ The '-l' option causes 'grep' to print only the names of files that
+contain the string, rather than the lines that contain it. The string
+argument ('thing') is actually a regular expression, so it can contain
+metacharacters. This method can be refined a little by using the '-r'
+option to make 'xargs' not run 'grep' if 'find' produces no output, and
+using the 'find' action '-print0' and the 'xargs' option '-0' to avoid
+misinterpreting files whose names contain spaces:
+
+ find . -name '*.[ch]' -print0 | xargs -r -0 grep -l thing
+
+ For a fuller treatment of finding files whose contents match a
+pattern, see the manual page for 'grep'.
+
+
+File: find.info, Node: Directories, Next: Filesystems, Prev: Contents, Up: Finding Files
+
+2.9 Directories
+===============
+
+Here is how to control which directories 'find' searches, and how it
+searches them. These two options allow you to process a horizontal
+slice of a directory tree.
+
+ -- Option: -maxdepth levels
+ Descend at most LEVELS (a non-negative integer) levels of
+ directories below the command line arguments. '-maxdepth 0' means
+ only apply the tests and actions to the command line arguments.
+
+ -- Option: -mindepth levels
+ Do not apply any tests or actions at levels less than LEVELS (a
+ non-negative integer). '-mindepth 1' means process all files
+ except the command line arguments.
+
+ -- Option: -depth
+ Process each directory's contents before the directory itself.
+ Doing this is a good idea when producing lists of files to archive
+ with 'cpio' or 'tar'. If a directory does not have write
+ permission for its owner, its contents can still be restored from
+ the archive since the directory's permissions are restored after
+ its contents.
+
+ -- Option: -d
+ This is a deprecated synonym for '-depth', for compatibility with
+ Mac OS X, FreeBSD and OpenBSD. The '-depth' option is a POSIX
+ feature, so it is better to use that.
+
+ -- Action: -prune
+ If the file is a directory, do not descend into it. The result is
+ true. For example, to skip the directory 'src/emacs' and all files
+ and directories under it, and print the names of the other files
+ found:
+
+ find . -wholename './src/emacs' -prune -o -print
+
+ The above command will not print './src/emacs' among its list of
+ results. This however is not due to the effect of the '-prune'
+ action (which only prevents further descent, it doesn't make sure
+ we ignore that item). Instead, this effect is due to the use of
+ '-o'. Since the left hand side of the "or" condition has succeeded
+ for './src/emacs', it is not necessary to evaluate the
+ right-hand-side ('-print') at all for this particular file. If you
+ wanted to print that directory name you could use either an extra
+ '-print' action:
+
+ find . -wholename './src/emacs' -prune -print -o -print
+
+ or use the comma operator:
+
+ find . -wholename './src/emacs' -prune , -print
+
+ If the '-depth' option is in effect, the subdirectories will have
+ already been visited in any case. Hence '-prune' has no effect in
+ this case.
+
+ Because '-delete' implies '-depth', using '-prune' in combination
+ with '-delete' may well result in the deletion of more files than
+ you intended.
+
+ -- Action: -quit
+ Exit immediately (with return value zero if no errors have
+ occurred). This is different to '-prune' because '-prune' only
+ applies to the contents of pruned directories, while '-quit' simply
+ makes 'find' stop immediately. No child processes will be left
+ running, but no more files specified on the command line will be
+ processed. For example, 'find /tmp/foo /tmp/bar -print -quit' will
+ print only '/tmp/foo'. Any command lines which have been built by
+ '-exec ... \+' or '-execdir ... \+' are invoked before the program
+ is exited.
+
+ -- Option: -noleaf
+ Do not optimize by assuming that directories contain 2 fewer
+ subdirectories than their hard link count. This option is needed
+ when searching filesystems that do not follow the Unix
+ directory-link convention, such as CD-ROM or MS-DOS filesystems or
+ AFS volume mount points. Each directory on a normal Unix
+ filesystem has at least 2 hard links: its name and its '.' entry.
+ Additionally, its subdirectories (if any) each have a '..' entry
+ linked to that directory. When 'find' is examining a directory,
+ after it has statted 2 fewer subdirectories than the directory's
+ link count, it knows that the rest of the entries in the directory
+ are non-directories ("leaf" files in the directory tree). If only
+ the files' names need to be examined, there is no need to stat
+ them; this gives a significant increase in search speed.
+
+ -- Option: -ignore_readdir_race
+ If a file disappears after its name has been read from a directory
+ but before 'find' gets around to examining the file with 'stat',
+ don't issue an error message. If you don't specify this option, an
+ error message will be issued. This option can be useful in system
+ scripts (cron scripts, for example) that examine areas of the
+ filesystem that change frequently (mail queues, temporary
+ directories, and so forth), because this scenario is common for
+ those sorts of directories. Completely silencing error messages
+ from 'find' is undesirable, so this option neatly solves the
+ problem. There is no way to search one part of the filesystem with
+ this option on and part of it with this option off, though. When
+ this option is turned on and find discovers that one of the
+ start-point files specified on the command line does not exist, no
+ error message will be issued.
+
+ -- Option: -noignore_readdir_race
+ This option reverses the effect of the '-ignore_readdir_race'
+ option.
+
+
+File: find.info, Node: Filesystems, Next: Combining Primaries With Operators, Prev: Directories, Up: Finding Files
+
+2.10 Filesystems
+================
+
+A "filesystem" is a section of a disk, either on the local host or
+mounted from a remote host over a network. Searching network
+filesystems can be slow, so it is common to make 'find' avoid them.
+
+ There are two ways to avoid searching certain filesystems. One way
+is to tell 'find' to only search one filesystem:
+
+ -- Option: -xdev
+ -- Option: -mount
+ Don't descend directories on other filesystems. These options are
+ synonyms.
+
+ The other way is to check the type of filesystem each file is on, and
+not descend directories that are on undesirable filesystem types:
+
+ -- Test: -fstype type
+ True if the file is on a filesystem of type TYPE. The valid
+ filesystem types vary among different versions of Unix; an
+ incomplete list of filesystem types that are accepted on some
+ version of Unix or another is:
+ ext2 ext3 proc sysfs ufs 4.2 4.3 nfs tmp mfs S51K S52K
+ You can use '-printf' with the '%F' directive to see the types of
+ your filesystems. The '%D' directive shows the device number.
+ *Note Print File Information::. '-fstype' is usually used with
+ '-prune' to avoid searching remote filesystems (*note
+ Directories::).
+
+
+File: find.info, Node: Combining Primaries With Operators, Prev: Filesystems, Up: Finding Files
+
+2.11 Combining Primaries With Operators
+=======================================
+
+Operators build a complex expression from tests and actions. The
+operators are, in order of decreasing precedence:
+
+'( EXPR )'
+ Force precedence. True if EXPR is true.
+
+'! EXPR'
+'-not EXPR'
+ True if EXPR is false. In some shells, it is necessary to protect
+ the '!' from shell interpretation by quoting it.
+
+'EXPR1 EXPR2'
+'EXPR1 -a EXPR2'
+'EXPR1 -and EXPR2'
+ And; EXPR2 is not evaluated if EXPR1 is false.
+
+'EXPR1 -o EXPR2'
+'EXPR1 -or EXPR2'
+ Or; EXPR2 is not evaluated if EXPR1 is true.
+
+'EXPR1 , EXPR2'
+ List; both EXPR1 and EXPR2 are always evaluated. True if EXPR2 is
+ true. The value of EXPR1 is discarded. This operator lets you do
+ multiple independent operations on one traversal, without depending
+ on whether other operations succeeded. The two operations EXPR1
+ and EXPR2 are not always fully independent, since EXPR1 might have
+ side effects like touching or deleting files, or it might use
+ '-prune' which would also affect EXPR2.
+
+ 'find' searches the directory tree rooted at each file name by
+evaluating the expression from left to right, according to the rules of
+precedence, until the outcome is known (the left hand side is false for
+'-and', true for '-or'), at which point 'find' moves on to the next file
+name.
+
+ There are two other tests that can be useful in complex expressions:
+
+ -- Test: -true
+ Always true.
+
+ -- Test: -false
+ Always false.
+
+
+File: find.info, Node: Actions, Next: Databases, Prev: Finding Files, Up: Top
+
+3 Actions
+*********
+
+There are several ways you can print information about the files that
+match the criteria you gave in the 'find' expression. You can print the
+information either to the standard output or to a file that you name.
+You can also execute commands that have the file names as arguments.
+You can use those commands as further filters to select files.
+
+* Menu:
+
+* Print File Name::
+* Print File Information::
+* Run Commands::
+* Delete Files::
+* Adding Tests::
+
+
+File: find.info, Node: Print File Name, Next: Print File Information, Up: Actions
+
+3.1 Print File Name
+===================
+
+ -- Action: -print
+ True; print the entire file name on the standard output, followed
+ by a newline. If there is the faintest possibility that one of the
+ files for which you are searching might contain a newline, you
+ should use '-print0' instead.
+
+ -- Action: -fprint file
+ True; print the entire file name into file FILE, followed by a
+ newline. If FILE does not exist when 'find' is run, it is created;
+ if it does exist, it is truncated to 0 bytes. The named output
+ file is always created, even if no output is sent to it. The file
+ names '/dev/stdout' and '/dev/stderr' are handled specially; they
+ refer to the standard output and standard error output,
+ respectively.
+
+ If there is the faintest possibility that one of the files for
+ which you are searching might contain a newline, you should use
+ '-fprint0' instead.
+
+
+File: find.info, Node: Print File Information, Next: Run Commands, Prev: Print File Name, Up: Actions
+
+3.2 Print File Information
+==========================
+
+ -- Action: -ls
+ True; list the current file in 'ls -dils' format on the standard
+ output. The output looks like this:
+
+ 204744 17 -rw-r--r-- 1 djm staff 17337 Nov 2 1992 ./lwall-quotes
+
+ The fields are:
+
+ 1. The inode number of the file. *Note Hard Links::, for how to
+ find files based on their inode number.
+
+ 2. the number of blocks in the file. The block counts are of 1K
+ blocks, unless the environment variable 'POSIXLY_CORRECT' is
+ set, in which case 512-byte blocks are used. *Note Size::,
+ for how to find files based on their size.
+
+ 3. The file's type and file mode bits. The type is shown as a
+ dash for a regular file; for other file types, a letter like
+ for '-type' is used (*note Type::). The file mode bits are
+ read, write, and execute/search for the file's owner, its
+ group, and other users, respectively; a dash means the
+ permission is not granted. *Note File Permissions::, for more
+ details about file permissions. *Note Mode Bits::, for how to
+ find files based on their file mode bits.
+
+ 4. The number of hard links to the file.
+
+ 5. The user who owns the file.
+
+ 6. The file's group.
+
+ 7. The file's size in bytes.
+
+ 8. The date the file was last modified.
+
+ 9. The file's name. '-ls' quotes non-printable characters in the
+ file names using C-like backslash escapes. This may change
+ soon, as the treatment of unprintable characters is harmonised
+ for '-ls', '-fls', '-print', '-fprint', '-printf' and
+ '-fprintf'.
+
+ -- Action: -fls file
+ True; like '-ls' but write to FILE like '-fprint' (*note Print File
+ Name::). The named output file is always created, even if no
+ output is sent to it.
+
+ -- Action: -printf format
+ True; print FORMAT on the standard output, interpreting '\' escapes
+ and '%' directives (more details in the following sections).
+
+ Field widths and precisions can be specified as with the 'printf' C
+ function. Format flags (like '#' for example) may not work as you
+ expect because many of the fields, even numeric ones, are printed
+ with %s. Numeric flags which are affected in this way include 'G',
+ 'U', 'b', 'D', 'k' and 'n'. This difference in behaviour means
+ though that the format flag '-' will work; it forces left-alignment
+ of the field. Unlike '-print', '-printf' does not add a newline at
+ the end of the string. If you want a newline at the end of the
+ string, add a '\n'.
+
+ As an example, an approximate equivalent of '-ls' with
+ null-terminated filenames can be achieved with this '-printf'
+ format:
+
+ find -printf "%i %4k %M %3n %-8u %-8g %8s %T+ %p\n->%l\0" | cat
+
+ A practical reason for doing this would be to get literal filenames
+ in the output, instead of '-ls''s backslash-escaped names. (Using
+ 'cat' here prevents this happening for the '%p' format specifier;
+ *note Unusual Characters in File Names::). This format also
+ outputs a uniform timestamp format.
+
+ As for symlinks, the format above outputs the symlink target on a
+ second line, following '\n->'. There is nothing following the
+ arrow for non-symlinks. Another approach, for complete
+ consistency, would be to '-fprintf' the symlinks into a separate
+ file, so they too can be null-terminated.
+
+ -- Action: -fprintf file format
+ True; like '-printf' but write to FILE like '-fprint' (*note Print
+ File Name::). The output file is always created, even if no output
+ is ever sent to it.
+
+* Menu:
+
+* Escapes::
+* Format Directives::
+* Time Formats::
+* Formatting Flags::
+
+
+File: find.info, Node: Escapes, Next: Format Directives, Up: Print File Information
+
+3.2.1 Escapes
+-------------
+
+The escapes that '-printf' and '-fprintf' recognise are:
+
+'\a'
+ Alarm bell.
+'\b'
+ Backspace.
+'\c'
+ Stop printing from this format immediately and flush the output.
+'\f'
+ Form feed.
+'\n'
+ Newline.
+'\r'
+ Carriage return.
+'\t'
+ Horizontal tab.
+'\v'
+ Vertical tab.
+'\\'
+ A literal backslash ('\').
+'\0'
+ ASCII NUL.
+'\NNN'
+ The character whose ASCII code is NNN (octal).
+
+ A '\' character followed by any other character is treated as an
+ordinary character, so they both are printed, and a warning message is
+printed to the standard error output (because it was probably a typo).
+
+
+File: find.info, Node: Format Directives, Next: Time Formats, Prev: Escapes, Up: Print File Information
+
+3.2.2 Format Directives
+-----------------------
+
+'-printf' and '-fprintf' support the following format directives to
+print information about the file being processed. The C 'printf'
+function, field width and precision specifiers are supported, as applied
+to string (%s) types. That is, you can specify "minimum field
+width"."maximum field width" for each directive. Format flags (like '#'
+for example) may not work as you expect because many of the fields, even
+numeric ones, are printed with %s. The format flag '-' does work; it
+forces left-alignment of the field.
+
+ '%%' is a literal percent sign. *Note Reserved and Unknown
+Directives::, for a description of how format directives not mentioned
+below are handled.
+
+ A '%' at the end of the format argument causes undefined behaviour
+since there is no following character. In some locales, it may hide
+your door keys, while in others it may remove the final page from the
+novel you are reading.
+
+* Menu:
+
+* Name Directives::
+* Ownership Directives::
+* Size Directives::
+* Location Directives::
+* Time Directives::
+* Other Directives::
+* Reserved and Unknown Directives::
+
+
+File: find.info, Node: Name Directives, Next: Ownership Directives, Up: Format Directives
+
+3.2.2.1 Name Directives
+.......................
+
+'%p'
+ File's name (not the absolute path name, but the name of the file
+ as it was encountered by 'find' - that is, as a relative path from
+ one of the starting points).
+'%f'
+ File's name with any leading directories removed (only the last
+ element).
+'%h'
+ Leading directories of file's name (all but the last element and
+ the slash before it). If the file's name contains no slashes (for
+ example because it was named on the command line and is in the
+ current working directory), then "%h" expands to ".". This
+ prevents "%h/%f" expanding to "/foo", which would be surprising and
+ probably not desirable.
+'%P'
+ File's name with the name of the command line argument under which
+ it was found removed from the beginning.
+'%H'
+ Command line argument under which file was found.
+
+
+File: find.info, Node: Ownership Directives, Next: Size Directives, Prev: Name Directives, Up: Format Directives
+
+3.2.2.2 Ownership Directives
+............................
+
+'%g'
+ File's group name, or numeric group ID if the group has no name.
+'%G'
+ File's numeric group ID.
+'%u'
+ File's user name, or numeric user ID if the user has no name.
+'%U'
+ File's numeric user ID.
+'%m'
+ File's mode bits (in octal). If you always want to have a leading
+ zero on the number, use the '#' format flag, for example '%#m'.
+
+ The file mode bit numbers used are the traditional Unix numbers,
+ which will be as expected on most systems, but if your system's
+ file mode bit layout differs from the traditional Unix semantics,
+ you will see a difference between the mode as printed by '%m' and
+ the mode as it appears in 'struct stat'.
+
+'%M'
+ File's type and mode bits (in symbolic form, as for 'ls'). This
+ directive is supported in findutils 4.2.5 and later.
+
+
+File: find.info, Node: Size Directives, Next: Location Directives, Prev: Ownership Directives, Up: Format Directives
+
+3.2.2.3 Size Directives
+.......................
+
+'%k'
+ The amount of disk space used for this file in 1K blocks. Since
+ disk space is allocated in multiples of the filesystem block size
+ this is usually greater than %s/1024, but it can also be smaller if
+ the file is a sparse file (that is, it has "holes").
+'%b'
+ The amount of disk space used for this file in 512-byte blocks.
+ Since disk space is allocated in multiples of the filesystem block
+ size this is usually greater than %s/512, but it can also be
+ smaller if the file is a sparse file (that is, it has "holes").
+'%s'
+ File's size in bytes.
+'%S'
+ File's sparseness. This is calculated as '(BLOCKSIZE*st_blocks /
+ st_size)'. The exact value you will get for an ordinary file of a
+ certain length is system-dependent. However, normally sparse files
+ will have values less than 1.0, and files which use indirect blocks
+ and have few holes may have a value which is greater than 1.0. The
+ value used for BLOCKSIZE is system-dependent, but is usually 512
+ bytes. If the file size is zero, the value printed is undefined.
+ On systems which lack support for st_blocks, a file's sparseness is
+ assumed to be 1.0.
+
+
+File: find.info, Node: Location Directives, Next: Time Directives, Prev: Size Directives, Up: Format Directives
+
+3.2.2.4 Location Directives
+...........................
+
+'%d'
+ File's depth in the directory tree (depth below a file named on the
+ command line, not depth below the root directory). Files named on
+ the command line have a depth of 0. Subdirectories immediately
+ below them have a depth of 1, and so on.
+'%D'
+ The device number on which the file exists (the 'st_dev' field of
+ 'struct stat'), in decimal.
+'%F'
+ Type of the filesystem the file is on; this value can be used for
+ '-fstype' (*note Directories::).
+'%l'
+ Object of symbolic link (empty string if file is not a symbolic
+ link).
+'%i'
+ File's inode number (in decimal).
+'%n'
+ Number of hard links to file.
+'%y'
+ Type of the file as used with '-type'. If the file is a symbolic
+ link, 'l' will be printed.
+'%Y'
+ Type of the file as used with '-type'. If the file is a symbolic
+ link, it is dereferenced. If the file is a broken symbolic link,
+ 'N' is printed.
+
+
+File: find.info, Node: Time Directives, Next: Other Directives, Prev: Location Directives, Up: Format Directives
+
+3.2.2.5 Time Directives
+.......................
+
+Some of these directives use the C 'ctime' function. Its output depends
+on the current locale, but it typically looks like
+
+ Wed Nov 2 00:42:36 1994
+
+'%a'
+ File's last access time in the format returned by the C 'ctime'
+ function.
+'%AK'
+ File's last access time in the format specified by K (*note Time
+ Formats::).
+'%c'
+ File's last status change time in the format returned by the C
+ 'ctime' function.
+'%CK'
+ File's last status change time in the format specified by K (*note
+ Time Formats::).
+'%t'
+ File's last modification time in the format returned by the C
+ 'ctime' function.
+'%TK'
+ File's last modification time in the format specified by K (*note
+ Time Formats::).
+
+
+File: find.info, Node: Other Directives, Next: Reserved and Unknown Directives, Prev: Time Directives, Up: Format Directives
+
+3.2.2.6 Other Directives
+........................
+
+'%Z'
+ File's SELinux context, or empty string if the file has no SELinux
+ context.
+
+
+File: find.info, Node: Reserved and Unknown Directives, Prev: Other Directives, Up: Format Directives
+
+3.2.2.7 Reserved and Unknown Directives
+.......................................
+
+The '%(', '%{' and '%[' format directives, with or without field with
+and precision specifications, are reserved for future use. Don't use
+them and don't rely on current experiment to predict future behaviour.
+To print '(', simply use '(' rather than '%('. Likewise for '{' and
+'['.
+
+ Similarly, a '%' character followed by any other unrecognised
+character (i.e., not a known directive or 'printf' field width and
+precision specifier), is discarded (but the unrecognised character is
+printed), and a warning message is printed to the standard error output
+(because it was probably a typo). Don't rely on this behaviour, because
+other directives may be added in the future.
+
+
+File: find.info, Node: Time Formats, Next: Formatting Flags, Prev: Format Directives, Up: Print File Information
+
+3.2.3 Time Formats
+------------------
+
+Below are the formats for the directives '%A', '%C', and '%T', which
+print the file's timestamps. Some of these formats might not be
+available on all systems, due to differences in the C 'strftime'
+function between systems.
+
+* Menu:
+
+* Time Components::
+* Date Components::
+* Combined Time Formats::
+
+
+File: find.info, Node: Time Components, Next: Date Components, Up: Time Formats
+
+3.2.3.1 Time Components
+.......................
+
+The following format directives print single components of the time.
+
+'H'
+ hour (00..23)
+'I'
+ hour (01..12)
+'k'
+ hour ( 0..23)
+'l'
+ hour ( 1..12)
+'p'
+ locale's AM or PM
+'Z'
+ time zone (e.g., EDT), or nothing if no time zone is determinable
+'M'
+ minute (00..59)
+'S'
+ second (00..61). There is a fractional part.
+'@'
+ seconds since Jan. 1, 1970, 00:00 GMT, with fractional part.
+
+ The fractional part of the seconds field is of indeterminate length
+and precision. That is, the length of the fractional part of the
+seconds field will in general vary between findutils releases and
+between systems. This means that it is unwise to assume that field has
+any specific length. The length of this field is not usually a guide to
+the precision of timestamps in the underlying file system.
+
+
+File: find.info, Node: Date Components, Next: Combined Time Formats, Prev: Time Components, Up: Time Formats
+
+3.2.3.2 Date Components
+.......................
+
+The following format directives print single components of the date.
+
+'a'
+ locale's abbreviated weekday name (Sun..Sat)
+'A'
+ locale's full weekday name, variable length (Sunday..Saturday)
+'b'
+'h'
+ locale's abbreviated month name (Jan..Dec)
+'B'
+ locale's full month name, variable length (January..December)
+'m'
+ month (01..12)
+'d'
+ day of month (01..31)
+'w'
+ day of week (0..6)
+'j'
+ day of year (001..366)
+'U'
+ week number of year with Sunday as first day of week (00..53)
+'W'
+ week number of year with Monday as first day of week (00..53)
+'Y'
+ year (1970...)
+'y'
+ last two digits of year (00..99)
+
+
+File: find.info, Node: Combined Time Formats, Prev: Date Components, Up: Time Formats
+
+3.2.3.3 Combined Time Formats
+.............................
+
+The following format directives print combinations of time and date
+components.
+
+'r'
+ time, 12-hour (hh:mm:ss [AP]M)
+'T'
+ time, 24-hour (hh:mm:ss)
+'X'
+ locale's time representation (H:M:S)
+'c'
+ locale's date and time in ctime format (Sat Nov 04 12:02:33 EST
+ 1989). This format does not include any fractional part in the
+ seconds field.
+'D'
+ date (mm/dd/yy)
+'x'
+ locale's date representation (mm/dd/yy)
+'+'
+ Date and time, separated by '+', for example
+ '2004-04-28+22:22:05.0000000000'. The time is given in the current
+ timezone (which may be affected by setting the TZ environment
+ variable). This is a GNU extension. The seconds field includes a
+ fractional part.
+
+
+File: find.info, Node: Formatting Flags, Prev: Time Formats, Up: Print File Information
+
+3.2.4 Formatting Flags
+----------------------
+
+The '%m' and '%d' directives support the '#', '0' and '+' flags, but the
+other directives do not, even if they print numbers. Numeric directives
+that do not support these flags include
+
+ 'G', 'U', 'b', 'D', 'k' and 'n'.
+
+ All fields support the format flag '-', which makes fields
+left-aligned. That is, if the field width is greater than the actual
+contents of the field, the requisite number of spaces are printed after
+the field content instead of before it.
+
+
+File: find.info, Node: Run Commands, Next: Delete Files, Prev: Print File Information, Up: Actions
+
+3.3 Run Commands
+================
+
+You can use the list of file names created by 'find' or 'locate' as
+arguments to other commands. In this way you can perform arbitrary
+actions on the files.
+
+* Menu:
+
+* Single File::
+* Multiple Files::
+* Querying::
+
+
+File: find.info, Node: Single File, Next: Multiple Files, Up: Run Commands
+
+3.3.1 Single File
+-----------------
+
+Here is how to run a command on one file at a time.
+
+ -- Action: -execdir command ;
+ Execute COMMAND; true if COMMAND returns zero. 'find' takes all
+ arguments after '-execdir' to be part of the command until an
+ argument consisting of ';' is reached. It replaces the string '{}'
+ by the current file name being processed everywhere it occurs in
+ the command. Both of these constructions need to be escaped (with
+ a '\') or quoted to protect them from expansion by the shell. The
+ command is executed in the directory which 'find' was searching at
+ the time the action was executed (that is, {} will expand to a file
+ in the local directory).
+
+ For example, to compare each C header file in or below the current
+ directory with the file '/tmp/master':
+
+ find . -name '*.h' -execdir diff -u '{}' /tmp/master ';'
+
+ If you use '-execdir', you must ensure that the '$PATH' variable
+contains only absolute directory names. Having an empty element in
+'$PATH' or explicitly including '.' (or any other non-absolute name) is
+insecure. GNU find will refuse to run if you use '-execdir' and it
+thinks your '$PATH' setting is insecure. For example:
+
+'/bin:/usr/bin:'
+ Insecure; empty path element (at the end)
+':/bin:/usr/bin:/usr/local/bin'
+ Insecure; empty path element (at the start)
+'/bin:/usr/bin::/usr/local/bin'
+ Insecure; empty path element (two colons in a row)
+'/bin:/usr/bin:.:/usr/local/bin'
+ Insecure; '.' is a path element ('.' is not an absolute file name)
+'/bin:/usr/bin:sbin:/usr/local/bin'
+ Insecure; 'sbin' is not an absolute file name
+'/bin:/usr/bin:/sbin:/usr/local/bin'
+ Secure (if you control the contents of those directories and any
+ access to them)
+
+ Another similar option, '-exec' is supported, but is less secure.
+*Note Security Considerations::, for a discussion of the security
+problems surrounding '-exec'.
+
+ -- Action: -exec command ;
+ This insecure variant of the '-execdir' action is specified by
+ POSIX. Like '-execdir command ;' it is true if zero is returned by
+ COMMAND. The main difference is that the command is executed in
+ the directory from which 'find' was invoked, meaning that '{}' is
+ expanded to a relative path starting with the name of one of the
+ starting directories, rather than just the basename of the matched
+ file.
+
+ While some implementations of 'find' replace the '{}' only where it
+ appears on its own in an argument, GNU 'find' replaces '{}'
+ wherever it appears.
+
+
+File: find.info, Node: Multiple Files, Next: Querying, Prev: Single File, Up: Run Commands
+
+3.3.2 Multiple Files
+--------------------
+
+Sometimes you need to process files one at a time. But usually this is
+not necessary, and, it is faster to run a command on as many files as
+possible at a time, rather than once per file. Doing this saves on the
+time it takes to start up the command each time.
+
+ The '-execdir' and '-exec' actions have variants that build command
+lines containing as many matched files as possible.
+
+ -- Action: -execdir command {} +
+ This works as for '-execdir command ;', except that the result is
+ always true, and the '{}' at the end of the command is expanded to
+ a list of names of matching files. This expansion is done in such
+ a way as to avoid exceeding the maximum command line length
+ available on the system. Only one '{}' is allowed within the
+ command, and it must appear at the end, immediately before the '+'.
+ A '+' appearing in any position other than immediately after '{}'
+ is not considered to be special (that is, it does not terminate the
+ command).
+
+ -- Action: -exec command {} +
+ This insecure variant of the '-execdir' action is specified by
+ POSIX. The main difference is that the command is executed in the
+ directory from which 'find' was invoked, meaning that '{}' is
+ expanded to a relative path starting with the name of one of the
+ starting directories, rather than just the basename of the matched
+ file. The result is always true.
+
+ Before 'find' exits, any partially-built command lines are executed.
+This happens even if the exit was caused by the '-quit' action.
+However, some types of error (for example not being able to invoke
+'stat()' on the current directory) can cause an immediate fatal exit.
+In this situation, any partially-built command lines will not be invoked
+(this prevents possible infinite loops).
+
+ At first sight, it looks like the list of filenames to be processed
+can only be at the end of the command line, and that this might be a
+problem for some commands ('cp' and 'rsync' for example).
+
+ However, there is a slightly obscure but powerful workaround for this
+problem which takes advantage of the behaviour of 'sh -c':
+
+ find startpoint -tests ... -exec sh -c 'scp "$@" remote:/dest' sh {} +
+
+ In the example above, the filenames we want to work on need to occur
+on the 'scp' command line before the name of the destination. We use
+the shell to invoke the command 'scp "$@" remote:/dest' and the shell
+expands '"$@"' to the list of filenames we want to process.
+
+ Another, but less secure, way to run a command on more than one file
+at once, is to use the 'xargs' command, which is invoked like this:
+
+ xargs [OPTION...] [COMMAND [INITIAL-ARGUMENTS]]
+
+ 'xargs' normally reads arguments from the standard input. These
+arguments are delimited by blanks (which can be protected with double or
+single quotes or a backslash) or newlines. It executes the COMMAND (the
+default is 'echo') one or more times with any INITIAL-ARGUMENTS followed
+by arguments read from standard input. Blank lines on the standard
+input are ignored. If the '-L' option is in use, trailing blanks
+indicate that 'xargs' should consider the following line to be part of
+this one.
+
+ Instead of blank-delimited names, it is safer to use 'find -print0'
+or 'find -fprint0' and process the output by giving the '-0' or '--null'
+option to GNU 'xargs', GNU 'tar', GNU 'cpio', or 'perl'. The 'locate'
+command also has a '-0' or '--null' option which does the same thing.
+
+ You can use shell command substitution (backquotes) to process a list
+of arguments, like this:
+
+ grep -l sprintf `find $HOME -name '*.c' -print`
+
+ However, that method produces an error if the length of the '.c' file
+names exceeds the operating system's command line length limit. 'xargs'
+avoids that problem by running the command as many times as necessary
+without exceeding the limit:
+
+ find $HOME -name '*.c' -print | xargs grep -l sprintf
+
+ However, if the command needs to have its standard input be a
+terminal ('less', for example), you have to use the shell command
+substitution method or use the '--arg-file' option of 'xargs'.
+
+ The 'xargs' command will process all its input, building command
+lines and executing them, unless one of the commands exits with a status
+of 255 (this will cause xargs to issue an error message and stop) or it
+reads a line contains the end of file string specified with the '--eof'
+option.
+
+* Menu:
+
+* Unsafe File Name Handling::
+* Safe File Name Handling::
+* Unusual Characters in File Names::
+* Limiting Command Size::
+* Controlling Parallelism::
+* Interspersing File Names::
+
+
+File: find.info, Node: Unsafe File Name Handling, Next: Safe File Name Handling, Up: Multiple Files
+
+3.3.2.1 Unsafe File Name Handling
+.................................
+
+Because file names can contain quotes, backslashes, blank characters,
+and even newlines, it is not safe to process them using 'xargs' in its
+default mode of operation. But since most files' names do not contain
+blanks, this problem occurs only infrequently. If you are only
+searching through files that you know have safe names, then you need not
+be concerned about it.
+
+ Error messages issued by 'find' and 'locate' quote unusual characters
+in file names in order to prevent unwanted changes in the terminal's
+state.
+
+ In many applications, if 'xargs' botches processing a file because
+its name contains special characters, some data might be lost. The
+importance of this problem depends on the importance of the data and
+whether anyone notices the loss soon enough to correct it. However,
+here is an extreme example of the problems that using blank-delimited
+names can cause. If the following command is run daily from 'cron',
+then any user can remove any file on the system:
+
+ find / -name '#*' -atime +7 -print | xargs rm
+
+ For example, you could do something like this:
+
+ eg$ echo > '#
+ vmunix'
+
+and then 'cron' would delete '/vmunix', if it ran 'xargs' with '/' as
+its current directory.
+
+ To delete other files, for example '/u/joeuser/.plan', you could do
+this:
+
+ eg$ mkdir '#
+ '
+ eg$ cd '#
+ '
+ eg$ mkdir u u/joeuser u/joeuser/.plan'
+ '
+ eg$ echo > u/joeuser/.plan'
+ /#foo'
+ eg$ cd ..
+ eg$ find . -name '#*' -print | xargs echo
+ ./# ./# /u/joeuser/.plan /#foo
+
+
+File: find.info, Node: Safe File Name Handling, Next: Unusual Characters in File Names, Prev: Unsafe File Name Handling, Up: Multiple Files
+
+3.3.2.2 Safe File Name Handling
+...............................
+
+Here is how to make 'find' output file names so that they can be used by
+other programs without being mangled or misinterpreted. You can process
+file names generated this way by giving the '-0' or '--null' option to
+GNU 'xargs', GNU 'tar', GNU 'cpio', or 'perl'.
+
+ -- Action: -print0
+ True; print the entire file name on the standard output, followed
+ by a null character.
+
+ -- Action: -fprint0 file
+ True; like '-print0' but write to FILE like '-fprint' (*note Print
+ File Name::). The output file is always created.
+
+ As of findutils version 4.2.4, the 'locate' program also has a
+'--null' option which does the same thing. For similarity with 'xargs',
+the short form of the option '-0' can also be used.
+
+ If you want to be able to handle file names safely but need to run
+commands which want to be connected to a terminal on their input, you
+can use the '--arg-file' option to 'xargs' like this:
+
+ find / -name xyzzy -print0 > list
+ xargs --null --arg-file=list munge
+
+ The example above runs the 'munge' program on all the files named
+'xyzzy' that we can find, but 'munge''s input will still be the terminal
+(or whatever the shell was using as standard input). If your shell has
+the "process substitution" feature '<(...)', you can do this in just one
+step:
+
+ xargs --null --arg-file=<(find / -name xyzzy -print0) munge
+
+
+File: find.info, Node: Unusual Characters in File Names, Next: Limiting Command Size, Prev: Safe File Name Handling, Up: Multiple Files
+
+3.3.2.3 Unusual Characters in File Names
+........................................
+
+As discussed above, you often need to be careful about how the names of
+files are handled by 'find' and other programs. If the output of 'find'
+is not going to another program but instead is being shown on a
+terminal, this can still be a problem. For example, some character
+sequences can reprogram the function keys on some terminals. *Note
+Security Considerations::, for a discussion of other security problems
+relating to 'find'.
+
+ Unusual characters are handled differently by various actions, as
+described below.
+
+'-print0'
+'-fprint0'
+ Always print the exact file name, unchanged, even if the output is
+ going to a terminal.
+'-ok'
+'-okdir'
+ Always print the exact file name, unchanged. This will probably
+ change in a future release.
+'-ls'
+'-fls'
+ Unusual characters are always escaped. White space, backslash, and
+ double quote characters are printed using C-style escaping (for
+ example '\f', '\"'). Other unusual characters are printed using an
+ octal escape. Other printable characters (for '-ls' and '-fls'
+ these are the characters between octal 041 and 0176) are printed
+ as-is.
+'-printf'
+'-fprintf'
+ If the output is not going to a terminal, it is printed as-is.
+ Otherwise, the result depends on which directive is in use:
+
+ %D, %F, %H, %Y, %y
+ These expand to values which are not under control of files'
+ owners, and so are printed as-is.
+ %a, %b, %c, %d, %g, %G, %i, %k, %m, %M, %n, %s, %t, %u, %U
+ These have values which are under the control of files' owners
+ but which cannot be used to send arbitrary data to the
+ terminal, and so these are printed as-is.
+ %f, %h, %l, %p, %P
+ The output of these directives is quoted if the output is
+ going to a terminal. The setting of the 'LC_CTYPE'
+ environment variable is used to determine which characters
+ need to be quoted.
+
+ This quoting is performed in the same way as for GNU 'ls'.
+ This is not the same quoting mechanism as the one used for
+ '-ls' and 'fls'. If you are able to decide what format to use
+ for the output of 'find' then it is normally better to use
+ '\0' as a terminator than to use newline, as file names can
+ contain white space and newline characters.
+'-print'
+'-fprint'
+ Quoting is handled in the same way as for the '%p' directive of
+ '-printf' and '-fprintf'. If you are using 'find' in a script or
+ in a situation where the matched files might have arbitrary names,
+ you should consider using '-print0' instead of '-print'.
+
+ The 'locate' program quotes and escapes unusual characters in file
+names in the same way as 'find''s '-print' action.
+
+ The behaviours described above may change soon, as the treatment of
+unprintable characters is harmonised for '-ls', '-fls', '-print',
+'-fprint', '-printf' and '-fprintf'.
+
+
+File: find.info, Node: Limiting Command Size, Next: Controlling Parallelism, Prev: Unusual Characters in File Names, Up: Multiple Files
+
+3.3.2.4 Limiting Command Size
+.............................
+
+'xargs' gives you control over how many arguments it passes to the
+command each time it executes it. By default, it uses up to 'ARG_MAX' -
+2k, or 128k, whichever is smaller, characters per command. It uses as
+many lines and arguments as fit within that limit. The following
+options modify those values.
+
+'--no-run-if-empty'
+'-r'
+ If the standard input does not contain any nonblanks, do not run
+ the command. By default, the command is run once even if there is
+ no input. This option is a GNU extension.
+
+'--max-lines[=MAX-LINES]'
+'-L MAX-LINES'
+'-l[MAX-LINES]'
+ Use at most MAX-LINES nonblank input lines per command line;
+ MAX-LINES defaults to 1 if omitted; omitting the argument is not
+ allowed in the case of the '-L' option. Trailing blanks cause an
+ input line to be logically continued on the next input line, for
+ the purpose of counting the lines. Implies '-x'. The preferred
+ name for this option is '-L' as this is specified by POSIX.
+
+'--max-args=MAX-ARGS'
+'-n MAX-ARGS'
+ Use at most MAX-ARGS arguments per command line. Fewer than
+ MAX-ARGS arguments will be used if the size (see the '-s' option)
+ is exceeded, unless the '-x' option is given, in which case 'xargs'
+ will exit.
+
+'--max-chars=MAX-CHARS'
+'-s MAX-CHARS'
+ Use at most MAX-CHARS characters per command line, including the
+ command initial arguments and the terminating nulls at the ends of
+ the argument strings. If you specify a value for this option which
+ is too large or small, a warning message is printed and the
+ appropriate upper or lower limit is used instead. You can use
+ '--show-limits' option to understand the command-line limits
+ applying to 'xargs' and how this is affected by any other options.
+ The POSIX limits shown when you do this have already been adjusted
+ to take into account the size of your environment variables.
+
+ The largest allowed value is system-dependent, and is calculated as
+ the argument length limit for exec, less the size of your
+ environment, less 2048 bytes of headroom. If this value is more
+ than 128KiB, 128Kib is used as the default value; otherwise, the
+ default value is the maximum.
+
+
+File: find.info, Node: Controlling Parallelism, Next: Interspersing File Names, Prev: Limiting Command Size, Up: Multiple Files
+
+3.3.2.5 Controlling Parallelism
+...............................
+
+Normally, 'xargs' runs one command at a time. This is called "serial"
+execution; the commands happen in a series, one after another. If you'd
+like 'xargs' to do things in "parallel", you can ask it to do so, either
+when you invoke it, or later while it is running. Running several
+commands at one time can make the entire operation go more quickly, if
+the commands are independent, and if your system has enough resources to
+handle the load. When parallelism works in your application, 'xargs'
+provides an easy way to get your work done faster.
+
+'--max-procs=MAX-PROCS'
+'-P MAX-PROCS'
+ Run up to MAX-PROCS processes at a time; the default is 1. If
+ MAX-PROCS is 0, 'xargs' will run as many processes as possible at a
+ time. Use the '-n', '-s', or '-L' option with '-P'; otherwise
+ chances are that the command will be run only once.
+
+ For example, suppose you have a directory tree of large image files
+and a 'makeallsizes' script that takes a single file name and creates
+various sized images from it (thumbnail-sized, web-page-sized,
+printer-sized, and the original large file). The script is doing enough
+work that it takes significant time to run, even on a single image. You
+could run:
+
+ find originals -name '*.jpg' | xargs -1 makeallsizes
+
+ This will run 'makeallsizes FILENAME' once for each '.jpg' file in
+the 'originals' directory. However, if your system has two central
+processors, this script will only keep one of them busy. Instead, you
+could probably finish in about half the time by running:
+
+ find originals -name '*.jpg' | xargs -1 -P 2 makeallsizes
+
+ 'xargs' will run the first two commands in parallel, and then
+whenever one of them terminates, it will start another one, until the
+entire job is done.
+
+ The same idea can be generalized to as many processors as you have
+handy. It also generalizes to other resources besides processors. For
+example, if 'xargs' is running commands that are waiting for a response
+from a distant network connection, running a few in parallel may reduce
+the overall latency by overlapping their waiting time.
+
+ If you are running commands in parallel, you need to think about how
+they should arbitrate access to any resources that they share. For
+example, if more than one of them tries to print to stdout, the ouptut
+will be produced in an indeterminate order (and very likely mixed up)
+unless the processes collaborate in some way to prevent this. Using
+some kind of locking scheme is one way to prevent such problems. In
+general, using a locking scheme will help ensure correct output but
+reduce performance. If you don't want to tolerate the performance
+difference, simply arrange for each process to produce a separate output
+file (or otherwise use separate resources).
+
+ 'xargs' also allows you to "turn up" or "turn down" its parallelism
+in the middle of a run. Suppose you are keeping your four-processor
+system busy for hours, processing thousands of images using '-P 4'.
+Now, in the middle of the run, you or someone else wants you to reduce
+your load on the system, so that something else will run faster. If you
+interrupt 'xargs', your job will be half-done, and it may take
+significant manual work to resume it only for the remaining images. If
+you suspend 'xargs' using your shell's job controls (e.g. 'control-Z'),
+then it will get no work done while suspended.
+
+ Find out the process ID of the 'xargs' process, either from your
+shell or with the 'ps' command. After you send it the signal 'SIGUSR2',
+'xargs' will run one fewer command in parallel. If you send it the
+signal 'SIGUSR1', it will run one more command in parallel. For
+example:
+
+ shell$ xargs <allimages -1 -P 4 makeallsizes &
+ [4] 27643
+ ... at some later point ...
+ shell$ kill -USR2 27643
+ shell$ kill -USR2 %4
+
+ The first 'kill' command will cause 'xargs' to wait for two commands
+to terminate before starting the next command (reducing the parallelism
+from 4 to 3). The second 'kill' will reduce it from 3 to 2. ('%4'
+works in some shells as a shorthand for the process ID of the background
+job labeled '[4]'.)
+
+ Similarly, if you started a long 'xargs' job without parallelism, you
+can easily switch it to start running two commands in parallel by
+sending it a 'SIGUSR1'.
+
+ 'xargs' will never terminate any existing commands when you ask it to
+run fewer processes. It merely waits for the excess commands to finish.
+If you ask it to run more commands, it will start the next one
+immediately (if it has more work to do). If the degree of parallelism
+is already 1, sending 'SIGUSR2' will have no further effect (since
+'--max-procs=0' means that there should be no limit on the number of
+processes to run).
+
+ There is an implementation-defined limit on the number of processes.
+This limit is shown with 'xargs --show-limits'. The limit is at least
+127 on all systems (and on the author's system it is 2147483647).
+
+ If you send several identical signals quickly, the operating system
+does not guarantee that each of them will be delivered to 'xargs'. This
+means that you can't rapidly increase or decrease the parallelism by
+more than one command at a time. You can avoid this problem by sending
+a signal, observing the result, then sending the next one; or merely by
+delaying for a few seconds between signals (unless your system is very
+heavily loaded).
+
+ Whether or not parallel execution will work well for you depends on
+the nature of the commmand you are running in parallel, on the
+configuration of the system on which you are running the command, and on
+the other work being done on the system at the time.
+
+
+File: find.info, Node: Interspersing File Names, Prev: Controlling Parallelism, Up: Multiple Files
+
+3.3.2.6 Interspersing File Names
+................................
+
+'xargs' can insert the name of the file it is processing between
+arguments you give for the command. Unless you also give options to
+limit the command size (*note Limiting Command Size::), this mode of
+operation is equivalent to 'find -exec' (*note Single File::).
+
+'--replace[=REPLACE-STR]'
+'-I REPLACE-STR'
+'-i REPLACE-STR'
+ Replace occurrences of REPLACE-STR in the initial arguments with
+ names read from the input. Also, unquoted blanks do not terminate
+ arguments; instead, the input is split at newlines only. For the
+ '-i' option, if REPLACE-STR is omitted for '--replace' or '-i', it
+ defaults to '{}' (like for 'find -exec'). Implies '-x' and '-l 1'.
+ '-i' is deprecated in favour of '-I'. As an example, to sort each
+ file in the 'bills' directory, leaving the output in that file name
+ with '.sorted' appended, you could do:
+
+ find bills -type f | xargs -I XX sort -o XX.sorted XX
+
+ The equivalent command using 'find -execdir' is:
+
+ find bills -type f -execdir sort -o '{}.sorted' '{}' ';'
+
+ When you use the '-I' option, each line read from the input is
+buffered internally. This means that there is an upper limit on the
+length of input line that 'xargs' will accept when used with the '-I'
+option. To work around this limitation, you can use the '-s' option to
+increase the amount of buffer space that xargs uses, and you can also
+use an extra invocation of xargs to ensure that very long lines do not
+occur. For example:
+
+ somecommand | xargs -s 50000 echo | xargs -I '{}' -s 100000 rm '{}'
+
+ Here, the first invocation of 'xargs' has no input line length limit
+because it doesn't use the '-I' option. The second invocation of
+'xargs' does have such a limit, but we have ensured that it never
+encounters a line which is longer than it can handle.
+
+ This is not an ideal solution. Instead, the '-I' option should not
+impose a line length limit (apart from any limit imposed by the
+operating system) and so one might consider this limitation to be a bug.
+A better solution would be to allow 'xargs -I' to automatically move to
+a larger value for the '-s' option when this is needed.
+
+ This sort of problem doesn't occur with the output of 'find' because
+it emits just one filename per line.
+
+
+File: find.info, Node: Querying, Prev: Multiple Files, Up: Run Commands
+
+3.3.3 Querying
+--------------
+
+To ask the user whether to execute a command on a single file, you can
+use the 'find' primary '-okdir' instead of '-execdir', and the 'find'
+primary '-ok' instead of '-exec':
+
+ -- Action: -okdir command ;
+ Like '-execdir' (*note Single File::), but ask the user first. If
+ the user does not agree to run the command, just return false.
+ Otherwise, run it, with standard input redirected from '/dev/null'.
+
+ The response to the prompt is matched against a pair of regular
+ expressions to determine if it is a yes or no response. These
+ regular expressions are obtained from the system ('nl_langinfo'
+ items YESEXPR and NOEXPR are used) if the 'POSIXLY_CORRECT'
+ environment variable is set and the system has such patterns
+ available. Otherwise, 'find''s message translations are used. In
+ either case, the 'LC_MESSAGES' environment variable will determine
+ the regular expressions used to determine if the answer is
+ affirmative or negative. The interpretation of the regular
+ expressions themselves will be affected by the environment
+ variables 'LC_CTYPE' (character classes) and 'LC_COLLATE'
+ (character ranges and equivalence classes).
+
+ -- Action: -ok command ;
+ This insecure variant of the '-okdir' action is specified by POSIX.
+ The main difference is that the command is executed in the
+ directory from which 'find' was invoked, meaning that '{}' is
+ expanded to a relative path starting with the name of one of the
+ starting directories, rather than just the basename of the matched
+ file. If the command is run, its standard input is redirected from
+ '/dev/null'.
+
+ When processing multiple files with a single command, to query the
+user you give 'xargs' the following option. When using this option, you
+might find it useful to control the number of files processed per
+invocation of the command (*note Limiting Command Size::).
+
+'--interactive'
+'-p'
+ Prompt the user about whether to run each command line and read a
+ line from the terminal. Only run the command line if the response
+ starts with 'y' or 'Y'. Implies '-t'.
+
+
+File: find.info, Node: Delete Files, Next: Adding Tests, Prev: Run Commands, Up: Actions
+
+3.4 Delete Files
+================
+
+ -- Action: -delete
+ Delete files or directories; true if removal succeeded. If the
+ removal failed, an error message is issued.
+
+ The use of the '-delete' action on the command line automatically
+ turns on the '-depth' option (*note find Expressions::). This can
+ be surprising if you were previously just testing with '-print', so
+ it is usually best to remember to use '-depth' explicitly.
+
+ If '-delete' fails, 'find''s exit status will be nonzero (when it
+ eventually exits).
+
+
+File: find.info, Node: Adding Tests, Prev: Delete Files, Up: Actions
+
+3.5 Adding Tests
+================
+
+You can test for file attributes that none of the 'find' builtin tests
+check. To do this, use 'xargs' to run a program that filters a list of
+files printed by 'find'. If possible, use 'find' builtin tests to pare
+down the list, so the program run by 'xargs' has less work to do. The
+tests builtin to 'find' will likely run faster than tests that other
+programs perform.
+
+ For reasons of efficiency it is often useful to limit the number of
+times an external program has to be run. For this reason, it is often a
+good idea to implement "extended" tests by using 'xargs'.
+
+ For example, here is a way to print the names of all of the
+unstripped binaries in the '/usr/local' directory tree. Builtin tests
+avoid running 'file' on files that are not regular files or are not
+executable.
+
+ find /usr/local -type f -perm /a=x | xargs file |
+ grep 'not stripped' | cut -d: -f1
+
+The 'cut' program removes everything after the file name from the output
+of 'file'.
+
+ However, using 'xargs' can present important security problems (*note
+Security Considerations::). These can be avoided by using '-execdir'.
+The '-execdir' action is also a useful way of putting your own test in
+the middle of a set of other tests or actions for 'find' (for example,
+you might want to use '-prune').
+
+ To place a special test somewhere in the middle of a 'find'
+expression, you can use '-execdir' (or, less securely, '-exec') to run a
+program that performs the test. Because '-execdir' evaluates to the
+exit status of the executed program, you can use a program (which can be
+a shell script) that tests for a special attribute and make it exit with
+a true (zero) or false (non-zero) status. It is a good idea to place
+such a special test _after_ the builtin tests, because it starts a new
+process which could be avoided if a builtin test evaluates to false.
+
+ Here is a shell script called 'unstripped' that checks whether its
+argument is an unstripped binary file:
+
+ #! /bin/sh
+ file "$1" | grep -q "not stripped"
+
+ This script relies on the shell exiting with the status of the last
+command in the pipeline, in this case 'grep'. The 'grep' command exits
+with a true status if it found any matches, false if not. Here is an
+example of using the script (assuming it is in your search path). It
+lists the stripped executables (and shell scripts) in the file 'sbins'
+and the unstripped ones in 'ubins'.
+
+ find /usr/local -type f -perm /a=x \
+ \( -execdir unstripped '{}' \; -fprint ubins -o -fprint sbins \)
+
+
+File: find.info, Node: Databases, Next: File Permissions, Prev: Actions, Up: Top
+
+4 File Name Databases
+*********************
+
+The file name databases used by 'locate' contain lists of files that
+were in particular directory trees when the databases were last updated.
+The file name of the default database is determined when 'locate' and
+'updatedb' are configured and installed. The frequency with which the
+databases are updated and the directories for which they contain entries
+depend on how often 'updatedb' is run, and with which arguments.
+
+ You can obtain some statistics about the databases by using 'locate
+--statistics'.
+
+* Menu:
+
+* Database Locations::
+* Database Formats::
+* Newline Handling::
+
+
+File: find.info, Node: Database Locations, Next: Database Formats, Up: Databases
+
+4.1 Database Locations
+======================
+
+There can be multiple file name databases. Users can select which
+databases 'locate' searches using the 'LOCATE_PATH' environment variable
+or a command line option. The system administrator can choose the file
+name of the default database, the frequency with which the databases are
+updated, and the directories for which they contain entries. File name
+databases are updated by running the 'updatedb' program, typically
+nightly.
+
+ In networked environments, it often makes sense to build a database
+at the root of each filesystem, containing the entries for that
+filesystem. 'updatedb' is then run for each filesystem on the
+fileserver where that filesystem is on a local disk, to prevent
+thrashing the network.
+
+ *Note Invoking updatedb::, for the description of the options to
+'updatedb'. These options can be used to specify which directories are
+indexed by each database file.
+
+ The default location for the locate database depends on how findutils
+is built, but the findutils installation accompanying this manual uses
+the default location '/usr/local/var/locatedb'.
+
+ If no database exists at '/usr/local/var/locatedb' but the user did
+not specify where to look (by using '-d' or setting 'LOCATE_PATH'), then
+'locate' will also check for a "secure" database in
+'/var/lib/slocate/slocate.db'.
+
+
+File: find.info, Node: Database Formats, Next: Newline Handling, Prev: Database Locations, Up: Databases
+
+4.2 Database Formats
+====================
+
+The file name databases contain lists of files that were in particular
+directory trees when the databases were last updated. The file name
+database format changed starting with GNU 'locate' version 4.0 to allow
+machines with different byte orderings to share the databases.
+
+ GNU 'locate' can read both the old and new database formats.
+However, old versions of 'locate' (on other Unix systems, or GNU
+'locate' before version 4.0) produce incorrect results if run against a
+database in something other than the old format.
+
+ Support for the old database format will eventually be discontinued,
+first in 'updatedb' and later in 'locate'.
+
+ If you run 'locate --statistics', the resulting summary indicates the
+type of each 'locate' database. You select which database format
+'updatedb' will use with the '--dbformat' option.
+
+* Menu:
+
+* LOCATE02 Database Format::
+* Sample LOCATE02 Database::
+* slocate Database Format::
+* Old Database Format::
+
+
+File: find.info, Node: LOCATE02 Database Format, Next: Sample LOCATE02 Database, Up: Database Formats
+
+4.2.1 LOCATE02 Database Format
+------------------------------
+
+'updatedb' runs a program called 'frcode' to "front-compress" the list
+of file names, which reduces the database size by a factor of 4 to 5.
+Front-compression (also known as incremental encoding) works as follows.
+
+ The database entries are a sorted list (case-insensitively, for
+users' convenience). Since the list is sorted, each entry is likely to
+share a prefix (initial string) with the previous entry. Each database
+entry begins with an offset-differential count byte, which is the
+additional number of characters of prefix of the preceding entry to use
+beyond the number that the preceding entry is using of its predecessor.
+(The counts can be negative.) Following the count is a null-terminated
+ASCII remainder - the part of the name that follows the shared prefix.
+
+ If the offset-differential count is larger than can be stored in a
+byte (+/-127), the byte has the value 0x80 and the count follows in a
+2-byte word, with the high byte first (network byte order).
+
+ Every database begins with a dummy entry for a file called
+'LOCATE02', which 'locate' checks for to ensure that the database file
+has the correct format; it ignores the entry in doing the search.
+
+ Databases cannot be concatenated together, even if the first (dummy)
+entry is trimmed from all but the first database. This is because the
+offset-differential count in the first entry of the second and following
+databases will be wrong.
+
+ In the output of 'locate --statistics', the new database format is
+referred to as 'LOCATE02'.
+
+
+File: find.info, Node: Sample LOCATE02 Database, Next: slocate Database Format, Prev: LOCATE02 Database Format, Up: Database Formats
+
+4.2.2 Sample LOCATE02 Database
+------------------------------
+
+Sample input to 'frcode':
+
+ /usr/src
+ /usr/src/cmd/aardvark.c
+ /usr/src/cmd/armadillo.c
+ /usr/tmp/zoo
+
+ Length of the longest prefix of the preceding entry to share:
+
+ 0 /usr/src
+ 8 /cmd/aardvark.c
+ 14 rmadillo.c
+ 5 tmp/zoo
+
+ Output from 'frcode', with trailing nulls changed to newlines and
+count bytes made printable:
+
+ 0 LOCATE02
+ 0 /usr/src
+ 8 /cmd/aardvark.c
+ 6 rmadillo.c
+ -9 tmp/zoo
+
+ (6 = 14 - 8, and -9 = 5 - 14)
+
+
+File: find.info, Node: slocate Database Format, Next: Old Database Format, Prev: Sample LOCATE02 Database, Up: Database Formats
+
+4.2.3 slocate Database Format
+-----------------------------
+
+The 'slocate' program uses a database format similar to, but not quite
+the same as, GNU 'locate'. The first byte of the database specifies its
+"security level". If the security level is 0, 'slocate' will read,
+match and print filenames on the basis of the information in the
+database only. However, if the security level byte is 1, 'slocate'
+omits entries from its output if the invoking user is unable to access
+them. The second byte of the database is zero. The second byte is
+immediately followed by the first database entry. The first entry in
+the database is not preceded by any differential count or dummy entry.
+Instead the differential count for the first item is assumed to be zero.
+
+ Starting with the second entry (if any) in the database, data is
+interpreted as for the GNU LOCATE02 format.
+
+
+File: find.info, Node: Old Database Format, Prev: slocate Database Format, Up: Database Formats
+
+4.2.4 Old Database Format
+-------------------------
+
+The old database format is used by Unix 'locate' and 'find' programs and
+earlier releases of the GNU ones. 'updatedb' produces this format if
+given the '--old-format' option.
+
+ 'updatedb' runs programs called 'bigram' and 'code' to produce
+old-format databases. The old format differs from the new one in the
+following ways. Instead of each entry starting with an
+offset-differential count byte and ending with a null, byte values from
+0 through 28 indicate offset-differential counts from -14 through 14.
+The byte value indicating that a long offset-differential count follows
+is 0x1e (30), not 0x80. The long counts are stored in host byte order,
+which is not necessarily network byte order, and host integer word size,
+which is usually 4 bytes. They also represent a count 14 less than
+their value. The database lines have no termination byte; the start of
+the next line is indicated by its first byte having a value <= 30.
+
+ In addition, instead of starting with a dummy entry, the old database
+format starts with a 256 byte table containing the 128 most common
+bigrams in the file list. A bigram is a pair of adjacent bytes. Bytes
+in the database that have the high bit set are indexes (with the high
+bit cleared) into the bigram table. The bigram and offset-differential
+count coding makes these databases 20-25% smaller than the new format,
+but makes them not 8-bit clean. Any byte in a file name that is in the
+ranges used for the special codes is replaced in the database by a
+question mark, which not coincidentally is the shell wildcard to match a
+single character.
+
+ The old format therefore cannot faithfully store entries with
+non-ASCII characters. It therefore should not be used in
+internationalised environments. That is, most installations should not
+use it.
+
+ Because the long counts are stored by the 'code' program as
+native-order machine words, the database format is not easily used in
+environments which differ in terms of byte order. If locate databases
+are to be shared between machines, the LOCATE02 database format should
+be used. This has other benefits as discussed above. However, the
+length of the filename currently being processed can normally be used to
+place reasonable limits on the long counts and so this information is
+used by locate to help it guess the byte ordering of the old format
+database. Unless it finds evidence to the contrary, 'locate' will
+assume that the byte order of the database is the same as the native
+byte order of the machine running 'locate'. The output of 'locate
+--statistics' also includes information about the byte order of
+old-format databases.
+
+ The output of 'locate --statistics' will give an incorrect count of
+the number of file names containing newlines or high-bit characters for
+old-format databases.
+
+ Old versions of GNU 'locate' fail to correctly handle very long file
+names, possibly leading to security problems relating to a heap buffer
+overrun. *Note Security Considerations for locate::, for a detailed
+explanation.
+
+
+File: find.info, Node: Newline Handling, Prev: Database Formats, Up: Databases
+
+4.3 Newline Handling
+====================
+
+Within the database, file names are terminated with a null character.
+This is the case for both the old and the new format.
+
+ When the new database format is being used, the compression technique
+used to generate the database though relies on the ability to sort the
+list of files before they are presented to 'frcode'.
+
+ If the system's sort command allows its input list of files to be
+separated with null characters via the '-z' option, this option is used
+and therefore 'updatedb' and 'locate' will both correctly handle file
+names containing newlines. If the 'sort' command lacks support for
+this, the list of files is delimited with the newline character, meaning
+that parts of file names containing newlines will be incorrectly sorted.
+This can result in both incorrect matches and incorrect failures to
+match.
+
+ On the other hand, if you are using the old database format, file
+names with embedded newlines are not correctly handled. There is no
+technical limitation which enforces this, it's just that the 'bigram'
+program has not been updated to support lists of file names separated by
+nulls.
+
+ So, if you are using the new database format (this is the default)
+and your system uses GNU 'sort', newlines will be correctly handled at
+all times. Otherwise, newlines may not be correctly handled.
+
+
+File: find.info, Node: File Permissions, Next: Date input formats, Prev: Databases, Up: Top
+
+5 File Permissions
+******************
+
+Each file has a set of "permissions" that control the kinds of access
+that users have to that file. The permissions for a file are also
+called its "access mode". They can be represented either in symbolic
+form or as an octal number.
+
+* Menu:
+
+* Mode Structure:: Structure of file permissions.
+* Symbolic Modes:: Mnemonic permissions representation.
+* Numeric Modes:: Permissions as octal numbers.
+
+
+File: find.info, Node: Mode Structure, Next: Symbolic Modes, Up: File Permissions
+
+5.1 Structure of File Permissions
+=================================
+
+There are three kinds of permissions that a user can have for a file:
+
+ 1. permission to read the file. For directories, this means
+ permission to list the contents of the directory.
+ 2. permission to write to (change) the file. For directories, this
+ means permission to create and remove files in the directory.
+ 3. permission to execute the file (run it as a program). For
+ directories, this means permission to access files in the
+ directory.
+
+ There are three categories of users who may have different
+permissions to perform any of the above operations on a file:
+
+ 1. the file's owner;
+ 2. other users who are in the file's group;
+ 3. everyone else.
+
+ Files are given an owner and group when they are created. Usually
+the owner is the current user and the group is the group of the
+directory the file is in, but this varies with the operating system, the
+file system the file is created on, and the way the file is created.
+You can change the owner and group of a file by using the 'chown' and
+'chgrp' commands.
+
+ In addition to the three sets of three permissions listed above, a
+file's permissions have three special components, which affect only
+executable files (programs) and, on some systems, directories:
+
+ 1. Set the process's effective user ID to that of the file upon
+ execution (called the "setuid bit"). No effect on directories.
+ 2. Set the process's effective group ID to that of the file upon
+ execution (called the "setgid bit"). For directories on some
+ systems, put files created in the directory into the same group as
+ the directory, no matter what group the user who creates them is
+ in.
+ 3. prevent users from removing or renaming a file in a directory
+ unless they own the file or the directory; this is called the
+ "restricted deletion flag" for the directory. For regular files on
+ some systems, save the program's text image on the swap device so
+ it will load more quickly when run; this is called the "sticky
+ bit".
+
+ In addition to the permissions listed above, there may be file
+attributes specific to the file system, e.g: access control lists
+(ACLs), whether a file is compressed, whether a file can be modified
+(immutability), whether a file can be dumped. These are usually set
+using programs specific to the file system. For example:
+
+ext2
+ On GNU and GNU/Linux the file permissions ("attributes") specific
+ to the ext2 file system are set using 'chattr'.
+
+FFS
+ On FreeBSD the file permissions ("flags") specific to the FFS file
+ system are set using 'chrflags'.
+
+ Although a file's permission "bits" allow an operation on that file,
+that operation may still fail, because:
+
+ * the file-system-specific permissions do not permit it;
+
+ * the file system is mounted as read-only.
+
+ For example, if the immutable attribute is set on a file, it cannot
+be modified, regardless of the fact that you may have just run 'chmod
+a+w FILE'.
+
+
+File: find.info, Node: Symbolic Modes, Next: Numeric Modes, Prev: Mode Structure, Up: File Permissions
+
+5.2 Symbolic Modes
+==================
+
+"Symbolic modes" represent changes to files' permissions as operations
+on single-character symbols. They allow you to modify either all or
+selected parts of files' permissions, optionally based on their previous
+values, and perhaps on the current 'umask' as well (*note Umask and
+Protection::).
+
+ The format of symbolic modes is:
+
+ [ugoa...][+-=]PERMS...[,...]
+
+where PERMS is either zero or more letters from the set 'rwxXst', or a
+single letter from the set 'ugo'.
+
+ The following sections describe the operators and other details of
+symbolic modes.
+
+* Menu:
+
+* Setting Permissions:: Basic operations on permissions.
+* Copying Permissions:: Copying existing permissions.
+* Changing Special Permissions:: Special permissions.
+* Conditional Executability:: Conditionally affecting executability.
+* Multiple Changes:: Making multiple changes.
+* Umask and Protection:: The effect of the umask.
+
+
+File: find.info, Node: Setting Permissions, Next: Copying Permissions, Up: Symbolic Modes
+
+5.2.1 Setting Permissions
+-------------------------
+
+The basic symbolic operations on a file's permissions are adding,
+removing, and setting the permission that certain users have to read,
+write, and execute the file. These operations have the following
+format:
+
+ USERS OPERATION PERMISSIONS
+
+The spaces between the three parts above are shown for readability only;
+symbolic modes cannot contain spaces.
+
+ The USERS part tells which users' access to the file is changed. It
+consists of one or more of the following letters (or it can be empty;
+*note Umask and Protection::, for a description of what happens then).
+When more than one of these letters is given, the order that they are in
+does not matter.
+
+'u'
+ the user who owns the file;
+'g'
+ other users who are in the file's group;
+'o'
+ all other users;
+'a'
+ all users; the same as 'ugo'.
+
+ The OPERATION part tells how to change the affected users' access to
+the file, and is one of the following symbols:
+
+'+'
+ to add the PERMISSIONS to whatever permissions the USERS already
+ have for the file;
+'-'
+ to remove the PERMISSIONS from whatever permissions the USERS
+ already have for the file;
+'='
+ to make the PERMISSIONS the only permissions that the USERS have
+ for the file.
+
+ The PERMISSIONS part tells what kind of access to the file should be
+changed; it is normally zero or more of the following letters. As with
+the USERS part, the order does not matter when more than one letter is
+given. Omitting the PERMISSIONS part is useful only with the '='
+operation, where it gives the specified USERS no access at all to the
+file.
+
+'r'
+ the permission the USERS have to read the file;
+'w'
+ the permission the USERS have to write to the file;
+'x'
+ the permission the USERS have to execute the file.
+
+ For example, to give everyone permission to read and write a file,
+but not to execute it, use:
+
+ a=rw
+
+ To remove write permission for all users other than the file's owner,
+use:
+
+ go-w
+
+The above command does not affect the access that the owner of the file
+has to it, nor does it affect whether other users can read or execute
+the file.
+
+ To give everyone except a file's owner no permission to do anything
+with that file, use the mode below. Other users could still remove the
+file, if they have write permission on the directory it is in.
+
+ go=
+
+Another way to specify the same thing is:
+
+ og-rwx
+
+
+File: find.info, Node: Copying Permissions, Next: Changing Special Permissions, Prev: Setting Permissions, Up: Symbolic Modes
+
+5.2.2 Copying Existing Permissions
+----------------------------------
+
+You can base a file's permissions on its existing permissions. To do
+this, instead of using a series of 'r', 'w', or 'x' letters after the
+operator, you use the letter 'u', 'g', or 'o'. For example, the mode
+
+ o+g
+
+adds the permissions for users who are in a file's group to the
+permissions that other users have for the file. Thus, if the file
+started out as mode 664 ('rw-rw-r--'), the above mode would change it to
+mode 666 ('rw-rw-rw-'). If the file had started out as mode 741
+('rwxr----x'), the above mode would change it to mode 745 ('rwxr--r-x').
+The '-' and '=' operations work analogously.
+
+
+File: find.info, Node: Changing Special Permissions, Next: Conditional Executability, Prev: Copying Permissions, Up: Symbolic Modes
+
+5.2.3 Changing Special Permissions
+----------------------------------
+
+In addition to changing a file's read, write, and execute permissions,
+you can change its special permissions. *Note Mode Structure::, for a
+summary of these permissions.
+
+ To change a file's permission to set the user ID on execution, use
+'u' in the USERS part of the symbolic mode and 's' in the PERMISSIONS
+part.
+
+ To change a file's permission to set the group ID on execution, use
+'g' in the USERS part of the symbolic mode and 's' in the PERMISSIONS
+part.
+
+ To change a file's permission to set the restricted deletion flag or
+sticky bit, omit the USERS part of the symbolic mode (or use 'a') and
+put 't' in the PERMISSIONS part.
+
+ For example, to add set-user-ID permission to a program, you can use
+the mode:
+
+ u+s
+
+ To remove both set-user-ID and set-group-ID permission from it, you
+can use the mode:
+
+ ug-s
+
+ To set the restricted deletion flag or sticky bit, you can use the
+mode:
+
+ +t
+
+ The combination 'o+s' has no effect. On GNU systems the combinations
+'u+t' and 'g+t' have no effect, and 'o+t' acts like plain '+t'.
+
+ The '=' operator is not very useful with special permissions; for
+example, the mode:
+
+ o=t
+
+does set the restricted deletion flag or sticky bit, but it also removes
+all read, write, and execute permissions that users not in the file's
+group might have had for it.
+
+
+File: find.info, Node: Conditional Executability, Next: Multiple Changes, Prev: Changing Special Permissions, Up: Symbolic Modes
+
+5.2.4 Conditional Executability
+-------------------------------
+
+There is one more special type of symbolic permission: if you use 'X'
+instead of 'x', execute permission is affected only if the file is a
+directory or already had execute permission.
+
+ For example, this mode:
+
+ a+X
+
+gives all users permission to search directories, or to execute files if
+anyone could execute them before.
+
+
+File: find.info, Node: Multiple Changes, Next: Umask and Protection, Prev: Conditional Executability, Up: Symbolic Modes
+
+5.2.5 Making Multiple Changes
+-----------------------------
+
+The format of symbolic modes is actually more complex than described
+above (*note Setting Permissions::). It provides two ways to make
+multiple changes to files' permissions.
+
+ The first way is to specify multiple OPERATION and PERMISSIONS parts
+after a USERS part in the symbolic mode.
+
+ For example, the mode:
+
+ og+rX-w
+
+gives users other than the owner of the file read permission and, if it
+is a directory or if someone already had execute permission to it, gives
+them execute permission; and it also denies them write permission to the
+file. It does not affect the permission that the owner of the file has
+for it. The above mode is equivalent to the two modes:
+
+ og+rX
+ og-w
+
+ The second way to make multiple changes is to specify more than one
+simple symbolic mode, separated by commas. For example, the mode:
+
+ a+r,go-w
+
+gives everyone permission to read the file and removes write permission
+on it for all users except its owner. Another example:
+
+ u=rwx,g=rx,o=
+
+sets all of the non-special permissions for the file explicitly. (It
+gives users who are not in the file's group no permission at all for
+it.)
+
+ The two methods can be combined. The mode:
+
+ a+r,g+x-w
+
+gives all users permission to read the file, and gives users who are in
+the file's group permission to execute it, as well, but not permission
+to write to it. The above mode could be written in several different
+ways; another is:
+
+ u+r,g+rx,o+r,g-w
+
+
+File: find.info, Node: Umask and Protection, Prev: Multiple Changes, Up: Symbolic Modes
+
+5.2.6 The Umask and Protection
+------------------------------
+
+If the USERS part of a symbolic mode is omitted, it defaults to 'a'
+(affect all users), except that any permissions that are _set_ in the
+system variable 'umask' are _not affected_. The value of 'umask' can be
+set using the 'umask' command. Its default value varies from system to
+system.
+
+ Omitting the USERS part of a symbolic mode is generally not useful
+with operations other than '+'. It is useful with '+' because it allows
+you to use 'umask' as an easily customizable protection against giving
+away more permission to files than you intended to.
+
+ As an example, if 'umask' has the value 2, which removes write
+permission for users who are not in the file's group, then the mode:
+
+ +w
+
+adds permission to write to the file to its owner and to other users who
+are in the file's group, but _not_ to other users. In contrast, the
+mode:
+
+ a+w
+
+ignores 'umask', and _does_ give write permission for the file to all
+users.
+
+
+File: find.info, Node: Numeric Modes, Prev: Symbolic Modes, Up: File Permissions
+
+5.3 Numeric Modes
+=================
+
+As an alternative to giving a symbolic mode, you can give an octal (base
+8) number that represents the new mode. This number is always
+interpreted in octal; you do not have to add a leading 0, as you do in
+C. Mode 0055 is the same as mode 55.
+
+ A numeric mode is usually shorter than the corresponding symbolic
+mode, but it is limited in that it cannot take into account a file's
+previous permissions; it can only set them absolutely.
+
+ The permissions granted to the user, to other users in the file's
+group, and to other users not in the file's group each require three
+bits, which are represented as one octal digit. The three special
+permissions also require one bit each, and they are as a group
+represented as another octal digit. Here is how the bits are arranged,
+starting with the lowest valued bit:
+
+ Value in Corresponding
+ Mode Permission
+
+ Other users not in the file's group:
+ 1 Execute
+ 2 Write
+ 4 Read
+
+ Other users in the file's group:
+ 10 Execute
+ 20 Write
+ 40 Read
+
+ The file's owner:
+ 100 Execute
+ 200 Write
+ 400 Read
+
+ Special permissions:
+ 1000 Restricted deletion flag or sticky bit
+ 2000 Set group ID on execution
+ 4000 Set user ID on execution
+
+ For example, numeric mode 4755 corresponds to symbolic mode
+'u=rwxs,go=rx', and numeric mode 664 corresponds to symbolic mode
+'ug=rw,o=r'. Numeric mode 0 corresponds to symbolic mode 'a='.
+
+
+File: find.info, Node: Date input formats, Next: Configuration, Prev: File Permissions, Up: Top
+
+6 Date input formats
+********************
+
+First, a quote:
+
+ Our units of temporal measurement, from seconds on up to months,
+ are so complicated, asymmetrical and disjunctive so as to make
+ coherent mental reckoning in time all but impossible. Indeed, had
+ some tyrannical god contrived to enslave our minds to time, to make
+ it all but impossible for us to escape subjection to sodden
+ routines and unpleasant surprises, he could hardly have done better
+ than handing down our present system. It is like a set of
+ trapezoidal building blocks, with no vertical or horizontal
+ surfaces, like a language in which the simplest thought demands
+ ornate constructions, useless particles and lengthy
+ circumlocutions. Unlike the more successful patterns of language
+ and science, which enable us to face experience boldly or at least
+ level-headedly, our system of temporal calculation silently and
+ persistently encourages our terror of time.
+
+ ... It is as though architects had to measure length in feet, width
+ in meters and height in ells; as though basic instruction manuals
+ demanded a knowledge of five different languages. It is no wonder
+ then that we often look into our own immediate past or future, last
+ Tuesday or a week from Sunday, with feelings of helpless confusion.
+ ...
+
+ --Robert Grudin, 'Time and the Art of Living'.
+
+ This section describes the textual date representations that GNU
+programs accept. These are the strings you, as a user, can supply as
+arguments to the various programs. The C interface (via the
+'parse_datetime' function) is not described here.
+
+* Menu:
+
+* General date syntax:: Common rules.
+* Calendar date items:: 19 Dec 1994.
+* Time of day items:: 9:20pm.
+* Time zone items:: EST, PDT, UTC, ...
+* Combined date and time of day items:: 1972-09-24T20:02:00,000000-0500.
+* Day of week items:: Monday and others.
+* Relative items in date strings:: next tuesday, 2 years ago.
+* Pure numbers in date strings:: 19931219, 1440.
+* Seconds since the Epoch:: @1078100502.
+* Specifying time zone rules:: TZ="America/New_York", TZ="UTC0".
+* Authors of parse_datetime:: Bellovin, Eggert, Salz, Berets, et al.
+
+
+File: find.info, Node: General date syntax, Next: Calendar date items, Up: Date input formats
+
+6.1 General date syntax
+=======================
+
+A "date" is a string, possibly empty, containing many items separated by
+whitespace. The whitespace may be omitted when no ambiguity arises.
+The empty string means the beginning of today (i.e., midnight). Order
+of the items is immaterial. A date string may contain many flavors of
+items:
+
+ * calendar date items
+ * time of day items
+ * time zone items
+ * combined date and time of day items
+ * day of the week items
+ * relative items
+ * pure numbers.
+
+We describe each of these item types in turn, below.
+
+ A few ordinal numbers may be written out in words in some contexts.
+This is most useful for specifying day of the week items or relative
+items (see below). Among the most commonly used ordinal numbers, the
+word 'last' stands for -1, 'this' stands for 0, and 'first' and 'next'
+both stand for 1. Because the word 'second' stands for the unit of time
+there is no way to write the ordinal number 2, but for convenience
+'third' stands for 3, 'fourth' for 4, 'fifth' for 5, 'sixth' for 6,
+'seventh' for 7, 'eighth' for 8, 'ninth' for 9, 'tenth' for 10,
+'eleventh' for 11 and 'twelfth' for 12.
+
+ When a month is written this way, it is still considered to be
+written numerically, instead of being "spelled in full"; this changes
+the allowed strings.
+
+ In the current implementation, only English is supported for words
+and abbreviations like 'AM', 'DST', 'EST', 'first', 'January', 'Sunday',
+'tomorrow', and 'year'.
+
+ The output of the 'date' command is not always acceptable as a date
+string, not only because of the language problem, but also because there
+is no standard meaning for time zone items like 'IST'. When using
+'date' to generate a date string intended to be parsed later, specify a
+date format that is independent of language and that does not use time
+zone items other than 'UTC' and 'Z'. Here are some ways to do this:
+
+ $ LC_ALL=C TZ=UTC0 date
+ Mon Mar 1 00:21:42 UTC 2004
+ $ TZ=UTC0 date +'%Y-%m-%d %H:%M:%SZ'
+ 2004-03-01 00:21:42Z
+ $ date --rfc-3339=ns # --rfc-3339 is a GNU extension.
+ 2004-02-29 16:21:42.692722128-08:00
+ $ date --rfc-2822 # a GNU extension
+ Sun, 29 Feb 2004 16:21:42 -0800
+ $ date +'%Y-%m-%d %H:%M:%S %z' # %z is a GNU extension.
+ 2004-02-29 16:21:42 -0800
+ $ date +'@%s.%N' # %s and %N are GNU extensions.
+ @1078100502.692722128
+
+ Alphabetic case is completely ignored in dates. Comments may be
+introduced between round parentheses, as long as included parentheses
+are properly nested. Hyphens not followed by a digit are currently
+ignored. Leading zeros on numbers are ignored.
+
+ Invalid dates like '2005-02-29' or times like '24:00' are rejected.
+In the typical case of a host that does not support leap seconds, a time
+like '23:59:60' is rejected even if it corresponds to a valid leap
+second.
+
+
+File: find.info, Node: Calendar date items, Next: Time of day items, Prev: General date syntax, Up: Date input formats
+
+6.2 Calendar date items
+=======================
+
+A "calendar date item" specifies a day of the year. It is specified
+differently, depending on whether the month is specified numerically or
+literally. All these strings specify the same calendar date:
+
+ 1972-09-24 # ISO 8601.
+ 72-9-24 # Assume 19xx for 69 through 99,
+ # 20xx for 00 through 68.
+ 72-09-24 # Leading zeros are ignored.
+ 9/24/72 # Common U.S. writing.
+ 24 September 1972
+ 24 Sept 72 # September has a special abbreviation.
+ 24 Sep 72 # Three-letter abbreviations always allowed.
+ Sep 24, 1972
+ 24-sep-72
+ 24sep72
+
+ The year can also be omitted. In this case, the last specified year
+is used, or the current year if none. For example:
+
+ 9/24
+ sep 24
+
+ Here are the rules.
+
+ For numeric months, the ISO 8601 format 'YEAR-MONTH-DAY' is allowed,
+where YEAR is any positive number, MONTH is a number between 01 and 12,
+and DAY is a number between 01 and 31. A leading zero must be present
+if a number is less than ten. If YEAR is 68 or smaller, then 2000 is
+added to it; otherwise, if YEAR is less than 100, then 1900 is added to
+it. The construct 'MONTH/DAY/YEAR', popular in the United States, is
+accepted. Also 'MONTH/DAY', omitting the year.
+
+ Literal months may be spelled out in full: 'January', 'February',
+'March', 'April', 'May', 'June', 'July', 'August', 'September',
+'October', 'November' or 'December'. Literal months may be abbreviated
+to their first three letters, possibly followed by an abbreviating dot.
+It is also permitted to write 'Sept' instead of 'September'.
+
+ When months are written literally, the calendar date may be given as
+any of the following:
+
+ DAY MONTH YEAR
+ DAY MONTH
+ MONTH DAY YEAR
+ DAY-MONTH-YEAR
+
+ Or, omitting the year:
+
+ MONTH DAY
+
+
+File: find.info, Node: Time of day items, Next: Time zone items, Prev: Calendar date items, Up: Date input formats
+
+6.3 Time of day items
+=====================
+
+A "time of day item" in date strings specifies the time on a given day.
+Here are some examples, all of which represent the same time:
+
+ 20:02:00.000000
+ 20:02
+ 8:02pm
+ 20:02-0500 # In EST (U.S. Eastern Standard Time).
+
+ More generally, the time of day may be given as 'HOUR:MINUTE:SECOND',
+where HOUR is a number between 0 and 23, MINUTE is a number between 0
+and 59, and SECOND is a number between 0 and 59 possibly followed by '.'
+or ',' and a fraction containing one or more digits. Alternatively,
+':SECOND' can be omitted, in which case it is taken to be zero. On the
+rare hosts that support leap seconds, SECOND may be 60.
+
+ If the time is followed by 'am' or 'pm' (or 'a.m.' or 'p.m.'), HOUR
+is restricted to run from 1 to 12, and ':MINUTE' may be omitted (taken
+to be zero). 'am' indicates the first half of the day, 'pm' indicates
+the second half of the day. In this notation, 12 is the predecessor of
+1: midnight is '12am' while noon is '12pm'. (This is the zero-oriented
+interpretation of '12am' and '12pm', as opposed to the old tradition
+derived from Latin which uses '12m' for noon and '12pm' for midnight.)
+
+ The time may alternatively be followed by a time zone correction,
+expressed as 'SHHMM', where S is '+' or '-', HH is a number of zone
+hours and MM is a number of zone minutes. The zone minutes term, MM,
+may be omitted, in which case the one- or two-digit correction is
+interpreted as a number of hours. You can also separate HH from MM with
+a colon. When a time zone correction is given this way, it forces
+interpretation of the time relative to Coordinated Universal Time (UTC),
+overriding any previous specification for the time zone or the local
+time zone. For example, '+0530' and '+05:30' both stand for the time
+zone 5.5 hours ahead of UTC (e.g., India). This is the best way to
+specify a time zone correction by fractional parts of an hour. The
+maximum zone correction is 24 hours.
+
+ Either 'am'/'pm' or a time zone correction may be specified, but not
+both.
+
+
+File: find.info, Node: Time zone items, Next: Combined date and time of day items, Prev: Time of day items, Up: Date input formats
+
+6.4 Time zone items
+===================
+
+A "time zone item" specifies an international time zone, indicated by a
+small set of letters, e.g., 'UTC' or 'Z' for Coordinated Universal Time.
+Any included periods are ignored. By following a non-daylight-saving
+time zone by the string 'DST' in a separate word (that is, separated by
+some white space), the corresponding daylight saving time zone may be
+specified. Alternatively, a non-daylight-saving time zone can be
+followed by a time zone correction, to add the two values. This is
+normally done only for 'UTC'; for example, 'UTC+05:30' is equivalent to
+'+05:30'.
+
+ Time zone items other than 'UTC' and 'Z' are obsolescent and are not
+recommended, because they are ambiguous; for example, 'EST' has a
+different meaning in Australia than in the United States. Instead, it's
+better to use unambiguous numeric time zone corrections like '-0500', as
+described in the previous section.
+
+ If neither a time zone item nor a time zone correction is supplied,
+time stamps are interpreted using the rules of the default time zone
+(*note Specifying time zone rules::).
+
+
+File: find.info, Node: Combined date and time of day items, Next: Day of week items, Prev: Time zone items, Up: Date input formats
+
+6.5 Combined date and time of day items
+=======================================
+
+The ISO 8601 date and time of day extended format consists of an ISO
+8601 date, a 'T' character separator, and an ISO 8601 time of day. This
+format is also recognized if the 'T' is replaced by a space.
+
+ In this format, the time of day should use 24-hour notation.
+Fractional seconds are allowed, with either comma or period preceding
+the fraction. ISO 8601 fractional minutes and hours are not supported.
+Typically, hosts support nanosecond timestamp resolution; excess
+precision is silently discarded.
+
+ Here are some examples:
+
+ 2012-09-24T20:02:00.052-05:00
+ 2012-12-31T23:59:59,999999999+11:00
+ 1970-01-01 00:00Z
+
+
+File: find.info, Node: Day of week items, Next: Relative items in date strings, Prev: Combined date and time of day items, Up: Date input formats
+
+6.6 Day of week items
+=====================
+
+The explicit mention of a day of the week will forward the date (only if
+necessary) to reach that day of the week in the future.
+
+ Days of the week may be spelled out in full: 'Sunday', 'Monday',
+'Tuesday', 'Wednesday', 'Thursday', 'Friday' or 'Saturday'. Days may be
+abbreviated to their first three letters, optionally followed by a
+period. The special abbreviations 'Tues' for 'Tuesday', 'Wednes' for
+'Wednesday' and 'Thur' or 'Thurs' for 'Thursday' are also allowed.
+
+ A number may precede a day of the week item to move forward
+supplementary weeks. It is best used in expression like 'third monday'.
+In this context, 'last DAY' or 'next DAY' is also acceptable; they move
+one week before or after the day that DAY by itself would represent.
+
+ A comma following a day of the week item is ignored.
+
+
+File: find.info, Node: Relative items in date strings, Next: Pure numbers in date strings, Prev: Day of week items, Up: Date input formats
+
+6.7 Relative items in date strings
+==================================
+
+"Relative items" adjust a date (or the current date if none) forward or
+backward. The effects of relative items accumulate. Here are some
+examples:
+
+ 1 year
+ 1 year ago
+ 3 years
+ 2 days
+
+ The unit of time displacement may be selected by the string 'year' or
+'month' for moving by whole years or months. These are fuzzy units, as
+years and months are not all of equal duration. More precise units are
+'fortnight' which is worth 14 days, 'week' worth 7 days, 'day' worth 24
+hours, 'hour' worth 60 minutes, 'minute' or 'min' worth 60 seconds, and
+'second' or 'sec' worth one second. An 's' suffix on these units is
+accepted and ignored.
+
+ The unit of time may be preceded by a multiplier, given as an
+optionally signed number. Unsigned numbers are taken as positively
+signed. No number at all implies 1 for a multiplier. Following a
+relative item by the string 'ago' is equivalent to preceding the unit by
+a multiplier with value -1.
+
+ The string 'tomorrow' is worth one day in the future (equivalent to
+'day'), the string 'yesterday' is worth one day in the past (equivalent
+to 'day ago').
+
+ The strings 'now' or 'today' are relative items corresponding to
+zero-valued time displacement, these strings come from the fact a
+zero-valued time displacement represents the current time when not
+otherwise changed by previous items. They may be used to stress other
+items, like in '12:00 today'. The string 'this' also has the meaning of
+a zero-valued time displacement, but is preferred in date strings like
+'this thursday'.
+
+ When a relative item causes the resulting date to cross a boundary
+where the clocks were adjusted, typically for daylight saving time, the
+resulting date and time are adjusted accordingly.
+
+ The fuzz in units can cause problems with relative items. For
+example, '2003-07-31 -1 month' might evaluate to 2003-07-01, because
+2003-06-31 is an invalid date. To determine the previous month more
+reliably, you can ask for the month before the 15th of the current
+month. For example:
+
+ $ date -R
+ Thu, 31 Jul 2003 13:02:39 -0700
+ $ date --date='-1 month' +'Last month was %B?'
+ Last month was July?
+ $ date --date="$(date +%Y-%m-15) -1 month" +'Last month was %B!'
+ Last month was June!
+
+ Also, take care when manipulating dates around clock changes such as
+daylight saving leaps. In a few cases these have added or subtracted as
+much as 24 hours from the clock, so it is often wise to adopt universal
+time by setting the 'TZ' environment variable to 'UTC0' before embarking
+on calendrical calculations.
+
+
+File: find.info, Node: Pure numbers in date strings, Next: Seconds since the Epoch, Prev: Relative items in date strings, Up: Date input formats
+
+6.8 Pure numbers in date strings
+================================
+
+The precise interpretation of a pure decimal number depends on the
+context in the date string.
+
+ If the decimal number is of the form YYYYMMDD and no other calendar
+date item (*note Calendar date items::) appears before it in the date
+string, then YYYY is read as the year, MM as the month number and DD as
+the day of the month, for the specified calendar date.
+
+ If the decimal number is of the form HHMM and no other time of day
+item appears before it in the date string, then HH is read as the hour
+of the day and MM as the minute of the hour, for the specified time of
+day. MM can also be omitted.
+
+ If both a calendar date and a time of day appear to the left of a
+number in the date string, but no relative item, then the number
+overrides the year.
+
+
+File: find.info, Node: Seconds since the Epoch, Next: Specifying time zone rules, Prev: Pure numbers in date strings, Up: Date input formats
+
+6.9 Seconds since the Epoch
+===========================
+
+If you precede a number with '@', it represents an internal time stamp
+as a count of seconds. The number can contain an internal decimal point
+(either '.' or ','); any excess precision not supported by the internal
+representation is truncated toward minus infinity. Such a number cannot
+be combined with any other date item, as it specifies a complete time
+stamp.
+
+ Internally, computer times are represented as a count of seconds
+since an epoch--a well-defined point of time. On GNU and POSIX systems,
+the epoch is 1970-01-01 00:00:00 UTC, so '@0' represents this time, '@1'
+represents 1970-01-01 00:00:01 UTC, and so forth. GNU and most other
+POSIX-compliant systems support such times as an extension to POSIX,
+using negative counts, so that '@-1' represents 1969-12-31 23:59:59 UTC.
+
+ Traditional Unix systems count seconds with 32-bit two's-complement
+integers and can represent times from 1901-12-13 20:45:52 through
+2038-01-19 03:14:07 UTC. More modern systems use 64-bit counts of
+seconds with nanosecond subcounts, and can represent all the times in
+the known lifetime of the universe to a resolution of 1 nanosecond.
+
+ On most hosts, these counts ignore the presence of leap seconds. For
+example, on most hosts '@915148799' represents 1998-12-31 23:59:59 UTC,
+'@915148800' represents 1999-01-01 00:00:00 UTC, and there is no way to
+represent the intervening leap second 1998-12-31 23:59:60 UTC.
+
+
+File: find.info, Node: Specifying time zone rules, Next: Authors of parse_datetime, Prev: Seconds since the Epoch, Up: Date input formats
+
+6.10 Specifying time zone rules
+===============================
+
+Normally, dates are interpreted using the rules of the current time
+zone, which in turn are specified by the 'TZ' environment variable, or
+by a system default if 'TZ' is not set. To specify a different set of
+default time zone rules that apply just to one date, start the date with
+a string of the form 'TZ="RULE"'. The two quote characters ('"') must
+be present in the date, and any quotes or backslashes within RULE must
+be escaped by a backslash.
+
+ For example, with the GNU 'date' command you can answer the question
+"What time is it in New York when a Paris clock shows 6:30am on October
+31, 2004?" by using a date beginning with 'TZ="Europe/Paris"' as shown
+in the following shell transcript:
+
+ $ export TZ="America/New_York"
+ $ date --date='TZ="Europe/Paris" 2004-10-31 06:30'
+ Sun Oct 31 01:30:00 EDT 2004
+
+ In this example, the '--date' operand begins with its own 'TZ'
+setting, so the rest of that operand is processed according to
+'Europe/Paris' rules, treating the string '2004-10-31 06:30' as if it
+were in Paris. However, since the output of the 'date' command is
+processed according to the overall time zone rules, it uses New York
+time. (Paris was normally six hours ahead of New York in 2004, but this
+example refers to a brief Halloween period when the gap was five hours.)
+
+ A 'TZ' value is a rule that typically names a location in the 'tz'
+database (http://www.twinsun.com/tz/tz-link.htm). A recent catalog of
+location names appears in the TWiki Date and Time Gateway
+(http://twiki.org/cgi-bin/xtra/tzdate). A few non-GNU hosts require a
+colon before a location name in a 'TZ' setting, e.g.,
+'TZ=":America/New_York"'.
+
+ The 'tz' database includes a wide variety of locations ranging from
+'Arctic/Longyearbyen' to 'Antarctica/South_Pole', but if you are at sea
+and have your own private time zone, or if you are using a non-GNU host
+that does not support the 'tz' database, you may need to use a POSIX
+rule instead. Simple POSIX rules like 'UTC0' specify a time zone
+without daylight saving time; other rules can specify simple daylight
+saving regimes. *Note Specifying the Time Zone with 'TZ': (libc)TZ
+Variable.
+
+
+File: find.info, Node: Authors of parse_datetime, Prev: Specifying time zone rules, Up: Date input formats
+
+6.11 Authors of 'parse_datetime'
+================================
+
+'parse_datetime' started life as 'getdate', as originally implemented by
+Steven M. Bellovin (<smb@research.att.com>) while at the University of
+North Carolina at Chapel Hill. The code was later tweaked by a couple
+of people on Usenet, then completely overhauled by Rich $alz
+(<rsalz@bbn.com>) and Jim Berets (<jberets@bbn.com>) in August, 1990.
+Various revisions for the GNU system were made by David MacKenzie, Jim
+Meyering, Paul Eggert and others, including renaming it to 'get_date' to
+avoid a conflict with the alternative Posix function 'getdate', and a
+later rename to 'parse_datetime'. The Posix function 'getdate' can
+parse more locale-specific dates using 'strptime', but relies on an
+environment variable and external file, and lacks the thread-safety of
+'parse_datetime'.
+
+ This chapter was originally produced by Franc,ois Pinard
+(<pinard@iro.umontreal.ca>) from the 'parse_datetime.y' source code, and
+then edited by K. Berry (<kb@cs.umb.edu>).
+
+
+File: find.info, Node: Configuration, Next: Reference, Prev: Date input formats, Up: Top
+
+7 Configuration
+***************
+
+The findutils source distribution includes a 'configure' script which
+examines the system and generates files required to build findutils.
+See the files 'README' and 'INSTALL'.
+
+ A number of options can be specified on the 'configure' command line,
+and many of these are straightforward, adequately documented in the
+'--help' output, or not normally useful. Options which are useful or
+which are not obvious are explained here.
+
+* Menu:
+
+* Leaf Optimisation:: Take advantage of Unix file system semantics.
+* d_type Optimisation:: Take advantage of file type information.
+* fts:: A non-recursive file system search.
+
+
+File: find.info, Node: Leaf Optimisation, Next: d_type Optimisation, Up: Configuration
+
+7.1 Leaf Optimisation
+=====================
+
+Files in Unix file systems have a link count which indicates how many
+names point to the same inode. Directories in Unix filssytems have a
+'..' entry which functions as a hard link to the parent directory and a
+'.' entry which functions as a link to the directory itself. The '..'
+entry of the root directory also points to the root. This means that
+'find' can deduce the number of subdirectories a directory has, simply
+by subtracting 2 from the directory's link count. This allows 'find'
+the calls to 'stat' which would otherwise be needed to discover which
+directory entries are subdirectories.
+
+ File systems which don't have these semantics should simply return a
+value less than 2 in the 'st_nlinks' member of 'struct stat' in response
+to a successful call to 'stat'.
+
+ If you are building 'find' for a system on which the value of
+'st_nlinks' is unreliable, you can specify '--disable-leaf-optimisation'
+to 'configure' to prevent this assumption being made.
+
+
+File: find.info, Node: d_type Optimisation, Next: fts, Prev: Leaf Optimisation, Up: Configuration
+
+7.2 d_type Optimisation
+=======================
+
+When this feature is enabled, 'find' takes advantage of the fact that on
+some systems 'readdir' will return the type of a file in 'struct
+dirent'.
+
+
+File: find.info, Node: fts, Prev: d_type Optimisation, Up: Configuration
+
+7.3 fts
+=======
+
+The findutils source distribution contains two different implementations
+of 'find'. The older implementation descends the file system
+recursively, while the newer one uses 'fts'. Both are normally
+installed.
+
+ If the option '--without-fts' was passed to 'configure', the
+recursive implementation is installed as 'find' and the fts-based
+implementation is installed as 'ftsfind'. Otherwise, the fts-based
+implementation is installed as 'find' and the recursive implementation
+is installed as 'oldfind'.
+
+
+File: find.info, Node: Reference, Next: Common Tasks, Prev: Configuration, Up: Top
+
+8 Reference
+***********
+
+Below are summaries of the command line syntax for the programs
+discussed in this manual.
+
+* Menu:
+
+* Invoking find::
+* Invoking locate::
+* Invoking updatedb::
+* Invoking xargs::
+* Regular Expressions::
+* Environment Variables::
+
+
+File: find.info, Node: Invoking find, Next: Invoking locate, Up: Reference
+
+8.1 Invoking 'find'
+===================
+
+ find [-H] [-L] [-P] [-D DEBUGOPTIONS] [-OLEVEL] [FILE...] [EXPRESSION]
+
+ 'find' searches the directory tree rooted at each file name FILE by
+evaluating the EXPRESSION on each file it finds in the tree.
+
+ The command line may begin with the '-H', '-L', '-P', '-D' and '-O'
+options. These are followed by a list of files or directories that
+should be searched. If no files to search are specified, the current
+directory ('.') is used.
+
+ This list of files to search is followed by a list of expressions
+describing the files we wish to search for. The first part of the
+expression is recognised by the fact that it begins with '-' followed by
+some other letters (for example '-print'), or is either '(' or '!'. Any
+arguments after it are the rest of the expression.
+
+ If no expression is given, the expression '-print' is used.
+
+ The 'find' command exits with status zero if all files matched are
+processed successfully, greater than zero if errors occur.
+
+ The 'find' program also recognises two options for administrative
+use:
+
+'--help'
+ Print a summary of the command line usage and exit.
+'--version'
+ Print the version number of 'find' and exit.
+
+ The '-version' option is a synonym for '--version'
+
+* Menu:
+
+* Filesystem Traversal Options::
+* Warning Messages::
+* Optimisation Options::
+* Debug Options::
+* Find Expressions::
+
+
+File: find.info, Node: Filesystem Traversal Options, Next: Warning Messages, Up: Invoking find
+
+8.1.1 Filesystem Traversal Options
+----------------------------------
+
+The options '-H', '-L' or '-P' may be specified at the start of the
+command line (if none of these is specified, '-P' is assumed). If you
+specify more than one of these options, the last one specified takes
+effect (but note that the '-follow' option is equivalent to '-L').
+
+'-P'
+ Never follow symbolic links (this is the default), except in the
+ case of the '-xtype' predicate.
+'-L'
+ Always follow symbolic links, except in the case of the '-xtype'
+ predicate.
+'-H'
+ Follow symbolic links specified in the list of files to search, or
+ which are otherwise specified on the command line.
+
+ If 'find' would follow a symbolic link, but cannot for any reason
+(for example, because it has insufficient permissions or the link is
+broken), it falls back on using the properties of the symbolic link
+itself. *note Symbolic Links:: for a more complete description of how
+symbolic links are handled.
+
+
+File: find.info, Node: Warning Messages, Next: Optimisation Options, Prev: Filesystem Traversal Options, Up: Invoking find
+
+8.1.2 Warning Messages
+----------------------
+
+If there is an error on the 'find' command line, an error message is
+normally issued. However, there are some usages that are inadvisable
+but which 'find' should still accept. Under these circumstances, 'find'
+may issue a warning message.
+
+ By default, warnings are enabled only if 'find' is being run
+interactively (specifically, if the standard input is a terminal) and
+the 'POSIXLY_CORRECT' environment variable is not set. Warning messages
+can be controlled explicitly by the use of options on the command line:
+
+'-warn'
+ Issue warning messages where appropriate.
+'-nowarn'
+ Do not issue warning messages.
+
+ These options take effect at the point on the command line where they
+are specified. Therefore it's not useful to specify '-nowarn' at the
+end of the command line. The warning messages affected by the above
+options are triggered by:
+
+ - Use of the '-d' option which is deprecated; please use '-depth'
+ instead, since the latter is POSIX-compliant.
+ - Use of the '-ipath' option which is deprecated; please use
+ '-iwholename' instead.
+ - Specifying an option (for example '-mindepth') after a non-option
+ (for example '-type' or '-print') on the command line.
+ - Use of the '-name' or '-iname' option with a slash character in the
+ pattern. Since the name predicates only compare against the
+ basename of the visited files, the only file that can match a slash
+ is the root directory itself.
+
+ The default behaviour above is designed to work in that way so that
+existing shell scripts don't generate spurious errors, but people will
+be made aware of the problem.
+
+ Some warning messages are issued for less common or more serious
+problems, and consequently cannot be turned off:
+
+ - Use of an unrecognised backslash escape sequence with '-fprintf'
+ - Use of an unrecognised formatting directive with '-fprintf'
+
+
+File: find.info, Node: Optimisation Options, Next: Debug Options, Prev: Warning Messages, Up: Invoking find
+
+8.1.3 Optimisation Options
+--------------------------
+
+The '-OLEVEL' option sets 'find''s optimisation level to LEVEL. The
+default optimisation level is 1.
+
+ At certain optimisation levels, 'find' reorders tests to speed up
+execution while preserving the overall effect; that is, predicates with
+side effects are not reordered relative to each other. The
+optimisations performed at each optimisation level are as follows.
+
+'0'
+ Currently equivalent to optimisation level 1.
+
+'1'
+ This is the default optimisation level and corresponds to the
+ traditional behaviour. Expressions are reordered so that tests
+ based only on the names of files (for example' -name' and '-regex')
+ are performed first.
+
+'2'
+ Any '-type' or '-xtype' tests are performed after any tests based
+ only on the names of files, but before any tests that require
+ information from the inode. On many modern versions of Unix, file
+ types are returned by 'readdir()' and so these predicates are
+ faster to evaluate than predicates which need to stat the file
+ first.
+
+ If you use the '-fstype FOO' predicate and specify a filsystem type
+ 'FOO' which is not known (that is, present in '/etc/mtab') at the
+ time 'find' starts, that predicate is equivalent to '-false'.
+
+'3'
+ At this optimisation level, the full cost-based query optimiser is
+ enabled. The order of tests is modified so that cheap (i.e., fast)
+ tests are performed first and more expensive ones are performed
+ later, if necessary. Within each cost band, predicates are
+ evaluated earlier or later according to whether they are likely to
+ succeed or not. For '-o', predicates which are likely to succeed
+ are evaluated earlier, and for '-a', predicates which are likely to
+ fail are evaluated earlier.
+
+
+File: find.info, Node: Debug Options, Next: Find Expressions, Prev: Optimisation Options, Up: Invoking find
+
+8.1.4 Debug Options
+-------------------
+
+The '-D' option makes 'find' produce diagnostic output. Much of the
+information is useful only for diagnosing problems, and so most people
+will not find this option helpful.
+
+ The list of debug options should be comma separated. Compatibility
+of the debug options is not guaranteed between releases of findutils.
+For a complete list of valid debug options, see the output of 'find -D
+help'. Valid debug options include:
+'help'
+ Explain the debugging options.
+'tree'
+ Show the expression tree in its original and optimised form.
+'stat'
+ Print messages as files are examined with the stat and lstat system
+ calls. The find program tries to minimise such calls.
+'opt'
+ Prints diagnostic information relating to the optimisation of the
+ expression tree; see the '-O' option.
+'rates'
+ Prints a summary indicating how often each predicate succeeded or
+ failed.
+
+
+File: find.info, Node: Find Expressions, Prev: Debug Options, Up: Invoking find
+
+8.1.5 Find Expressions
+----------------------
+
+The final part of the 'find' command line is a list of expressions.
+*Note Primary Index::, for a summary of all of the tests, actions, and
+options that the expression can contain. If the expression is missing,
+'-print' is assumed.
+
+
+File: find.info, Node: Invoking locate, Next: Invoking updatedb, Prev: Invoking find, Up: Reference
+
+8.2 Invoking 'locate'
+=====================
+
+ locate [OPTION...] PATTERN...
+
+ For each PATTERN given 'locate' searches one or more file name
+databases returning each match of PATTERN.
+
+'--all'
+'-A'
+ Print only names which match all non-option arguments, not those
+ matching one or more non-option arguments.
+
+'--basename'
+'-b'
+ The specified pattern is matched against just the last component of
+ the name of a file in the 'locate' database. This last component
+ is also called the "base name". For example, the base name of
+ '/tmp/mystuff/foo.old.c' is 'foo.old.c'. If the pattern contains
+ metacharacters, it must match the base name exactly. If not, it
+ must match part of the base name.
+
+'--count'
+'-c'
+ Instead of printing the matched file names, just print the total
+ number of matches found, unless '--print' ('-p') is also present.
+
+'--database=PATH'
+'-d PATH'
+ Instead of searching the default 'locate' database
+ '/usr/local/var/locatedb', 'locate' searches the file name
+ databases in PATH, which is a colon-separated list of database file
+ names. You can also use the environment variable 'LOCATE_PATH' to
+ set the list of database files to search. The option overrides the
+ environment variable if both are used. Empty elements in PATH
+ (that is, a leading or trailing colon, or two colons in a row) are
+ taken to stand for the default database. A database can be
+ supplied on stdin, using '-' as an element of 'path'. If more than
+ one element of 'path' is '-', later instances are ignored (but a
+ warning message is printed).
+
+'--existing'
+'-e'
+ Only print out such names which currently exist (instead of such
+ names which existed when the database was created). Note that this
+ may slow down the program a lot, if there are many matches in the
+ database. The way in which broken symbolic links are treated is
+ affected by the '-L', '-P' and '-H' options. Please note that it
+ is possible for the file to be deleted after 'locate' has checked
+ that it exists, but before you use it. This option is
+ automatically turned on when reading an 'slocate' database in
+ secure mode (*note slocate Database Format::).
+
+'--non-existing'
+'-E'
+ Only print out such names which currently do not exist (instead of
+ such names which existed when the database was created). Note that
+ this may slow down the program a lot, if there are many matches in
+ the database. The way in which broken symbolic links are treated
+ is affected by the '-L', '-P' and '-H' options. Please note that
+ 'locate' checks that the file does not exist, but a file of the
+ same name might be created after 'locate''s check but before you
+ read 'locate''s output.
+
+'--follow'
+'-L'
+ If testing for the existence of files (with the '-e' or '-E'
+ options), consider broken symbolic links to be non-existing. This
+ is the default behaviour.
+
+'--nofollow'
+'-P'
+'-H'
+ If testing for the existence of files (with the '-e' or '-E'
+ options), treat broken symbolic links as if they were existing
+ files. The '-H' form of this option is provided purely for
+ similarity with 'find'; the use of '-P' is recommended over '-H'.
+
+'--ignore-case'
+'-i'
+ Ignore case distinctions in both the pattern and the file names.
+
+'--limit=N'
+'-l N'
+ Limit the number of results printed to N. When used with the
+ '--count' option, the value printed will never be larger than this
+ limit.
+'--max-database-age=D'
+ Normally, 'locate' will issue a warning message when it searches a
+ database which is more than 8 days old. This option changes that
+ value to something other than 8. The effect of specifying a
+ negative value is undefined.
+'--mmap'
+'-m'
+ Accepted but does nothing. The option is supported only to provide
+ compatibility with BSD's 'locate'.
+
+'--null'
+'-0'
+ Results are separated with the ASCII NUL character rather than the
+ newline character. To get the full benefit of this option, use the
+ new 'locate' database format (that is the default anyway).
+
+'--print'
+'-p'
+ Print search results when they normally would not be due to use of
+ '--statistics' ('-S') or '--count' ('-c').
+
+'--wholename'
+'-w'
+ The specified pattern is matched against the whole name of the file
+ in the 'locate' database. If the pattern contains metacharacters,
+ it must match exactly. If not, it must match part of the whole
+ file name. This is the default behaviour.
+
+'--regex'
+'-r'
+ Instead of using substring or shell glob matching, the pattern
+ specified on the command line is understood to be a regular
+ expression. GNU Emacs-style regular expressions are assumed unless
+ the '--regextype' option is also given. File names from the
+ 'locate' database are matched using the specified regular
+ expression. If the '-i' flag is also given, matching is
+ case-insensitive. Matches are performed against the whole path
+ name, and so by default a pathname will be matched if any part of
+ it matches the specified regular expression. The regular
+ expression may use '^' or '$' to anchor a match at the beginning or
+ end of a pathname.
+
+'--regextype'
+ This option changes the regular expression syntax and behaviour
+ used by the '--regex' option. *note Regular Expressions:: for more
+ information on the regular expression dialects understood by GNU
+ findutils.
+
+'--stdio'
+'-s'
+ Accepted but does nothing. The option is supported only to provide
+ compatibility with BSD's 'locate'.
+
+'--statistics'
+'-S'
+ Print some summary information for each 'locate' database. No
+ search is performed unless non-option arguments are given.
+ Although the BSD version of locate also has this option, the format
+ of the output is different.
+
+'--help'
+ Print a summary of the command line usage for 'locate' and exit.
+
+'--version'
+ Print the version number of 'locate' and exit.
+
+
+File: find.info, Node: Invoking updatedb, Next: Invoking xargs, Prev: Invoking locate, Up: Reference
+
+8.3 Invoking 'updatedb'
+=======================
+
+ updatedb [OPTION...]
+
+ 'updatedb' creates and updates the database of file names used by
+'locate'. 'updatedb' generates a list of files similar to the output of
+'find' and then uses utilities for optimizing the database for
+performance. 'updatedb' is often run periodically as a 'cron' job and
+configured with environment variables or command options. Typically,
+operating systems have a shell script that "exports" configurations for
+variable definitions and uses another shell script that "sources" the
+configuration file into the environment and then executes 'updatedb' in
+the environment.
+
+'--findoptions='OPTION...''
+ Global options to pass on to 'find'. The environment variable
+ 'FINDOPTIONS' also sets this value. Default is none.
+
+'--localpaths='PATH...''
+ Non-network directories to put in the database. Default is '/'.
+
+'--netpaths='PATH...''
+ Network (NFS, AFS, RFS, etc.) directories to put in the database.
+ The environment variable 'NETPATHS' also sets this value. Default
+ is none.
+
+'--prunepaths='PATH...''
+ Directories to omit from the database, which would otherwise be
+ included. The environment variable 'PRUNEPATHS' also sets this
+ value. Default is '/tmp /usr/tmp /var/tmp /afs'. The paths are
+ used as regular expressions (with 'find ... -regex', so you need to
+ specify these paths in the same way that 'find' will encounter
+ them. This means for example that the paths must not include
+ trailing slashes.
+
+'--prunefs='PATH...''
+ Filesystems to omit from the database, which would otherwise be
+ included. Note that files are pruned when a filesystem is reached;
+ Any filesystem mounted under an undesired filesystem will be
+ ignored. The environment variable 'PRUNEFS' also sets this value.
+ Default is 'nfs NFS proc'.
+
+'--output=DBFILE'
+ The database file to build. The default is system-dependent, but
+ when this document was formatted it was '/usr/local/var/locatedb'.
+
+'--localuser=USER'
+ The user to search the non-network directories as, using 'su'.
+ Default is to search the non-network directories as the current
+ user. You can also use the environment variable 'LOCALUSER' to set
+ this user.
+
+'--netuser=USER'
+ The user to search network directories as, using 'su'. Default
+ 'user' is 'daemon'. You can also use the environment variable
+ 'NETUSER' to set this user.
+
+'--old-format'
+ Generate a 'locate' database in the old format, for compatibility
+ with versions of 'locate' other than GNU 'locate'. Using this
+ option means that 'locate' will not be able to properly handle
+ non-ASCII characters in file names (that is, file names containing
+ characters which have the eighth bit set, such as many of the
+ characters from the ISO-8859-1 character set). *Note Database
+ Formats::, for a detailed description of the supported database
+ formats.
+
+'--dbformat=FORMAT'
+ Generate the locate database in format 'FORMAT'. Supported
+ database formats include 'LOCATE02' (which is the default), 'old'
+ and 'slocate'. The 'old' format exists for compatibility with
+ implementations of 'locate' on other Unix systems. The 'slocate'
+ format exists for compatibility with 'slocate'. *Note Database
+ Formats::, for a detailed description of each format.
+
+'--help'
+ Print a summary of the command line usage and exit.
+'--version'
+ Print the version number of 'updatedb' and exit.
+
+
+File: find.info, Node: Invoking xargs, Next: Regular Expressions, Prev: Invoking updatedb, Up: Reference
+
+8.4 Invoking 'xargs'
+====================
+
+ xargs [OPTION...] [COMMAND [INITIAL-ARGUMENTS]]
+
+ 'xargs' exits with the following status:
+
+0
+ if it succeeds
+123
+ if any invocation of the command exited with status 1-125
+124
+ if the command exited with status 255
+125
+ if the command is killed by a signal
+126
+ if the command cannot be run
+127
+ if the command is not found
+1
+ if some other error occurred.
+
+ Exit codes greater than 128 are used by the shell to indicate that a
+program died due to a fatal signal.
+
+* Menu:
+
+* xargs options::
+* Invoking the shell from xargs::
+
+
+File: find.info, Node: xargs options, Next: Invoking the shell from xargs, Up: Invoking xargs
+
+8.4.1 xargs options
+-------------------
+
+'--arg-file=INPUTFILE'
+'-a INPUTFILE'
+ Read names from the file INPUTFILE instead of standard input. If
+ you use this option, the standard input stream remains unchanged
+ when commands are run. Otherwise, stdin is redirected from
+ '/dev/null'.
+
+'--null'
+'-0'
+ Input file names are terminated by a null character instead of by
+ whitespace, and any quotes and backslash characters are not
+ considered special (every character is taken literally). Disables
+ the end of file string, which is treated like any other argument.
+
+'--delimiter DELIM'
+'-d DELIM'
+
+ Input file names are terminated by the specified character DELIM
+ instead of by whitespace, and any quotes and backslash characters
+ are not considered special (every character is taken literally).
+ Disables the logical end of file marker string, which is treated
+ like any other argument.
+
+ The specified delimiter may be a single character, a C-style
+ character escape such as '\n', or an octal or hexadecimal escape
+ code. Octal and hexadecimal escape codes are understood as for the
+ 'printf' command. Multibyte characters are not supported.
+
+'-E EOF-STR'
+'--eof[=EOF-STR]'
+'-e[EOF-STR]'
+
+ Set the logical end of file marker string to EOF-STR. If the
+ logical end of file marker string occurs as a line of input, the
+ rest of the input is ignored. If EOF-STR is omitted ('-e') or
+ blank (either '-e' or '-E'), there is no logical end of file marker
+ string. The '-e' form of this option is deprecated in favour of
+ the POSIX-compliant '-E' option, which you should use instead. As
+ of GNU 'xargs' version 4.2.9, the default behaviour of 'xargs' is
+ not to have a logical end of file marker string. The POSIX
+ standard (IEEE Std 1003.1, 2004 Edition) allows this.
+
+ The logical end of file marker string is not treated specially if
+ the '-d' or the '-0' options are in effect. That is, when either
+ of these options are in effect, the whole input file will be read
+ even if '-E' was used.
+
+'--help'
+ Print a summary of the options to 'xargs' and exit.
+
+'-I REPLACE-STR'
+'--replace[=REPLACE-STR]'
+'-i[REPLACE-STR]'
+ Replace occurrences of REPLACE-STR in the initial arguments with
+ names read from standard input. Also, unquoted blanks do not
+ terminate arguments; instead, the input is split at newlines only.
+ If REPLACE-STR is omitted (omitting it is allowed only for '-i'),
+ it defaults to '{}' (like for 'find -exec'). Implies '-x' and '-l
+ 1'. The '-i' option is deprecated in favour of the '-I' option.
+
+'-L MAX-LINES'
+'--max-lines[=MAX-LINES]'
+'-l[MAX-LINES]'
+ Use at most MAX-LINES non-blank input lines per command line. For
+ '-l', MAX-LINES defaults to 1 if omitted. For '-L', the argument
+ is mandatory. Trailing blanks cause an input line to be logically
+ continued on the next input line, for the purpose of counting the
+ lines. Implies '-x'. The '-l' form of this option is deprecated
+ in favour of the POSIX-compliant '-L' option.
+
+'--max-args=MAX-ARGS'
+'-n MAX-ARGS'
+ Use at most MAX-ARGS arguments per command line. Fewer than
+ MAX-ARGS arguments will be used if the size (see the '-s' option)
+ is exceeded, unless the '-x' option is given, in which case 'xargs'
+ will exit.
+
+'--interactive'
+'-p'
+ Prompt the user about whether to run each command line and read a
+ line from the terminal. Only run the command line if the response
+ starts with 'y' or 'Y'. Implies '-t'.
+
+'--no-run-if-empty'
+'-r'
+ If the standard input is completely empty, do not run the command.
+ By default, the command is run once even if there is no input.
+
+'--max-chars=MAX-CHARS'
+'-s MAX-CHARS'
+ Use at most MAX-CHARS characters per command line, including the
+ command, initial arguments and any terminating nulls at the ends of
+ the argument strings.
+
+'--show-limits'
+ Display the limits on the command-line length which are imposed by
+ the operating system, 'xargs'' choice of buffer size and the '-s'
+ option. Pipe the input from '/dev/null' (and perhaps specify
+ '--no-run-if-empty') if you don't want 'xargs' to do anything.
+
+'--verbose'
+'-t'
+ Print the command line on the standard error output before
+ executing it.
+
+'--version'
+ Print the version number of 'xargs' and exit.
+
+'--exit'
+'-x'
+ Exit if the size (see the '-s' option) is exceeded.
+
+'--max-procs=MAX-PROCS'
+'-P MAX-PROCS'
+ Run simultaneously up to MAX-PROCS processes at once; the default
+ is 1. If MAX-PROCS is 0, 'xargs' will run as many processes as
+ possible simultaneously. *Note Controlling Parallelism::, for
+ information on dynamically controlling parallelism.
+
+'--process-slot-var=ENVIRONMENT-VARIABLE-NAME'
+ Set the environment variable ENVIRONMENT-VARIABLE-NAME to a unique
+ value in each running child process. Each value is a decimal
+ integer. Values are reused once child processes exit. This can be
+ used in a rudimentary load distribution scheme, for example.
+
+
+File: find.info, Node: Invoking the shell from xargs, Prev: xargs options, Up: Invoking xargs
+
+8.4.2 Invoking the shell from xargs
+-----------------------------------
+
+Normally, 'xargs' will exec the command you specified directly, without
+invoking a shell. This is normally the behaviour one would want. It's
+somewhat more efficient and avoids problems with shell metacharacters,
+for example. However, sometimes it is necessary to manipulate the
+environment of a command before it is run, in a way that 'xargs' does
+not directly support.
+
+ Invoking a shell from 'xargs' is a good way of performing such
+manipulations. However, some care must be taken to prevent problems,
+for example unwanted interpretation of shell metacharacters.
+
+ This command moves a set of files into an archive directory:
+
+ find /foo -maxdepth 1 -atime +366 -exec mv {} /archive \;
+
+ However, this will only move one file at a time. We cannot in this
+case use '-exec ... +' because the matched file names are added at the
+end of the command line, while the destination directory would need to
+be specified last. We also can't use 'xargs' in the obvious way for the
+same reason. One way of working around this problem is to make use of
+the special properties of GNU 'mv'; it has a '-t' option that allows the
+target directory to be specified before the list of files to be moved.
+However, while this technique works for GNU 'mv', it doesn't solve the
+more general problem.
+
+ Here is a more general technique for solving this problem:
+
+ find /foo -maxdepth 1 -atime +366 -print0 |
+ xargs -r0 sh -c 'mv "$@" /archive' move
+
+ Here, a shell is being invoked. There are two shell instances to
+think about. The first is the shell which launches the 'xargs' command
+(this might be the shell into which you are typing, for example). The
+second is the shell launched by 'xargs' (in fact it will probably launch
+several, one after the other, depending on how many files need to be
+archived). We'll refer to this second shell as a subshell.
+
+ Our example uses the '-c' option of 'sh'. Its argument is a shell
+command to be executed by the subshell. Along with the rest of that
+command, the $@ is enclosed by single quotes to make sure it is passed
+to the subshell without being expanded by the parent shell. It is also
+enclosed with double quotes so that the subshell will expand '$@'
+correctly even if one of the file names contains a space or newline.
+
+ The subshell will use any non-option arguments as positional
+parameters (that is, in the expansion of '$@'). Because 'xargs'
+launches the 'sh -c' subshell with a list of files, those files will end
+up as the expansion of '$@'.
+
+ You may also notice the 'move' at the end of the command line. This
+is used as the value of '$0' by the subshell. We include it because
+otherwise the name of the first file to be moved would be used instead.
+If that happened it would not be included in the subshell's expansion of
+'$@', and so it wouldn't actually get moved.
+
+ Another reason to use the 'sh -c' construct could be to perform
+redirection:
+
+ find /usr/include -name '*.h' | xargs grep -wl mode_t |
+ xargs -r sh -c 'exec emacs "$@" < /dev/tty' Emacs
+
+ Notice that we use the shell builtin 'exec' here. That's simply
+because the subshell needs to do nothing once Emacs has been invoked.
+Therefore instead of keeping a 'sh' process around for no reason, we
+just arrange for the subshell to exec Emacs, saving an extra process
+creation.
+
+ Sometimes, though, it can be helpful to keep the shell process
+around:
+
+ find /foo -maxdepth 1 -atime +366 -print0 |
+ xargs -r0 sh -c 'mv "$@" /archive || exit 255' move
+
+ Here, the shell will exit with status 255 if any 'mv' failed. This
+causes 'xargs' to stop immediately.
+
+
+File: find.info, Node: Regular Expressions, Next: Environment Variables, Prev: Invoking xargs, Up: Reference
+
+8.5 Regular Expressions
+=======================
+
+The '-regex' and '-iregex' tests of 'find' allow matching by regular
+expression, as does the '--regex' option of 'locate'.
+
+ Your locale configuration affects how regular expressions are
+interpreted. *Note Environment Variables::, for a description of how
+your locale setup affects the interpretation of regular expressions.
+
+ There are also several different types of regular expression, and
+these are interpreted differently. Normally, the type of regular
+expression used by 'find' and 'locate' is the same as is used in GNU
+Emacs. Both programs provide an option which allows you to select an
+alternative regular expression syntax; for 'find' this is the
+'-regextype' option, and for 'locate' this is the '--regextype' option.
+
+ These options take a single argument, which indicates the specific
+regular expression syntax and behaviour that should be used. This
+should be one of the following:
+
+* Menu:
+
+* findutils-default regular expression syntax::
+* awk regular expression syntax::
+* egrep regular expression syntax::
+* emacs regular expression syntax::
+* gnu-awk regular expression syntax::
+* grep regular expression syntax::
+* posix-awk regular expression syntax::
+* posix-basic regular expression syntax::
+* posix-egrep regular expression syntax::
+* posix-extended regular expression syntax::
+
+
+File: find.info, Node: findutils-default regular expression syntax, Next: awk regular expression syntax, Up: Regular Expressions
+
+8.5.1 'findutils-default' regular expression syntax
+---------------------------------------------------
+
+The character '.' matches any single character.
+
+'+'
+ indicates that the regular expression should match one or more
+ occurrences of the previous atom or regexp.
+'?'
+ indicates that the regular expression should match zero or one
+ occurrence of the previous atom or regexp.
+'\+'
+ matches a '+'
+'\?'
+ matches a '?'.
+
+ Bracket expressions are used to match ranges of characters. Bracket
+expressions where the range is backward, for example '[z-a]', are
+ignored. Within square brackets, '\' is taken literally. Character
+classes are not supported, so for example you would need to use '[0-9]'
+instead of '[[:digit:]]'.
+
+ GNU extensions are supported:
+
+ 1. '\w' matches a character within a word
+
+ 2. '\W' matches a character which is not within a word
+
+ 3. '\<' matches the beginning of a word
+
+ 4. '\>' matches the end of a word
+
+ 5. '\b' matches a word boundary
+
+ 6. '\B' matches characters which are not a word boundary
+
+ 7. '\`' matches the beginning of the whole input
+
+ 8. '\'' matches the end of the whole input
+
+ Grouping is performed with backslashes followed by parentheses '\(',
+'\)'. A backslash followed by a digit acts as a back-reference and
+matches the same thing as the previous grouped expression indicated by
+that number. For example '\2' matches the second group expression. The
+order of group expressions is determined by the position of their
+opening parenthesis '\('.
+
+ The alternation operator is '\|'.
+
+ The character '^' only represents the beginning of a string when it
+appears:
+
+ 1. At the beginning of a regular expression
+
+ 2. After an open-group, signified by '\('
+
+ 3. After the alternation operator '\|'
+
+ The character '$' only represents the end of a string when it
+appears:
+
+ 1. At the end of a regular expression
+
+ 2. Before a close-group, signified by '\)'
+ 3. Before the alternation operator '\|'
+
+ '*', '+' and '?' are special at any point in a regular expression
+except:
+
+ 1. At the beginning of a regular expression
+
+ 2. After an open-group, signified by '\('
+ 3. After the alternation operator '\|'
+
+ The longest possible match is returned; this applies to the regular
+expression as a whole and (subject to this constraint) to subexpressions
+within groups.
+
+
+File: find.info, Node: awk regular expression syntax, Next: egrep regular expression syntax, Prev: findutils-default regular expression syntax, Up: Regular Expressions
+
+8.5.2 'awk' regular expression syntax
+-------------------------------------
+
+The character '.' matches any single character except the null
+character.
+
+'+'
+ indicates that the regular expression should match one or more
+ occurrences of the previous atom or regexp.
+'?'
+ indicates that the regular expression should match zero or one
+ occurrence of the previous atom or regexp.
+'\+'
+ matches a '+'
+'\?'
+ matches a '?'.
+
+ Bracket expressions are used to match ranges of characters. Bracket
+expressions where the range is backward, for example '[z-a]', are
+invalid. Within square brackets, '\' can be used to quote the following
+character. Character classes are supported; for example '[[:digit:]]'
+will match a single decimal digit.
+
+ GNU extensions are not supported and so '\w', '\W', '\<', '\>', '\b',
+'\B', '\`', and '\'' match 'w', 'W', '<', '>', 'b', 'B', '`', and '''
+respectively.
+
+ Grouping is performed with parentheses '()'. An unmatched ')'
+matches just itself. A backslash followed by a digit matches that
+digit.
+
+ The alternation operator is '|'.
+
+ The characters '^' and '$' always represent the beginning and end of
+a string respectively, except within square brackets. Within brackets,
+'^' can be used to invert the membership of the character class being
+specified.
+
+ '*', '+' and '?' are special at any point in a regular expression
+except:
+
+ 1. At the beginning of a regular expression
+
+ 2. After an open-group, signified by '('
+ 3. After the alternation operator '|'
+
+ The longest possible match is returned; this applies to the regular
+expression as a whole and (subject to this constraint) to subexpressions
+within groups.
+
+
+File: find.info, Node: egrep regular expression syntax, Next: emacs regular expression syntax, Prev: awk regular expression syntax, Up: Regular Expressions
+
+8.5.3 'egrep' regular expression syntax
+---------------------------------------
+
+The character '.' matches any single character.
+
+'+'
+ indicates that the regular expression should match one or more
+ occurrences of the previous atom or regexp.
+'?'
+ indicates that the regular expression should match zero or one
+ occurrence of the previous atom or regexp.
+'\+'
+ matches a '+'
+'\?'
+ matches a '?'.
+
+ Bracket expressions are used to match ranges of characters. Bracket
+expressions where the range is backward, for example '[z-a]', are
+invalid. Within square brackets, '\' is taken literally. Character
+classes are supported; for example '[[:digit:]]' will match a single
+decimal digit.
+
+ GNU extensions are supported:
+
+ 1. '\w' matches a character within a word
+
+ 2. '\W' matches a character which is not within a word
+
+ 3. '\<' matches the beginning of a word
+
+ 4. '\>' matches the end of a word
+
+ 5. '\b' matches a word boundary
+
+ 6. '\B' matches characters which are not a word boundary
+
+ 7. '\`' matches the beginning of the whole input
+
+ 8. '\'' matches the end of the whole input
+
+ Grouping is performed with parentheses '()'. An unmatched ')'
+matches just itself. A backslash followed by a digit acts as a
+back-reference and matches the same thing as the previous grouped
+expression indicated by that number. For example '\2' matches the
+second group expression. The order of group expressions is determined
+by the position of their opening parenthesis '('.
+
+ The alternation operator is '|'.
+
+ The characters '^' and '$' always represent the beginning and end of
+a string respectively, except within square brackets. Within brackets,
+'^' can be used to invert the membership of the character class being
+specified.
+
+ The characters '*', '+' and '?' are special anywhere in a regular
+expression.
+
+ Intervals are specified by '{' and '}'. Invalid intervals are
+treated as literals, for example 'a{1' is treated as 'a\{1'
+
+ The longest possible match is returned; this applies to the regular
+expression as a whole and (subject to this constraint) to subexpressions
+within groups.
+
+
+File: find.info, Node: emacs regular expression syntax, Next: gnu-awk regular expression syntax, Prev: egrep regular expression syntax, Up: Regular Expressions
+
+8.5.4 'emacs' regular expression syntax
+---------------------------------------
+
+The character '.' matches any single character except newline.
+
+'+'
+ indicates that the regular expression should match one or more
+ occurrences of the previous atom or regexp.
+'?'
+ indicates that the regular expression should match zero or one
+ occurrence of the previous atom or regexp.
+'\+'
+ matches a '+'
+'\?'
+ matches a '?'.
+
+ Bracket expressions are used to match ranges of characters. Bracket
+expressions where the range is backward, for example '[z-a]', are
+ignored. Within square brackets, '\' is taken literally. Character
+classes are not supported, so for example you would need to use '[0-9]'
+instead of '[[:digit:]]'.
+
+ GNU extensions are supported:
+
+ 1. '\w' matches a character within a word
+
+ 2. '\W' matches a character which is not within a word
+
+ 3. '\<' matches the beginning of a word
+
+ 4. '\>' matches the end of a word
+
+ 5. '\b' matches a word boundary
+
+ 6. '\B' matches characters which are not a word boundary
+
+ 7. '\`' matches the beginning of the whole input
+
+ 8. '\'' matches the end of the whole input
+
+ Grouping is performed with backslashes followed by parentheses '\(',
+'\)'. A backslash followed by a digit acts as a back-reference and
+matches the same thing as the previous grouped expression indicated by
+that number. For example '\2' matches the second group expression. The
+order of group expressions is determined by the position of their
+opening parenthesis '\('.
+
+ The alternation operator is '\|'.
+
+ The character '^' only represents the beginning of a string when it
+appears:
+
+ 1. At the beginning of a regular expression
+
+ 2. After an open-group, signified by '\('
+
+ 3. After the alternation operator '\|'
+
+ The character '$' only represents the end of a string when it
+appears:
+
+ 1. At the end of a regular expression
+
+ 2. Before a close-group, signified by '\)'
+ 3. Before the alternation operator '\|'
+
+ '*', '+' and '?' are special at any point in a regular expression
+except:
+
+ 1. At the beginning of a regular expression
+
+ 2. After an open-group, signified by '\('
+ 3. After the alternation operator '\|'
+
+ The longest possible match is returned; this applies to the regular
+expression as a whole and (subject to this constraint) to subexpressions
+within groups.
+
+
+File: find.info, Node: gnu-awk regular expression syntax, Next: grep regular expression syntax, Prev: emacs regular expression syntax, Up: Regular Expressions
+
+8.5.5 'gnu-awk' regular expression syntax
+-----------------------------------------
+
+The character '.' matches any single character.
+
+'+'
+ indicates that the regular expression should match one or more
+ occurrences of the previous atom or regexp.
+'?'
+ indicates that the regular expression should match zero or one
+ occurrence of the previous atom or regexp.
+'\+'
+ matches a '+'
+'\?'
+ matches a '?'.
+
+ Bracket expressions are used to match ranges of characters. Bracket
+expressions where the range is backward, for example '[z-a]', are
+invalid. Within square brackets, '\' can be used to quote the following
+character. Character classes are supported; for example '[[:digit:]]'
+will match a single decimal digit.
+
+ GNU extensions are supported:
+
+ 1. '\w' matches a character within a word
+
+ 2. '\W' matches a character which is not within a word
+
+ 3. '\<' matches the beginning of a word
+
+ 4. '\>' matches the end of a word
+
+ 5. '\b' matches a word boundary
+
+ 6. '\B' matches characters which are not a word boundary
+
+ 7. '\`' matches the beginning of the whole input
+
+ 8. '\'' matches the end of the whole input
+
+ Grouping is performed with parentheses '()'. An unmatched ')'
+matches just itself. A backslash followed by a digit acts as a
+back-reference and matches the same thing as the previous grouped
+expression indicated by that number. For example '\2' matches the
+second group expression. The order of group expressions is determined
+by the position of their opening parenthesis '('.
+
+ The alternation operator is '|'.
+
+ The characters '^' and '$' always represent the beginning and end of
+a string respectively, except within square brackets. Within brackets,
+'^' can be used to invert the membership of the character class being
+specified.
+
+ '*', '+' and '?' are special at any point in a regular expression
+except:
+
+ 1. At the beginning of a regular expression
+
+ 2. After an open-group, signified by '('
+ 3. After the alternation operator '|'
+
+ Intervals are specified by '{' and '}'. Invalid intervals are
+treated as literals, for example 'a{1' is treated as 'a\{1'
+
+ The longest possible match is returned; this applies to the regular
+expression as a whole and (subject to this constraint) to subexpressions
+within groups.
+
+
+File: find.info, Node: grep regular expression syntax, Next: posix-awk regular expression syntax, Prev: gnu-awk regular expression syntax, Up: Regular Expressions
+
+8.5.6 'grep' regular expression syntax
+--------------------------------------
+
+The character '.' matches any single character.
+
+'\+'
+ indicates that the regular expression should match one or more
+ occurrences of the previous atom or regexp.
+'\?'
+ indicates that the regular expression should match zero or one
+ occurrence of the previous atom or regexp.
+'+ and ?'
+ match themselves.
+
+ Bracket expressions are used to match ranges of characters. Bracket
+expressions where the range is backward, for example '[z-a]', are
+invalid. Within square brackets, '\' is taken literally. Character
+classes are supported; for example '[[:digit:]]' will match a single
+decimal digit.
+
+ GNU extensions are supported:
+
+ 1. '\w' matches a character within a word
+
+ 2. '\W' matches a character which is not within a word
+
+ 3. '\<' matches the beginning of a word
+
+ 4. '\>' matches the end of a word
+
+ 5. '\b' matches a word boundary
+
+ 6. '\B' matches characters which are not a word boundary
+
+ 7. '\`' matches the beginning of the whole input
+
+ 8. '\'' matches the end of the whole input
+
+ Grouping is performed with backslashes followed by parentheses '\(',
+'\)'. A backslash followed by a digit acts as a back-reference and
+matches the same thing as the previous grouped expression indicated by
+that number. For example '\2' matches the second group expression. The
+order of group expressions is determined by the position of their
+opening parenthesis '\('.
+
+ The alternation operator is '\|'.
+
+ The character '^' only represents the beginning of a string when it
+appears:
+
+ 1. At the beginning of a regular expression
+
+ 2. After an open-group, signified by '\('
+
+ 3. After a newline
+
+ 4. After the alternation operator '\|'
+
+ The character '$' only represents the end of a string when it
+appears:
+
+ 1. At the end of a regular expression
+
+ 2. Before a close-group, signified by '\)'
+ 3. Before a newline
+
+ 4. Before the alternation operator '\|'
+
+ '\*', '\+' and '\?' are special at any point in a regular expression
+except:
+
+ 1. At the beginning of a regular expression
+
+ 2. After an open-group, signified by '\('
+ 3. After a newline
+
+ 4. After the alternation operator '\|'
+
+ Intervals are specified by '\{' and '\}'. Invalid intervals such as
+'a\{1z' are not accepted.
+
+ The longest possible match is returned; this applies to the regular
+expression as a whole and (subject to this constraint) to subexpressions
+within groups.
+
+
+File: find.info, Node: posix-awk regular expression syntax, Next: posix-basic regular expression syntax, Prev: grep regular expression syntax, Up: Regular Expressions
+
+8.5.7 'posix-awk' regular expression syntax
+-------------------------------------------
+
+The character '.' matches any single character except the null
+character.
+
+'+'
+ indicates that the regular expression should match one or more
+ occurrences of the previous atom or regexp.
+'?'
+ indicates that the regular expression should match zero or one
+ occurrence of the previous atom or regexp.
+'\+'
+ matches a '+'
+'\?'
+ matches a '?'.
+
+ Bracket expressions are used to match ranges of characters. Bracket
+expressions where the range is backward, for example '[z-a]', are
+invalid. Within square brackets, '\' can be used to quote the following
+character. Character classes are supported; for example '[[:digit:]]'
+will match a single decimal digit.
+
+ GNU extensions are not supported and so '\w', '\W', '\<', '\>', '\b',
+'\B', '\`', and '\'' match 'w', 'W', '<', '>', 'b', 'B', '`', and '''
+respectively.
+
+ Grouping is performed with parentheses '()'. An unmatched ')'
+matches just itself. A backslash followed by a digit acts as a
+back-reference and matches the same thing as the previous grouped
+expression indicated by that number. For example '\2' matches the
+second group expression. The order of group expressions is determined
+by the position of their opening parenthesis '('.
+
+ The alternation operator is '|'.
+
+ The characters '^' and '$' always represent the beginning and end of
+a string respectively, except within square brackets. Within brackets,
+'^' can be used to invert the membership of the character class being
+specified.
+
+ '*', '+' and '?' are special at any point in a regular expression
+except the following places, where they are not allowed:
+
+ 1. At the beginning of a regular expression
+
+ 2. After an open-group, signified by '('
+ 3. After the alternation operator '|'
+
+ Intervals are specified by '{' and '}'. Invalid intervals are
+treated as literals, for example 'a{1' is treated as 'a\{1'
+
+ The longest possible match is returned; this applies to the regular
+expression as a whole and (subject to this constraint) to subexpressions
+within groups.
+
+
+File: find.info, Node: posix-basic regular expression syntax, Next: posix-egrep regular expression syntax, Prev: posix-awk regular expression syntax, Up: Regular Expressions
+
+8.5.8 'posix-basic' regular expression syntax
+---------------------------------------------
+
+This is a synonym for ed.
+
+
+File: find.info, Node: posix-egrep regular expression syntax, Next: posix-extended regular expression syntax, Prev: posix-basic regular expression syntax, Up: Regular Expressions
+
+8.5.9 'posix-egrep' regular expression syntax
+---------------------------------------------
+
+This is a synonym for egrep.
+
+
+File: find.info, Node: posix-extended regular expression syntax, Prev: posix-egrep regular expression syntax, Up: Regular Expressions
+
+8.5.10 'posix-extended' regular expression syntax
+-------------------------------------------------
+
+The character '.' matches any single character except the null
+character.
+
+'+'
+ indicates that the regular expression should match one or more
+ occurrences of the previous atom or regexp.
+'?'
+ indicates that the regular expression should match zero or one
+ occurrence of the previous atom or regexp.
+'\+'
+ matches a '+'
+'\?'
+ matches a '?'.
+
+ Bracket expressions are used to match ranges of characters. Bracket
+expressions where the range is backward, for example '[z-a]', are
+invalid. Within square brackets, '\' is taken literally. Character
+classes are supported; for example '[[:digit:]]' will match a single
+decimal digit.
+
+ GNU extensions are supported:
+
+ 1. '\w' matches a character within a word
+
+ 2. '\W' matches a character which is not within a word
+
+ 3. '\<' matches the beginning of a word
+
+ 4. '\>' matches the end of a word
+
+ 5. '\b' matches a word boundary
+
+ 6. '\B' matches characters which are not a word boundary
+
+ 7. '\`' matches the beginning of the whole input
+
+ 8. '\'' matches the end of the whole input
+
+ Grouping is performed with parentheses '()'. An unmatched ')'
+matches just itself. A backslash followed by a digit acts as a
+back-reference and matches the same thing as the previous grouped
+expression indicated by that number. For example '\2' matches the
+second group expression. The order of group expressions is determined
+by the position of their opening parenthesis '('.
+
+ The alternation operator is '|'.
+
+ The characters '^' and '$' always represent the beginning and end of
+a string respectively, except within square brackets. Within brackets,
+'^' can be used to invert the membership of the character class being
+specified.
+
+ '*', '+' and '?' are special at any point in a regular expression
+except the following places, where they are not allowed:
+
+ 1. At the beginning of a regular expression
+
+ 2. After an open-group, signified by '('
+ 3. After the alternation operator '|'
+
+ Intervals are specified by '{' and '}'. Invalid intervals such as
+'a{1z' are not accepted.
+
+ The longest possible match is returned; this applies to the regular
+expression as a whole and (subject to this constraint) to subexpressions
+within groups.
+
+
+File: find.info, Node: Environment Variables, Prev: Regular Expressions, Up: Reference
+
+8.6 Environment Variables
+=========================
+
+'LANG'
+ Provides a default value for the internationalisation variables
+ that are unset or null.
+
+'LC_ALL'
+ If set to a non-empty string value, override the values of all the
+ other internationalisation variables.
+
+'LC_COLLATE'
+ The POSIX standard specifies that this variable affects the pattern
+ matching to be used for the '\-name' option. GNU find uses the GNU
+ version of the 'fnmatch' library function.
+
+ This variable also affects the interpretation of the response to
+ '-ok'; while the 'LC_MESSAGES' variable selects the actual pattern
+ used to interpret the response to '-ok', the interpretation of any
+ bracket expressions in the pattern will be affected by the
+ 'LC_COLLATE' variable.
+
+'LC_CTYPE'
+ This variable affects the treatment of character classes used in
+ regular expression and with the '-name' test, if the 'fnmatch'
+ function supports this.
+
+ This variable also affects the interpretation of any character
+ classes in the regular expressions used to interpret the response
+ to the prompt issued by '-ok'. The 'LC_CTYPE' environment variable
+ will also affect which characters are considered to be unprintable
+ when filenames are printed (*note Unusual Characters in File
+ Names::).
+
+'LC_MESSAGES'
+ Determines the locale to be used for internationalised messages,
+ including the interpretation of the response to the prompt made by
+ the '-ok' action.
+
+'NLSPATH'
+ Determines the location of the internationalisation message
+ catalogues.
+
+'PATH'
+ Affects the directories which are searched to find the executables
+ invoked by '-exec', '-execdir' '-ok' and '-okdir'. If the PATH
+ environment variable includes the current directory (by explicitly
+ including '.' or by having an empty element), and the find command
+ line includes '-execdir' or '-okdir', 'find' will refuse to run.
+ *Note Security Considerations::, for a more detailed discussion of
+ security matters.
+
+'POSIXLY_CORRECT'
+ Determines the block size used by '-ls' and '-fls'. If
+ 'POSIXLY_CORRECT' is set, blocks are units of 512 bytes. Otherwise
+ they are units of 1024 bytes.
+
+ Setting this variable also turns off warning messages (that is,
+ implies '-nowarn') by default, because POSIX requires that apart
+ from the output for '-ok', all messages printed on stderr are
+ diagnostics and must result in a non-zero exit status.
+
+ When 'POSIXLY_CORRECT' is set, the response to the prompt made by
+ the '-ok' action is interpreted according to the system's message
+ catalogue, as opposed to according to 'find''s own message
+ translations.
+
+'TZ'
+ Affects the time zone used for some of the time-related format
+ directives of '-printf' and '-fprintf'.
+
+
+File: find.info, Node: Common Tasks, Next: Worked Examples, Prev: Reference, Up: Top
+
+9 Common Tasks
+**************
+
+The sections that follow contain some extended examples that both give a
+good idea of the power of these programs, and show you how to solve
+common real-world problems.
+
+* Menu:
+
+* Viewing And Editing::
+* Archiving::
+* Cleaning Up::
+* Strange File Names::
+* Fixing Permissions::
+* Classifying Files::
+
+
+File: find.info, Node: Viewing And Editing, Next: Archiving, Up: Common Tasks
+
+9.1 Viewing And Editing
+=======================
+
+To view a list of files that meet certain criteria, simply run your file
+viewing program with the file names as arguments. Shells substitute a
+command enclosed in backquotes with its output, so the whole command
+looks like this:
+
+ less `find /usr/include -name '*.h' | xargs grep -l mode_t`
+
+You can edit those files by giving an editor name instead of a file
+viewing program:
+
+ emacs `find /usr/include -name '*.h' | xargs grep -l mode_t`
+
+ Because there is a limit to the length of any individual command
+line, there is a limit to the number of files that can be handled in
+this way. We can get around this difficulty by using 'xargs' like this:
+
+ find /usr/include -name '*.h' | xargs grep -l mode_t > todo
+ xargs --arg-file=todo emacs
+
+ Here, 'xargs' will run 'emacs' as many times as necessary to visit
+all of the files listed in the file 'todo'. Generating a temporary file
+is not always convenient, though. This command does much the same thing
+without needing one:
+
+ find /usr/include -name '*.h' | xargs grep -l mode_t |
+ xargs sh -c 'emacs "$@" < /dev/tty' Emacs
+
+ The example above illustrates a useful trick; Using 'sh -c' you can
+invoke a shell command from 'xargs'. The '$@' in the command line is
+expanded by the shell to a list of arguments as provided by 'xargs'.
+The single quotes in the command line protect the '$@' against expansion
+by your interactive shell (which will normally have no arguments and
+thus expand '$@' to nothing). The capitalised 'Emacs' on the command
+line is used as '$0' by the shell that 'xargs' launches.
+
+
+File: find.info, Node: Archiving, Next: Cleaning Up, Prev: Viewing And Editing, Up: Common Tasks
+
+9.2 Archiving
+=============
+
+You can pass a list of files produced by 'find' to a file archiving
+program. GNU 'tar' and 'cpio' can both read lists of file names from
+the standard input - either delimited by nulls (the safe way) or by
+blanks (the lazy, risky default way). To use null-delimited names, give
+them the '--null' option. You can store a file archive in a file, write
+it on a tape, or send it over a network to extract on another machine.
+
+ One common use of 'find' to archive files is to send a list of the
+files in a directory tree to 'cpio'. Use '-depth' so if a directory
+does not have write permission for its owner, its contents can still be
+restored from the archive since the directory's permissions are restored
+after its contents. Here is an example of doing this using 'cpio'; you
+could use a more complex 'find' expression to archive only certain
+files.
+
+ find . -depth -print0 |
+ cpio --create --null --format=crc --file=/dev/nrst0
+
+ You could restore that archive using this command:
+
+ cpio --extract --null --make-dir --unconditional \
+ --preserve --file=/dev/nrst0
+
+ Here are the commands to do the same things using 'tar':
+
+ find . -depth -print0 |
+ tar --create --null --files-from=- --file=/dev/nrst0
+
+ tar --extract --null --preserve-perm --same-owner \
+ --file=/dev/nrst0
+
+ Here is an example of copying a directory from one machine to
+another:
+
+ find . -depth -print0 | cpio -0o -Hnewc |
+ rsh OTHER-MACHINE "cd `pwd` && cpio -i0dum"
+
+
+File: find.info, Node: Cleaning Up, Next: Strange File Names, Prev: Archiving, Up: Common Tasks
+
+9.3 Cleaning Up
+===============
+
+This section gives examples of removing unwanted files in various
+situations. Here is a command to remove the CVS backup files created
+when an update requires a merge:
+
+ find . -name '.#*' -print0 | xargs -0r rm -f
+
+ If your 'find' command removes directories, you may find that you get
+a spurious error message when 'find' tries to recurse into a directory
+that has now been removed. Using the '-depth' option will normally
+resolve this problem.
+
+ It is also possible to use the '-delete' action:
+
+ find . -depth -name '.#*' -delete
+
+ You can run this command to clean out your clutter in '/tmp'. You
+might place it in the file your shell runs when you log out
+('.bash_logout', '.logout', or '.zlogout', depending on which shell you
+use).
+
+ find /tmp -depth -user "$LOGNAME" -type f -delete
+
+ To remove old Emacs backup and auto-save files, you can use a command
+like the following. It is especially important in this case to use
+null-terminated file names because Emacs packages like the VM mailer
+often create temporary file names with spaces in them, like '#reply to
+David J. MacKenzie<1>#'.
+
+ find ~ \( -name '*~' -o -name '#*#' \) -print0 |
+ xargs --no-run-if-empty --null rm -vf
+
+ Removing old files from '/tmp' is commonly done from 'cron':
+
+ find /tmp /var/tmp -depth -not -type d -mtime +3 -delete
+ find /tmp /var/tmp -depth -mindepth 1 -type d -empty -delete
+
+ The second 'find' command above cleans out empty directories
+depth-first ('-delete' implies '-depth' anyway), hoping that the parents
+become empty and can be removed too. It uses '-mindepth' to avoid
+removing '/tmp' itself if it becomes totally empty.
+
+ Lastly, an example of a program that almost certainly does not do
+what the user intended:
+
+ find dirname -delete -name quux
+
+ If the user hoped to delete only files named 'quux' they will get an
+unpleasant surprise; this command will attempt to delete everything at
+or below the starting point 'dirname'. This is because 'find' evaluates
+the items on the command line as an expression. The 'find' program will
+normally execute an action if the preceding action succeeds. Here,
+there is no action or test before the '-delete' so it will always be
+executed. The '-name quux' test will be performed for files we
+successfully deleted, but that test has no effect since '-delete' also
+disables the default '-print' operation. So the above example will
+probably delete a lot of files the user didn't want to delete.
+
+ This command is also likely to do something you did not intend:
+ find dirname -path dirname/foo -prune -o -delete
+
+ Because '-delete' turns on '-depth', the '-prune' action has no
+effect and files in 'dirname/foo' will be deleted too.
+
+
+File: find.info, Node: Strange File Names, Next: Fixing Permissions, Prev: Cleaning Up, Up: Common Tasks
+
+9.4 Strange File Names
+======================
+
+'find' can help you remove or rename a file with strange characters in
+its name. People are sometimes stymied by files whose names contain
+characters such as spaces, tabs, control characters, or characters with
+the high bit set. The simplest way to remove such files is:
+
+ rm -i SOME*PATTERN*THAT*MATCHES*THE*PROBLEM*FILE
+
+ 'rm' asks you whether to remove each file matching the given pattern.
+If you are using an old shell, this approach might not work if the file
+name contains a character with the high bit set; the shell may strip it
+off. A more reliable way is:
+
+ find . -maxdepth 1 TESTS -okdir rm '{}' \;
+
+where TESTS uniquely identify the file. The '-maxdepth 1' option
+prevents 'find' from wasting time searching for the file in any
+subdirectories; if there are no subdirectories, you may omit it. A good
+way to uniquely identify the problem file is to figure out its inode
+number; use
+
+ ls -i
+
+ Suppose you have a file whose name contains control characters, and
+you have found that its inode number is 12345. This command prompts you
+for whether to remove it:
+
+ find . -maxdepth 1 -inum 12345 -okdir rm -f '{}' \;
+
+ If you don't want to be asked, perhaps because the file name may
+contain a strange character sequence that will mess up your screen when
+printed, then use '-execdir' instead of '-okdir'.
+
+ If you want to rename the file instead, you can use 'mv' instead of
+'rm':
+
+ find . -maxdepth 1 -inum 12345 -okdir mv '{}' NEW-FILE-NAME \;
+
+
+File: find.info, Node: Fixing Permissions, Next: Classifying Files, Prev: Strange File Names, Up: Common Tasks
+
+9.5 Fixing Permissions
+======================
+
+Suppose you want to make sure that everyone can write to the directories
+in a certain directory tree. Here is a way to find directories lacking
+either user or group write permission (or both), and fix their
+permissions:
+
+ find . -type d -not -perm -ug=w | xargs chmod ug+w
+
+You could also reverse the operations, if you want to make sure that
+directories do _not_ have world write permission.
+
+
+File: find.info, Node: Classifying Files, Prev: Fixing Permissions, Up: Common Tasks
+
+9.6 Classifying Files
+=====================
+
+If you want to classify a set of files into several groups based on
+different criteria, you can use the comma operator to perform multiple
+independent tests on the files. Here is an example:
+
+ find / -type d \( -perm -o=w -fprint allwrite , \
+ -perm -o=x -fprint allexec \)
+
+ echo "Directories that can be written to by everyone:"
+ cat allwrite
+ echo ""
+ echo "Directories with search permissions for everyone:"
+ cat allexec
+
+ 'find' has only to make one scan through the directory tree (which is
+one of the most time consuming parts of its work).
+
+
+File: find.info, Node: Worked Examples, Next: Security Considerations, Prev: Common Tasks, Up: Top
+
+10 Worked Examples
+******************
+
+The tools in the findutils package, and in particular 'find', have a
+large number of options. This means that quite often, there is more
+than one way to do things. Some of the options and facilities only
+exist for compatibility with other tools, and findutils provides
+improved ways of doing things.
+
+ This chapter describes a number of useful tasks that are commonly
+performed, and compares the different ways of achieving them.
+
+* Menu:
+
+* Deleting Files::
+* Copying A Subset of Files::
+* Updating A Timestamp File::
+* Finding the Shallowest Instance::
+
+
+File: find.info, Node: Deleting Files, Next: Copying A Subset of Files, Up: Worked Examples
+
+10.1 Deleting Files
+===================
+
+One of the most common tasks that 'find' is used for is locating files
+that can be deleted. This might include:
+
+ * Files last modified more than 3 years ago which haven't been
+ accessed for at least 2 years
+ * Files belonging to a certain user
+ * Temporary files which are no longer required
+
+ This example concentrates on the actual deletion task rather than on
+sophisticated ways of locating the files that need to be deleted. We'll
+assume that the files we want to delete are old files underneath
+'/var/tmp/stuff'.
+
+10.1.1 The Traditional Way
+--------------------------
+
+The traditional way to delete files in '/var/tmp/stuff' that have not
+been modified in over 90 days would have been:
+
+ find /var/tmp/stuff -mtime +90 -exec /bin/rm {} \;
+
+ The above command uses '-exec' to run the '/bin/rm' command to remove
+each file. This approach works and in fact would have worked in Version
+7 Unix in 1979. However, there are a number of problems with this
+approach.
+
+ The most obvious problem with the approach above is that it causes
+'find' to fork every time it finds a file that needs to delete, and the
+child process then has to use the 'exec' system call to launch
+'/bin/rm'. All this is quite inefficient. If we are going to use
+'/bin/rm' to do this job, it is better to make it delete more than one
+file at a time.
+
+ The most obvious way of doing this is to use the shell's command
+expansion feature:
+
+ /bin/rm `find /var/tmp/stuff -mtime +90 -print`
+ or you could use the more modern form
+ /bin/rm $(find /var/tmp/stuff -mtime +90 -print)
+
+ The commands above are much more efficient than the first attempt.
+However, there is a problem with them. The shell has a maximum command
+length which is imposed by the operating system (the actual limit varies
+between systems). This means that while the command expansion technique
+will usually work, it will suddenly fail when there are lots of files to
+delete. Since the task is to delete unwanted files, this is precisely
+the time we don't want things to go wrong.
+
+10.1.2 Making Use of 'xargs'
+----------------------------
+
+So, is there a way to be more efficient in the use of 'fork()' and
+'exec()' without running up against this limit? Yes, we can be almost
+optimally efficient by making use of the 'xargs' command. The 'xargs'
+command reads arguments from its standard input and builds them into
+command lines. We can use it like this:
+
+ find /var/tmp/stuff -mtime +90 -print | xargs /bin/rm
+
+ For example if the files found by 'find' are '/var/tmp/stuff/A',
+'/var/tmp/stuff/B' and '/var/tmp/stuff/C' then 'xargs' might issue the
+commands
+
+ /bin/rm /var/tmp/stuff/A /var/tmp/stuff/B
+ /bin/rm /var/tmp/stuff/C
+
+ The above assumes that 'xargs' has a very small maximum command line
+length. The real limit is much larger but the idea is that 'xargs' will
+run '/bin/rm' as many times as necessary to get the job done, given the
+limits on command line length.
+
+ This usage of 'xargs' is pretty efficient, and the 'xargs' command is
+widely implemented (all modern versions of Unix offer it). So far then,
+the news is all good. However, there is bad news too.
+
+10.1.3 Unusual characters in filenames
+--------------------------------------
+
+Unix-like systems allow any characters to appear in file names with the
+exception of the ASCII NUL character and the slash. Slashes can occur
+in path names (as the directory separator) but not in the names of
+actual directory entries. This means that the list of files that
+'xargs' reads could in fact contain white space characters - spaces,
+tabs and newline characters. Since by default, 'xargs' assumes that the
+list of files it is reading uses white space as an argument separator,
+it cannot correctly handle the case where a filename actually includes
+white space. This makes the default behaviour of 'xargs' almost useless
+for handling arbitrary data.
+
+ To solve this problem, GNU findutils introduced the '-print0' action
+for 'find'. This uses the ASCII NUL character to separate the entries
+in the file list that it produces. This is the ideal choice of
+separator since it is the only character that cannot appear within a
+path name. The '-0' option to 'xargs' makes it assume that arguments
+are separated with ASCII NUL instead of white space. It also turns off
+another misfeature in the default behaviour of 'xargs', which is that it
+pays attention to quote characters in its input. Some versions of
+'xargs' also terminate when they see a lone '_' in the input, but GNU
+'find' no longer does that (since it has become an optional behaviour in
+the Unix standard).
+
+ So, putting 'find -print0' together with 'xargs -0' we get this
+command:
+
+ find /var/tmp/stuff -mtime +90 -print0 | xargs -0 /bin/rm
+
+ The result is an efficient way of proceeding that correctly handles
+all the possible characters that could appear in the list of files to
+delete. This is good news. However, there is, as I'm sure you're
+expecting, also more bad news. The problem is that this is not a
+portable construct; although other versions of Unix (notably BSD-derived
+ones) support '-print0', it's not universal. So, is there a more
+universal mechanism?
+
+10.1.4 Going back to '-exec'
+----------------------------
+
+There is indeed a more universal mechanism, which is a slight
+modification to the '-exec' action. The normal '-exec' action assumes
+that the command to run is terminated with a semicolon (the semicolon
+normally has to be quoted in order to protect it from interpretation as
+the shell command separator). The SVR4 edition of Unix introduced a
+slight variation, which involves terminating the command with '+'
+instead:
+
+ find /var/tmp/stuff -mtime +90 -exec /bin/rm {} \+
+
+ The above use of '-exec' causes 'find' to build up a long command
+line and then issue it. This can be less efficient than some uses of
+'xargs'; for example 'xargs' allows new command lines to be built up
+while the previous command is still executing, and allows you to specify
+a number of commands to run in parallel. However, the 'find ... -exec
+... +' construct has the advantage of wide portability. GNU findutils
+did not support '-exec ... +' until version 4.2.12; one of the reasons
+for this is that it already had the '-print0' action in any case.
+
+10.1.5 A more secure version of '-exec'
+---------------------------------------
+
+The command above seems to be efficient and portable. However, within
+it lurks a security problem. The problem is shared with all the
+commands we've tried in this worked example so far, too. The security
+problem is a race condition; that is, if it is possible for somebody to
+manipulate the filesystem that you are searching while you are searching
+it, it is possible for them to persuade your 'find' command to cause the
+deletion of a file that you can delete but they normally cannot.
+
+ The problem occurs because the '-exec' action is defined by the POSIX
+standard to invoke its command with the same working directory as 'find'
+had when it was started. This means that the arguments which replace
+the {} include a relative path from 'find''s starting point down the
+file that needs to be deleted. For example,
+
+ find /var/tmp/stuff -mtime +90 -exec /bin/rm {} \+
+
+ might actually issue the command:
+
+ /bin/rm /var/tmp/stuff/A /var/tmp/stuff/B /var/tmp/stuff/passwd
+
+ Notice the file '/var/tmp/stuff/passwd'. Likewise, the command:
+
+ cd /var/tmp && find stuff -mtime +90 -exec /bin/rm {} \+
+
+ might actually issue the command:
+
+ /bin/rm stuff/A stuff/B stuff/passwd
+
+ If an attacker can rename 'stuff' to something else (making use of
+their write permissions in '/var/tmp') they can replace it with a
+symbolic link to '/etc'. That means that the '/bin/rm' command will be
+invoked on '/etc/passwd'. If you are running your 'find' command as
+root, the attacker has just managed to delete a vital file. All they
+needed to do to achieve this was replace a subdirectory with a symbolic
+link at the vital moment.
+
+ There is however, a simple solution to the problem. This is an
+action which works a lot like '-exec' but doesn't need to traverse a
+chain of directories to reach the file that it needs to work on. This
+is the '-execdir' action, which was introduced by the BSD family of
+operating systems. The command,
+
+ find /var/tmp/stuff -mtime +90 -execdir /bin/rm {} \+
+
+ might delete a set of files by performing these actions:
+
+ 1. Change directory to /var/tmp/stuff/foo
+ 2. Invoke '/bin/rm ./file1 ./file2 ./file3'
+ 3. Change directory to /var/tmp/stuff/bar
+ 4. Invoke '/bin/rm ./file99 ./file100 ./file101'
+
+ This is a much more secure method. We are no longer exposed to a
+race condition. For many typical uses of 'find', this is the best
+strategy. It's reasonably efficient, but the length of the command line
+is limited not just by the operating system limits, but also by how many
+files we actually need to delete from each directory.
+
+ Is it possible to do any better? In the case of general file
+processing, no. However, in the specific case of deleting files it is
+indeed possible to do better.
+
+10.1.6 Using the '-delete' action
+---------------------------------
+
+The most efficient and secure method of solving this problem is to use
+the '-delete' action:
+
+ find /var/tmp/stuff -mtime +90 -delete
+
+ This alternative is more efficient than any of the '-exec' or
+'-execdir' actions, since it entirely avoids the overhead of forking a
+new process and using 'exec' to run '/bin/rm'. It is also normally more
+efficient than 'xargs' for the same reason. The file deletion is
+performed from the directory containing the entry to be deleted, so the
+'-delete' action has the same security advantages as the '-execdir'
+action has.
+
+ The '-delete' action was introduced by the BSD family of operating
+systems.
+
+10.1.7 Improving things still further
+-------------------------------------
+
+Is it possible to improve things still further? Not without either
+modifying the system library to the operating system or having more
+specific knowledge of the layout of the filesystem and disk I/O
+subsystem, or both.
+
+ The 'find' command traverses the filesystem, reading directories. It
+then issues a separate system call for each file to be deleted. If we
+could modify the operating system, there are potential gains that could
+be made:
+
+ * We could have a system call to which we pass more than one filename
+ for deletion
+ * Alternatively, we could pass in a list of inode numbers (on
+ GNU/Linux systems, 'readdir()' also returns the inode number of
+ each directory entry) to be deleted.
+
+ The above possibilities sound interesting, but from the kernel's
+point of view it is difficult to enforce standard Unix access controls
+for such processing by inode number. Such a facility would probably
+need to be restricted to the superuser.
+
+ Another way of improving performance would be to increase the
+parallelism of the process. For example if the directory hierarchy we
+are searching is actually spread across a number of disks, we might
+somehow be able to arrange for 'find' to process each disk in parallel.
+In practice GNU 'find' doesn't have such an intimate understanding of
+the system's filesystem layout and disk I/O subsystem.
+
+ However, since the system administrator can have such an
+understanding they can take advantage of it like so:
+
+ find /var/tmp/stuff1 -mtime +90 -delete &
+ find /var/tmp/stuff2 -mtime +90 -delete &
+ find /var/tmp/stuff3 -mtime +90 -delete &
+ find /var/tmp/stuff4 -mtime +90 -delete &
+ wait
+
+ In the example above, four separate instances of 'find' are used to
+search four subdirectories in parallel. The 'wait' command simply waits
+for all of these to complete. Whether this approach is more or less
+efficient than a single instance of 'find' depends on a number of
+things:
+
+ * Are the directories being searched in parallel actually on separate
+ disks? If not, this parallel search might just result in a lot of
+ disk head movement and so the speed might even be slower.
+ * Other activity - are other programs also doing things on those
+ disks?
+
+10.1.8 Conclusion
+-----------------
+
+The fastest and most secure way to delete files with the help of 'find'
+is to use '-delete'. Using 'xargs -0 -P N' can also make effective use
+of the disk, but it is not as secure.
+
+ In the case where we're doing things other than deleting files, the
+most secure alternative is '-execdir ... +', but this is not as portable
+as the insecure action '-exec ... +'.
+
+ The '-delete' action is not completely portable, but the only other
+possibility which is as secure ('-execdir') is no more portable. The
+most efficient portable alternative is '-exec ...+', but this is
+insecure and isn't supported by versions of GNU findutils prior to
+4.2.12.
+
+
+File: find.info, Node: Copying A Subset of Files, Next: Updating A Timestamp File, Prev: Deleting Files, Up: Worked Examples
+
+10.2 Copying A Subset of Files
+==============================
+
+Suppose you want to copy some files from '/source-dir' to '/dest-dir',
+but there are a small number of files in '/source-dir' you don't want to
+copy.
+
+ One option of course is 'cp /source-dir /dest-dir' followed by
+deletion of the unwanted material under '/dest-dir'. But often that can
+be inconvenient, because for example we would have copied a large amount
+of extraneous material, or because '/dest-dir' is too small. Naturally
+there are many other possible reasons why this strategy may be
+unsuitable.
+
+ So we need to have some way of identifying which files we want to
+copy, and we need to have a way of copying that file list. The second
+part of this condition is met by 'cpio -p'. Of course, we can identify
+the files we wish to copy by using 'find'. Here is a command that
+solves our problem:
+
+ cd /source-dir
+ find . -name '.snapshot' -prune -o \( \! -name '*~' -print0 \) |
+ cpio -pmd0 /dest-dir
+
+ The first part of the 'find' command here identifies files or
+directories named '.snapshot' and tells 'find' not to recurse into them
+(since they do not need to be copied). The combination '-name
+'.snapshot' -prune' yields false for anything that didn't get pruned,
+but it is exactly those files we want to copy. Therefore we need to use
+an OR ('-o') condition to introduce the rest of our expression. The
+remainder of the expression simply arranges for the name of any file not
+ending in '~' to be printed.
+
+ Using '-print0' ensures that white space characters in file names do
+not pose a problem. The 'cpio' command does the actual work of copying
+files. The program as a whole fails if the 'cpio' program returns
+nonzero. If the 'find' command returns non-zero on the other hand, the
+Unix shell will not diagnose a problem (since 'find' is not the last
+command in the pipeline).
+
+
+File: find.info, Node: Updating A Timestamp File, Next: Finding the Shallowest Instance, Prev: Copying A Subset of Files, Up: Worked Examples
+
+10.3 Updating A Timestamp File
+==============================
+
+Suppose we have a directory full of files which is maintained with a set
+of automated tools; perhaps one set of tools updates them and another
+set of tools uses the result. In this situation, it might be useful for
+the second set of tools to know if the files have recently been changed.
+It might be useful, for example, to have a 'timestamp' file which gives
+the timestamp on the newest file in the collection.
+
+ We can use 'find' to achieve this, but there are several different
+ways to do it.
+
+10.3.1 Updating the Timestamp The Wrong Way
+-------------------------------------------
+
+The obvious but wrong answer is just to use '-newer':
+
+ find subdir -newer timestamp -exec touch -r {} timestamp \;
+
+ This does the right sort of thing but has a bug. Suppose that two
+files in the subdirectory have been updated, and that these are called
+'file1' and 'file2'. The command above will update 'timestamp' with the
+modification time of 'file1' or that of 'file2', but we don't know which
+one. Since the timestamps on 'file1' and 'file2' will in general be
+different, this could well be the wrong value.
+
+ One solution to this problem is to modify 'find' to recheck the
+modification time of 'timestamp' every time a file is to be compared
+against it, but that will reduce the performance of 'find'.
+
+10.3.2 Using the test utility to compare timestamps
+---------------------------------------------------
+
+The 'test' command can be used to compare timestamps:
+
+ find subdir -exec test {} -nt timestamp \; -exec touch -r {} timestamp \;
+
+ This will ensure that any changes made to the modification time of
+'timestamp' that take place during the execution of 'find' are taken
+into account. This resolves our earlier problem, but unfortunately this
+runs much more slowly.
+
+10.3.3 A combined approach
+--------------------------
+
+We can of course still use '-newer' to cut down on the number of calls
+to 'test':
+
+ find subdir -newer timestamp -and \
+ -exec test {} -nt timestamp \; -and \
+ -exec touch -r {} timestamp \;
+
+ Here, the '-newer' test excludes all the files which are definitely
+older than the timestamp, but all the files which are newer than the old
+value of the timestamp are compared against the current updated
+timestamp.
+
+ This is indeed faster in general, but the speed difference will
+depend on how many updated files there are.
+
+10.3.4 Using '-printf' and 'sort' to compare timestamps
+-------------------------------------------------------
+
+It is possible to use the '-printf' action to abandon the use of 'test'
+entirely:
+
+ newest=$(find subdir -newer timestamp -printf "%A%p\n" |
+ sort -n |
+ tail -1 |
+ cut -d: -f2- )
+ touch -r "${newest:-timestamp}" timestamp
+
+ The command above works by generating a list of the timestamps and
+names of all the files which are newer than the timestamp. The 'sort',
+'tail' and 'cut' commands simply pull out the name of the file with the
+largest timestamp value (that is, the latest file). The 'touch' command
+is then used to update the timestamp,
+
+ The '"${newest:-timestamp}"' expression simply expands to the value
+of '$newest' if that variable is set, but to 'timestamp' otherwise.
+This ensures that an argument is always given to the '-r' option of the
+'touch' command.
+
+ This approach seems quite efficient, but unfortunately it has a
+problem. Many operating systems now keep file modification time
+information at a granularity which is finer than one second. Findutils
+version 4.3.3 and later will print a fractional part with %A@, but older
+versions will not.
+
+10.3.5 Solving the problem with 'make'
+--------------------------------------
+
+Another tool which often works with timestamps is 'make'. We can use
+'find' to generate a 'Makefile' file on the fly and then use 'make' to
+update the timestamps:
+
+ makefile=$(mktemp)
+ find subdir \
+ \( \! -xtype l \) \
+ -newer timestamp \
+ -printf "timestamp:: %p\n\ttouch -r %p timestamp\n\n" > "$makefile"
+ make -f "$makefile"
+ rm -f "$makefile"
+
+ Unfortunately although the solution above is quite elegant, it fails
+to cope with white space within file names, and adjusting it to do so
+would require a rather complex shell script.
+
+10.3.6 Coping with odd filenames too
+------------------------------------
+
+We can fix both of these problems (looping and problems with white
+space), and do things more efficiently too. The following command works
+with newlines and doesn't need to sort the list of filenames.
+
+ find subdir -newer timestamp -printf "%A@:%p\0" |
+ perl -0 newest.pl |
+ xargs --no-run-if-empty --null -i \
+ find {} -maxdepth 0 -newer timestamp -exec touch -r {} timestamp \;
+
+ The first 'find' command generates a list of files which are newer
+than the original timestamp file, and prints a list of them with their
+timestamps. The 'newest.pl' script simply filters out all the filenames
+which have timestamps which are older than whatever the newest file is:
+
+ #! /usr/bin/perl -0
+ my @newest = ();
+ my $latest_stamp = undef;
+ while (<>) {
+ my ($stamp, $name) = split(/:/);
+ if (!defined($latest_stamp) || ($tstamp > $latest_stamp)) {
+ $latest_stamp = $stamp;
+ @newest = ();
+ }
+ if ($tstamp >= $latest_stamp) {
+ push @newest, $name;
+ }
+ }
+ print join("\0", @newest);
+
+ This prints a list of zero or more files, all of which are newer than
+the original timestamp file, and which have the same timestamp as each
+other, to the nearest second. The second 'find' command takes each
+resulting file one at a time, and if that is newer than the timestamp
+file, the timestamp is updated.
+
+
+File: find.info, Node: Finding the Shallowest Instance, Prev: Updating A Timestamp File, Up: Worked Examples
+
+10.4 Finding the Shallowest Instance
+====================================
+
+Suppose you maintain local copies of sources from various projects, each
+with their own choice of directory organisation and source code
+management (SCM) tool. You need to periodically synchronize each
+project with its upstream tree. As the number local repositories grows,
+so does the work involved in maintaining synchronization. SCM utilities
+typically create some sort of administrative directory: .svn for
+Subversion, CVS for CVS, and so on. These directories can be used as a
+key to search for the bases of the project source trees. Suppose we
+have the following directory structure:
+
+ repo/project1/CVS
+ repo/gnu/project2/.svn
+ repo/gnu/project3/.svn
+ repo/gnu/project3/src/.svn
+ repo/gnu/project3/doc/.svn
+ repo/project4/.git
+
+ One would expect to update each of the 'projectX' directories, but
+not their subdirectories (src, doc, etc.). To locate the project roots,
+we would need to find the least deeply nested directories containing an
+SCM-related subdirectory. The following command discovers those roots
+efficiently. It is efficient because it avoids searching subdirectories
+inside projects whose SCM directory we already found.
+
+ find repo/ \
+ -exec test -d {}/.svn \; -or \
+ -exec test -d {}/.git \; -or \
+ -exec test -d {}/CVS \; -print -prune
+
+ In this example, 'test' is used to tell if we are currently examining
+a directory which appears to the a project's root directory (because it
+has an SCM subdirectory). When we find a project root, there is no need
+to search inside it, and '-prune' makes sure that we descend no further.
+
+ For large, complex trees like the Linux kernel, this will prevent
+searching a large portion of the structure, saving a good deal of time.
+
+
+File: find.info, Node: Security Considerations, Next: Error Messages, Prev: Worked Examples, Up: Top
+
+11 Security Considerations
+**************************
+
+Security considerations are important if you are using 'find' or 'xargs'
+to search for or process files that don't belong to you or which other
+people have control. Security considerations relating to 'locate' may
+also apply if you have files which you do not want others to see.
+
+ The most severe forms of security problems affecting 'find' and
+related programs are when third parties bring about a situation allowing
+them to do something they would normally not be able to accomplish.
+This is called _privilege elevation_. This might include deleting files
+they would not normally be able to delete. It is common for the
+operating system to periodically invoke 'find' for self-maintenance
+purposes. These invocations of 'find' are particularly problematic from
+a security point of view as these are often invoked by the superuser and
+search the entire filesystem hierarchy. Generally, the severity of any
+associated problem depends on what the system is going to do with the
+files found by 'find'.
+
+* Menu:
+
+* Levels of Risk:: What is your level of exposure to security problems?
+* Security Considerations for find:: Security problems with find
+* Security Considerations for xargs:: Security problems with xargs
+* Security Considerations for locate:: Security problems with locate
+* Security Summary:: That was all very complex, what does it boil down to?
+* Further Reading on Security::
+
+
+File: find.info, Node: Levels of Risk, Next: Security Considerations for find, Up: Security Considerations
+
+11.1 Levels of Risk
+===================
+
+There are some security risks inherent in the use of 'find', 'xargs' and
+(to a lesser extent) 'locate'. The severity of these risks depends on
+what sort of system you are using:
+
+*High risk*
+ Multi-user systems where you do not control (or trust) the other
+ users, and on which you execute 'find', including areas where those
+ other users can manipulate the filesystem (for example beneath
+ '/home' or '/tmp').
+
+*Medium Risk*
+ Systems where the actions of other users can create file names
+ chosen by them, but to which they don't have access while 'find' is
+ being run. This access might include leaving programs running
+ (shell background jobs, 'at' or 'cron' tasks, for example). On
+ these sorts of systems, carefully written commands (avoiding use of
+ '-print' for example) should not expose you to a high degree of
+ risk. Most systems fall into this category.
+
+*Low Risk*
+ Systems to which untrusted parties do not have access, cannot
+ create file names of their own choice (even remotely) and which
+ contain no security flaws which might enable an untrusted third
+ party to gain access. Most systems do not fall into this category
+ because there are many ways in which external parties can affect
+ the names of files that are created on your system. The system on
+ which I am writing this for example automatically downloads
+ software updates from the Internet; the names of the files in which
+ these updates exist are chosen by third parties(1).
+
+ In the discussion above, "risk" denotes the likelihood that someone
+can cause 'find', 'xargs', 'locate' or some other program which is
+controlled by them to do something you did not intend. The levels of
+risk suggested do not take any account of the consequences of this sort
+of event. That is, if you operate a "low risk" type system, but the
+consequences of a security problem are disastrous, then you should still
+give serious thought to all the possible security problems, many of
+which of course will not be discussed here - this section of the manual
+is intended to be informative but not comprehensive or exhaustive.
+
+ If you are responsible for the operation of a system where the
+consequences of a security problem could be very important, you should
+do two things:
+
+ 1. Define a security policy which defines who is allowed to do what on
+ your system.
+ 2. Seek competent advice on how to enforce your policy, detect
+ breaches of that policy, and take account of any potential problems
+ that might fall outside the scope of your policy.
+
+ ---------- Footnotes ----------
+
+ (1) Of course, I trust these parties to a large extent anyway,
+because I install software provided by them; I choose to trust them in
+this way, and that's a deliberate choice
+
+
+File: find.info, Node: Security Considerations for find, Next: Security Considerations for xargs, Prev: Levels of Risk, Up: Security Considerations
+
+11.2 Security Considerations for 'find'
+=======================================
+
+Some of the actions 'find' might take have a direct effect; these
+include '-exec' and '-delete'. However, it is also common to use
+'-print' explicitly or implicitly, and so if 'find' produces the wrong
+list of file names, that can also be a security problem; consider the
+case for example where 'find' is producing a list of files to be
+deleted.
+
+ We normally assume that the 'find' command line expresses the file
+selection criteria and actions that the user had in mind - that is, the
+command line is "trusted" data.
+
+ From a security analysis point of view, the output of 'find' should
+be correct; that is, the output should contain only the names of those
+files which meet the user's criteria specified on the command line.
+This applies for the '-exec' and '-delete' actions; one can consider
+these to be part of the output.
+
+ On the other hand, the contents of the filesystem can be manipulated
+by other people, and hence we regard this as "untrusted" data. This
+implies that the 'find' command line is a filter which converts the
+untrusted contents of the filesystem into a correct list of output
+files.
+
+ The filesystem will in general change while 'find' is searching it;
+in fact, most of the potential security problems with 'find' relate to
+this issue in some way.
+
+ "Race conditions" are a general class of security problem where the
+relative ordering of actions taken by 'find' (for example) and something
+else are critically important in getting the correct and expected
+result(1) .
+
+ For 'find', an attacker might move or rename files or directories in
+the hope that an action might be taken against a file which was not
+normally intended to be affected. Alternatively, this sort of attack
+might be intended to persuade 'find' to search part of the filesystem
+which would not normally be included in the search (defeating the
+'-prune' action for example).
+
+* Menu:
+
+* Problems with -exec and filenames::
+* Changing the Current Working Directory::
+* Race Conditions with -exec::
+* Race Conditions with -print and -print0::
+
+ ---------- Footnotes ----------
+
+ (1) This is more or less the definition of the term "race condition"
+
+
+File: find.info, Node: Problems with -exec and filenames, Next: Changing the Current Working Directory, Up: Security Considerations for find
+
+11.2.1 Problems with '-exec' and filenames
+------------------------------------------
+
+It is safe in many cases to use the '-execdir' action with any file
+name. Because '-execdir' prefixes the arguments it passes to programs
+with './', you will not accidentally pass an argument which is
+interpreted as an option. For example the file '-f' would be passed to
+'rm' as './-f', which is harmless.
+
+ However, your degree of safety does depend on the nature of the
+program you are running. For example constructs such as these two
+commands
+
+ # risky
+ find -exec sh -c "something {}" \;
+ find -execdir sh -c "something {}" \;
+
+ are very dangerous. The reason for this is that the '{}' is expanded
+to a filename which might contain a semicolon or other characters
+special to the shell. If for example someone creates the file
+'/tmp/foo; rm -rf $HOME' then the two commands above could delete
+someone's home directory.
+
+ So for this reason do not run any command which will pass untrusted
+data (such as the names of files) to commands which interpret arguments
+as commands to be further interpreted (for example 'sh').
+
+ In the case of the shell, there is a clever workaround for this
+problem:
+
+ # safer
+ find -exec sh -c 'something "$@"' sh {} \;
+ find -execdir sh -c 'something "$@"' sh {} \;
+
+ This approach is not guaranteed to avoid every problem, but it is
+much safer than substituting data of an attacker's choice into the text
+of a shell command.
+
+
+File: find.info, Node: Changing the Current Working Directory, Next: Race Conditions with -exec, Prev: Problems with -exec and filenames, Up: Security Considerations for find
+
+11.2.2 Changing the Current Working Directory
+---------------------------------------------
+
+As 'find' searches the filesystem, it finds subdirectories and then
+searches within them by changing its working directory. First, 'find'
+reaches and recognises a subdirectory. It then decides if that
+subdirectory meets the criteria for being searched; that is, any '-xdev'
+or '-prune' expressions are taken into account. The 'find' program will
+then change working directory and proceed to search the directory.
+
+ A race condition attack might take the form that once the checks
+relevant to '-xdev' and '-prune' have been done, an attacker might
+rename the directory that was being considered, and put in its place a
+symbolic link that actually points somewhere else.
+
+ The idea behind this attack is to fool 'find' into going into the
+wrong directory. This would leave 'find' with a working directory
+chosen by an attacker, bypassing any protection apparently provided by
+'-xdev' and '-prune', and any protection provided by being able to _not_
+list particular directories on the 'find' command line. This form of
+attack is particularly problematic if the attacker can predict when the
+'find' command will be run, as is the case with 'cron' tasks for
+example.
+
+ GNU 'find' has specific safeguards to prevent this general class of
+problem. The exact form of these safeguards depends on the properties
+of your system.
+
+* Menu:
+
+* O_NOFOLLOW:: Safely changing directory using 'fchdir'.
+* Systems without O_NOFOLLOW:: Checking for symbolic links after 'chdir'.
+
+
+File: find.info, Node: O_NOFOLLOW, Next: Systems without O_NOFOLLOW, Up: Changing the Current Working Directory
+
+11.2.2.1 'O_NOFOLLOW'
+.....................
+
+If your system supports the 'O_NOFOLLOW' flag (1) to the 'open(2)'
+system call, 'find' uses it to safely change directories. The target
+directory is first opened and then 'find' changes working directory with
+the 'fchdir()' system call. This ensures that symbolic links are not
+followed, preventing the sort of race condition attack in which use is
+made of symbolic links.
+
+ If for any reason this approach does not work, 'find' will fall back
+on the method which is normally used if 'O_NOFOLLOW' is not supported.
+
+ You can tell if your system supports 'O_NOFOLLOW' by running
+
+ find --version
+
+ This will tell you the version number and which features are enabled.
+For example, if I run this on my system now, this gives:
+ find (GNU findutils) 4.5.11-git
+ Copyright (C) 2012 Free Software Foundation, Inc.
+ License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
+ This is free software: you are free to change and redistribute it.
+ There is NO WARRANTY, to the extent permitted by law.
+
+ Written by Eric B. Decker, James Youngman, and Kevin Dalley.
+ Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION FTS(FTS_CWDFD) CBO(level=2)
+
+ Here, you can see that I am running a version of 'find' which was
+built from the development (git) code prior to the release of
+findutils-4.5.12, and that several features including 'O_NOFOLLOW' are
+present. 'O_NOFOLLOW' is qualified with "enabled". This simply means
+that the current system seems to support 'O_NOFOLLOW'. This check is
+needed because it is possible to build 'find' on a system that defines
+'O_NOFOLLOW' and then run it on a system that ignores the 'O_NOFOLLOW'
+flag. We try to detect such cases at startup by checking the operating
+system and version number; when this happens you will see
+'O_NOFOLLOW(disabled)' instead.
+
+ ---------- Footnotes ----------
+
+ (1) GNU/Linux (kernel version 2.1.126 and later) and FreeBSD
+(3.0-CURRENT and later) support this
+
+
+File: find.info, Node: Systems without O_NOFOLLOW, Prev: O_NOFOLLOW, Up: Changing the Current Working Directory
+
+11.2.2.2 Systems without 'O_NOFOLLOW'
+.....................................
+
+The strategy for preventing this type of problem on systems that lack
+support for the 'O_NOFOLLOW' flag is more complex. Each time 'find'
+changes directory, it examines the directory it is about to move to,
+issues the 'chdir()' system call, and then checks that it has ended up
+in the subdirectory it expected. If all is as expected, processing
+continues as normal. However, there are two main reasons why the
+directory might change: the use of an automounter and the someone
+removing the old directory and replacing it with something else while
+'find' is trying to descend into it.
+
+ Where a filesystem "automounter" is in use it can be the case that
+the use of the 'chdir()' system call can itself cause a new filesystem
+to be mounted at that point. On systems that do not support
+'O_NOFOLLOW', this will cause 'find''s security check to fail.
+
+ However, this does not normally represent a security problem, since
+the automounter configuration is normally set up by the system
+administrator. Therefore, if the 'chdir()' sanity check fails, 'find'
+will make one more attempt(1). If that succeeds, execution carries on
+as normal. This is the usual case for automounters.
+
+ Where an attacker is trying to exploit a race condition, the problem
+may not have gone away on the second attempt. If this is the case,
+'find' will issue a warning message and then ignore that subdirectory.
+When this happens, actions such as '-exec' or '-print' may already have
+taken place for the problematic subdirectory. This is because 'find'
+applies tests and actions to directories before searching within them
+(unless '-depth' was specified).
+
+ Because of the nature of the directory-change operation and security
+check, in the worst case the only things that 'find' would have done
+with the directory are to move into it and back out to the original
+parent. No operations would have been performed within that directory.
+
+ ---------- Footnotes ----------
+
+ (1) This may not be the case for the fts-based executable
+
+
+File: find.info, Node: Race Conditions with -exec, Next: Race Conditions with -print and -print0, Prev: Changing the Current Working Directory, Up: Security Considerations for find
+
+11.2.3 Race Conditions with '-exec'
+-----------------------------------
+
+The '-exec' action causes another program to be run. It passes to the
+program the name of the file which is being considered at the time. The
+invoked program will typically then perform some action on that file.
+Once again, there is a race condition which can be exploited here. We
+shall take as a specific example the command
+
+ find /tmp -path /tmp/umsp/passwd -exec /bin/rm
+
+ In this simple example, we are identifying just one file to be
+deleted and invoking '/bin/rm' to delete it. A problem exists because
+there is a time gap between the point where 'find' decides that it needs
+to process the '-exec' action and the point where the '/bin/rm' command
+actually issues the 'unlink()' system call to delete the file from the
+filesystem. Within this time period, an attacker can rename the
+'/tmp/umsp' directory, replacing it with a symbolic link to '/etc'.
+There is no way for '/bin/rm' to determine that it is working on the
+same file that 'find' had in mind. Once the symbolic link is in place,
+the attacker has persuaded 'find' to cause the deletion of the
+'/etc/passwd' file, which is not the effect intended by the command
+which was actually invoked.
+
+ One possible defence against this type of attack is to modify the
+behaviour of '-exec' so that the '/bin/rm' command is run with the
+argument './passwd' and a suitable choice of working directory. This
+would allow the normal sanity check that 'find' performs to protect
+against this form of attack too. Unfortunately, this strategy cannot be
+used as the POSIX standard specifies that the current working directory
+for commands invoked with '-exec' must be the same as the current
+working directory from which 'find' was invoked. This means that the
+'-exec' action is inherently insecure and can't be fixed.
+
+ GNU 'find' implements a more secure variant of the '-exec' action,
+'-execdir'. The '-execdir' action ensures that it is not necessary to
+dereference subdirectories to process target files. The current
+directory used to invoke programs is the same as the directory in which
+the file to be processed exists ('/tmp/umsp' in our example, and only
+the basename of the file to be processed is passed to the invoked
+command, with a './' prepended (giving './passwd' in our example).
+
+ The '-execdir' action refuses to do anything if the current directory
+is included in the $PATH environment variable. This is necessary
+because '-execdir' runs programs in the same directory in which it finds
+files - in general, such a directory might be writable by untrusted
+users. For similar reasons, '-execdir' does not allow '{}' to appear in
+the name of the command to be run.
+
+
+File: find.info, Node: Race Conditions with -print and -print0, Prev: Race Conditions with -exec, Up: Security Considerations for find
+
+11.2.4 Race Conditions with '-print' and '-print0'
+--------------------------------------------------
+
+The '-print' and '-print0' actions can be used to produce a list of
+files matching some criteria, which can then be used with some other
+command, perhaps with 'xargs'. Unfortunately, this means that there is
+an unavoidable time gap between 'find' deciding that one or more files
+meet its criteria and the relevant command being executed. For this
+reason, the '-print' and '-print0' actions are just as insecure as
+'-exec'.
+
+ In fact, since the construction
+
+ find ... -print | xargs ...
+
+ does not cope correctly with newlines or other "white space" in file
+names, and copes poorly with file names containing quotes, the '-print'
+action is less secure even than '-print0'.
+
+
+File: find.info, Node: Security Considerations for xargs, Next: Security Considerations for locate, Prev: Security Considerations for find, Up: Security Considerations
+
+11.3 Security Considerations for 'xargs'
+========================================
+
+The description of the race conditions affecting the '-print' action of
+'find' shows that 'xargs' cannot be secure if it is possible for an
+attacker to modify a filesystem after 'find' has started but before
+'xargs' has completed all its actions.
+
+ However, there are other security issues that exist even if it is not
+possible for an attacker to have access to the filesystem in real time.
+Firstly, if it is possible for an attacker to create files with names of
+their choice on the filesystem, then 'xargs' is insecure unless the '-0'
+option is used. If a file with the name
+'/home/someuser/foo/bar\n/etc/passwd' exists (assume that '\n' stands
+for a newline character), then 'find ... -print' can be persuaded to
+print three separate lines:
+
+ /home/someuser/foo/bar
+
+ /etc/passwd
+
+ If it finds a blank line in the input, 'xargs' will ignore it.
+Therefore, if some action is to be taken on the basis of this list of
+files, the '/etc/passwd' file would be included even if this was not the
+intent of the person running find. There are circumstances in which an
+attacker can use this to their advantage. The same consideration
+applies to file names containing ordinary spaces rather than newlines,
+except that of course the list of file names will no longer contain an
+"extra" newline.
+
+ This problem is an unavoidable consequence of the default behaviour
+of the 'xargs' command, which is specified by the POSIX standard. The
+only ways to avoid this problem are either to avoid all use of 'xargs'
+in favour for example of 'find -exec' or (where available) 'find
+-execdir', or to use the '-0' option, which ensures that 'xargs'
+considers file names to be separated by ASCII NUL characters rather than
+whitespace. However, useful as this option is, the POSIX standard does
+not make it mandatory.
+
+ POSIX also specifies that 'xargs' interprets quoting and trailing
+whitespace specially in filenames, too. This means that using 'find ...
+-print | xargs ...' can cause the commands run by 'xargs' to receive a
+list of file names which is not the same as the list printed by 'find'.
+The interpretation of quotes and trailing whitespace is turned off by
+the '-0' argument to 'xargs', which is another reason to use that
+option.
+
+
+File: find.info, Node: Security Considerations for locate, Next: Security Summary, Prev: Security Considerations for xargs, Up: Security Considerations
+
+11.4 Security Considerations for 'locate'
+=========================================
+
+11.4.1 Race Conditions
+----------------------
+
+It is fairly unusual for the output of 'locate' to be fed into another
+command. However, if this were to be done, this would raise the same
+set of security issues as the use of 'find ... -print'. Although the
+problems relating to whitespace in file names can be resolved by using
+'locate''s '-0' option, this still leaves the race condition problems
+associated with 'find ... -print0'. There is no way to avoid these
+problems in the case of 'locate'.
+
+11.4.2 Long File Name Bugs with Old-Format Databases
+----------------------------------------------------
+
+Old versions of 'locate' have a bug in the way that old-format databases
+are read. This bug affects the following versions of 'locate':
+
+ 1. All releases prior to 4.2.31
+ 2. All 4.3.x releases prior to 4.3.7
+
+ The affected versions of 'locate' read file names into a fixed-length
+1026 byte buffer, allocated on the heap. This buffer is not extended if
+file names are too long to fit into the buffer. No range checking on
+the length of the filename is performed. This could in theory lead to a
+privilege escalation attack. Findutils versions 4.3.0 to 4.3.6 are also
+affected.
+
+ On systems using the old database format and affected versions of
+'locate', carefully-chosen long file names could in theory allow
+malicious users to run code of their choice as any user invoking locate.
+
+ If remote users can choose the names of files stored on your system,
+and these files are indexed by 'updatedb', this may be a remote security
+vulnerability. Findutils version 4.2.31 and findutils version 4.3.7
+include fixes for this problem. The 'updatedb', 'bigram' and 'code'
+programs do no appear to be affected.
+
+ If you are also using GNU coreutils, you can use the following
+command to determine the length of the longest file name on a given
+system:
+
+ find / -print0 | tr -c '\0' 'x' | tr '\0' '\n' | wc -L
+
+ Although this problem is significant, the old database format is not
+the default, and use of the old database format is not common. Most
+installations and most users will not be affected by this problem.
+
+
+File: find.info, Node: Security Summary, Next: Further Reading on Security, Prev: Security Considerations for locate, Up: Security Considerations
+
+11.5 Summary
+============
+
+Where untrusted parties can create files on the system, or affect the
+names of files that are created, all uses for 'find', 'locate' and
+'xargs' have known security problems except the following:
+
+Informational use only
+ Uses where the programs are used to prepare lists of file names
+ upon which no further action will ever be taken.
+
+'-delete'
+ Use of the '-delete' action with 'find' to delete files which meet
+ specified criteria
+
+'-execdir'
+ Use of the '-execdir' action with 'find' where the 'PATH'
+ environment variable contains directories which contain only
+ trusted programs.
+
+
+File: find.info, Node: Further Reading on Security, Prev: Security Summary, Up: Security Considerations
+
+11.6 Further Reading on Security
+================================
+
+While there are a number of books on computer security, there are also
+useful articles on the web that touch on the issues described above:
+
+<http://goo.gl/DAvh>
+ This article describes some of the unfortunate effects of allowing
+ free choice of file names.
+<http://cwe.mitre.org/data/definitions/78.html>
+ Describes OS Command Injection
+<https://cwe.mitre.org/data/definitions/73.html>
+ Describes problems arising from allowing remote computers to send
+ requests which specify file names of their choice
+<http://cwe.mitre.org/data/definitions/116.html>
+ Describes problems relating to encoding file names and escaping
+ characters. This article is relevant to findutils because for
+ command lines processed via the shell, the encoding and escaping
+ rules are already set by the shell. For example command lines like
+ 'find ... -print | some-shell-script' require specific care.
+<http://xkcd.com/327/>
+ A humorous and pithy summary of the broader problem.
+
+
+File: find.info, Node: Error Messages, Next: GNU Free Documentation License, Prev: Security Considerations, Up: Top
+
+12 Error Messages
+*****************
+
+This section describes some of the error messages sometimes made by
+'find', 'xargs', or 'locate', explains them and in some cases provides
+advice as to what you should do about this.
+
+ This manual is written in English. The GNU findutils software
+features translations of error messages for many languages. For this
+reason the error messages produced by the programs are made to be as
+self-explanatory as possible. This approach avoids leaving people to
+figure out which test an English-language error message corresponds to.
+Error messages which are self-explanatory will not normally be mentioned
+in this document. For those messages mentioned in this document, only
+the English-language version of the message will be listed.
+
+* Menu:
+
+* Error Messages From find::
+* Error Messages From xargs::
+* Error Messages From locate::
+* Error Messages From updatedb::
+
+
+File: find.info, Node: Error Messages From find, Next: Error Messages From xargs, Up: Error Messages
+
+12.1 Error Messages From 'find'
+===============================
+
+Most error messages produced by find are self-explanatory. Error
+messages sometimes include a filename. When this happens, the filename
+is quoted in order to prevent any unusual characters in the filename
+making unwanted changes in the state of the terminal.
+
+'invalid predicate `-foo''
+ This means that the 'find' command line included something that
+ started with a dash or other special character. The 'find' program
+ tried to interpret this as a test, action or option, but didn't
+ recognise it. If it was intended to be a test, check what was
+ specified against the documentation. If, on the other hand, the
+ string is the name of a file which has been expanded from a
+ wildcard (for example because you have a '*' on the command line),
+ consider using './*' or just '.' instead.
+
+'unexpected extra predicate'
+ This usually happens if you have an extra bracket on the command
+ line (for example 'find . -print \)').
+
+'Warning: filesystem /path/foo has recently been mounted'
+'Warning: filesystem /path/foo has recently been unmounted'
+ These messages might appear when 'find' moves into a directory and
+ finds that the device number and inode are different from what it
+ expected them to be. If the directory 'find' has moved into is on
+ a network filesystem (NFS), it will not issue this message, because
+ 'automount' frequently mounts new filesystems on directories as you
+ move into them (that is how it knows you want to use the
+ filesystem). So, if you do see this message, be wary - 'automount'
+ may not have been responsible. Consider the possibility that
+ someone else is manipulating the filesystem while 'find' is
+ running. Some people might do this in order to mislead 'find' or
+ persuade it to look at one set of files when it thought it was
+ looking at another set.
+
+'/path/foo changed during execution of find (old device number 12345, new device number 6789, filesystem type is <whatever>) [ref XXX]'
+ This message is issued when 'find' moves into a directory and ends
+ up somewhere it didn't expect to be. This happens in one of two
+ circumstances. Firstly, this happens when 'automount' intervenes
+ on a system where 'find' doesn't know how to determine what the
+ current set of mounted filesystems is.
+
+ Secondly, this can happen when the device number of a directory
+ appears to change during a change of current directory, but 'find'
+ is moving up the filesystem hierarchy rather than down into it. In
+ order to prevent 'find' wandering off into some unexpected part of
+ the filesystem, we stop it at this point.
+
+'Don't know how to use getmntent() to read `/etc/mtab'. This is a bug.'
+ This message is issued when a problem similar to the above occurs
+ on a system where 'find' doesn't know how to figure out the current
+ list of mount points. Ask for help on <bug-findutils@gnu.org>.
+
+'/path/foo/bar changed during execution of find (old inode number 12345, new inode number 67893, filesystem type is <whatever>) [ref XXX]"),'
+ This message is issued when 'find' moves into a directory and
+ discovers that the inode number of that directory is different from
+ the inode number that it obtained when it examined the directory
+ previously. This usually means that while 'find' was deep in a
+ directory hierarchy doing a time consuming operation, somebody has
+ moved one of the parent directories to another location in the same
+ filesystem. This may or may not have been done maliciously. In
+ any case, 'find' stops at this point to avoid traversing parts of
+ the filesystem that it wasn't intended to. You can use 'ls -li' or
+ 'find /path -inum 12345 -o -inum 67893' to find out more about what
+ has happened.
+
+'sanity check of the fnmatch() library function failed.'
+ Please submit a bug report. You may well be asked questions about
+ your system, and if you compiled the 'findutils' code yourself, you
+ should keep your copy of the build tree around. The likely
+ explanation is that your system has a buggy implementation of
+ 'fnmatch' that looks enough like the GNU version to fool
+ 'configure', but which doesn't work properly.
+
+'cannot fork'
+ This normally happens if you use the '-exec' action or something
+ similar ('-ok' and so forth) but the system has run out of free
+ process slots. This is either because the system is very busy and
+ the system has reached its maximum process limit, or because you
+ have a resource limit in place and you've reached it. Check the
+ system for runaway processes (with 'ps', if possible). Some
+ process slots are normally reserved for use by 'root'.
+
+'some-program terminated by signal 99'
+ Some program which was launched with '-exec' or similar was killed
+ with a fatal signal. This is just an advisory message.
+
+
+File: find.info, Node: Error Messages From xargs, Next: Error Messages From locate, Prev: Error Messages From find, Up: Error Messages
+
+12.2 Error Messages From 'xargs'
+================================
+
+'environment is too large for exec'
+ This message means that you have so many environment variables set
+ (or such large values for them) that there is no room within the
+ system-imposed limits on program command line argument length to
+ invoke any program. This is an unlikely situation and is more
+ likely result of an attempt to test the limits of 'xargs', or break
+ it. Please try unsetting some environment variables, or exiting
+ the current shell. You can also use 'xargs --show-limits' to
+ understand the relevant sizes.
+
+'argument list too long'
+ You are using the '-I' option and 'xargs' doesn't have enough space
+ to build a command line because it has read a really large item and
+ it doesn't fit. You may be able to work around this problem with
+ the '-s' option, but the default size is pretty large. This is a
+ rare situation and is more likely an attempt to test the limits of
+ 'xargs', or break it. Otherwise, you will need to try to shorten
+ the problematic argument or not use 'xargs'.
+
+'argument line too long'
+ You are using the '-L' or '-l' option and one of the input lines is
+ too long. You may be able to work around this problem with the
+ '-s' option, but the default size is pretty large. If you can
+ modify the your 'xargs' command not to use '-L' or '-l', that will
+ be more likely to result in success.
+
+'cannot fork'
+ See the description of the similar message for 'find'.
+
+'<program>: exited with status 255; aborting'
+ When a command run by 'xargs' exits with status 255, 'xargs' is
+ supposed to stop. If this is not what you intended, wrap the
+ program you are trying to invoke in a shell script which doesn't
+ return status 255.
+
+'<program>: terminated by signal 99'
+ See the description of the similar message for 'find'.
+
+'cannot set SIGUSR1 signal handler'
+ 'xargs' is having trouble preparing for you to be able to send it
+ signals to increase or decrease the parallelism of its processing.
+ If you don't plan to send it those signals, this warning can be
+ ignored (though if you're a programmer, you may want to help us
+ figure out why 'xargs' is confused by your operating system).
+
+
+File: find.info, Node: Error Messages From locate, Next: Error Messages From updatedb, Prev: Error Messages From xargs, Up: Error Messages
+
+12.3 Error Messages From 'locate'
+=================================
+
+'warning: database '/usr/local/var/locatedb' is more than 8 days old'
+ The 'locate' program relies on a database which is periodically
+ built by the 'updatedb' program. That hasn't happened in a long
+ time. To fix this problem, run 'updatedb' manually. This can
+ often happen on systems that are generally not left on, so the
+ periodic "cron" task which normally does this doesn't get a chance
+ to run.
+
+'locate database '/usr/local/var/locatedb' is corrupt or invalid'
+ This should not happen. Re-run 'updatedb'. If that works, but
+ 'locate' still produces this error, run 'locate --version' and
+ 'updatedb --version'. These should produce the same output. If
+ not, you are using a mixed toolset; check your '$PATH' environment
+ variable and your shell aliases (if you have any). If both
+ programs claim to be GNU versions, this is a bug; all versions of
+ these programs should interoperate without problem. Ask for help
+ on <bug-findutils@gnu.org>.
+
+
+File: find.info, Node: Error Messages From updatedb, Prev: Error Messages From locate, Up: Error Messages
+
+12.4 Error Messages From 'updatedb'
+===================================
+
+The 'updatedb' program (and the programs it invokes) do issue error
+messages, but none seem to be candidates for guidance. If you are
+having a problem understanding one of these, ask for help on
+<bug-findutils@gnu.org>.
+
+
+File: find.info, Node: GNU Free Documentation License, Next: Primary Index, Prev: Error Messages, Up: Top
+
+Appendix A GNU Free Documentation License
+*****************************************
+
+ Version 1.3, 3 November 2008
+
+ Copyright (C) 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
+ <http://fsf.org/>
+
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ 0. PREAMBLE
+
+ The purpose of this License is to make a manual, textbook, or other
+ functional and useful document "free" in the sense of freedom: to
+ assure everyone the effective freedom to copy and redistribute it,
+ with or without modifying it, either commercially or
+ noncommercially. Secondarily, this License preserves for the
+ author and publisher a way to get credit for their work, while not
+ being considered responsible for modifications made by others.
+
+ This License is a kind of "copyleft", which means that derivative
+ works of the document must themselves be free in the same sense.
+ It complements the GNU General Public License, which is a copyleft
+ license designed for free software.
+
+ We have designed this License in order to use it for manuals for
+ free software, because free software needs free documentation: a
+ free program should come with manuals providing the same freedoms
+ that the software does. But this License is not limited to
+ software manuals; it can be used for any textual work, regardless
+ of subject matter or whether it is published as a printed book. We
+ recommend this License principally for works whose purpose is
+ instruction or reference.
+
+ 1. APPLICABILITY AND DEFINITIONS
+
+ This License applies to any manual or other work, in any medium,
+ that contains a notice placed by the copyright holder saying it can
+ be distributed under the terms of this License. Such a notice
+ grants a world-wide, royalty-free license, unlimited in duration,
+ to use that work under the conditions stated herein. The
+ "Document", below, refers to any such manual or work. Any member
+ of the public is a licensee, and is addressed as "you". You accept
+ the license if you copy, modify or distribute the work in a way
+ requiring permission under copyright law.
+
+ A "Modified Version" of the Document means any work containing the
+ Document or a portion of it, either copied verbatim, or with
+ modifications and/or translated into another language.
+
+ A "Secondary Section" is a named appendix or a front-matter section
+ of the Document that deals exclusively with the relationship of the
+ publishers or authors of the Document to the Document's overall
+ subject (or to related matters) and contains nothing that could
+ fall directly within that overall subject. (Thus, if the Document
+ is in part a textbook of mathematics, a Secondary Section may not
+ explain any mathematics.) The relationship could be a matter of
+ historical connection with the subject or with related matters, or
+ of legal, commercial, philosophical, ethical or political position
+ regarding them.
+
+ The "Invariant Sections" are certain Secondary Sections whose
+ titles are designated, as being those of Invariant Sections, in the
+ notice that says that the Document is released under this License.
+ If a section does not fit the above definition of Secondary then it
+ is not allowed to be designated as Invariant. The Document may
+ contain zero Invariant Sections. If the Document does not identify
+ any Invariant Sections then there are none.
+
+ The "Cover Texts" are certain short passages of text that are
+ listed, as Front-Cover Texts or Back-Cover Texts, in the notice
+ that says that the Document is released under this License. A
+ Front-Cover Text may be at most 5 words, and a Back-Cover Text may
+ be at most 25 words.
+
+ A "Transparent" copy of the Document means a machine-readable copy,
+ represented in a format whose specification is available to the
+ general public, that is suitable for revising the document
+ straightforwardly with generic text editors or (for images composed
+ of pixels) generic paint programs or (for drawings) some widely
+ available drawing editor, and that is suitable for input to text
+ formatters or for automatic translation to a variety of formats
+ suitable for input to text formatters. A copy made in an otherwise
+ Transparent file format whose markup, or absence of markup, has
+ been arranged to thwart or discourage subsequent modification by
+ readers is not Transparent. An image format is not Transparent if
+ used for any substantial amount of text. A copy that is not
+ "Transparent" is called "Opaque".
+
+ Examples of suitable formats for Transparent copies include plain
+ ASCII without markup, Texinfo input format, LaTeX input format,
+ SGML or XML using a publicly available DTD, and standard-conforming
+ simple HTML, PostScript or PDF designed for human modification.
+ Examples of transparent image formats include PNG, XCF and JPG.
+ Opaque formats include proprietary formats that can be read and
+ edited only by proprietary word processors, SGML or XML for which
+ the DTD and/or processing tools are not generally available, and
+ the machine-generated HTML, PostScript or PDF produced by some word
+ processors for output purposes only.
+
+ The "Title Page" means, for a printed book, the title page itself,
+ plus such following pages as are needed to hold, legibly, the
+ material this License requires to appear in the title page. For
+ works in formats which do not have any title page as such, "Title
+ Page" means the text near the most prominent appearance of the
+ work's title, preceding the beginning of the body of the text.
+
+ The "publisher" means any person or entity that distributes copies
+ of the Document to the public.
+
+ A section "Entitled XYZ" means a named subunit of the Document
+ whose title either is precisely XYZ or contains XYZ in parentheses
+ following text that translates XYZ in another language. (Here XYZ
+ stands for a specific section name mentioned below, such as
+ "Acknowledgements", "Dedications", "Endorsements", or "History".)
+ To "Preserve the Title" of such a section when you modify the
+ Document means that it remains a section "Entitled XYZ" according
+ to this definition.
+
+ The Document may include Warranty Disclaimers next to the notice
+ which states that this License applies to the Document. These
+ Warranty Disclaimers are considered to be included by reference in
+ this License, but only as regards disclaiming warranties: any other
+ implication that these Warranty Disclaimers may have is void and
+ has no effect on the meaning of this License.
+
+ 2. VERBATIM COPYING
+
+ You may copy and distribute the Document in any medium, either
+ commercially or noncommercially, provided that this License, the
+ copyright notices, and the license notice saying this License
+ applies to the Document are reproduced in all copies, and that you
+ add no other conditions whatsoever to those of this License. You
+ may not use technical measures to obstruct or control the reading
+ or further copying of the copies you make or distribute. However,
+ you may accept compensation in exchange for copies. If you
+ distribute a large enough number of copies you must also follow the
+ conditions in section 3.
+
+ You may also lend copies, under the same conditions stated above,
+ and you may publicly display copies.
+
+ 3. COPYING IN QUANTITY
+
+ If you publish printed copies (or copies in media that commonly
+ have printed covers) of the Document, numbering more than 100, and
+ the Document's license notice requires Cover Texts, you must
+ enclose the copies in covers that carry, clearly and legibly, all
+ these Cover Texts: Front-Cover Texts on the front cover, and
+ Back-Cover Texts on the back cover. Both covers must also clearly
+ and legibly identify you as the publisher of these copies. The
+ front cover must present the full title with all words of the title
+ equally prominent and visible. You may add other material on the
+ covers in addition. Copying with changes limited to the covers, as
+ long as they preserve the title of the Document and satisfy these
+ conditions, can be treated as verbatim copying in other respects.
+
+ If the required texts for either cover are too voluminous to fit
+ legibly, you should put the first ones listed (as many as fit
+ reasonably) on the actual cover, and continue the rest onto
+ adjacent pages.
+
+ If you publish or distribute Opaque copies of the Document
+ numbering more than 100, you must either include a machine-readable
+ Transparent copy along with each Opaque copy, or state in or with
+ each Opaque copy a computer-network location from which the general
+ network-using public has access to download using public-standard
+ network protocols a complete Transparent copy of the Document, free
+ of added material. If you use the latter option, you must take
+ reasonably prudent steps, when you begin distribution of Opaque
+ copies in quantity, to ensure that this Transparent copy will
+ remain thus accessible at the stated location until at least one
+ year after the last time you distribute an Opaque copy (directly or
+ through your agents or retailers) of that edition to the public.
+
+ It is requested, but not required, that you contact the authors of
+ the Document well before redistributing any large number of copies,
+ to give them a chance to provide you with an updated version of the
+ Document.
+
+ 4. MODIFICATIONS
+
+ You may copy and distribute a Modified Version of the Document
+ under the conditions of sections 2 and 3 above, provided that you
+ release the Modified Version under precisely this License, with the
+ Modified Version filling the role of the Document, thus licensing
+ distribution and modification of the Modified Version to whoever
+ possesses a copy of it. In addition, you must do these things in
+ the Modified Version:
+
+ A. Use in the Title Page (and on the covers, if any) a title
+ distinct from that of the Document, and from those of previous
+ versions (which should, if there were any, be listed in the
+ History section of the Document). You may use the same title
+ as a previous version if the original publisher of that
+ version gives permission.
+
+ B. List on the Title Page, as authors, one or more persons or
+ entities responsible for authorship of the modifications in
+ the Modified Version, together with at least five of the
+ principal authors of the Document (all of its principal
+ authors, if it has fewer than five), unless they release you
+ from this requirement.
+
+ C. State on the Title page the name of the publisher of the
+ Modified Version, as the publisher.
+
+ D. Preserve all the copyright notices of the Document.
+
+ E. Add an appropriate copyright notice for your modifications
+ adjacent to the other copyright notices.
+
+ F. Include, immediately after the copyright notices, a license
+ notice giving the public permission to use the Modified
+ Version under the terms of this License, in the form shown in
+ the Addendum below.
+
+ G. Preserve in that license notice the full lists of Invariant
+ Sections and required Cover Texts given in the Document's
+ license notice.
+
+ H. Include an unaltered copy of this License.
+
+ I. Preserve the section Entitled "History", Preserve its Title,
+ and add to it an item stating at least the title, year, new
+ authors, and publisher of the Modified Version as given on the
+ Title Page. If there is no section Entitled "History" in the
+ Document, create one stating the title, year, authors, and
+ publisher of the Document as given on its Title Page, then add
+ an item describing the Modified Version as stated in the
+ previous sentence.
+
+ J. Preserve the network location, if any, given in the Document
+ for public access to a Transparent copy of the Document, and
+ likewise the network locations given in the Document for
+ previous versions it was based on. These may be placed in the
+ "History" section. You may omit a network location for a work
+ that was published at least four years before the Document
+ itself, or if the original publisher of the version it refers
+ to gives permission.
+
+ K. For any section Entitled "Acknowledgements" or "Dedications",
+ Preserve the Title of the section, and preserve in the section
+ all the substance and tone of each of the contributor
+ acknowledgements and/or dedications given therein.
+
+ L. Preserve all the Invariant Sections of the Document, unaltered
+ in their text and in their titles. Section numbers or the
+ equivalent are not considered part of the section titles.
+
+ M. Delete any section Entitled "Endorsements". Such a section
+ may not be included in the Modified Version.
+
+ N. Do not retitle any existing section to be Entitled
+ "Endorsements" or to conflict in title with any Invariant
+ Section.
+
+ O. Preserve any Warranty Disclaimers.
+
+ If the Modified Version includes new front-matter sections or
+ appendices that qualify as Secondary Sections and contain no
+ material copied from the Document, you may at your option designate
+ some or all of these sections as invariant. To do this, add their
+ titles to the list of Invariant Sections in the Modified Version's
+ license notice. These titles must be distinct from any other
+ section titles.
+
+ You may add a section Entitled "Endorsements", provided it contains
+ nothing but endorsements of your Modified Version by various
+ parties--for example, statements of peer review or that the text
+ has been approved by an organization as the authoritative
+ definition of a standard.
+
+ You may add a passage of up to five words as a Front-Cover Text,
+ and a passage of up to 25 words as a Back-Cover Text, to the end of
+ the list of Cover Texts in the Modified Version. Only one passage
+ of Front-Cover Text and one of Back-Cover Text may be added by (or
+ through arrangements made by) any one entity. If the Document
+ already includes a cover text for the same cover, previously added
+ by you or by arrangement made by the same entity you are acting on
+ behalf of, you may not add another; but you may replace the old
+ one, on explicit permission from the previous publisher that added
+ the old one.
+
+ The author(s) and publisher(s) of the Document do not by this
+ License give permission to use their names for publicity for or to
+ assert or imply endorsement of any Modified Version.
+
+ 5. COMBINING DOCUMENTS
+
+ You may combine the Document with other documents released under
+ this License, under the terms defined in section 4 above for
+ modified versions, provided that you include in the combination all
+ of the Invariant Sections of all of the original documents,
+ unmodified, and list them all as Invariant Sections of your
+ combined work in its license notice, and that you preserve all
+ their Warranty Disclaimers.
+
+ The combined work need only contain one copy of this License, and
+ multiple identical Invariant Sections may be replaced with a single
+ copy. If there are multiple Invariant Sections with the same name
+ but different contents, make the title of each such section unique
+ by adding at the end of it, in parentheses, the name of the
+ original author or publisher of that section if known, or else a
+ unique number. Make the same adjustment to the section titles in
+ the list of Invariant Sections in the license notice of the
+ combined work.
+
+ In the combination, you must combine any sections Entitled
+ "History" in the various original documents, forming one section
+ Entitled "History"; likewise combine any sections Entitled
+ "Acknowledgements", and any sections Entitled "Dedications". You
+ must delete all sections Entitled "Endorsements."
+
+ 6. COLLECTIONS OF DOCUMENTS
+
+ You may make a collection consisting of the Document and other
+ documents released under this License, and replace the individual
+ copies of this License in the various documents with a single copy
+ that is included in the collection, provided that you follow the
+ rules of this License for verbatim copying of each of the documents
+ in all other respects.
+
+ You may extract a single document from such a collection, and
+ distribute it individually under this License, provided you insert
+ a copy of this License into the extracted document, and follow this
+ License in all other respects regarding verbatim copying of that
+ document.
+
+ 7. AGGREGATION WITH INDEPENDENT WORKS
+
+ A compilation of the Document or its derivatives with other
+ separate and independent documents or works, in or on a volume of a
+ storage or distribution medium, is called an "aggregate" if the
+ copyright resulting from the compilation is not used to limit the
+ legal rights of the compilation's users beyond what the individual
+ works permit. When the Document is included in an aggregate, this
+ License does not apply to the other works in the aggregate which
+ are not themselves derivative works of the Document.
+
+ If the Cover Text requirement of section 3 is applicable to these
+ copies of the Document, then if the Document is less than one half
+ of the entire aggregate, the Document's Cover Texts may be placed
+ on covers that bracket the Document within the aggregate, or the
+ electronic equivalent of covers if the Document is in electronic
+ form. Otherwise they must appear on printed covers that bracket
+ the whole aggregate.
+
+ 8. TRANSLATION
+
+ Translation is considered a kind of modification, so you may
+ distribute translations of the Document under the terms of section
+ 4. Replacing Invariant Sections with translations requires special
+ permission from their copyright holders, but you may include
+ translations of some or all Invariant Sections in addition to the
+ original versions of these Invariant Sections. You may include a
+ translation of this License, and all the license notices in the
+ Document, and any Warranty Disclaimers, provided that you also
+ include the original English version of this License and the
+ original versions of those notices and disclaimers. In case of a
+ disagreement between the translation and the original version of
+ this License or a notice or disclaimer, the original version will
+ prevail.
+
+ If a section in the Document is Entitled "Acknowledgements",
+ "Dedications", or "History", the requirement (section 4) to
+ Preserve its Title (section 1) will typically require changing the
+ actual title.
+
+ 9. TERMINATION
+
+ You may not copy, modify, sublicense, or distribute the Document
+ except as expressly provided under this License. Any attempt
+ otherwise to copy, modify, sublicense, or distribute it is void,
+ and will automatically terminate your rights under this License.
+
+ However, if you cease all violation of this License, then your
+ license from a particular copyright holder is reinstated (a)
+ provisionally, unless and until the copyright holder explicitly and
+ finally terminates your license, and (b) permanently, if the
+ copyright holder fails to notify you of the violation by some
+ reasonable means prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+ reinstated permanently if the copyright holder notifies you of the
+ violation by some reasonable means, this is the first time you have
+ received notice of violation of this License (for any work) from
+ that copyright holder, and you cure the violation prior to 30 days
+ after your receipt of the notice.
+
+ Termination of your rights under this section does not terminate
+ the licenses of parties who have received copies or rights from you
+ under this License. If your rights have been terminated and not
+ permanently reinstated, receipt of a copy of some or all of the
+ same material does not give you any rights to use it.
+
+ 10. FUTURE REVISIONS OF THIS LICENSE
+
+ The Free Software Foundation may publish new, revised versions of
+ the GNU Free Documentation License from time to time. Such new
+ versions will be similar in spirit to the present version, but may
+ differ in detail to address new problems or concerns. See
+ <http://www.gnu.org/copyleft/>.
+
+ Each version of the License is given a distinguishing version
+ number. If the Document specifies that a particular numbered
+ version of this License "or any later version" applies to it, you
+ have the option of following the terms and conditions either of
+ that specified version or of any later version that has been
+ published (not as a draft) by the Free Software Foundation. If the
+ Document does not specify a version number of this License, you may
+ choose any version ever published (not as a draft) by the Free
+ Software Foundation. If the Document specifies that a proxy can
+ decide which future versions of this License can be used, that
+ proxy's public statement of acceptance of a version permanently
+ authorizes you to choose that version for the Document.
+
+ 11. RELICENSING
+
+ "Massive Multiauthor Collaboration Site" (or "MMC Site") means any
+ World Wide Web server that publishes copyrightable works and also
+ provides prominent facilities for anybody to edit those works. A
+ public wiki that anybody can edit is an example of such a server.
+ A "Massive Multiauthor Collaboration" (or "MMC") contained in the
+ site means any set of copyrightable works thus published on the MMC
+ site.
+
+ "CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0
+ license published by Creative Commons Corporation, a not-for-profit
+ corporation with a principal place of business in San Francisco,
+ California, as well as future copyleft versions of that license
+ published by that same organization.
+
+ "Incorporate" means to publish or republish a Document, in whole or
+ in part, as part of another Document.
+
+ An MMC is "eligible for relicensing" if it is licensed under this
+ License, and if all works that were first published under this
+ License somewhere other than this MMC, and subsequently
+ incorporated in whole or in part into the MMC, (1) had no cover
+ texts or invariant sections, and (2) were thus incorporated prior
+ to November 1, 2008.
+
+ The operator of an MMC Site may republish an MMC contained in the
+ site under CC-BY-SA on the same site at any time before August 1,
+ 2009, provided the MMC is eligible for relicensing.
+
+ADDENDUM: How to use this License for your documents
+====================================================
+
+To use this License in a document you have written, include a copy of
+the License in the document and put the following copyright and license
+notices just after the title page:
+
+ Copyright (C) YEAR YOUR NAME.
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.3
+ or any later version published by the Free Software Foundation;
+ with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
+ Texts. A copy of the license is included in the section entitled ``GNU
+ Free Documentation License''.
+
+ If you have Invariant Sections, Front-Cover Texts and Back-Cover
+Texts, replace the "with...Texts." line with this:
+
+ with the Invariant Sections being LIST THEIR TITLES, with
+ the Front-Cover Texts being LIST, and with the Back-Cover Texts
+ being LIST.
+
+ If you have Invariant Sections without Cover Texts, or some other
+combination of the three, merge those two alternatives to suit the
+situation.
+
+ If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of free
+software license, such as the GNU General Public License, to permit
+their use in free software.
+
diff --git a/doc/find.info-2 b/doc/find.info-2
new file mode 100644
index 0000000..d0d0145
--- /dev/null
+++ b/doc/find.info-2
Binary files differ
diff --git a/doc/find.texi b/doc/find.texi
new file mode 100644
index 0000000..fdeb841
--- /dev/null
+++ b/doc/find.texi
@@ -0,0 +1,5712 @@
+\input texinfo @c -*-texinfo-*-
+@c %**start of header
+@setfilename find.info
+@settitle Finding Files
+@c For double-sided printing, uncomment:
+@c @setchapternewpage odd
+@c %**end of header
+
+@include version.texi
+@include dblocation.texi
+
+@iftex
+@finalout
+@end iftex
+
+@dircategory Basics
+@direntry
+* Finding files: (find). Operating on files matching certain criteria.
+@end direntry
+
+@dircategory Individual utilities
+@direntry
+* find: (find)Invoking find. Finding and acting on files.
+* locate: (find)Invoking locate. Finding files in a database.
+* updatedb: (find)Invoking updatedb. Building the locate database.
+* xargs: (find)Invoking xargs. Operating on many files.
+@end direntry
+
+@copying
+
+This file documents the GNU utilities for finding files that match
+certain criteria and performing various operations on them.
+
+Copyright @copyright{} 1994, 1996, 1998, 2000, 2001, 2003-2015 Free
+Software Foundation, Inc.
+
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.3 or
+any later version published by the Free Software Foundation; with no
+Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
+A copy of the license is included in the section entitled
+``GNU Free Documentation License''.
+@end copying
+
+@titlepage
+@title Finding Files
+@subtitle Edition @value{EDITION}, for GNU @code{find} version @value{VERSION}
+@subtitle @value{UPDATED}
+@author by David MacKenzie and James Youngman
+
+@page
+@vskip 0pt plus 1filll
+@insertcopying
+@end titlepage
+
+@contents
+
+@ifnottex
+@node Top
+@top GNU Findutils
+@comment node-name, next, previous, up
+@insertcopying
+
+This file documents the GNU utilities for finding files that match
+certain criteria and performing various actions on them.
+
+This is edition @value{EDITION}, for @code{find} version @value{VERSION}.
+@end ifnottex
+
+@c The master menu, created with texinfo-master-menu, goes here.
+
+@menu
+* Introduction:: Summary of the tasks this manual describes.
+* Finding Files:: Finding files that match certain criteria.
+* Actions:: Doing things to files you have found.
+* Databases:: Maintaining file name databases.
+* File Permissions:: How to control access to files.
+* Date input formats:: Specifying literal times.
+* Configuration:: Options you can select at compile time.
+* Reference:: Summary of how to invoke the programs.
+* Common Tasks:: Solutions to common real-world problems.
+* Worked Examples:: Examples demonstrating more complex points.
+* Security Considerations:: Security issues relating to findutils.
+* Error Messages:: Explanations of some messages you might see.
+* GNU Free Documentation License:: Copying and sharing this manual.
+* Primary Index:: The components of @code{find} expressions.
+@end menu
+
+@node Introduction
+@chapter Introduction
+
+This manual shows how to find files that meet criteria you specify,
+and how to perform various actions on the files that you find. The
+principal programs that you use to perform these tasks are
+@code{find}, @code{locate}, and @code{xargs}. Some of the examples in
+this manual use capabilities specific to the GNU versions of those
+programs.
+
+GNU @code{find} was originally written by Eric Decker, with
+enhancements by David MacKenzie, Jay Plett, and Tim Wood. GNU
+@code{xargs} was originally written by Mike Rendell, with enhancements
+by David MacKenzie. GNU @code{locate} and its associated utilities
+were originally written by James Woods, with enhancements by David
+MacKenzie. The idea for @samp{find -print0} and @samp{xargs -0} came
+from Dan Bernstein. The current maintainer of GNU findutils (and this
+manual) is James Youngman. Many other people have contributed bug
+fixes, small improvements, and helpful suggestions. Thanks!
+
+To report a bug in GNU findutils, please use the form on the Savannah
+web site at
+@code{http://savannah.gnu.org/bugs/?group=findutils}. Reporting bugs
+this way means that you will then be able to track progress in fixing
+the problem.
+
+If you don't have web access, you can also just send mail to the
+mailing list. The mailing list @email{bug-findutils@@gnu.org} carries
+discussion of bugs in findutils, questions and answers about the
+software and discussion of the development of the programs. To join
+the list, send email to @email{bug-findutils-request@@gnu.org}.
+
+Please read any relevant sections of this manual before asking for
+help on the mailing list. You may also find it helpful to read the
+NON-BUGS section of the @code{find} manual page.
+
+If you ask for help on the mailing list, people will be able to help
+you much more effectively if you include the following things:
+
+@itemize @bullet
+@item The version of the software you are running. You can find this
+out by running @samp{locate --version}.
+@item What you were trying to do
+@item The @emph{exact} command line you used
+@item The @emph{exact} output you got (if this is very long, try to
+find a smaller example which exhibits the same problem)
+@item The output you expected to get
+@end itemize
+
+It may also be the case that the bug you are describing has already
+been fixed, if it is a bug. Please check the most recent findutils
+releases at @url{ftp://ftp.gnu.org/gnu/findutils} and, if possible,
+the development branch at @url{ftp://alpha.gnu.org/gnu/findutils}.
+If you take the time to check that your bug still exists in current
+releases, this will greatly help people who want to help you solve
+your problem. Please also be aware that if you obtained findutils as
+part of the GNU/Linux 'distribution', the distributions often lag
+seriously behind findutils releases, even the stable release. Please
+check the GNU FTP site.
+
+@menu
+* Scope::
+* Overview::
+* find Expressions::
+@end menu
+
+@node Scope
+@section Scope
+
+For brevity, the word @dfn{file} in this manual means a regular file,
+a directory, a symbolic link, or any other kind of node that has a
+directory entry. A directory entry is also called a @dfn{file name}.
+A file name may contain some, all, or none of the directories in a
+path that leads to the file. These are all examples of what this
+manual calls ``file names'':
+
+@example
+parser.c
+README
+./budget/may-94.sc
+fred/.cshrc
+/usr/local/include/termcap.h
+@end example
+
+A @dfn{directory tree} is a directory and the files it contains, all
+of its subdirectories and the files they contain, etc. It can also be
+a single non-directory file.
+
+These programs enable you to find the files in one or more directory
+trees that:
+
+@itemize @bullet
+@item
+have names that contain certain text or match a certain pattern;
+@item
+are links to certain files;
+@item
+were last used during a certain period of time;
+@item
+are within a certain size range;
+@item
+are of a certain type (regular file, directory, symbolic link, etc.);
+@item
+are owned by a certain user or group;
+@item
+have certain access permissions or special mode bits;
+@item
+contain text that matches a certain pattern;
+@item
+are within a certain depth in the directory tree;
+@item
+or some combination of the above.
+@end itemize
+
+Once you have found the files you're looking for (or files that are
+potentially the ones you're looking for), you can do more to them than
+simply list their names. You can get any combination of the files'
+attributes, or process the files in many ways, either individually or
+in groups of various sizes. Actions that you might want to perform on
+the files you have found include, but are not limited to:
+
+@itemize @bullet
+@item
+view or edit
+@item
+store in an archive
+@item
+remove or rename
+@item
+change access permissions
+@item
+classify into groups
+@end itemize
+
+This manual describes how to perform each of those tasks, and more.
+
+@node Overview
+@section Overview
+
+The principal programs used for making lists of files that match given
+criteria and running commands on them are @code{find}, @code{locate},
+and @code{xargs}. An additional command, @code{updatedb}, is used by
+system administrators to create databases for @code{locate} to use.
+
+@code{find} searches for files in a directory hierarchy and prints
+information about the files it found. It is run like this:
+
+@example
+find @r{[}@var{file}@dots{}@r{]} @r{[}@var{expression}@r{]}
+@end example
+
+@noindent
+Here is a typical use of @code{find}. This example prints the names
+of all files in the directory tree rooted in @file{/usr/src} whose
+name ends with @samp{.c} and that are larger than 100 Kilobytes.
+@example
+find /usr/src -name '*.c' -size +100k -print
+@end example
+
+Notice that the wildcard must be enclosed in quotes in order to
+protect it from expansion by the shell.
+
+@code{locate} searches special file name databases for file names that
+match patterns. The system administrator runs the @code{updatedb}
+program to create the databases. @code{locate} is run like this:
+
+@example
+locate @r{[}@var{option}@dots{}@r{]} @var{pattern}@dots{}
+@end example
+
+@noindent
+This example prints the names of all files in the default file name
+database whose name ends with @samp{Makefile} or @samp{makefile}.
+Which file names are stored in the database depends on how the system
+administrator ran @code{updatedb}.
+@example
+locate '*[Mm]akefile'
+@end example
+
+The name @code{xargs}, pronounced EX-args, means ``combine
+arguments.'' @code{xargs} builds and executes command lines by
+gathering together arguments it reads on the standard input. Most
+often, these arguments are lists of file names generated by
+@code{find}. @code{xargs} is run like this:
+
+@example
+xargs @r{[}@var{option}@dots{}@r{]} @r{[}@var{command} @r{[}@var{initial-arguments}@r{]}@r{]}
+@end example
+
+@noindent
+The following command searches the files listed in the file
+@file{file-list} and prints all of the lines in them that contain the
+word @samp{typedef}.
+@example
+xargs grep typedef < file-list
+@end example
+
+@node find Expressions
+@section @code{find} Expressions
+
+The expression that @code{find} uses to select files consists of one
+or more @dfn{primaries}, each of which is a separate command line
+argument to @code{find}. @code{find} evaluates the expression each
+time it processes a file. An expression can contain any of the
+following types of primaries:
+
+@table @dfn
+@item options
+affect overall operation rather than the processing of a specific
+file;
+@item tests
+return a true or false value, depending on the file's attributes;
+@item actions
+have side effects and return a true or false value; and
+@item operators
+connect the other arguments and affect when and whether they are
+evaluated.
+@end table
+
+You can omit the operator between two primaries; it defaults to
+@samp{-and}. @xref{Combining Primaries With Operators}, for ways to
+connect primaries into more complex expressions. If the expression
+contains no actions other than @samp{-prune}, @samp{-print} is
+performed on all files for which the entire expression is true
+(@pxref{Print File Name}).
+
+Options take effect immediately, rather than being evaluated for each
+file when their place in the expression is reached. Therefore, for
+clarity, it is best to place them at the beginning of the expression.
+There are two exceptions to this; @samp{-daystart} and @samp{-follow}
+have different effects depending on where in the command line they
+appear. This can be confusing, so it's best to keep them at the
+beginning, too.
+
+Many of the primaries take arguments, which immediately follow them in
+the next command line argument to @code{find}. Some arguments are
+file names, patterns, or other strings; others are numbers. Numeric
+arguments can be specified as
+
+@table @code
+@item +@var{n}
+for greater than @var{n},
+@item -@var{n}
+for less than @var{n},
+@item @var{n}
+for exactly @var{n}.
+@end table
+
+@node Finding Files
+@chapter Finding Files
+
+By default, @code{find} prints to the standard output the names of the
+files that match the given criteria. @xref{Actions}, for how to get
+more information about the matching files.
+
+
+@menu
+* Name::
+* Links::
+* Time::
+* Size::
+* Type::
+* Owner::
+* Mode Bits::
+* Contents::
+* Directories::
+* Filesystems::
+* Combining Primaries With Operators::
+@end menu
+
+@node Name
+@section Name
+
+Here are ways to search for files whose name matches a certain
+pattern. @xref{Shell Pattern Matching}, for a description of the
+@var{pattern} arguments to these tests.
+
+Each of these tests has a case-sensitive version and a
+case-insensitive version, whose name begins with @samp{i}. In a
+case-insensitive comparison, the patterns @samp{fo*} and @samp{F??}
+match the file names @file{Foo}, @samp{FOO}, @samp{foo}, @samp{fOo},
+etc.
+
+@menu
+* Base Name Patterns::
+* Full Name Patterns::
+* Fast Full Name Search::
+* Shell Pattern Matching:: Wildcards used by these programs.
+@end menu
+
+@node Base Name Patterns
+@subsection Base Name Patterns
+
+@deffn Test -name pattern
+@deffnx Test -iname pattern
+True if the base of the file name (the path with the leading
+directories removed) matches shell pattern @var{pattern}. For
+@samp{-iname}, the match is case-insensitive.@footnote{Because we
+need to perform case-insensitive matching, the GNU fnmatch
+implementation is always used; if the C library includes the GNU
+implementation, we use that and otherwise we use the one from gnulib}
+To ignore a whole directory tree, use @samp{-prune}
+(@pxref{Directories}). As an example, to find Texinfo source files in
+@file{/usr/local/doc}:
+
+@example
+find /usr/local/doc -name '*.texi'
+@end example
+
+Notice that the wildcard must be enclosed in quotes in order to
+protect it from expansion by the shell.
+
+As of findutils version 4.2.2, patterns for @samp{-name} and
+@samp{-iname} will match a file name with a leading @samp{.}. For
+example the command @samp{find /tmp -name \*bar} will match the file
+@file{/tmp/.foobar}. Braces within the pattern (@samp{@{@}}) are not
+considered to be special (that is, @code{find . -name 'foo@{1,2@}'}
+matches a file named @file{foo@{1,2@}}, not the files @file{foo1} and
+@file{foo2}.
+
+Because the leading directories are removed, the file names considered
+for a match with @samp{-name} will never include a slash, so
+@samp{-name a/b} will never match anything (you probably need to use
+@samp{-path} instead).
+@end deffn
+
+
+@node Full Name Patterns
+@subsection Full Name Patterns
+
+@deffn Test -path pattern
+@deffnx Test -wholename pattern
+True if the entire file name, starting with the command line argument
+under which the file was found, matches shell pattern @var{pattern}.
+To ignore a whole directory tree, use @samp{-prune} rather than
+checking every file in the tree (@pxref{Directories}). The ``entire
+file name'' as used by @code{find} starts with the starting-point
+specified on the command line, and is not converted to an absolute
+pathname, so for example @code{cd /; find tmp -wholename /tmp} will
+never match anything.
+
+Find compares the @samp{-path} argument with the concatenation of a
+directory name and the base name of the file it's considering.
+Since the concatenation will never end with a slash, @samp{-path}
+arguments ending in @samp{/} will match nothing (except perhaps a
+start point specified on the command line).
+
+The name @samp{-wholename} is GNU-specific, but @samp{-path} is more
+portable; it is supported by HP-UX @code{find} and is part of the
+POSIX 2008 standard.
+
+@end deffn
+
+@deffn Test -ipath pattern
+@deffnx Test -iwholename pattern
+These tests are like @samp{-wholename} and @samp{-path}, but the match
+is case-insensitive.
+@end deffn
+
+
+In the context of the tests @samp{-path}, @samp{-wholename},
+@samp{-ipath} and @samp{-wholename}, a ``full path'' is the name of
+all the directories traversed from @code{find}'s start point to the
+file being tested, followed by the base name of the file itself.
+These paths are often not absolute paths; for example
+
+@example
+$ cd /tmp
+$ mkdir -p foo/bar/baz
+$ find foo -path foo/bar -print
+foo/bar
+$ find foo -path /tmp/foo/bar -print
+$ find /tmp/foo -path /tmp/foo/bar -print
+/tmp/foo/bar
+@end example
+
+Notice that the second @code{find} command prints nothing, even though
+@file{/tmp/foo/bar} exists and was examined by @code{find}.
+
+Unlike file name expansion on the command line, a @samp{*} in the pattern
+will match both @samp{/} and leading dots in file names:
+
+@example
+$ find . -path '*f'
+./quux/bar/baz/f
+$ find . -path '*/*config'
+./quux/bar/baz/.config
+@end example
+
+
+@deffn Test -regex expr
+@deffnx Test -iregex expr
+True if the entire file name matches regular expression @var{expr}.
+This is a match on the whole path, not a search. For example, to
+match a file named @file{./fubar3}, you can use the regular expression
+@samp{.*bar.} or @samp{.*b.*3}, but not @samp{f.*r3}. @xref{Regexps,
+, Syntax of Regular Expressions, emacs, The GNU Emacs Manual}, for a
+description of the syntax of regular expressions. For @samp{-iregex},
+the match is case-insensitive.
+
+As for @samp{-path}, the candidate file name never ends with a slash,
+so regular expressions which only match something that ends in slash
+will always fail.
+
+There are several varieties of regular expressions; by default this
+test uses POSIX basic regular expressions, but this can be changed
+with the option @samp{-regextype}.
+@end deffn
+
+@deffn Option -regextype name
+This option controls the variety of regular expression syntax
+understood by the @samp{-regex} and @samp{-iregex} tests. This option
+is positional; that is, it only affects regular expressions which
+occur later in the command line. If this option is not given, GNU
+Emacs regular expressions are assumed. Currently-implemented types
+are
+
+
+@table @samp
+@item emacs
+Regular expressions compatible with GNU Emacs; this is also the
+default behaviour if this option is not used.
+@item posix-awk
+Regular expressions compatible with the POSIX awk command (not GNU awk)
+@item posix-basic
+POSIX Basic Regular Expressions.
+@item posix-egrep
+Regular expressions compatible with the POSIX egrep command
+@item posix-extended
+POSIX Extended Regular Expressions
+@end table
+
+@ref{Regular Expressions} for more information on the regular
+expression dialects understood by GNU findutils.
+
+
+@end deffn
+
+@node Fast Full Name Search
+@subsection Fast Full Name Search
+
+To search for files by name without having to actually scan the
+directories on the disk (which can be slow), you can use the
+@code{locate} program. For each shell pattern you give it,
+@code{locate} searches one or more databases of file names and
+displays the file names that contain the pattern. @xref{Shell Pattern
+Matching}, for details about shell patterns.
+
+If a pattern is a plain string -- it contains no
+metacharacters -- @code{locate} displays all file names in the database
+that contain that string. If a pattern contains
+metacharacters, @code{locate} only displays file names that match the
+pattern exactly. As a result, patterns that contain metacharacters
+should usually begin with a @samp{*}, and will most often end with one
+as well. The exceptions are patterns that are intended to explicitly
+match the beginning or end of a file name.
+
+If you only want @code{locate} to match against the last component of
+the file names (the ``base name'' of the files) you can use the
+@samp{--basename} option. The opposite behaviour is the default, but
+can be selected explicitly by using the option @samp{--wholename}.
+
+The command
+@example
+locate @var{pattern}
+@end example
+
+is almost equivalent to
+@example
+find @var{directories} -name @var{pattern}
+@end example
+
+where @var{directories} are the directories for which the file name
+databases contain information. The differences are that the
+@code{locate} information might be out of date, and that @code{locate}
+handles wildcards in the pattern slightly differently than @code{find}
+(@pxref{Shell Pattern Matching}).
+
+The file name databases contain lists of files that were on the system
+when the databases were last updated. The system administrator can
+choose the file name of the default database, the frequency with which
+the databases are updated, and the directories for which they contain
+entries.
+
+Here is how to select which file name databases @code{locate}
+searches. The default is system-dependent. At the time this document
+was generated, the default was @file{@value{LOCATE_DB}}.
+
+@table @code
+@item --database=@var{path}
+@itemx -d @var{path}
+Instead of searching the default file name database, search the file
+name databases in @var{path}, which is a colon-separated list of
+database file names. You can also use the environment variable
+@code{LOCATE_PATH} to set the list of database files to search. The
+option overrides the environment variable if both are used.
+@end table
+
+GNU @code{locate} can read file name databases generated by the
+@code{slocate} package. However, these generally contain a list of
+all the files on the system, and so when using this database,
+@code{locate} will produce output only for files which are accessible
+to you. @xref{Invoking locate}, for a description of the
+@samp{--existing} option which is used to do this.
+
+The @code{updatedb} program can also generate database in a format
+compatible with @code{slocate}. @xref{Invoking updatedb}, for a
+description of its @samp{--dbformat} and @samp{--output} options.
+
+
+@node Shell Pattern Matching
+@subsection Shell Pattern Matching
+
+@code{find} and @code{locate} can compare file names, or parts of file
+names, to shell patterns. A @dfn{shell pattern} is a string that may
+contain the following special characters, which are known as
+@dfn{wildcards} or @dfn{metacharacters}.
+
+You must quote patterns that contain metacharacters to prevent the
+shell from expanding them itself. Double and single quotes both work;
+so does escaping with a backslash.
+
+@table @code
+@item *
+Matches any zero or more characters.
+
+@item ?
+Matches any one character.
+
+@item [@var{string}]
+Matches exactly one character that is a member of the string
+@var{string}. This is called a @dfn{character class}. As a
+shorthand, @var{string} may contain ranges, which consist of two
+characters with a dash between them. For example, the class
+@samp{[a-z0-9_]} matches a lowercase letter, a number, or an
+underscore. You can negate a class by placing a @samp{!} or @samp{^}
+immediately after the opening bracket. Thus, @samp{[^A-Z@@]} matches
+any character except an uppercase letter or an at sign.
+
+@item \
+Removes the special meaning of the character that follows it. This
+works even in character classes.
+@end table
+
+In the @code{find} tests that do shell pattern matching (@samp{-name},
+@samp{-wholename}, etc.), wildcards in the pattern will match a
+@samp{.} at the beginning of a file name. This is also the case for
+@code{locate}. Thus, @samp{find -name '*macs'} will match a file
+named @file{.emacs}, as will @samp{locate '*macs'}.
+
+Slash characters have no special significance in the shell pattern
+matching that @code{find} and @code{locate} do, unlike in the shell,
+in which wildcards do not match them. Therefore, a pattern
+@samp{foo*bar} can match a file name @samp{foo3/bar}, and a pattern
+@samp{./sr*sc} can match a file name @samp{./src/misc}.
+
+If you want to locate some files with the @samp{locate} command but
+don't need to see the full list you can use the @samp{--limit} option
+to see just a small number of results, or the @samp{--count} option to
+display only the total number of matches.
+
+@node Links
+@section Links
+
+There are two ways that files can be linked together. @dfn{Symbolic
+links} are a special type of file whose contents are a portion of the
+name of another file. @dfn{Hard links} are multiple directory entries
+for one file; the file names all have the same index node
+(@dfn{inode}) number on the disk.
+
+@menu
+* Symbolic Links::
+* Hard Links::
+@end menu
+
+@node Symbolic Links
+@subsection Symbolic Links
+
+Symbolic links are names that reference other files. GNU @code{find}
+will handle symbolic links in one of two ways; firstly, it can
+dereference the links for you - this means that if it comes across a
+symbolic link, it examines the file that the link points to, in order
+to see if it matches the criteria you have specified. Secondly, it
+can check the link itself in case you might be looking for the actual
+link. If the file that the symbolic link points to is also within the
+directory hierarchy you are searching with the @code{find} command,
+you may not see a great deal of difference between these two
+alternatives.
+
+By default, @code{find} examines symbolic links themselves when it
+finds them (and, if it later comes across the linked-to file, it will
+examine that, too). If you would prefer @code{find} to dereference
+the links and examine the file that each link points to, specify the
+@samp{-L} option to @code{find}. You can explicitly specify the
+default behaviour by using the @samp{-P} option. The @samp{-H}
+option is a half-way-between option which ensures that any symbolic
+links listed on the command line are dereferenced, but other symbolic
+links are not.
+
+Symbolic links are different from ``hard links'' in the sense that you
+need permission to search the directories
+in the linked-to file name to
+dereference the link. This can mean that even if you specify the
+@samp{-L} option, @code{find} may not be able to determine the
+properties of the file that the link points to (because you don't have
+sufficient permission). In this situation, @code{find} uses the
+properties of the link itself. This also occurs if a symbolic link
+exists but points to a file that is missing.
+
+The options controlling the behaviour of @code{find} with respect to
+links are as follows:
+
+@table @samp
+@item -P
+@code{find} does not dereference symbolic links at all. This is the
+default behaviour. This option must be specified before any of the
+file names on the command line.
+@item -H
+@code{find} does not dereference symbolic links (except in the case of
+file names on the command line, which are dereferenced). If a
+symbolic link cannot be dereferenced, the information for the symbolic
+link itself is used. This option must be specified before any of the
+file names on the command line.
+@item -L
+@code{find} dereferences symbolic links where possible, and where this
+is not possible it uses the properties of the symbolic link itself.
+This option must be specified before any of the file names on the
+command line. Use of this option also implies the same behaviour as
+the @samp{-noleaf} option. If you later use the @samp{-H} or
+@samp{-P} options, this does not turn off @samp{-noleaf}.
+
+Actions that can cause symbolic links to become broken while
+@samp{find} is executing (for example @samp{-delete}) can give rise to
+confusing behaviour. Take for example the command line
+@samp{find -L . -type d -delete}. This will delete empty
+directories. If a subtree includes only directories and symbolic
+links to directoires, this command may still not successfully delete
+it, since deletion of the target of the symbolic link will cause the
+symbolic link to become broken and @samp{-type d} is false for broken
+symbolic links.
+
+@item -follow
+This option forms part of the ``expression'' and must be specified
+after the file names, but it is otherwise equivalent to @samp{-L}.
+The @samp{-follow} option affects only those tests which appear after
+it on the command line. This option is deprecated. Where possible,
+you should use @samp{-L} instead.
+@end table
+
+The following differences in behaviour occur when the @samp{-L} option
+is used:
+
+@itemize @bullet
+@item
+@code{find} follows symbolic links to directories when searching
+directory trees.
+@item
+@samp{-lname} and @samp{-ilname} always return false (unless they
+happen to match broken symbolic links).
+@item
+@samp{-type} reports the types of the files that symbolic links point
+to. This means that in combination with @samp{-L}, @samp{-type l}
+will be true only for broken symbolic links. To check for symbolic
+links when @samp{-L} has been specified, use @samp{-xtype l}.
+@item
+Implies @samp{-noleaf} (@pxref{Directories}).
+@end itemize
+
+If the @samp{-L} option or the @samp{-H} option is used,
+the file names used as arguments to @samp{-newer}, @samp{-anewer}, and
+@samp{-cnewer} are dereferenced and the timestamp from the pointed-to
+file is used instead (if possible -- otherwise the timestamp from the
+symbolic link is used).
+
+@deffn Test -lname pattern
+@deffnx Test -ilname pattern
+True if the file is a symbolic link whose contents match shell pattern
+@var{pattern}. For @samp{-ilname}, the match is case-insensitive.
+@xref{Shell Pattern Matching}, for details about the @var{pattern}
+argument. If the @samp{-L} option is in effect, this test will always
+return false for symbolic links unless they are broken. So, to list
+any symbolic links to @file{sysdep.c} in the current directory and its
+subdirectories, you can do:
+
+@example
+find . -lname '*sysdep.c'
+@end example
+@end deffn
+
+@node Hard Links
+@subsection Hard Links
+
+Hard links allow more than one name to refer to the same file. To
+find all the names which refer to the same file as @var{name}, use
+@samp{-samefile NAME}. If you are not using the @samp{-L} option, you
+can confine your search to one filesystem using the @samp{-xdev}
+option. This is useful because hard links cannot point outside a
+single filesystem, so this can cut down on needless searching.
+
+If the @samp{-L} option is in effect, and @var{name} is in fact a symbolic
+link, the symbolic link will be dereferenced. Hence you are searching
+for other links (hard or symbolic) to the file pointed to by @var{name}. If
+@samp{-L} is in effect but @var{name} is not itself a symbolic link, other
+symbolic links to the file @var{name} will be matched.
+
+You can also search for files by inode number. This can occasionally
+be useful in diagnosing problems with filesystems for example, because
+@code{fsck} tends to print inode numbers. Inode numbers also
+occasionally turn up in log messages for some types of software, and
+are used to support the @code{ftok()} library function.
+
+You can learn a file's inode number and the number of links to it by
+running @samp{ls -li} or @samp{find -ls}.
+
+You can search for hard links to inode number NUM by using @samp{-inum
+NUM}. If there are any filesystem mount points below the directory
+where you are starting the search, use the @samp{-xdev} option unless
+you are also using the @samp{-L} option. Using @samp{-xdev} this
+saves needless searching, since hard links to a file must be on the
+same filesystem. @xref{Filesystems}.
+
+@deffn Test -samefile NAME
+File is a hard link to the same inode as @var{name}. If the @samp{-L}
+option is in effect, symbolic links to the same file as @var{name} points to
+are also matched.
+@end deffn
+
+@deffn Test -inum n
+File has inode number @var{n}. The @samp{+} and @samp{-} qualifiers
+also work, though these are rarely useful. Much of the time it is
+easier to use @samp{-samefile} rather than this option.
+@end deffn
+
+You can also search for files that have a certain number of links,
+with @samp{-links}. Directories normally have at least two hard
+links; their @file{.} entry is the second one. If they have
+subdirectories, each of those also has a hard link called @file{..} to
+its parent directory. The @file{.} and @file{..} directory entries
+are not normally searched unless they are mentioned on the @code{find}
+command line.
+
+@deffn Test -links n
+File has @var{n} hard links.
+@end deffn
+
+@deffn Test -links +n
+File has more than @var{n} hard links.
+@end deffn
+
+@deffn Test -links -n
+File has fewer than @var{n} hard links.
+@end deffn
+
+@node Time
+@section Time
+
+Each file has three time stamps, which record the last time that
+certain operations were performed on the file:
+
+@enumerate
+@item
+access (read the file's contents)
+@item
+change the status (modify the file or its attributes)
+@item
+modify (change the file's contents)
+@end enumerate
+
+Some systems also provide a timestamp that indicates when a file was
+@emph{created}. For example, the UFS2 filesystem under NetBSD-3.1
+records the @emph{birth time} of each file. This information is also
+available under other versions of BSD and some versions of Cygwin.
+However, even on systems which support file birth time, files may
+exist for which this information was not recorded (for example, UFS1
+file systems simply do not contain this information).
+
+You can search for files whose time stamps are within a certain age
+range, or compare them to other time stamps.
+
+@menu
+* Age Ranges::
+* Comparing Timestamps::
+@end menu
+
+@node Age Ranges
+@subsection Age Ranges
+
+These tests are mainly useful with ranges (@samp{+@var{n}} and
+@samp{-@var{n}}).
+
+@deffn Test -atime n
+@deffnx Test -ctime n
+@deffnx Test -mtime n
+True if the file was last accessed (or its status changed, or it was
+modified) @var{n}*24 hours ago. The number of 24-hour periods since
+the file's timestamp is always rounded down; therefore 0 means ``less
+than 24 hours ago'', 1 means ``between 24 and 48 hours ago'', and so
+forth. Fractional values are supported but this only really makes
+sense for the case where ranges (@samp{+@var{n}} and @samp{-@var{n}})
+are used.
+@end deffn
+
+@deffn Test -amin n
+@deffnx Test -cmin n
+@deffnx Test -mmin n
+True if the file was last accessed (or its status changed, or it was
+modified) @var{n} minutes ago. These tests provide finer granularity
+of measurement than @samp{-atime} et al., but rounding is done in a
+similar way (again, fractions are supported). For example, to list
+files in @file{/u/bill} that were last read from 2 to 6 minutes ago:
+
+@example
+find /u/bill -amin +2 -amin -6
+@end example
+@end deffn
+
+@deffn Option -daystart
+Measure times from the beginning of today rather than from 24 hours
+ago. So, to list the regular files in your home directory that were
+modified yesterday, do
+
+@example
+find ~/ -daystart -type f -mtime 1
+@end example
+
+The @samp{-daystart} option is unlike most other options in that it
+has an effect on the way that other tests are performed. The affected
+tests are @samp{-amin}, @samp{-cmin}, @samp{-mmin}, @samp{-atime},
+@samp{-ctime} and @samp{-mtime}. The @samp{-daystart} option only
+affects the behaviour of any tests which appear after it on the
+command line.
+@end deffn
+
+@node Comparing Timestamps
+@subsection Comparing Timestamps
+
+@deffn Test -newerXY reference
+Succeeds if timestamp @samp{X} of the file being considered is newer
+than timestamp @samp{Y} of the file @file{reference}. The letters
+@samp{X} and @samp{Y} can be any of the following letters:
+
+@table @samp
+@item a
+Last-access time of @file{reference}
+@item B
+Birth time of @file{reference} (when this is not known, the test cannot succeed)
+@item c
+Last-change time of @file{reference}
+@item m
+Last-modification time of @file{reference}
+@item t
+The @file{reference} argument is interpreted as a literal time, rather
+than the name of a file. @xref{Date input formats}, for a description
+of how the timestamp is understood. Tests of the form @samp{-newerXt}
+are valid but tests of the form @samp{-newertY} are not.
+@end table
+
+For example the test @code{-newerac /tmp/foo} succeeds for all files
+which have been accessed more recently than @file{/tmp/foo} was
+changed. Here @samp{X} is @samp{a} and @samp{Y} is @samp{c}.
+
+Not all files have a known birth time. If @samp{Y} is @samp{b} and
+the birth time of @file{reference} is not available, @code{find} exits
+with an explanatory error message. If @samp{X} is @samp{b} and we do
+not know the birth time the file currently being considered, the test
+simply fails (that is, it behaves like @code{-false} does).
+
+Some operating systems (for example, most implementations of Unix) do
+not support file birth times. Some others, for example NetBSD-3.1,
+do. Even on operating systems which support file birth times, the
+information may not be available for specific files. For example,
+under NetBSD, file birth times are supported on UFS2 file systems, but
+not UFS1 file systems.
+
+@end deffn
+
+
+
+There are two ways to list files in @file{/usr} modified after
+February 1 of the current year. One uses @samp{-newermt}:
+
+@example
+find /usr -newermt "Feb 1"
+@end example
+
+The other way of doing this works on the versions of find before 4.3.3:
+
+@c Idea from Rick Sladkey.
+@example
+touch -t 02010000 /tmp/stamp$$
+find /usr -newer /tmp/stamp$$
+rm -f /tmp/stamp$$
+@end example
+
+@deffn Test -anewer file
+@deffnx Test -cnewer file
+@deffnx Test -newer file
+True if the file was last accessed (or its status changed, or it was
+modified) more recently than @var{file} was modified. These tests are
+affected by @samp{-follow} only if @samp{-follow} comes before them on
+the command line. @xref{Symbolic Links}, for more information on
+@samp{-follow}. As an example, to list any files modified since
+@file{/bin/sh} was last modified:
+
+@example
+find . -newer /bin/sh
+@end example
+@end deffn
+
+@deffn Test -used n
+True if the file was last accessed @var{n} days after its status was
+last changed. Useful for finding files that are not being used, and
+could perhaps be archived or removed to save disk space.
+@end deffn
+
+@node Size
+@section Size
+
+@deffn Test -size n@r{[}bckwMG@r{]}
+True if the file uses @var{n} units of space, rounding up. The units
+are 512-byte blocks by default, but they can be changed by adding a
+one-character suffix to @var{n}:
+
+@table @code
+@item b
+512-byte blocks (never 1024)
+@item c
+bytes
+@item k
+kilobytes (1024 bytes)
+@item w
+2-byte words
+@item M
+Megabytes (units of 1048576 bytes)
+@item G
+Gigabytes (units of 1073741824 bytes)
+@end table
+
+The `b' suffix always considers blocks to be 512 bytes. This is not
+affected by the setting (or non-setting) of the @code{POSIXLY_CORRECT}
+environment variable. This behaviour is different from the behaviour of
+the @samp{-ls} action). If you want to use 1024-byte units, use the
+`k' suffix instead.
+
+The number can be prefixed with a `+' or a `-'. A plus sign indicates
+that the test should succeed if the file uses at least @var{n} units
+of storage (a common use of this test) and a minus sign
+indicates that the test should succeed if the file uses less than
+@var{n} units of storage. There is no `=' prefix, because that's the
+default anyway.
+
+The size does not count indirect blocks, but it does count blocks in
+sparse files that are not actually allocated. In other words, it's
+consistent with the result you get for @samp{ls -l} or @samp{wc -c}.
+This handling of sparse files differs from the output of the @samp{%k}
+and @samp{%b} format specifiers for the @samp{-printf} predicate.
+
+@end deffn
+
+@deffn Test -empty
+True if the file is empty and is either a regular file or a directory.
+This might help determine good candidates for deletion. This test is
+useful with @samp{-depth} (@pxref{Directories}) and @samp{-delete}
+(@pxref{Single File}).
+@end deffn
+
+@node Type
+@section Type
+
+@deffn Test -type c
+True if the file is of type @var{c}:
+
+@table @code
+@item b
+block (buffered) special
+@item c
+character (unbuffered) special
+@item d
+directory
+@item p
+named pipe (FIFO)
+@item f
+regular file
+@item l
+symbolic link; if @samp{-L} is in effect, this is true only for broken
+symbolic links. If you want to search for symbolic links when
+@samp{-L} is in effect, use @samp{-xtype} instead of @samp{-type}.
+@item s
+socket
+@item D
+door (Solaris)
+@end table
+@end deffn
+
+@deffn Test -xtype c
+This test behaves the same as @samp{-type} unless the file is a
+symbolic link. If the file is a symbolic link, the result is as
+follows (in the table below, @samp{X} should be understood to
+represent any letter except @samp{l}):
+
+@table @samp
+@item @samp{-P -xtype l}
+True if the symbolic link is broken
+@item @samp{-P -xtype X}
+True if the (ultimate) target file is of type @samp{X}.
+@item @samp{-L -xtype l}
+Always true
+@item @samp{-L -xtype X}
+False unless the symbolic link is broken
+@end table
+
+In other words, for symbolic links, @samp{-xtype} checks the type of
+the file that @samp{-type} does not check.
+
+The @samp{-H} option also affects the behaviour of @samp{-xtype}.
+When @samp{-H} is in effect, @samp{-xtype} behaves as if @samp{-L} had
+been specified when examining files listed on the command line, and as
+if @samp{-P} had been specified otherwise. If neither @samp{-H} nor
+@samp{-L} was specified, @samp{-xtype} behaves as if @samp{-P} had
+been specified.
+
+@xref{Symbolic Links}, for more information on @samp{-follow} and
+@samp{-L}.
+@end deffn
+
+@node Owner
+@section Owner
+
+@deffn Test -user uname
+@deffnx Test -group gname
+True if the file is owned by user @var{uname} (belongs to group
+@var{gname}). A numeric ID is allowed.
+@end deffn
+
+@deffn Test -uid n
+@deffnx Test -gid n
+True if the file's numeric user ID (group ID) is @var{n}. These tests
+support ranges (@samp{+@var{n}} and @samp{-@var{n}}), unlike
+@samp{-user} and @samp{-group}.
+@end deffn
+
+@deffn Test -nouser
+@deffnx Test -nogroup
+True if no user corresponds to the file's numeric user ID (no group
+corresponds to the numeric group ID). These cases usually mean that
+the files belonged to users who have since been removed from the
+system. You probably should change the ownership of such files to an
+existing user or group, using the @code{chown} or @code{chgrp}
+program.
+@end deffn
+
+@node Mode Bits
+@section File Mode Bits
+
+@xref{File Permissions}, for information on how file mode bits are
+structured and how to specify them.
+
+Four tests determine what users can do with files. These are
+@samp{-readable}, @samp{-writable}, @samp{-executable} and
+@samp{-perm}. The first three tests ask the operating system if the
+current user can perform the relevant operation on a file, while
+@samp{-perm} just examines the file's mode. The file mode may give
+a misleading impression of what the user can actually do, because the
+file may have an access control list, or exist on a read-only
+filesystem, for example. Of these four tests though, only
+@samp{-perm} is specified by the POSIX standard.
+
+The @samp{-readable}, @samp{-writable} and @samp{-executable} tests
+are implemented via the @code{access} system call. This is
+implemented within the operating system itself. If the file being
+considered is on an NFS filesystem, the remote system may allow or
+forbid read or write operations for reasons of which the NFS client
+cannot take account. This includes user-ID mapping, either in the
+general sense or the more restricted sense in which remote superusers
+are treated by the NFS server as if they are the local user
+@samp{nobody} on the NFS server.
+
+None of the tests in this section should be used to verify that a user
+is authorised to perform any operation (on the file being tested or
+any other file) because of the possibility of a race condition. That
+is, the situation may change between the test and an action being
+taken on the basis of the result of that test.
+
+
+@deffn Test -readable
+True if the file can be read by the invoking user.
+@end deffn
+
+@deffn Test -writable
+True if the file can be written by the invoking user. This is an
+in-principle check, and other things may prevent a successful write
+operation; for example, the filesystem might be full.
+@end deffn
+
+@deffn Test -executable
+True if the file can be executed/searched by the invoking user.
+@end deffn
+
+@deffn Test -perm pmode
+
+True if the file's mode bits match @var{pmode}, which can be
+either a symbolic or numeric @var{mode} (@pxref{File Permissions})
+optionally prefixed by @samp{-} or @samp{/}.
+
+A @var{pmode} that starts with neither @samp{-} nor @samp{/} matches
+if @var{mode} exactly matches the file mode bits.
+(To avoid confusion with an obsolete GNU extension, @var{mode}
+must not start with a @samp{+} immediately followed by an octal digit.)
+
+A @var{pmode} that starts with @samp{-} matches if
+@emph{all} the file mode bits set in @var{mode} are set for the file;
+bits not set in @var{mode} are ignored.
+
+A @var{pmode} that starts with @samp{/} matches if
+@emph{any} of the file mode bits set in @var{mode} are set for the file;
+bits not set in @var{mode} are ignored.
+This is a GNU extension.
+
+If you don't use the @samp{/} or @samp{-} form with a symbolic mode
+string, you may have to specify a rather complex mode string. For
+example @samp{-perm g=w} will only match files that have mode 0020
+(that is, ones for which group write permission is the only file mode bit
+set). It is more likely that you will want to use the @samp{/} or
+@samp{-} forms, for example @samp{-perm -g=w}, which matches any file
+with group write permission.
+
+
+@table @samp
+@item -perm 664
+Match files that have read and write permission for their owner,
+and group, but that the rest of the world can read but not write to.
+Do not match files that meet these criteria but have other file mode
+bits set (for example if someone can execute/search the file).
+
+@item -perm -664
+Match files that have read and write permission for their owner,
+and group, but that the rest of the world can read but not write to,
+without regard to the presence of any extra file mode bits (for
+example the executable bit). This matches a file with mode
+0777, for example.
+
+@item -perm /222
+Match files that are writable by somebody (their owner, or
+their group, or anybody else).
+
+@item -perm /022
+Match files that are writable by either their owner or their
+group. The files don't have to be writable by both the owner and
+group to be matched; either will do.
+
+@item -perm /g+w,o+w
+As above.
+
+@item -perm /g=w,o=w
+As above.
+
+@item -perm -022
+Match files that are writable by both their owner and their
+group.
+
+@item -perm -444 -perm /222 ! -perm /111
+Match files that are readable for everybody, have at least one
+write bit set (i.e., somebody can write to them), but that cannot be
+executed/searched by anybody. Note that in some shells the @samp{!} must be
+escaped;.
+
+@item -perm -a+r -perm /a+w ! -perm /a+x
+As above.
+
+
+@item -perm -g+w,o+w
+As above.
+@end table
+
+@quotation Warning
+If you specify @samp{-perm /000} or @samp{-perm /mode} where the
+symbolic mode @samp{mode} has no bits set, the test matches all files.
+Versions of GNU @code{find} prior to 4.3.3 matched no files in this
+situation.
+@end quotation
+
+@end deffn
+
+@deffn Test -context pattern
+True if file's SELinux context matches the pattern @var{pattern}.
+The pattern uses shell glob matching.
+
+This predicate is supported only on @code{find} versions compiled with
+SELinux support and only when SELinux is enabled.
+@end deffn
+
+@node Contents
+@section Contents
+
+To search for files based on their contents, you can use the
+@code{grep} program. For example, to find out which C source files in
+the current directory contain the string @samp{thing}, you can do:
+
+@example
+grep -l thing *.[ch]
+@end example
+
+If you also want to search for the string in files in subdirectories,
+you can combine @code{grep} with @code{find} and @code{xargs}, like
+this:
+
+@example
+find . -name '*.[ch]' | xargs grep -l thing
+@end example
+
+The @samp{-l} option causes @code{grep} to print only the names of
+files that contain the string, rather than the lines that contain it.
+The string argument (@samp{thing}) is actually a regular expression,
+so it can contain metacharacters. This method can be refined a little
+by using the @samp{-r} option to make @code{xargs} not run @code{grep}
+if @code{find} produces no output, and using the @code{find} action
+@samp{-print0} and the @code{xargs} option @samp{-0} to avoid
+misinterpreting files whose names contain spaces:
+
+@example
+find . -name '*.[ch]' -print0 | xargs -r -0 grep -l thing
+@end example
+
+For a fuller treatment of finding files whose contents match a
+pattern, see the manual page for @code{grep}.
+
+@node Directories
+@section Directories
+
+Here is how to control which directories @code{find} searches, and how
+it searches them. These two options allow you to process a horizontal
+slice of a directory tree.
+
+@deffn Option -maxdepth levels
+Descend at most @var{levels} (a non-negative integer) levels of
+directories below the command line arguments. @samp{-maxdepth 0}
+means only apply the tests and actions to the command line arguments.
+@end deffn
+
+@deffn Option -mindepth levels
+Do not apply any tests or actions at levels less than @var{levels} (a
+non-negative integer). @samp{-mindepth 1} means process all files
+except the command line arguments.
+@end deffn
+
+@deffn Option -depth
+Process each directory's contents before the directory itself. Doing
+this is a good idea when producing lists of files to archive with
+@code{cpio} or @code{tar}. If a directory does not have write
+permission for its owner, its contents can still be restored from the
+archive since the directory's permissions are restored after its
+contents.
+@end deffn
+
+@deffn Option -d
+This is a deprecated synonym for @samp{-depth}, for compatibility with
+Mac OS X, FreeBSD and OpenBSD. The @samp{-depth} option is a POSIX
+feature, so it is better to use that.
+@end deffn
+
+@deffn Action -prune
+If the file is a directory, do not descend into it. The result is
+true. For example, to skip the directory @file{src/emacs} and all
+files and directories under it, and print the names of the other files
+found:
+
+@example
+find . -wholename './src/emacs' -prune -o -print
+@end example
+
+The above command will not print @file{./src/emacs} among its list of
+results. This however is not due to the effect of the @samp{-prune}
+action (which only prevents further descent, it doesn't make sure we
+ignore that item). Instead, this effect is due to the use of
+@samp{-o}. Since the left hand side of the ``or'' condition has
+succeeded for @file{./src/emacs}, it is not necessary to evaluate the
+right-hand-side (@samp{-print}) at all for this particular file. If
+you wanted to print that directory name you could use either an extra
+@samp{-print} action:
+
+@example
+find . -wholename './src/emacs' -prune -print -o -print
+@end example
+
+or use the comma operator:
+
+@example
+find . -wholename './src/emacs' -prune , -print
+@end example
+
+If the @samp{-depth} option is in effect, the subdirectories will have
+already been visited in any case. Hence @samp{-prune} has no effect
+in this case.
+
+Because @samp{-delete} implies @samp{-depth}, using @samp{-prune} in
+combination with @samp{-delete} may well result in the deletion of
+more files than you intended.
+@end deffn
+
+
+@deffn Action -quit
+Exit immediately (with return value zero if no errors have occurred).
+This is different to @samp{-prune} because @samp{-prune} only applies
+to the contents of pruned directories, while @samp{-quit} simply makes
+@code{find} stop immediately. No child processes will be left
+running, but no more files specified on the command line will be
+processed. For example, @code{find /tmp/foo /tmp/bar -print -quit}
+will print only @samp{/tmp/foo}. Any command lines which have been
+built by @samp{-exec ... \+} or @samp{-execdir ... \+} are invoked
+before the program is exited.
+@end deffn
+
+@deffn Option -noleaf
+Do not optimize by assuming that directories contain 2 fewer
+subdirectories than their hard link count. This option is needed when
+searching filesystems that do not follow the Unix directory-link
+convention, such as CD-ROM or MS-DOS filesystems or AFS volume mount
+points. Each directory on a normal Unix filesystem has at least 2
+hard links: its name and its @file{.} entry. Additionally, its
+subdirectories (if any) each have a @file{..} entry linked to that
+directory. When @code{find} is examining a directory, after it has
+statted 2 fewer subdirectories than the directory's link count, it
+knows that the rest of the entries in the directory are
+non-directories (@dfn{leaf} files in the directory tree). If only the
+files' names need to be examined, there is no need to stat them; this
+gives a significant increase in search speed.
+@end deffn
+
+@deffn Option -ignore_readdir_race
+If a file disappears after its name has been read from a directory but
+before @code{find} gets around to examining the file with @code{stat},
+don't issue an error message. If you don't specify this option, an
+error message will be issued. This option can be useful in system
+scripts (cron scripts, for example) that examine areas of the
+filesystem that change frequently (mail queues, temporary directories,
+and so forth), because this scenario is common for those sorts of
+directories. Completely silencing error messages from @code{find} is
+undesirable, so this option neatly solves the problem. There is no
+way to search one part of the filesystem with this option on and part
+of it with this option off, though. When this option is turned on and
+find discovers that one of the start-point files specified on the
+command line does not exist, no error message will be issued.
+
+@end deffn
+
+@deffn Option -noignore_readdir_race
+This option reverses the effect of the @samp{-ignore_readdir_race}
+option.
+@end deffn
+
+
+@node Filesystems
+@section Filesystems
+
+A @dfn{filesystem} is a section of a disk, either on the local host or
+mounted from a remote host over a network. Searching network
+filesystems can be slow, so it is common to make @code{find} avoid
+them.
+
+There are two ways to avoid searching certain filesystems. One way is
+to tell @code{find} to only search one filesystem:
+
+@deffn Option -xdev
+@deffnx Option -mount
+Don't descend directories on other filesystems. These options are
+synonyms.
+@end deffn
+
+The other way is to check the type of filesystem each file is on, and
+not descend directories that are on undesirable filesystem types:
+
+@deffn Test -fstype type
+True if the file is on a filesystem of type @var{type}. The valid
+filesystem types vary among different versions of Unix; an incomplete
+list of filesystem types that are accepted on some version of Unix or
+another is:
+@example
+ext2 ext3 proc sysfs ufs 4.2 4.3 nfs tmp mfs S51K S52K
+@end example
+You can use @samp{-printf} with the @samp{%F} directive to see the
+types of your filesystems. The @samp{%D} directive shows the device
+number. @xref{Print File Information}. @samp{-fstype} is usually
+used with @samp{-prune} to avoid searching remote filesystems
+(@pxref{Directories}).
+@end deffn
+
+@node Combining Primaries With Operators
+@section Combining Primaries With Operators
+
+Operators build a complex expression from tests and actions.
+The operators are, in order of decreasing precedence:
+
+@table @code
+@item @asis{( @var{expr} )}
+@findex ()
+Force precedence. True if @var{expr} is true.
+
+@item @asis{! @var{expr}}
+@itemx @asis{-not @var{expr}}
+@findex !
+@findex -not
+True if @var{expr} is false. In some shells, it is necessary to
+protect the @samp{!} from shell interpretation by quoting it.
+
+@item @asis{@var{expr1 expr2}}
+@itemx @asis{@var{expr1} -a @var{expr2}}
+@itemx @asis{@var{expr1} -and @var{expr2}}
+@findex -and
+@findex -a
+And; @var{expr2} is not evaluated if @var{expr1} is false.
+
+@item @asis{@var{expr1} -o @var{expr2}}
+@itemx @asis{@var{expr1} -or @var{expr2}}
+@findex -or
+@findex -o
+Or; @var{expr2} is not evaluated if @var{expr1} is true.
+
+@item @asis{@var{expr1} , @var{expr2}}
+@findex ,
+List; both @var{expr1} and @var{expr2} are always evaluated. True if
+@var{expr2} is true. The value of @var{expr1} is discarded. This
+operator lets you do multiple independent operations on one traversal,
+without depending on whether other operations succeeded. The two
+operations @var{expr1} and @var{expr2} are not always fully
+independent, since @var{expr1} might have side effects like touching
+or deleting files, or it might use @samp{-prune} which would also
+affect @var{expr2}.
+@end table
+
+@code{find} searches the directory tree rooted at each file name by
+evaluating the expression from left to right, according to the rules
+of precedence, until the outcome is known (the left hand side is false
+for @samp{-and}, true for @samp{-or}), at which point @code{find}
+moves on to the next file name.
+
+There are two other tests that can be useful in complex expressions:
+
+@deffn Test -true
+Always true.
+@end deffn
+
+@deffn Test -false
+Always false.
+@end deffn
+
+@node Actions
+@chapter Actions
+
+There are several ways you can print information about the files that
+match the criteria you gave in the @code{find} expression. You can
+print the information either to the standard output or to a file that
+you name. You can also execute commands that have the file names as
+arguments. You can use those commands as further filters to select
+files.
+
+@menu
+* Print File Name::
+* Print File Information::
+* Run Commands::
+* Delete Files::
+* Adding Tests::
+@end menu
+
+@node Print File Name
+@section Print File Name
+
+@deffn Action -print
+True; print the entire file name on the standard output, followed by a
+newline. If there is the faintest possibility that one of the files
+for which you are searching might contain a newline, you should use
+@samp{-print0} instead.
+@end deffn
+
+@deffn Action -fprint file
+True; print the entire file name into file @var{file}, followed by a
+newline. If @var{file} does not exist when @code{find} is run, it is
+created; if it does exist, it is truncated to 0 bytes. The named
+output file is always created, even if no output is sent to it. The
+file names @file{/dev/stdout} and @file{/dev/stderr} are handled
+specially; they refer to the standard output and standard error
+output, respectively.
+
+If there is the faintest possibility that one of the files for which
+you are searching might contain a newline, you should use
+@samp{-fprint0} instead.
+@end deffn
+
+
+@c @deffn Option -show-control-chars how
+@c This option affects how some of @code{find}'s actions treat
+@c unprintable characters in file names. If @samp{how} is
+@c @samp{literal}, any subsequent actions (i.e., actions further on in the
+@c command line) print file names as-is.
+@c
+@c If this option is not specified, it currently defaults to @samp{safe}.
+@c If @samp{how} is @samp{safe}, C-like backslash escapes are used to
+@c indicate the non-printable characters for @samp{-ls} and @samp{-fls}.
+@c On the other hand, @samp{-print}, @samp{-fprint}, @samp{-fprintf} and
+@c @code{-printf} all quote unprintable characters if the data is going
+@c to a tty, and otherwise the data is emitted literally.
+@c
+@c @table @code
+@c @item -ls
+@c Escaped if @samp{how} is @samp{safe}
+@c @item -fls
+@c Escaped if @samp{how} is @samp{safe}
+@c @item -print
+@c Always quoted if stdout is a tty,
+@c @samp{-show-control-chars} is ignored
+@c @item -print0
+@c Always literal, never escaped
+@c @item -fprint
+@c Always quoted if the destination is a tty;
+@c @samp{-show-control-chars} is ignored
+@c @item -fprint0
+@c Always literal, never escaped
+@c @item -fprintf
+@c If the destination is a tty, the @samp{%f},
+@c @samp{%F}, @samp{%h}, @samp{%l}, @samp{%p},
+@c and @samp{%P} directives produce quoted
+@c strings if stdout is a tty and are treated
+@c literally otherwise.
+@c @item -printf
+@c As for @code{-fprintf}.
+@c @end table
+@c @end deffn
+
+
+@node Print File Information
+@section Print File Information
+
+@deffn Action -ls
+True; list the current file in @samp{ls -dils} format on the standard
+output. The output looks like this:
+
+@smallexample
+204744 17 -rw-r--r-- 1 djm staff 17337 Nov 2 1992 ./lwall-quotes
+@end smallexample
+
+The fields are:
+
+@enumerate
+@item
+The inode number of the file. @xref{Hard Links}, for how to find
+files based on their inode number.
+
+@item
+the number of blocks in the file. The block counts are of 1K blocks,
+unless the environment variable @code{POSIXLY_CORRECT} is set, in
+which case 512-byte blocks are used. @xref{Size}, for how to find
+files based on their size.
+
+@item
+The file's type and file mode bits. The type is shown as a dash for a
+regular file; for other file types, a letter like for @samp{-type} is
+used (@pxref{Type}). The file mode bits are read, write, and execute/search for
+the file's owner, its group, and other users, respectively; a dash
+means the permission is not granted. @xref{File Permissions}, for
+more details about file permissions. @xref{Mode Bits}, for how to
+find files based on their file mode bits.
+
+@item
+The number of hard links to the file.
+
+@item
+The user who owns the file.
+
+@item
+The file's group.
+
+@item
+The file's size in bytes.
+
+@item
+The date the file was last modified.
+
+@item
+The file's name. @samp{-ls} quotes non-printable characters in the
+file names using C-like backslash escapes. This may change soon, as
+the treatment of unprintable characters is harmonised for @samp{-ls},
+@samp{-fls}, @samp{-print}, @samp{-fprint}, @samp{-printf} and
+@samp{-fprintf}.
+@end enumerate
+@end deffn
+
+@deffn Action -fls file
+True; like @samp{-ls} but write to @var{file} like @samp{-fprint}
+(@pxref{Print File Name}). The named output file is always created,
+even if no output is sent to it.
+@end deffn
+
+@deffn Action -printf format
+True; print @var{format} on the standard output, interpreting @samp{\}
+escapes and @samp{%} directives (more details in the following
+sections).
+
+Field widths and precisions can be specified as with the @code{printf} C
+function. Format flags (like @samp{#} for example) may not work as you
+expect because many of the fields, even numeric ones, are printed with
+%s. Numeric flags which are affected in this way include @samp{G},
+@samp{U}, @samp{b}, @samp{D}, @samp{k} and @samp{n}. This difference in
+behaviour means though that the format flag @samp{-} will work; it
+forces left-alignment of the field. Unlike @samp{-print},
+@samp{-printf} does not add a newline at the end of the string. If you
+want a newline at the end of the string, add a @samp{\n}.
+
+As an example, an approximate equivalent of @samp{-ls} with
+null-terminated filenames can be achieved with this @code{-printf}
+format:
+
+@example
+find -printf "%i %4k %M %3n %-8u %-8g %8s %T+ %p\n->%l\0" | cat
+@end example
+
+A practical reason for doing this would be to get literal filenames in
+the output, instead of @samp{-ls}'s backslash-escaped names. (Using
+@code{cat} here prevents this happening for the @samp{%p} format
+specifier; @pxref{Unusual Characters in File Names}). This format also
+outputs a uniform timestamp format.
+
+As for symlinks, the format above outputs the symlink target on a second
+line, following @samp{\n->}. There is nothing following the arrow for
+non-symlinks. Another approach, for complete consistency, would be to
+@code{-fprintf} the symlinks into a separate file, so they too can be
+null-terminated.
+@end deffn
+
+@deffn Action -fprintf file format
+True; like @samp{-printf} but write to @var{file} like @samp{-fprint}
+(@pxref{Print File Name}). The output file is always created, even if
+no output is ever sent to it.
+@end deffn
+
+@menu
+* Escapes::
+* Format Directives::
+* Time Formats::
+* Formatting Flags::
+@end menu
+
+@node Escapes
+@subsection Escapes
+
+The escapes that @samp{-printf} and @samp{-fprintf} recognise are:
+
+@table @code
+@item \a
+Alarm bell.
+@item \b
+Backspace.
+@item \c
+Stop printing from this format immediately and flush the output.
+@item \f
+Form feed.
+@item \n
+Newline.
+@item \r
+Carriage return.
+@item \t
+Horizontal tab.
+@item \v
+Vertical tab.
+@item \\
+A literal backslash (@samp{\}).
+@item \0
+ASCII NUL.
+@item \NNN
+The character whose ASCII code is NNN (octal).
+@end table
+
+A @samp{\} character followed by any other character is treated as an
+ordinary character, so they both are printed, and a warning message is
+printed to the standard error output (because it was probably a typo).
+
+@node Format Directives
+@subsection Format Directives
+
+@samp{-printf} and @samp{-fprintf} support the following format
+directives to print information about the file being processed. The C
+@code{printf} function, field width and precision specifiers are
+supported, as applied to string (%s) types. That is, you can specify
+"minimum field width"."maximum field width" for each directive.
+Format flags (like @samp{#} for example) may not work as you expect
+because many of the fields, even numeric ones, are printed with %s.
+The format flag @samp{-} does work; it forces left-alignment of the
+field.
+
+@samp{%%} is a literal percent sign. @xref{Reserved and Unknown
+Directives}, for a description of how format directives not mentioned
+below are handled.
+
+A @samp{%} at the end of the format argument causes undefined
+behaviour since there is no following character. In some locales, it
+may hide your door keys, while in others it may remove the final page
+from the novel you are reading.
+
+@menu
+* Name Directives::
+* Ownership Directives::
+* Size Directives::
+* Location Directives::
+* Time Directives::
+* Other Directives::
+* Reserved and Unknown Directives::
+@end menu
+
+@node Name Directives
+@subsubsection Name Directives
+
+@table @code
+@item %p
+@c supports %-X.Yp
+File's name (not the absolute path name, but the name of the file as
+it was encountered by @code{find} - that is, as a relative path from
+one of the starting points).
+@item %f
+File's name with any leading directories removed (only the last
+element).
+@c supports %-X.Yf
+@item %h
+Leading directories of file's name (all but the last element and the
+slash before it). If the file's name contains no slashes (for example
+because it was named on the command line and is in the current working
+directory), then ``%h'' expands to ``.''. This prevents ``%h/%f''
+expanding to ``/foo'', which would be surprising and probably not
+desirable.
+@c supports %-X.Yh
+@item %P
+File's name with the name of the command line argument under which
+it was found removed from the beginning.
+@c supports %-X.YP
+@item %H
+Command line argument under which file was found.
+@c supports %-X.YH
+@end table
+
+@node Ownership Directives
+@subsubsection Ownership Directives
+
+@table @code
+@item %g
+@c supports %-X.Yg
+File's group name, or numeric group ID if the group has no name.
+@item %G
+@c supports %-X.Yg
+@c TODO: Needs to support # flag and 0 flag
+File's numeric group ID.
+@item %u
+@c supports %-X.Yu
+File's user name, or numeric user ID if the user has no name.
+@item %U
+@c supports %-X.Yu
+@c TODO: Needs to support # flag
+File's numeric user ID.
+@item %m
+@c full support, including # and 0.
+File's mode bits (in octal). If you always want to have a leading
+zero on the number, use the '#' format flag, for example '%#m'.
+
+The file mode bit numbers used are the traditional Unix
+numbers, which will be as expected on most systems, but if your
+system's file mode bit layout differs from the traditional Unix
+semantics, you will see a difference between the mode as printed by
+@samp{%m} and the mode as it appears in @code{struct stat}.
+
+@item %M
+File's type and mode bits (in symbolic form, as for @code{ls}). This
+directive is supported in findutils 4.2.5 and later.
+@end table
+
+@node Size Directives
+@subsubsection Size Directives
+
+@table @code
+@item %k
+The amount of disk space used for this file in 1K blocks. Since disk
+space is allocated in multiples of the filesystem block size this is
+usually greater than %s/1024, but it can also be smaller if the file
+is a sparse file (that is, it has ``holes'').
+@item %b
+The amount of disk space used for this file in 512-byte blocks. Since
+disk space is allocated in multiples of the filesystem block size this
+is usually greater than %s/512, but it can also be smaller if the
+file is a sparse file (that is, it has ``holes'').
+@item %s
+File's size in bytes.
+@item %S
+File's sparseness. This is calculated as @code{(BLOCKSIZE*st_blocks /
+st_size)}. The exact value you will get for an ordinary file of a
+certain length is system-dependent. However, normally sparse files
+will have values less than 1.0, and files which use indirect blocks
+and have few holes may have a value which is greater than 1.0. The
+value used for BLOCKSIZE is system-dependent, but is usually 512
+bytes. If the file size is zero, the value printed is undefined. On
+systems which lack support for st_blocks, a file's sparseness is
+assumed to be 1.0.
+@end table
+
+@node Location Directives
+@subsubsection Location Directives
+
+@table @code
+@item %d
+File's depth in the directory tree (depth below a file named on the
+command line, not depth below the root directory). Files named on the
+command line have a depth of 0. Subdirectories immediately below them
+have a depth of 1, and so on.
+@item %D
+The device number on which the file exists (the @code{st_dev} field of
+@code{struct stat}), in decimal.
+@item %F
+Type of the filesystem the file is on; this value can be used for
+@samp{-fstype} (@pxref{Directories}).
+@item %l
+Object of symbolic link (empty string if file is not a symbolic link).
+@item %i
+File's inode number (in decimal).
+@item %n
+Number of hard links to file.
+@item %y
+Type of the file as used with @samp{-type}. If the file is a symbolic
+link, @samp{l} will be printed.
+@item %Y
+Type of the file as used with @samp{-type}. If the file is a symbolic
+link, it is dereferenced. If the file is a broken symbolic link,
+@samp{N} is printed.
+
+@end table
+
+@node Time Directives
+@subsubsection Time Directives
+
+Some of these directives use the C @code{ctime} function. Its output
+depends on the current locale, but it typically looks like
+
+@example
+Wed Nov 2 00:42:36 1994
+@end example
+
+@table @code
+@item %a
+File's last access time in the format returned by the C @code{ctime}
+function.
+@item %A@var{k}
+File's last access time in the format specified by @var{k}
+(@pxref{Time Formats}).
+@item %c
+File's last status change time in the format returned by the C
+@code{ctime} function.
+@item %C@var{k}
+File's last status change time in the format specified by @var{k}
+(@pxref{Time Formats}).
+@item %t
+File's last modification time in the format returned by the C
+@code{ctime} function.
+@item %T@var{k}
+File's last modification time in the format specified by @var{k}
+(@pxref{Time Formats}).
+@end table
+
+@node Other Directives
+@subsubsection Other Directives
+
+@table @code
+@item %Z
+File's SELinux context, or empty string if the file has no SELinux context.
+@end table
+
+@node Reserved and Unknown Directives
+@subsubsection Reserved and Unknown Directives
+
+The @samp{%(}, @samp{%@{} and @samp{%[} format directives, with or
+without field with and precision specifications, are reserved for
+future use. Don't use them and don't rely on current experiment to
+predict future behaviour. To print @samp{(}, simply use @samp{(}
+rather than @samp{%(}. Likewise for @samp{@{} and @samp{[}.
+
+Similarly, a @samp{%} character followed by any other unrecognised
+character (i.e., not a known directive or @code{printf} field width
+and precision specifier), is discarded (but the unrecognised character
+is printed), and a warning message is printed to the standard error
+output (because it was probably a typo). Don't rely on this
+behaviour, because other directives may be added in the future.
+
+
+@node Time Formats
+@subsection Time Formats
+
+Below are the formats for the directives @samp{%A}, @samp{%C}, and
+@samp{%T}, which print the file's timestamps. Some of these formats
+might not be available on all systems, due to differences in the C
+@code{strftime} function between systems.
+
+@menu
+* Time Components::
+* Date Components::
+* Combined Time Formats::
+@end menu
+
+@node Time Components
+@subsubsection Time Components
+
+The following format directives print single components of the time.
+
+@table @code
+@item H
+hour (00..23)
+@item I
+hour (01..12)
+@item k
+hour ( 0..23)
+@item l
+hour ( 1..12)
+@item p
+locale's AM or PM
+@item Z
+time zone (e.g., EDT), or nothing if no time zone is determinable
+@item M
+minute (00..59)
+@item S
+second (00..61). There is a fractional part.
+@item @@
+seconds since Jan. 1, 1970, 00:00 GMT, with fractional part.
+@end table
+
+The fractional part of the seconds field is of indeterminate length
+and precision. That is, the length of the fractional part of the
+seconds field will in general vary between findutils releases and
+between systems. This means that it is unwise to assume that field
+has any specific length. The length of this field is not usually a
+guide to the precision of timestamps in the underlying file system.
+
+
+
+@node Date Components
+@subsubsection Date Components
+
+The following format directives print single components of the date.
+
+@table @code
+@item a
+locale's abbreviated weekday name (Sun..Sat)
+@item A
+locale's full weekday name, variable length (Sunday..Saturday)
+@item b
+@itemx h
+locale's abbreviated month name (Jan..Dec)
+@item B
+locale's full month name, variable length (January..December)
+@item m
+month (01..12)
+@item d
+day of month (01..31)
+@item w
+day of week (0..6)
+@item j
+day of year (001..366)
+@item U
+week number of year with Sunday as first day of week (00..53)
+@item W
+week number of year with Monday as first day of week (00..53)
+@item Y
+year (1970@dots{})
+@item y
+last two digits of year (00..99)
+@end table
+
+@node Combined Time Formats
+@subsubsection Combined Time Formats
+
+The following format directives print combinations of time and date
+components.
+
+@table @code
+@item r
+time, 12-hour (hh:mm:ss [AP]M)
+@item T
+time, 24-hour (hh:mm:ss)
+@item X
+locale's time representation (H:M:S)
+@item c
+locale's date and time in ctime format (Sat Nov 04 12:02:33 EST
+1989). This format does not include any fractional part in the
+seconds field.
+@item D
+date (mm/dd/yy)
+@item x
+locale's date representation (mm/dd/yy)
+@item +
+Date and time, separated by '+', for example
+`2004-04-28+22:22:05.0000000000'.
+The time is given in the current timezone (which may be affected by
+setting the TZ environment variable). This is a GNU extension. The
+seconds field includes a fractional part.
+@end table
+
+@node Formatting Flags
+@subsection Formatting Flags
+
+The @samp{%m} and @samp{%d} directives support the @samp{#}, @samp{0}
+and @samp{+} flags, but the other directives do not, even if they
+print numbers. Numeric directives that do not support these flags
+include
+
+@samp{G},
+@samp{U},
+@samp{b},
+@samp{D},
+@samp{k} and
+@samp{n}.
+
+All fields support the format flag @samp{-}, which makes fields
+left-aligned. That is, if the field width is greater than the actual
+contents of the field, the requisite number of spaces are printed
+after the field content instead of before it.
+
+@node Run Commands
+@section Run Commands
+
+You can use the list of file names created by @code{find} or
+@code{locate} as arguments to other commands. In this way you can
+perform arbitrary actions on the files.
+
+@menu
+* Single File::
+* Multiple Files::
+* Querying::
+@end menu
+
+@node Single File
+@subsection Single File
+
+Here is how to run a command on one file at a time.
+
+@deffn Action -execdir command ;
+Execute @var{command}; true if @var{command} returns zero. @code{find}
+takes all arguments after @samp{-execdir} to be part of the command until
+an argument consisting of @samp{;} is reached. It replaces the string
+@samp{@{@}} by the current file name being processed everywhere it
+occurs in the command. Both of these constructions need to be escaped
+(with a @samp{\}) or quoted to protect them from expansion by the
+shell. The command is executed in the directory which @code{find}
+was searching at the time the action was executed (that is, @{@} will
+expand to a file in the local directory).
+
+For example, to compare each C header file in or below the current
+directory with the file @file{/tmp/master}:
+
+@example
+find . -name '*.h' -execdir diff -u '@{@}' /tmp/master ';'
+@end example
+@end deffn
+
+If you use @samp{-execdir}, you must ensure that the @samp{$PATH}
+variable contains only absolute directory names. Having an empty
+element in @samp{$PATH} or explicitly including @samp{.} (or any other
+non-absolute name) is insecure. GNU find will refuse to run if you
+use @samp{-execdir} and it thinks your @samp{$PATH} setting is
+insecure. For example:
+
+@table @samp
+@item /bin:/usr/bin:
+Insecure; empty path element (at the end)
+@item :/bin:/usr/bin:/usr/local/bin
+Insecure; empty path element (at the start)
+@item /bin:/usr/bin::/usr/local/bin
+Insecure; empty path element (two colons in a row)
+@item /bin:/usr/bin:.:/usr/local/bin
+Insecure; @samp{.} is a path element (@file{.} is not an absolute file name)
+@item /bin:/usr/bin:sbin:/usr/local/bin
+Insecure; @samp{sbin} is not an absolute file name
+@item /bin:/usr/bin:/sbin:/usr/local/bin
+Secure (if you control the contents of those directories and any access to them)
+@end table
+
+Another similar option, @samp{-exec} is supported, but is less secure.
+@xref{Security Considerations}, for a discussion of the security
+problems surrounding @samp{-exec}.
+
+
+@deffn Action -exec command ;
+This insecure variant of the @samp{-execdir} action is specified by
+POSIX. Like @samp{-execdir command ;} it is true if zero is
+returned by @var{command}. The main difference is that the command is
+executed in the directory from which @code{find} was invoked, meaning
+that @samp{@{@}} is expanded to a relative path starting with the name
+of one of the starting directories, rather than just the basename of
+the matched file.
+
+While some implementations of @code{find} replace the @samp{@{@}} only
+where it appears on its own in an argument, GNU @code{find} replaces
+@samp{@{@}} wherever it appears.
+@end deffn
+
+
+@node Multiple Files
+@subsection Multiple Files
+
+Sometimes you need to process files one at a time. But usually this
+is not necessary, and, it is faster to run a command on as many files
+as possible at a time, rather than once per file. Doing this saves on
+the time it takes to start up the command each time.
+
+The @samp{-execdir} and @samp{-exec} actions have variants that build
+command lines containing as many matched files as possible.
+
+@deffn Action -execdir command @{@} +
+This works as for @samp{-execdir command ;}, except that the result is
+always true, and the @samp{@{@}} at the end of the command is expanded
+to a list of names of matching files. This expansion is done in such
+a way as to avoid exceeding the maximum command line length available
+on the system. Only one @samp{@{@}} is allowed within the command,
+and it must appear at the end, immediately before the @samp{+}. A
+@samp{+} appearing in any position other than immediately after
+@samp{@{@}} is not considered to be special (that is, it does not
+terminate the command).
+@end deffn
+
+
+@deffn Action -exec command @{@} +
+This insecure variant of the @samp{-execdir} action is specified by
+POSIX. The main difference is that the command is executed in the
+directory from which @code{find} was invoked, meaning that @samp{@{@}}
+is expanded to a relative path starting with the name of one of the
+starting directories, rather than just the basename of the matched
+file. The result is always true.
+@end deffn
+
+Before @code{find} exits, any partially-built command lines are
+executed. This happens even if the exit was caused by the
+@samp{-quit} action. However, some types of error (for example not
+being able to invoke @code{stat()} on the current directory) can cause
+an immediate fatal exit. In this situation, any partially-built
+command lines will not be invoked (this prevents possible infinite
+loops).
+
+At first sight, it looks like the list of filenames to be processed
+can only be at the end of the command line, and that this might be a
+problem for some commands (@code{cp} and @code{rsync} for example).
+
+However, there is a slightly obscure but powerful workaround for this
+problem which takes advantage of the behaviour of @code{sh -c}:
+
+@example
+find startpoint -tests @dots{} -exec sh -c 'scp "$@@" remote:/dest' sh @{@} +
+@end example
+
+In the example above, the filenames we want to work on need to occur
+on the @code{scp} command line before the name of the destination. We
+use the shell to invoke the command @code{scp "$@@" remote:/dest} and
+the shell expands @code{"$@@"} to the list of filenames we want to
+process.
+
+Another, but less secure, way to run a command on more than one file
+at once, is to use the @code{xargs} command, which is invoked like
+this:
+
+@example
+xargs @r{[}@var{option}@dots{}@r{]} @r{[}@var{command} @r{[}@var{initial-arguments}@r{]}@r{]}
+@end example
+
+@code{xargs} normally reads arguments from the standard input. These
+arguments are delimited by blanks (which can be protected with double
+or single quotes or a backslash) or newlines. It executes the
+@var{command} (the default is @file{echo}) one or more times with any
+@var{initial-arguments} followed by arguments read from standard
+input. Blank lines on the standard input are ignored. If the
+@samp{-L} option is in use, trailing blanks indicate that @code{xargs}
+should consider the following line to be part of this one.
+
+Instead of blank-delimited names, it is safer to use @samp{find
+-print0} or @samp{find -fprint0} and process the output by giving the
+@samp{-0} or @samp{--null} option to GNU @code{xargs}, GNU @code{tar},
+GNU @code{cpio}, or @code{perl}. The @code{locate} command also has a
+@samp{-0} or @samp{--null} option which does the same thing.
+
+You can use shell command substitution (backquotes) to process a list
+of arguments, like this:
+
+@example
+grep -l sprintf `find $HOME -name '*.c' -print`
+@end example
+
+However, that method produces an error if the length of the @samp{.c}
+file names exceeds the operating system's command line length limit.
+@code{xargs} avoids that problem by running the command as many times
+as necessary without exceeding the limit:
+
+@example
+find $HOME -name '*.c' -print | xargs grep -l sprintf
+@end example
+
+However, if the command needs to have its standard input be a terminal
+(@code{less}, for example), you have to use the shell command
+substitution method or use the @samp{--arg-file} option of
+@code{xargs}.
+
+The @code{xargs} command will process all its input, building command
+lines and executing them, unless one of the commands exits with a
+status of 255 (this will cause xargs to issue an error message and
+stop) or it reads a line contains the end of file string specified
+with the @samp{--eof} option.
+
+@menu
+* Unsafe File Name Handling::
+* Safe File Name Handling::
+* Unusual Characters in File Names::
+* Limiting Command Size::
+* Controlling Parallelism::
+* Interspersing File Names::
+@end menu
+
+@node Unsafe File Name Handling
+@subsubsection Unsafe File Name Handling
+
+Because file names can contain quotes, backslashes, blank characters,
+and even newlines, it is not safe to process them using @code{xargs}
+in its default mode of operation. But since most files' names do not
+contain blanks, this problem occurs only infrequently. If you are
+only searching through files that you know have safe names, then you
+need not be concerned about it.
+
+Error messages issued by @code{find} and @code{locate} quote unusual
+characters in file names in order to prevent unwanted changes in the
+terminal's state.
+
+
+@c This example is adapted from:
+@c From: pfalstad@stone.Princeton.EDU (Paul John Falstad)
+@c Newsgroups: comp.unix.shell
+@c Subject: Re: Beware xargs security holes
+@c Date: 16 Oct 90 19:12:06 GMT
+@c
+In many applications, if @code{xargs} botches processing a file
+because its name contains special characters, some data might be lost.
+The importance of this problem depends on the importance of the data
+and whether anyone notices the loss soon enough to correct it.
+However, here is an extreme example of the problems that using
+blank-delimited names can cause. If the following command is run
+daily from @code{cron}, then any user can remove any file on the
+system:
+
+@example
+find / -name '#*' -atime +7 -print | xargs rm
+@end example
+
+For example, you could do something like this:
+
+@example
+eg$ echo > '#
+vmunix'
+@end example
+
+@noindent
+and then @code{cron} would delete @file{/vmunix}, if it ran
+@code{xargs} with @file{/} as its current directory.
+
+To delete other files, for example @file{/u/joeuser/.plan}, you could
+do this:
+
+@example
+eg$ mkdir '#
+'
+eg$ cd '#
+'
+eg$ mkdir u u/joeuser u/joeuser/.plan'
+'
+eg$ echo > u/joeuser/.plan'
+/#foo'
+eg$ cd ..
+eg$ find . -name '#*' -print | xargs echo
+./# ./# /u/joeuser/.plan /#foo
+@end example
+
+@node Safe File Name Handling
+@subsubsection Safe File Name Handling
+
+Here is how to make @code{find} output file names so that they can be
+used by other programs without being mangled or misinterpreted. You
+can process file names generated this way by giving the @samp{-0} or
+@samp{--null} option to GNU @code{xargs}, GNU @code{tar}, GNU
+@code{cpio}, or @code{perl}.
+
+@deffn Action -print0
+True; print the entire file name on the standard output, followed by a
+null character.
+@end deffn
+
+@deffn Action -fprint0 file
+True; like @samp{-print0} but write to @var{file} like @samp{-fprint}
+(@pxref{Print File Name}). The output file is always created.
+@end deffn
+
+As of findutils version 4.2.4, the @code{locate} program also has a
+@samp{--null} option which does the same thing. For similarity with
+@code{xargs}, the short form of the option @samp{-0} can also be used.
+
+If you want to be able to handle file names safely but need to run
+commands which want to be connected to a terminal on their input, you
+can use the @samp{--arg-file} option to @code{xargs} like this:
+
+@example
+find / -name xyzzy -print0 > list
+xargs --null --arg-file=list munge
+@end example
+
+The example above runs the @code{munge} program on all the files named
+@file{xyzzy} that we can find, but @code{munge}'s input will still be
+the terminal (or whatever the shell was using as standard input). If
+your shell has the ``process substitution'' feature @samp{<(...)}, you
+can do this in just one step:
+
+@example
+xargs --null --arg-file=<(find / -name xyzzy -print0) munge
+@end example
+
+@node Unusual Characters in File Names
+@subsubsection Unusual Characters in File Names
+As discussed above, you often need to be careful about how the names
+of files are handled by @code{find} and other programs. If the output
+of @code{find} is not going to another program but instead is being
+shown on a terminal, this can still be a problem. For example, some
+character sequences can reprogram the function keys on some terminals.
+@xref{Security Considerations}, for a discussion of other security
+problems relating to @code{find}.
+
+Unusual characters are handled differently by various
+actions, as described below.
+
+@table @samp
+@item -print0
+@itemx -fprint0
+Always print the exact file name, unchanged, even if the output is
+going to a terminal.
+@item -ok
+@itemx -okdir
+Always print the exact file name, unchanged. This will probably
+change in a future release.
+@item -ls
+@itemx -fls
+Unusual characters are always escaped. White space, backslash, and
+double quote characters are printed using C-style escaping (for
+example @samp{\f}, @samp{\"}). Other unusual characters are printed
+using an octal escape. Other printable characters (for @samp{-ls} and
+@samp{-fls} these are the characters between octal 041 and 0176) are
+printed as-is.
+@item -printf
+@itemx -fprintf
+If the output is not going to a terminal, it is printed as-is.
+Otherwise, the result depends on which directive is in use:
+
+@table @asis
+@item %D, %F, %H, %Y, %y
+These expand to values which are not under control of files' owners,
+and so are printed as-is.
+@item %a, %b, %c, %d, %g, %G, %i, %k, %m, %M, %n, %s, %t, %u, %U
+These have values which are under the control of files' owners but
+which cannot be used to send arbitrary data to the terminal, and so
+these are printed as-is.
+@item %f, %h, %l, %p, %P
+The output of these directives is quoted if the output is going to a
+terminal. The setting of the @code{LC_CTYPE} environment
+variable is used to determine which characters need to be quoted.
+
+This quoting is performed in the same way as for GNU @code{ls}. This
+is not the same quoting mechanism as the one used for @samp{-ls} and
+@samp{fls}. If you are able to decide what format to use for the
+output of @code{find} then it is normally better to use @samp{\0} as a
+terminator than to use newline, as file names can contain white space
+and newline characters.
+@end table
+@item -print
+@itemx -fprint
+Quoting is handled in the same way as for the @samp{%p} directive of
+@samp{-printf} and @samp{-fprintf}. If you are using @code{find} in a
+script or in a situation where the matched files might have arbitrary
+names, you should consider using @samp{-print0} instead of
+@samp{-print}.
+@end table
+
+
+The @code{locate} program quotes and escapes unusual characters in
+file names in the same way as @code{find}'s @samp{-print} action.
+
+The behaviours described above may change soon, as the treatment of
+unprintable characters is harmonised for @samp{-ls}, @samp{-fls},
+@samp{-print}, @samp{-fprint}, @samp{-printf} and @samp{-fprintf}.
+
+@node Limiting Command Size
+@subsubsection Limiting Command Size
+
+@code{xargs} gives you control over how many arguments it passes to
+the command each time it executes it. By default, it uses up to
+@code{ARG_MAX} - 2k, or 128k, whichever is smaller, characters per
+command. It uses as many lines and arguments as fit within that
+limit. The following options modify those values.
+
+@table @code
+@item --no-run-if-empty
+@itemx -r
+If the standard input does not contain any nonblanks, do not run the
+command. By default, the command is run once even if there is no
+input. This option is a GNU extension.
+
+@item --max-lines@r{[}=@var{max-lines}@r{]}
+@itemx -L @var{max-lines}
+@itemx -l@r{[}@var{max-lines}@r{]}
+Use at most @var{max-lines} nonblank input lines per command line;
+@var{max-lines} defaults to 1 if omitted; omitting the argument is not
+allowed in the case of the @samp{-L} option. Trailing blanks cause an
+input line to be logically continued on the next input line, for the
+purpose of counting the lines. Implies @samp{-x}. The preferred name
+for this option is @samp{-L} as this is specified by POSIX.
+
+@item --max-args=@var{max-args}
+@itemx -n @var{max-args}
+Use at most @var{max-args} arguments per command line. Fewer than
+@var{max-args} arguments will be used if the size (see the @samp{-s}
+option) is exceeded, unless the @samp{-x} option is given, in which
+case @code{xargs} will exit.
+
+@item --max-chars=@var{max-chars}
+@itemx -s @var{max-chars}
+Use at most @var{max-chars} characters per command line, including the
+command initial arguments and the terminating nulls at the ends of the
+argument strings. If you specify a value for this option which is too
+large or small, a warning message is printed and the appropriate upper
+or lower limit is used instead. You can use @samp{--show-limits}
+option to understand the command-line limits applying to @code{xargs}
+and how this is affected by any other options. The POSIX limits shown
+when you do this have already been adjusted to take into account the
+size of your environment variables.
+
+The largest allowed value is system-dependent, and is calculated as
+the argument length limit for exec, less the size of your environment,
+less 2048 bytes of headroom. If this value is more than 128KiB,
+128Kib is used as the default value; otherwise, the default value is
+the maximum.
+@end table
+
+@node Controlling Parallelism
+@subsubsection Controlling Parallelism
+
+Normally, @code{xargs} runs one command at a time. This is called
+"serial" execution; the commands happen in a series, one after another.
+If you'd like @code{xargs} to do things in "parallel", you can ask it
+to do so, either when you invoke it, or later while it is running.
+Running several commands at one time can make the entire operation
+go more quickly, if the commands are independent, and if your system
+has enough resources to handle the load. When parallelism works in
+your application, @code{xargs} provides an easy way to get your work
+done faster.
+
+@table @code
+@item --max-procs=@var{max-procs}
+@itemx -P @var{max-procs}
+Run up to @var{max-procs} processes at a time; the default is 1. If
+@var{max-procs} is 0, @code{xargs} will run as many processes as
+possible at a time. Use the @samp{-n}, @samp{-s}, or @samp{-L} option
+with @samp{-P}; otherwise chances are that the command will be run
+only once.
+@end table
+
+For example, suppose you have a directory tree of large image files
+and a @code{makeallsizes} script that takes a single file name and
+creates various sized images from it (thumbnail-sized, web-page-sized,
+printer-sized, and the original large file). The script is doing enough
+work that it takes significant time to run, even on a single image.
+You could run:
+
+@example
+find originals -name '*.jpg' | xargs -1 makeallsizes
+@end example
+
+This will run @code{makeallsizes @var{filename}} once for each @code{.jpg}
+file in the @code{originals} directory. However, if your system has
+two central processors, this script will only keep one of them busy.
+Instead, you could probably finish in about half the time by running:
+
+@example
+find originals -name '*.jpg' | xargs -1 -P 2 makeallsizes
+@end example
+
+@code{xargs} will run the first two commands in parallel, and then
+whenever one of them terminates, it will start another one, until
+the entire job is done.
+
+The same idea can be generalized to as many processors as you have handy.
+It also generalizes to other resources besides processors. For example,
+if @code{xargs} is running commands that are waiting for a response from a
+distant network connection, running a few in parallel may reduce the
+overall latency by overlapping their waiting time.
+
+If you are running commands in parallel, you need to think about how
+they should arbitrate access to any resources that they share. For
+example, if more than one of them tries to print to stdout, the ouptut
+will be produced in an indeterminate order (and very likely mixed up)
+unless the processes collaborate in some way to prevent this. Using
+some kind of locking scheme is one way to prevent such problems. In
+general, using a locking scheme will help ensure correct output but
+reduce performance. If you don't want to tolerate the performance
+difference, simply arrange for each process to produce a separate output
+file (or otherwise use separate resources).
+
+@code{xargs} also allows you to ``turn up'' or ``turn down'' its parallelism
+in the middle of a run. Suppose you are keeping your four-processor
+system busy for hours, processing thousands of images using @code{-P 4}.
+Now, in the middle of the run, you or someone else wants you to reduce
+your load on the system, so that something else will run faster.
+If you interrupt @code{xargs}, your job will be half-done, and it
+may take significant manual work to resume it only for the remaining
+images. If you suspend @code{xargs} using your shell's job controls
+(e.g. @code{control-Z}), then it will get no work done while suspended.
+
+Find out the process ID of the @code{xargs} process, either from your
+shell or with the @code{ps} command. After you send it the signal
+@code{SIGUSR2}, @code{xargs} will run one fewer command in parallel.
+If you send it the signal @code{SIGUSR1}, it will run one more command
+in parallel. For example:
+
+@example
+shell$ xargs <allimages -1 -P 4 makeallsizes &
+[4] 27643
+ ... at some later point ...
+shell$ kill -USR2 27643
+shell$ kill -USR2 %4
+@end example
+
+The first @code{kill} command will cause @code{xargs} to wait for
+two commands to terminate before starting the next command (reducing
+the parallelism from 4 to 3). The second @code{kill} will reduce it from
+3 to 2. (@code{%4} works in some shells as a shorthand for the process
+ID of the background job labeled @code{[4]}.)
+
+Similarly, if you started a long @code{xargs} job without parallelism, you
+can easily switch it to start running two commands in parallel by sending
+it a @code{SIGUSR1}.
+
+@code{xargs} will never terminate any existing commands when you ask it
+to run fewer processes. It merely waits for the excess commands to
+finish. If you ask it to run more commands, it will start the next
+one immediately (if it has more work to do). If the degree of
+parallelism is already 1, sending @code{SIGUSR2} will have no further
+effect (since @code{--max-procs=0} means that there should be no limit
+on the number of processes to run).
+
+There is an implementation-defined limit on the number of processes.
+This limit is shown with @code{xargs --show-limits}. The limit is at
+least 127 on all systems (and on the author's system it is
+2147483647).
+
+If you send several identical signals quickly, the operating system
+does not guarantee that each of them will be delivered to @code{xargs}.
+This means that you can't rapidly increase or decrease the parallelism by
+more than one command at a time. You can avoid this problem by sending
+a signal, observing the result, then sending the next one; or merely by
+delaying for a few seconds between signals (unless your system is very
+heavily loaded).
+
+Whether or not parallel execution will work well for you depends on
+the nature of the commmand you are running in parallel, on the
+configuration of the system on which you are running the command, and
+on the other work being done on the system at the time.
+
+@node Interspersing File Names
+@subsubsection Interspersing File Names
+
+@code{xargs} can insert the name of the file it is processing between
+arguments you give for the command. Unless you also give options to
+limit the command size (@pxref{Limiting Command Size}), this mode of
+operation is equivalent to @samp{find -exec} (@pxref{Single File}).
+
+@table @code
+@item --replace@r{[}=@var{replace-str}@r{]}
+@itemx -I @var{replace-str}
+@itemx -i @var{replace-str}
+Replace occurrences of @var{replace-str} in the initial arguments with
+names read from the input. Also, unquoted blanks do not terminate
+arguments; instead, the input is split at newlines only. For the
+@samp{-i} option, if @var{replace-str} is omitted for @samp{--replace}
+or @samp{-i}, it defaults to @samp{@{@}} (like for @samp{find -exec}).
+Implies @samp{-x} and @samp{-l 1}. @samp{-i} is deprecated in favour
+of @samp{-I}. As an example, to sort each file in the @file{bills}
+directory, leaving the output in that file name with @file{.sorted}
+appended, you could do:
+
+@example
+find bills -type f | xargs -I XX sort -o XX.sorted XX
+@end example
+
+@noindent
+The equivalent command using @samp{find -execdir} is:
+
+@example
+find bills -type f -execdir sort -o '@{@}.sorted' '@{@}' ';'
+@end example
+@end table
+
+
+When you use the @samp{-I} option, each line read from the input is
+buffered internally. This means that there is an upper limit on the
+length of input line that @code{xargs} will accept when used with the
+@samp{-I} option. To work around this limitation, you can use the
+@samp{-s} option to increase the amount of buffer space that xargs
+uses, and you can also use an extra invocation of xargs to ensure that
+very long lines do not occur. For example:
+
+@example
+somecommand | xargs -s 50000 echo | xargs -I '@{@}' -s 100000 rm '@{@}'
+@end example
+
+Here, the first invocation of @code{xargs} has no input line length
+limit because it doesn't use the @samp{-I} option. The second
+invocation of @code{xargs} does have such a limit, but we have ensured
+that it never encounters a line which is longer than it can
+handle.
+
+This is not an ideal solution. Instead, the @samp{-I} option should
+not impose a line length limit (apart from any limit imposed by the
+operating system) and so one might consider this limitation to be a
+bug. A better solution would be to allow @code{xargs -I} to
+automatically move to a larger value for the @samp{-s} option when
+this is needed.
+
+This sort of problem doesn't occur with the output of @code{find}
+because it emits just one filename per line.
+
+@node Querying
+@subsection Querying
+
+To ask the user whether to execute a command on a single file, you can
+use the @code{find} primary @samp{-okdir} instead of @samp{-execdir},
+and the @code{find} primary @samp{-ok} instead of @samp{-exec}:
+
+@deffn Action -okdir command ;
+Like @samp{-execdir} (@pxref{Single File}), but ask the user first.
+If the user does not agree to run the command, just return false.
+Otherwise, run it, with standard input redirected from
+@file{/dev/null}.
+
+The response to the prompt is matched against a pair of regular
+expressions to determine if it is a yes or no response. These regular
+expressions are obtained from the system (@code{nl_langinfo} items
+YESEXPR and NOEXPR are used) if the @code{POSIXLY_CORRECT} environment
+variable is set and the system has such patterns available. Otherwise,
+@code{find}'s message translations are used. In either case, the
+@code{LC_MESSAGES} environment variable will determine the regular
+expressions used to determine if the answer is affirmative or negative.
+The interpretation of the regular expressions themselves will be
+affected by the environment variables @code{LC_CTYPE} (character
+classes) and @code{LC_COLLATE} (character ranges and equivalence
+classes).
+@end deffn
+
+@deffn Action -ok command ;
+This insecure variant of the @samp{-okdir} action is specified by
+POSIX. The main difference is that the command is executed in the
+directory from which @code{find} was invoked, meaning that @samp{@{@}}
+is expanded to a relative path starting with the name of one of the
+starting directories, rather than just the basename of the matched
+file. If the command is run, its standard input is redirected from
+@file{/dev/null}.
+@end deffn
+
+When processing multiple files with a single command, to query the
+user you give @code{xargs} the following option. When using this
+option, you might find it useful to control the number of files
+processed per invocation of the command (@pxref{Limiting Command
+Size}).
+
+@table @code
+@item --interactive
+@itemx -p
+Prompt the user about whether to run each command line and read a line
+from the terminal. Only run the command line if the response starts
+with @samp{y} or @samp{Y}. Implies @samp{-t}.
+@end table
+
+@node Delete Files
+@section Delete Files
+
+@deffn Action -delete
+Delete files or directories; true if removal succeeded. If the
+removal failed, an error message is issued.
+
+The use of the @samp{-delete} action on the command line automatically
+turns on the @samp{-depth} option (@pxref{find Expressions}). This
+can be surprising if you were previously just testing with
+@samp{-print}, so it is usually best to remember to use @samp{-depth}
+explicitly.
+
+If @samp{-delete} fails, @code{find}'s exit status will be nonzero
+(when it eventually exits).
+@end deffn
+
+@node Adding Tests
+@section Adding Tests
+
+You can test for file attributes that none of the @code{find} builtin
+tests check. To do this, use @code{xargs} to run a program that
+filters a list of files printed by @code{find}. If possible, use
+@code{find} builtin tests to pare down the list, so the program run by
+@code{xargs} has less work to do. The tests builtin to @code{find}
+will likely run faster than tests that other programs perform.
+
+For reasons of efficiency it is often useful to limit the number of
+times an external program has to be run. For this reason, it is often
+a good idea to implement ``extended'' tests by using @code{xargs}.
+
+For example, here is a way to print the names of all of the unstripped
+binaries in the @file{/usr/local} directory tree. Builtin tests avoid
+running @code{file} on files that are not regular files or are not
+executable.
+
+@example
+find /usr/local -type f -perm /a=x | xargs file |
+ grep 'not stripped' | cut -d: -f1
+@end example
+
+@noindent
+The @code{cut} program removes everything after the file name from the
+output of @code{file}.
+
+However, using @code{xargs} can present important security problems
+(@pxref{Security Considerations}). These can be avoided by using
+@samp{-execdir}. The @samp{-execdir} action is also a useful way of
+putting your own test in the middle of a set of other tests or actions
+for @code{find} (for example, you might want to use @samp{-prune}).
+
+@c Idea from Martin Weitzel.
+To place a special test somewhere in the middle of a @code{find}
+expression, you can use @samp{-execdir} (or, less securely,
+@samp{-exec}) to run a program that performs the test. Because
+@samp{-execdir} evaluates to the exit status of the executed program,
+you can use a program (which can be a shell script) that tests for a
+special attribute and make it exit with a true (zero) or false
+(non-zero) status. It is a good idea to place such a special test
+@emph{after} the builtin tests, because it starts a new process which
+could be avoided if a builtin test evaluates to false.
+
+Here is a shell script called @code{unstripped} that checks whether
+its argument is an unstripped binary file:
+
+@example
+#! /bin/sh
+file "$1" | grep -q "not stripped"
+@end example
+
+
+This script relies on the shell exiting with the status of
+the last command in the pipeline, in this case @code{grep}. The
+@code{grep} command exits with a true status if it found any matches,
+false if not. Here is an example of using the script (assuming it is
+in your search path). It lists the stripped executables (and shell
+scripts) in the file @file{sbins} and the unstripped ones in
+@file{ubins}.
+
+@example
+find /usr/local -type f -perm /a=x \
+ \( -execdir unstripped '@{@}' \; -fprint ubins -o -fprint sbins \)
+@end example
+
+
+@node Databases
+@chapter File Name Databases
+
+The file name databases used by @code{locate} contain lists of files
+that were in particular directory trees when the databases were last
+updated. The file name of the default database is determined when
+@code{locate} and @code{updatedb} are configured and installed. The
+frequency with which the databases are updated and the directories for
+which they contain entries depend on how often @code{updatedb} is run,
+and with which arguments.
+
+You can obtain some statistics about the databases by using
+@samp{locate --statistics}.
+
+@menu
+* Database Locations::
+* Database Formats::
+* Newline Handling::
+@end menu
+
+
+@node Database Locations
+@section Database Locations
+
+There can be multiple file name databases. Users can select which
+databases @code{locate} searches using the @code{LOCATE_PATH}
+environment variable or a command line option. The system
+administrator can choose the file name of the default database, the
+frequency with which the databases are updated, and the directories
+for which they contain entries. File name databases are updated by
+running the @code{updatedb} program, typically nightly.
+
+In networked environments, it often makes sense to build a database at
+the root of each filesystem, containing the entries for that
+filesystem. @code{updatedb} is then run for each filesystem on the
+fileserver where that filesystem is on a local disk, to prevent
+thrashing the network.
+
+@xref{Invoking updatedb}, for the description of the options to
+@code{updatedb}. These options can be used to specify which
+directories are indexed by each database file.
+
+The default location for the locate database depends on how findutils
+is built, but the findutils installation accompanying this manual uses
+the default location @file{@value{LOCATE_DB}}.
+
+If no database exists at @file{@value{LOCATE_DB}} but the user did not
+specify where to look (by using @samp{-d} or setting
+@code{LOCATE_PATH}), then @code{locate} will also check for a
+``secure'' database in @file{/var/lib/slocate/slocate.db}.
+
+@node Database Formats
+@section Database Formats
+
+The file name databases contain lists of files that were in particular
+directory trees when the databases were last updated. The file name
+database format changed starting with GNU @code{locate} version 4.0 to
+allow machines with different byte orderings to share the databases.
+
+GNU @code{locate} can read both the old and new database formats.
+However, old versions of @code{locate} (on other Unix systems, or GNU
+@code{locate} before version 4.0) produce incorrect results if run
+against a database in something other than the old format.
+
+Support for the old database format will eventually be discontinued,
+first in @code{updatedb} and later in @code{locate}.
+
+If you run @samp{locate --statistics}, the resulting summary indicates
+the type of each @code{locate} database. You select which database
+format @code{updatedb} will use with the @samp{--dbformat} option.
+
+
+@menu
+* LOCATE02 Database Format::
+* Sample LOCATE02 Database::
+* slocate Database Format::
+* Old Database Format::
+@end menu
+
+@node LOCATE02 Database Format
+@subsection LOCATE02 Database Format
+
+@code{updatedb} runs a program called @code{frcode} to
+@dfn{front-compress} the list of file names, which reduces the
+database size by a factor of 4 to 5. Front-compression (also known as
+incremental encoding) works as follows.
+
+The database entries are a sorted list (case-insensitively, for users'
+convenience). Since the list is sorted, each entry is likely to share
+a prefix (initial string) with the previous entry. Each database
+entry begins with an offset-differential count byte, which is the
+additional number of characters of prefix of the preceding entry to
+use beyond the number that the preceding entry is using of its
+predecessor. (The counts can be negative.) Following the count is a
+null-terminated ASCII remainder -- the part of the name that follows
+the shared prefix.
+
+If the offset-differential count is larger than can be stored in a
+byte (+/-127), the byte has the value 0x80 and the count follows in a
+2-byte word, with the high byte first (network byte order).
+
+Every database begins with a dummy entry for a file called
+@file{LOCATE02}, which @code{locate} checks for to ensure that the
+database file has the correct format; it ignores the entry in doing
+the search.
+
+Databases cannot be concatenated together, even if the first (dummy)
+entry is trimmed from all but the first database. This is because the
+offset-differential count in the first entry of the second and
+following databases will be wrong.
+
+In the output of @samp{locate --statistics}, the new database format
+is referred to as @samp{LOCATE02}.
+
+@node Sample LOCATE02 Database
+@subsection Sample LOCATE02 Database
+
+Sample input to @code{frcode}:
+@c with nulls changed to newlines:
+
+@example
+/usr/src
+/usr/src/cmd/aardvark.c
+/usr/src/cmd/armadillo.c
+/usr/tmp/zoo
+@end example
+
+Length of the longest prefix of the preceding entry to share:
+
+@example
+0 /usr/src
+8 /cmd/aardvark.c
+14 rmadillo.c
+5 tmp/zoo
+@end example
+
+Output from @code{frcode}, with trailing nulls changed to newlines
+and count bytes made printable:
+
+@example
+0 LOCATE02
+0 /usr/src
+8 /cmd/aardvark.c
+6 rmadillo.c
+-9 tmp/zoo
+@end example
+
+(6 = 14 - 8, and -9 = 5 - 14)
+
+@node slocate Database Format
+@subsection slocate Database Format
+
+The @code{slocate} program uses a database format similar to, but not
+quite the same as, GNU @code{locate}. The first byte of the database
+specifies its @dfn{security level}. If the security level is 0,
+@code{slocate} will read, match and print filenames on the basis of
+the information in the database only. However, if the security level
+byte is 1, @code{slocate} omits entries from its output if the
+invoking user is unable to access them. The second byte of the
+database is zero. The second byte is immediately followed by the
+first database entry. The first entry in the database is not preceded
+by any differential count or dummy entry. Instead the differential
+count for the first item is assumed to be zero.
+
+Starting with the second entry (if any) in the database, data is
+interpreted as for the GNU LOCATE02 format.
+
+@node Old Database Format
+@subsection Old Database Format
+
+The old database format is used by Unix @code{locate} and @code{find}
+programs and earlier releases of the GNU ones. @code{updatedb}
+produces this format if given the @samp{--old-format} option.
+
+@code{updatedb} runs programs called @code{bigram} and @code{code} to
+produce old-format databases. The old format differs from the new one
+in the following ways. Instead of each entry starting with an
+offset-differential count byte and ending with a null, byte values
+from 0 through 28 indicate offset-differential counts from -14 through
+14. The byte value indicating that a long offset-differential count
+follows is 0x1e (30), not 0x80. The long counts are stored in host
+byte order, which is not necessarily network byte order, and host
+integer word size, which is usually 4 bytes. They also represent a
+count 14 less than their value. The database lines have no
+termination byte; the start of the next line is indicated by its first
+byte having a value <= 30.
+
+In addition, instead of starting with a dummy entry, the old database
+format starts with a 256 byte table containing the 128 most common
+bigrams in the file list. A bigram is a pair of adjacent bytes.
+Bytes in the database that have the high bit set are indexes (with the
+high bit cleared) into the bigram table. The bigram and
+offset-differential count coding makes these databases 20-25% smaller
+than the new format, but makes them not 8-bit clean. Any byte in a
+file name that is in the ranges used for the special codes is replaced
+in the database by a question mark, which not coincidentally is the
+shell wildcard to match a single character.
+
+The old format therefore cannot faithfully store entries with
+non-ASCII characters. It therefore should not be used in
+internationalised environments. That is, most installations should
+not use it.
+
+Because the long counts are stored by the @code{code} program as
+native-order machine words, the database format is not easily used in
+environments which differ in terms of byte order. If locate databases
+are to be shared between machines, the LOCATE02 database format should
+be used. This has other benefits as discussed above. However, the
+length of the filename currently being processed can normally be used
+to place reasonable limits on the long counts and so this information
+is used by locate to help it guess the byte ordering of the old format
+database. Unless it finds evidence to the contrary, @code{locate}
+will assume that the byte order of the database is the same as the
+native byte order of the machine running @code{locate}. The output of
+@samp{locate --statistics} also includes information about the byte
+order of old-format databases.
+
+The output of @samp{locate --statistics} will give an incorrect count
+of the number of file names containing newlines or high-bit characters
+for old-format databases.
+
+Old versions of GNU @code{locate} fail to correctly handle very long
+file names, possibly leading to security problems relating to a heap
+buffer overrun. @xref{Security Considerations for locate}, for a
+detailed explanation.
+
+@node Newline Handling
+@section Newline Handling
+
+Within the database, file names are terminated with a null character.
+This is the case for both the old and the new format.
+
+When the new database format is being used, the compression technique
+used to generate the database though relies on the ability to sort the
+list of files before they are presented to @code{frcode}.
+
+If the system's sort command allows its input list of files to be
+separated with null characters via the @samp{-z} option, this option
+is used and therefore @code{updatedb} and @code{locate} will both
+correctly handle file names containing newlines. If the @code{sort}
+command lacks support for this, the list of files is delimited with
+the newline character, meaning that parts of file names containing
+newlines will be incorrectly sorted. This can result in both
+incorrect matches and incorrect failures to match.
+
+On the other hand, if you are using the old database format, file
+names with embedded newlines are not correctly handled. There is no
+technical limitation which enforces this, it's just that the
+@code{bigram} program has not been updated to support lists of file
+names separated by nulls.
+
+So, if you are using the new database format (this is the default) and
+your system uses GNU @code{sort}, newlines will be correctly handled
+at all times. Otherwise, newlines may not be correctly handled.
+
+@node File Permissions
+@chapter File Permissions
+
+@include perm.texi
+
+@include parse-datetime.texi
+
+@node Configuration
+@chapter Configuration
+
+The findutils source distribution includes a @code{configure} script
+which examines the system and generates files required to build
+findutils. See the files @file{README} and @file{INSTALL}.
+
+A number of options can be specified on the @code{configure} command
+line, and many of these are straightforward, adequately documented in
+the @code{--help} output, or not normally useful. Options which are
+useful or which are not obvious are explained here.
+
+@menu
+* Leaf Optimisation:: Take advantage of Unix file system semantics.
+* d_type Optimisation:: Take advantage of file type information.
+* fts:: A non-recursive file system search.
+@end menu
+
+@node Leaf Optimisation
+@section Leaf Optimisation
+
+Files in Unix file systems have a link count which indicates how many
+names point to the same inode. Directories in Unix filssytems have a
+@file{..} entry which functions as a hard link to the parent directory
+and a @file{.} entry which functions as a link to the directory itself.
+The @file{..} entry of the root directory also points to the root.
+This means that @code{find} can deduce the number of subdirectories a
+directory has, simply by subtracting 2 from the directory's link
+count. This allows @file{find} the calls to @code{stat} which would
+otherwise be needed to discover which directory entries are
+subdirectories.
+
+File systems which don't have these semantics should simply return a
+value less than 2 in the @code{st_nlinks} member of @code{struct stat}
+in response to a successful call to @code{stat}.
+
+If you are building @code{find} for a system on which the value of
+@code{st_nlinks} is unreliable, you can specify
+@code{--disable-leaf-optimisation} to @code{configure} to prevent this
+assumption being made.
+
+@node d_type Optimisation
+@section d_type Optimisation
+
+When this feature is enabled, @code{find} takes advantage of the fact
+that on some systems @code{readdir} will return the type of a file in
+@code{struct dirent}.
+
+@node fts
+@section fts
+
+The findutils source distribution contains two different implementations of
+@code{find}. The older implementation descends the file system
+recursively, while the newer one uses @code{fts}. Both are normally
+installed.
+
+If the option @code{--without-fts} was passed to @code{configure}, the
+recursive implementation is installed as @code{find} and the fts-based
+implementation is installed as @code{ftsfind}. Otherwise, the
+fts-based implementation is installed as @code{find} and the recursive
+implementation is installed as @code{oldfind}.
+
+
+
+@node Reference
+@chapter Reference
+
+Below are summaries of the command line syntax for the programs
+discussed in this manual.
+
+@menu
+* Invoking find::
+* Invoking locate::
+* Invoking updatedb::
+* Invoking xargs::
+* Regular Expressions::
+* Environment Variables::
+@end menu
+
+@node Invoking find
+@section Invoking @code{find}
+
+@example
+find @r{[-H] [-L] [-P] [-D @var{debugoptions}] [-O@var{level}]} @r{[}@var{file}@dots{}@r{]} @r{[}@var{expression}@r{]}
+@end example
+
+@code{find} searches the directory tree rooted at each file name
+@var{file} by evaluating the @var{expression} on each file it finds in
+the tree.
+
+The command line may begin with the @samp{-H}, @samp{-L}, @samp{-P},
+@samp{-D} and @samp{-O} options. These are followed by a list of
+files or directories that should be searched. If no files to search
+are specified, the current directory (@file{.}) is used.
+
+This list of files to search is followed by a list of expressions
+describing the files we wish to search for. The first part of the
+expression is recognised by the fact that it begins with @samp{-}
+followed by some other letters (for example @samp{-print}), or is
+either @samp{(} or @samp{!}. Any arguments after it are the rest of
+the expression.
+
+If no expression is given, the expression @samp{-print} is used.
+
+The @code{find} command exits with status zero if all files matched
+are processed successfully, greater than zero if errors occur.
+
+The @code{find} program also recognises two options for administrative
+use:
+
+@table @samp
+@item --help
+Print a summary of the command line usage and exit.
+@item --version
+Print the version number of @code{find} and exit.
+@end table
+
+The @samp{-version} option is a synonym for @samp{--version}
+
+
+@menu
+* Filesystem Traversal Options::
+* Warning Messages::
+* Optimisation Options::
+* Debug Options::
+* Find Expressions::
+@end menu
+
+@node Filesystem Traversal Options
+@subsection Filesystem Traversal Options
+
+The options @samp{-H}, @samp{-L} or @samp{-P} may be specified at the
+start of the command line (if none of these is specified, @samp{-P} is
+assumed). If you specify more than one of these options, the last one
+specified takes effect (but note that the @samp{-follow} option is
+equivalent to @samp{-L}).
+
+@table @code
+@item -P
+Never follow symbolic links (this is the default), except in the case
+of the @samp{-xtype} predicate.
+@item -L
+Always follow symbolic links, except in the case of the @samp{-xtype}
+predicate.
+@item -H
+Follow symbolic links specified in the list of files to search, or
+which are otherwise specified on the command line.
+@end table
+
+If @code{find} would follow a symbolic link, but cannot for any reason
+(for example, because it has insufficient permissions or the link is
+broken), it falls back on using the properties of the symbolic link
+itself. @ref{Symbolic Links} for a more complete description of how
+symbolic links are handled.
+
+@node Warning Messages
+@subsection Warning Messages
+
+If there is an error on the @code{find} command line, an error message
+is normally issued. However, there are some usages that are
+inadvisable but which @code{find} should still accept. Under these
+circumstances, @code{find} may issue a warning message.
+
+By default, warnings are enabled only if @code{find} is being run
+interactively (specifically, if the standard input is a terminal) and
+the @code{POSIXLY_CORRECT} environment variable is not set. Warning
+messages can be controlled explicitly by the use of options on the
+command line:
+
+@table @code
+@item -warn
+Issue warning messages where appropriate.
+@item -nowarn
+Do not issue warning messages.
+@end table
+
+These options take effect at the point on the command line where they
+are specified. Therefore it's not useful to specify @samp{-nowarn} at
+the end of the command line. The warning messages affected by the
+above options are triggered by:
+
+@itemize @minus
+@item
+Use of the @samp{-d} option which is deprecated; please use
+@samp{-depth} instead, since the latter is POSIX-compliant.
+@item
+Use of the @samp{-ipath} option which is deprecated; please use
+@samp{-iwholename} instead.
+@item
+Specifying an option (for example @samp{-mindepth}) after a non-option
+(for example @samp{-type} or @samp{-print}) on the command line.
+@item
+Use of the @samp{-name} or @samp{-iname} option with a slash character
+in the pattern. Since the name predicates only compare against the
+basename of the visited files, the only file that can match a slash is
+the root directory itself.
+@end itemize
+
+The default behaviour above is designed to work in that way so that
+existing shell scripts don't generate spurious errors, but people will
+be made aware of the problem.
+
+Some warning messages are issued for less common or more serious
+problems, and consequently cannot be turned off:
+
+@itemize @minus
+@item
+Use of an unrecognised backslash escape sequence with @samp{-fprintf}
+@item
+Use of an unrecognised formatting directive with @samp{-fprintf}
+@end itemize
+
+@node Optimisation Options
+@subsection Optimisation Options
+
+The @samp{-O@var{level}} option sets @code{find}'s optimisation level
+to @var{level}. The default optimisation level is 1.
+
+At certain optimisation levels, @code{find} reorders tests to speed up
+execution while preserving the overall effect; that is, predicates
+with side effects are not reordered relative to each other. The
+optimisations performed at each optimisation level are as follows.
+
+@table @samp
+@item 0
+Currently equivalent to optimisation level 1.
+
+@item 1
+This is the default optimisation level and corresponds to the
+traditional behaviour. Expressions are reordered so that tests based
+only on the names of files (for example@samp{ -name} and
+@samp{-regex}) are performed first.
+
+@item 2
+Any @samp{-type} or @samp{-xtype} tests are performed after any tests
+based only on the names of files, but before any tests that require
+information from the inode. On many modern versions of Unix, file
+types are returned by @code{readdir()} and so these predicates are
+faster to evaluate than predicates which need to stat the file first.
+
+If you use the @samp{-fstype FOO} predicate and specify a filsystem
+type @samp{FOO} which is not known (that is, present in
+@file{/etc/mtab}) at the time @code{find} starts, that predicate is
+equivalent to @samp{-false}.
+
+
+@item 3
+At this optimisation level, the full cost-based query optimiser is
+enabled. The order of tests is modified so that cheap (i.e., fast)
+tests are performed first and more expensive ones are performed later,
+if necessary. Within each cost band, predicates are evaluated earlier
+or later according to whether they are likely to succeed or not. For
+@samp{-o}, predicates which are likely to succeed are evaluated
+earlier, and for @samp{-a}, predicates which are likely to fail are
+evaluated earlier.
+@end table
+
+
+@node Debug Options
+@subsection Debug Options
+
+The @samp{-D} option makes @code{find} produce diagnostic output.
+Much of the information is useful only for diagnosing problems, and so
+most people will not find this option helpful.
+
+The list of debug options should be comma separated. Compatibility of
+the debug options is not guaranteed between releases of findutils.
+For a complete list of valid debug options, see the output of
+@code{find -D help}. Valid debug options include:
+@table @samp
+@item help
+Explain the debugging options.
+@item tree
+Show the expression tree in its original and optimised form.
+@item stat
+Print messages as files are examined with the stat and lstat system
+calls. The find program tries to minimise such calls.
+@item opt
+Prints diagnostic information relating to the optimisation of the
+expression tree; see the @samp{-O} option.
+@item rates
+Prints a summary indicating how often each predicate succeeded or
+failed.
+@end table
+
+@node Find Expressions
+@subsection Find Expressions
+
+The final part of the @code{find} command line is a list of
+expressions. @xref{Primary Index}, for a summary of all of the tests,
+actions, and options that the expression can contain. If the
+expression is missing, @samp{-print} is assumed.
+
+@node Invoking locate
+@section Invoking @code{locate}
+
+@example
+locate @r{[}@var{option}@dots{}@r{]} @var{pattern}@dots{}
+@end example
+
+For each @var{pattern} given @code{locate} searches one or more file
+name databases returning each match of @var{pattern}.
+
+@table @code
+@item --all
+@itemx -A
+Print only names which match all non-option arguments, not those
+matching one or more non-option arguments.
+
+@item --basename
+@itemx -b
+The specified pattern is matched against just the last component of
+the name of a file in the @code{locate} database. This last
+component is also called the ``base name''. For example, the base
+name of @file{/tmp/mystuff/foo.old.c} is @file{foo.old.c}. If the
+pattern contains metacharacters, it must match the base name exactly.
+If not, it must match part of the base name.
+
+@item --count
+@itemx -c
+Instead of printing the matched file names, just print the total
+number of matches found, unless @samp{--print} (@samp{-p}) is also
+present.
+
+
+@item --database=@var{path}
+@itemx -d @var{path}
+Instead of searching the default @code{locate} database
+@file{@value{LOCATE_DB}}, @code{locate} searches the file
+name databases in @var{path}, which is a colon-separated list of
+database file names. You can also use the environment variable
+@code{LOCATE_PATH} to set the list of database files to search. The
+option overrides the environment variable if both are used. Empty
+elements in @var{path} (that is, a leading or trailing colon, or two
+colons in a row) are taken to stand for the default database.
+A database can be supplied on stdin, using @samp{-} as an element
+of @samp{path}. If more than one element of @samp{path} is @samp{-},
+later instances are ignored (but a warning message is printed).
+
+@item --existing
+@itemx -e
+Only print out such names which currently exist (instead of such names
+which existed when the database was created). Note that this may slow
+down the program a lot, if there are many matches in the database.
+The way in which broken symbolic links are treated is affected by the
+@samp{-L}, @samp{-P} and @samp{-H} options. Please note that it is
+possible for the file to be deleted after @code{locate} has checked
+that it exists, but before you use it. This option is automatically
+turned on when reading an @code{slocate} database in secure mode
+(@pxref{slocate Database Format}).
+
+@item --non-existing
+@itemx -E
+Only print out such names which currently do not exist (instead of
+such names which existed when the database was created). Note that
+this may slow down the program a lot, if there are many matches in the
+database. The way in which broken symbolic links are treated is
+affected by the @samp{-L}, @samp{-P} and @samp{-H} options. Please
+note that @code{locate} checks that the file does not exist, but a
+file of the same name might be created after @code{locate}'s check but
+before you read @code{locate}'s output.
+
+@item --follow
+@itemx -L
+If testing for the existence of files (with the @samp{-e} or @samp{-E}
+options), consider broken symbolic links to be non-existing. This is
+the default behaviour.
+
+@item --nofollow
+@itemx -P
+@itemx -H
+If testing for the existence of files (with the @samp{-e} or @samp{-E}
+options), treat broken symbolic links as if they were existing files.
+The @samp{-H} form of this option is provided purely for similarity
+with @code{find}; the use of @samp{-P} is recommended over @samp{-H}.
+
+@item --ignore-case
+@itemx -i
+Ignore case distinctions in both the pattern and the file names.
+
+@item --limit=N
+@itemx -l N
+Limit the number of results printed to N. When used with the
+@samp{--count} option, the value printed will never be larger than
+this limit.
+@item --max-database-age=D
+Normally, @code{locate} will issue a warning message when it searches
+a database which is more than 8 days old. This option changes that
+value to something other than 8. The effect of specifying a negative
+value is undefined.
+@item --mmap
+@itemx -m
+Accepted but does nothing. The option is supported only to provide
+compatibility with BSD's @code{locate}.
+
+@item --null
+@itemx -0
+Results are separated with the ASCII NUL character rather than the
+newline character. To get the full benefit of this option,
+use the new @code{locate} database format (that is the default
+anyway).
+
+@item --print
+@itemx -p
+Print search results when they normally would not be due to
+use of @samp{--statistics} (@samp{-S}) or @samp{--count}
+(@samp{-c}).
+
+@item --wholename
+@itemx -w
+The specified pattern is matched against the whole name of the file in
+the @code{locate} database. If the pattern contains metacharacters,
+it must match exactly. If not, it must match part of the whole file
+name. This is the default behaviour.
+
+@item --regex
+@itemx -r
+Instead of using substring or shell glob matching, the pattern
+specified on the command line is understood to be a regular
+expression. GNU Emacs-style regular expressions are assumed unless
+the @samp{--regextype} option is also given. File names from the
+@code{locate} database are matched using the specified regular
+expression. If the @samp{-i} flag is also given, matching is
+case-insensitive. Matches are performed against the whole path name,
+and so by default a pathname will be matched if any part of it matches
+the specified regular expression. The regular expression may use
+@samp{^} or @samp{$} to anchor a match at the beginning or end of a
+pathname.
+
+@item --regextype
+This option changes the regular expression syntax and behaviour used
+by the @samp{--regex} option. @ref{Regular Expressions} for more
+information on the regular expression dialects understood by GNU
+findutils.
+
+@item --stdio
+@itemx -s
+Accepted but does nothing. The option is supported only to provide
+compatibility with BSD's @code{locate}.
+
+@item --statistics
+@itemx -S
+Print some summary information for each @code{locate} database. No
+search is performed unless non-option arguments are given.
+Although the BSD version of locate also has this option, the format of the
+output is different.
+
+@item --help
+Print a summary of the command line usage for @code{locate} and exit.
+
+@item --version
+Print the version number of @code{locate} and exit.
+@end table
+
+@node Invoking updatedb
+@section Invoking @code{updatedb}
+
+@example
+updatedb @r{[}@var{option}@dots{}@r{]}
+@end example
+
+@code{updatedb} creates and updates the database of file names used by
+@code{locate}. @code{updatedb} generates a list of files similar to
+the output of @code{find} and then uses utilities for optimizing the
+database for performance. @code{updatedb} is often run periodically
+as a @code{cron} job and configured with environment variables or
+command options. Typically, operating systems have a shell script
+that ``exports'' configurations for variable definitions and uses
+another shell script that ``sources'' the configuration file into the
+environment and then executes @code{updatedb} in the environment.
+
+@table @code
+@item --findoptions='@var{OPTION}@dots{}'
+Global options to pass on to @code{find}.
+The environment variable @code{FINDOPTIONS} also sets this value.
+Default is none.
+
+@item --localpaths='@var{path}@dots{}'
+Non-network directories to put in the database.
+Default is @file{/}.
+
+@item --netpaths='@var{path}@dots{}'
+Network (NFS, AFS, RFS, etc.) directories to put in the database.
+The environment variable @code{NETPATHS} also sets this value.
+Default is none.
+
+@item --prunepaths='@var{path}@dots{}'
+Directories to omit from the database, which would otherwise be
+included. The environment variable @code{PRUNEPATHS} also sets this
+value. Default is @file{/tmp /usr/tmp /var/tmp /afs}. The paths are
+used as regular expressions (with @code{find ... -regex}, so you need
+to specify these paths in the same way that @code{find} will encounter
+them. This means for example that the paths must not include trailing
+slashes.
+
+@item --prunefs='@var{path}@dots{}'
+Filesystems to omit from the database, which would otherwise be
+included. Note that files are pruned when a filesystem is reached;
+Any filesystem mounted under an undesired filesystem will be ignored.
+The environment variable @code{PRUNEFS} also sets this value. Default
+is @file{nfs NFS proc}.
+
+@item --output=@var{dbfile}
+The database file to build. The default is system-dependent, but
+when this document was formatted it was @file{@value{LOCATE_DB}}.
+
+@item --localuser=@var{user}
+The user to search the non-network directories as, using @code{su}.
+Default is to search the non-network directories as the current user.
+You can also use the environment variable @code{LOCALUSER} to set this user.
+
+@item --netuser=@var{user}
+The user to search network directories as, using @code{su}. Default
+@code{user} is @code{daemon}. You can also use the environment variable
+@code{NETUSER} to set this user.
+
+@item --old-format
+Generate a @code{locate} database in the old format, for compatibility
+with versions of @code{locate} other than GNU @code{locate}. Using
+this option means that @code{locate} will not be able to properly
+handle non-ASCII characters in file names (that is, file names
+containing characters which have the eighth bit set, such as many of
+the characters from the ISO-8859-1 character set). @xref{Database
+Formats}, for a detailed description of the supported database
+formats.
+
+@item --dbformat=@var{FORMAT}
+Generate the locate database in format @code{FORMAT}. Supported
+database formats include @code{LOCATE02} (which is the default),
+@code{old} and @code{slocate}. The @code{old} format exists for
+compatibility with implementations of @code{locate} on other Unix
+systems. The @code{slocate} format exists for compatibility with
+@code{slocate}. @xref{Database Formats}, for a detailed description
+of each format.
+
+@item --help
+Print a summary of the command line usage and exit.
+@item --version
+Print the version number of @code{updatedb} and exit.
+@end table
+
+@node Invoking xargs
+@section Invoking @code{xargs}
+
+@example
+xargs @r{[}@var{option}@dots{}@r{]} @r{[}@var{command} @r{[}@var{initial-arguments}@r{]}@r{]}
+@end example
+
+@code{xargs} exits with the following status:
+
+@table @asis
+@item 0
+if it succeeds
+@item 123
+if any invocation of the command exited with status 1-125
+@item 124
+if the command exited with status 255
+@item 125
+if the command is killed by a signal
+@item 126
+if the command cannot be run
+@item 127
+if the command is not found
+@item 1
+if some other error occurred.
+@end table
+
+Exit codes greater than 128 are used by the shell to indicate that
+a program died due to a fatal signal.
+
+
+@menu
+* xargs options::
+* Invoking the shell from xargs::
+@end menu
+
+@node xargs options
+@subsection xargs options
+
+@table @code
+@item --arg-file@r{=@var{inputfile}}
+@itemx -a @r{@var{inputfile}}
+Read names from the file @var{inputfile} instead of standard input.
+If you use this option, the standard input stream remains unchanged
+when commands are run. Otherwise, stdin is redirected from
+@file{/dev/null}.
+
+@item --null
+@itemx -0
+Input file names are terminated by a null character instead of by
+whitespace, and any quotes and backslash characters are not considered
+special (every character is taken literally). Disables the end of
+file string, which is treated like any other argument.
+
+@item --delimiter @var{delim}
+@itemx -d @var{delim}
+
+Input file names are terminated by the specified character @var{delim}
+instead of by whitespace, and any quotes and backslash characters are
+not considered special (every character is taken literally). Disables
+the logical end of file marker string, which is treated like any other
+argument.
+
+The specified delimiter may be a single character, a C-style character
+escape such as @samp{\n}, or an octal or hexadecimal escape code.
+Octal and hexadecimal escape codes are understood as for the
+@code{printf} command. Multibyte characters are not supported.
+
+@item -E @var{eof-str}
+@itemx --eof@r{[}=@var{eof-str}@r{]}
+@itemx -e@r{[}@var{eof-str}@r{]}
+
+Set the logical end of file marker string to @var{eof-str}. If the
+logical end of file marker string occurs as a line of input, the rest of
+the input is ignored. If @var{eof-str} is omitted (@samp{-e}) or blank
+(either @samp{-e} or @samp{-E}), there is no logical end of file marker
+string. The @samp{-e} form of this option is deprecated in favour of
+the POSIX-compliant @samp{-E} option, which you should use instead. As
+of GNU @code{xargs} version 4.2.9, the default behaviour of @code{xargs}
+is not to have a logical end of file marker string. The POSIX standard
+(IEEE Std 1003.1, 2004 Edition) allows this.
+
+The logical end of file marker string is not treated specially if the
+@samp{-d} or the @samp{-0} options are in effect. That is, when either
+of these options are in effect, the whole input file will be read even
+if @samp{-E} was used.
+
+@item --help
+Print a summary of the options to @code{xargs} and exit.
+
+@item -I @var{replace-str}
+@itemx --replace@r{[}=@var{replace-str}@r{]}
+@itemx -i@r{[}@var{replace-str}@r{]}
+Replace occurrences of @var{replace-str} in the initial arguments with
+names read from standard input. Also, unquoted blanks do not
+terminate arguments; instead, the input is split at newlines only. If
+@var{replace-str} is omitted (omitting it is allowed only for
+@samp{-i}), it defaults to @samp{@{@}} (like for @samp{find -exec}).
+Implies @samp{-x} and @samp{-l 1}. The @samp{-i} option is deprecated
+in favour of the @samp{-I} option.
+
+@item -L @var{max-lines}
+@itemx --max-lines@r{[}=@var{max-lines}@r{]}
+@itemx -l@r{[}@var{max-lines}@r{]}
+Use at most @var{max-lines} non-blank input lines per command line.
+For @samp{-l}, @var{max-lines} defaults to 1 if omitted. For
+@samp{-L}, the argument is mandatory. Trailing blanks cause an input
+line to be logically continued on the next input line, for the purpose
+of counting the lines. Implies @samp{-x}. The @samp{-l} form of this
+option is deprecated in favour of the POSIX-compliant @samp{-L}
+option.
+
+@item --max-args=@var{max-args}
+@itemx -n @var{max-args}
+Use at most @var{max-args} arguments per command line. Fewer than
+@var{max-args} arguments will be used if the size (see the @samp{-s}
+option) is exceeded, unless the @samp{-x} option is given, in which
+case @code{xargs} will exit.
+
+@item --interactive
+@itemx -p
+Prompt the user about whether to run each command line and read a line
+from the terminal. Only run the command line if the response starts
+with @samp{y} or @samp{Y}. Implies @samp{-t}.
+
+@item --no-run-if-empty
+@itemx -r
+If the standard input is completely empty, do not run the
+command. By default, the command is run once even if there is no
+input.
+
+@item --max-chars=@var{max-chars}
+@itemx -s @var{max-chars}
+Use at most @var{max-chars} characters per command line, including the
+command, initial arguments and any terminating nulls at the ends of
+the argument strings.
+
+@item --show-limits
+Display the limits on the command-line length which are imposed by the
+operating system, @code{xargs}' choice of buffer size and the
+@samp{-s} option. Pipe the input from @file{/dev/null} (and perhaps
+specify @samp{--no-run-if-empty}) if you don't want @code{xargs} to do
+anything.
+
+@item --verbose
+@itemx -t
+Print the command line on the standard error output before executing
+it.
+
+@item --version
+Print the version number of @code{xargs} and exit.
+
+@item --exit
+@itemx -x
+Exit if the size (see the @samp{-s} option) is exceeded.
+
+
+@item --max-procs=@var{max-procs}
+@itemx -P @var{max-procs}
+Run simultaneously up to @var{max-procs} processes at once; the default is 1. If
+@var{max-procs} is 0, @code{xargs} will run as many processes as
+possible simultaneously. @xref{Controlling Parallelism}, for
+information on dynamically controlling parallelism.
+
+@item --process-slot-var=@var{environment-variable-name}
+Set the environment variable @var{environment-variable-name} to a
+unique value in each running child process. Each value is a decimal
+integer. Values are reused once child processes exit. This can be
+used in a rudimentary load distribution scheme, for example.
+@end table
+
+@node Invoking the shell from xargs
+@subsection Invoking the shell from xargs
+
+Normally, @code{xargs} will exec the command you specified directly,
+without invoking a shell. This is normally the behaviour one would
+want. It's somewhat more efficient and avoids problems with shell
+metacharacters, for example. However, sometimes it is necessary to
+manipulate the environment of a command before it is run, in a way
+that @code{xargs} does not directly support.
+
+Invoking a shell from @code{xargs} is a good way of performing such
+manipulations. However, some care must be taken to prevent problems,
+for example unwanted interpretation of shell metacharacters.
+
+This command moves a set of files into an archive directory:
+
+@example
+find /foo -maxdepth 1 -atime +366 -exec mv @{@} /archive \;
+@end example
+
+However, this will only move one file at a time. We cannot in this
+case use @code{-exec ... +} because the matched file names are added
+at the end of the command line, while the destination directory would
+need to be specified last. We also can't use @code{xargs} in the
+obvious way for the same reason. One way of working around this
+problem is to make use of the special properties of GNU @code{mv}; it
+has a @code{-t} option that allows the target directory to be
+specified before the list of files to be moved. However, while this
+technique works for GNU @code{mv}, it doesn't solve the more general
+problem.
+
+Here is a more general technique for solving this problem:
+
+@example
+find /foo -maxdepth 1 -atime +366 -print0 |
+xargs -r0 sh -c 'mv "$@@" /archive' move
+@end example
+
+Here, a shell is being invoked. There are two shell instances to think
+about. The first is the shell which launches the @code{xargs} command
+(this might be the shell into which you are typing, for example). The
+second is the shell launched by @code{xargs} (in fact it will probably
+launch several, one after the other, depending on how many files need to
+be archived). We'll refer to this second shell as a subshell.
+
+Our example uses the @code{-c} option of @code{sh}. Its argument is a
+shell command to be executed by the subshell. Along with the rest of
+that command, the $@@ is enclosed by single quotes to make sure it is
+passed to the subshell without being expanded by the parent shell. It
+is also enclosed with double quotes so that the subshell will expand
+@code{$@@} correctly even if one of the file names contains a space or
+newline.
+
+The subshell will use any non-option arguments as positional
+parameters (that is, in the expansion of @code{$@@}). Because
+@code{xargs} launches the @code{sh -c} subshell with a list of files,
+those files will end up as the expansion of @code{$@@}.
+
+You may also notice the @samp{move} at the end of the command line.
+This is used as the value of @code{$0} by the subshell. We include it
+because otherwise the name of the first file to be moved would be used
+instead. If that happened it would not be included in the subshell's
+expansion of @code{$@@}, and so it wouldn't actually get moved.
+
+
+Another reason to use the @code{sh -c} construct could be to
+perform redirection:
+
+@example
+find /usr/include -name '*.h' | xargs grep -wl mode_t |
+xargs -r sh -c 'exec emacs "$@@" < /dev/tty' Emacs
+@end example
+
+Notice that we use the shell builtin @code{exec} here. That's simply
+because the subshell needs to do nothing once Emacs has been invoked.
+Therefore instead of keeping a @code{sh} process around for no reason,
+we just arrange for the subshell to exec Emacs, saving an extra
+process creation.
+
+Sometimes, though, it can be helpful to keep the shell process around:
+
+@example
+find /foo -maxdepth 1 -atime +366 -print0 |
+xargs -r0 sh -c 'mv "$@@" /archive || exit 255' move
+@end example
+
+Here, the shell will exit with status 255 if any @code{mv} failed.
+This causes @code{xargs} to stop immediately.
+
+
+@node Regular Expressions
+@section Regular Expressions
+
+The @samp{-regex} and @samp{-iregex} tests of @code{find} allow
+matching by regular expression, as does the @samp{--regex} option of
+@code{locate}.
+
+Your locale configuration affects how regular expressions are
+interpreted. @xref{Environment Variables}, for a description of how
+your locale setup affects the interpretation of regular expressions.
+
+There are also several different types of regular expression, and
+these are interpreted differently. Normally, the type of regular
+expression used by @code{find} and @code{locate} is the same as is
+used in GNU Emacs. Both programs provide an option which allows you
+to select an alternative regular expression syntax; for @code{find}
+this is the @samp{-regextype} option, and for @code{locate} this is
+the @samp{--regextype} option.
+
+These options take a single argument, which indicates the specific
+regular expression syntax and behaviour that should be used. This
+should be one of the following:
+
+@include regexprops.texi
+
+@node Environment Variables
+@section Environment Variables
+@c TODO: check the variable index still contains references to these
+@table @code
+@item LANG
+Provides a default value for the internationalisation variables that
+are unset or null.
+
+@item LC_ALL
+If set to a non-empty string value, override the values of all the
+other internationalisation variables.
+
+@item LC_COLLATE
+The POSIX standard specifies that this variable affects the pattern
+matching to be used for the `\-name' option. GNU find uses the
+GNU version of the @code{fnmatch} library function.
+
+This variable also affects the interpretation of the response to
+@code{-ok}; while the @code{LC_MESSAGES} variable selects the actual
+pattern used to interpret the response to @code{-ok}, the interpretation
+of any bracket expressions in the pattern will be affected by the
+@code{LC_COLLATE} variable.
+
+@item LC_CTYPE
+This variable affects the treatment of character classes used in
+regular expression and with
+the @samp{-name} test, if the @code{fnmatch} function supports this.
+
+This variable also affects the interpretation of any character classes
+in the regular expressions used to interpret the response to the
+prompt issued by @code{-ok}. The @code{LC_CTYPE} environment variable will
+also affect which characters are considered to be unprintable when
+filenames are printed (@pxref{Unusual Characters in File Names}).
+
+@item LC_MESSAGES
+Determines the locale to be used for internationalised messages,
+including the interpretation of the response to the prompt made by the
+@code{-ok} action.
+
+@item NLSPATH
+Determines the location of the internationalisation message catalogues.
+
+@item PATH
+Affects the directories which are searched to find the executables
+invoked by @samp{-exec}, @samp{-execdir} @samp{-ok} and @samp{-okdir}.
+If the @var{PATH} environment variable includes the current directory
+(by explicitly including @samp{.} or by having an empty element), and
+the find command line includes @samp{-execdir} or @samp{-okdir},
+@code{find} will refuse to run. @xref{Security Considerations}, for a
+more detailed discussion of security matters.
+
+@item POSIXLY_CORRECT
+Determines the block size used by @samp{-ls} and @samp{-fls}. If
+@code{POSIXLY_CORRECT} is set, blocks are units of 512 bytes. Otherwise
+they are units of 1024 bytes.
+
+Setting this variable also turns off warning messages (that is, implies
+@samp{-nowarn}) by default, because POSIX requires that apart from
+the output for @samp{-ok}, all messages printed on stderr are
+diagnostics and must result in a non-zero exit status.
+
+When @code{POSIXLY_CORRECT} is set, the response to the prompt made by the
+@code{-ok} action is interpreted according to the system's message
+catalogue, as opposed to according to @code{find}'s own message
+translations.
+
+@item TZ
+Affects the time zone used for some of the time-related format
+directives of @samp{-printf} and @samp{-fprintf}.
+@end table
+
+
+
+@node Common Tasks
+@chapter Common Tasks
+
+The sections that follow contain some extended examples that both give
+a good idea of the power of these programs, and show you how to solve
+common real-world problems.
+
+@menu
+* Viewing And Editing::
+* Archiving::
+* Cleaning Up::
+* Strange File Names::
+* Fixing Permissions::
+* Classifying Files::
+@end menu
+
+@node Viewing And Editing
+@section Viewing And Editing
+
+To view a list of files that meet certain criteria, simply run your
+file viewing program with the file names as arguments. Shells
+substitute a command enclosed in backquotes with its output, so the
+whole command looks like this:
+
+@example
+less `find /usr/include -name '*.h' | xargs grep -l mode_t`
+@end example
+
+@noindent
+You can edit those files by giving an editor name instead of a file
+viewing program:
+
+@example
+emacs `find /usr/include -name '*.h' | xargs grep -l mode_t`
+@end example
+
+Because there is a limit to the length of any individual command line,
+there is a limit to the number of files that can be handled in this way.
+We can get around this difficulty by using @code{xargs} like this:
+
+@example
+find /usr/include -name '*.h' | xargs grep -l mode_t > todo
+xargs --arg-file=todo emacs
+@end example
+
+Here, @code{xargs} will run @code{emacs} as many times as necessary to
+visit all of the files listed in the file @file{todo}. Generating a
+temporary file is not always convenient, though. This command does
+much the same thing without needing one:
+
+@example
+find /usr/include -name '*.h' | xargs grep -l mode_t |
+xargs sh -c 'emacs "$@@" < /dev/tty' Emacs
+@end example
+
+The example above illustrates a useful trick; Using @code{sh -c} you
+can invoke a shell command from @code{xargs}. The @code{$@@} in the
+command line is expanded by the shell to a list of arguments as
+provided by @code{xargs}. The single quotes in the command line
+protect the @code{$@@} against expansion by your interactive shell
+(which will normally have no arguments and thus expand @code{$@@} to
+nothing). The capitalised @samp{Emacs} on the command line is used as
+@code{$0} by the shell that @code{xargs} launches.
+
+@node Archiving
+@section Archiving
+
+You can pass a list of files produced by @code{find} to a file
+archiving program. GNU @code{tar} and @code{cpio} can both read lists
+of file names from the standard input -- either delimited by nulls (the
+safe way) or by blanks (the lazy, risky default way). To use
+null-delimited names, give them the @samp{--null} option. You can
+store a file archive in a file, write it on a tape, or send it over a
+network to extract on another machine.
+
+One common use of @code{find} to archive files is to send a list of
+the files in a directory tree to @code{cpio}. Use @samp{-depth} so if
+a directory does not have write permission for its owner, its contents
+can still be restored from the archive since the directory's
+permissions are restored after its contents. Here is an example of
+doing this using @code{cpio}; you could use a more complex @code{find}
+expression to archive only certain files.
+
+@example
+find . -depth -print0 |
+ cpio --create --null --format=crc --file=/dev/nrst0
+@end example
+
+You could restore that archive using this command:
+
+@example
+cpio --extract --null --make-dir --unconditional \
+ --preserve --file=/dev/nrst0
+@end example
+
+Here are the commands to do the same things using @code{tar}:
+
+@example
+find . -depth -print0 |
+ tar --create --null --files-from=- --file=/dev/nrst0
+
+tar --extract --null --preserve-perm --same-owner \
+ --file=/dev/nrst0
+@end example
+
+@c Idea from Rick Sladkey.
+Here is an example of copying a directory from one machine to another:
+
+@example
+find . -depth -print0 | cpio -0o -Hnewc |
+ rsh @var{other-machine} "cd `pwd` && cpio -i0dum"
+@end example
+
+@node Cleaning Up
+@section Cleaning Up
+
+@c Idea from Jim Meyering.
+This section gives examples of removing unwanted files in various
+situations. Here is a command to remove the CVS backup files created
+when an update requires a merge:
+
+@example
+find . -name '.#*' -print0 | xargs -0r rm -f
+@end example
+
+If your @code{find} command removes directories, you may find that
+you get a spurious error message when @code{find} tries to recurse
+into a directory that has now been removed. Using the @samp{-depth}
+option will normally resolve this problem.
+
+@c What does the following sentence mean? Why is -delete safer? --kasal
+@c The command above works, but the following is safer:
+
+It is also possible to use the @samp{-delete} action:
+
+@example
+find . -depth -name '.#*' -delete
+@end example
+
+@c Idea from Franc,ois Pinard.
+You can run this command to clean out your clutter in @file{/tmp}.
+You might place it in the file your shell runs when you log out
+(@file{.bash_logout}, @file{.logout}, or @file{.zlogout}, depending on
+which shell you use).
+
+@example
+find /tmp -depth -user "$LOGNAME" -type f -delete
+@end example
+
+@c Idea from Noah Friedman.
+To remove old Emacs backup and auto-save files, you can use a command
+like the following. It is especially important in this case to use
+null-terminated file names because Emacs packages like the VM mailer
+often create temporary file names with spaces in them, like
+@file{#reply to David J. MacKenzie<1>#}.
+
+@example
+find ~ \( -name '*~' -o -name '#*#' \) -print0 |
+ xargs --no-run-if-empty --null rm -vf
+@end example
+
+Removing old files from @file{/tmp} is commonly done from @code{cron}:
+
+@c Idea from Kaveh Ghazi.
+@example
+find /tmp /var/tmp -depth -not -type d -mtime +3 -delete
+find /tmp /var/tmp -depth -mindepth 1 -type d -empty -delete
+@end example
+
+The second @code{find} command above cleans out empty directories
+depth-first (@samp{-delete} implies @samp{-depth} anyway), hoping that
+the parents become empty and can be removed too. It uses
+@samp{-mindepth} to avoid removing @file{/tmp} itself if it becomes
+totally empty.
+
+
+Lastly, an example of a program that almost certainly does not do what
+the user intended:
+
+@c inspired by Savannah bug #20865 (Bruno De Fraine)
+@example
+find dirname -delete -name quux
+@end example
+
+If the user hoped to delete only files named @file{quux} they will get
+an unpleasant surprise; this command will attempt to delete everything
+at or below the starting point @file{dirname}. This is because
+@code{find} evaluates the items on the command line as an expression.
+The @code{find} program will normally execute an action if the
+preceding action succeeds. Here, there is no action or test before
+the @samp{-delete} so it will always be executed. The @samp{-name
+quux} test will be performed for files we successfully deleted, but
+that test has no effect since @samp{-delete} also disables the default
+@samp{-print} operation. So the above example will probably delete a
+lot of files the user didn't want to delete.
+
+This command is also likely to do something you did not intend:
+@example
+find dirname -path dirname/foo -prune -o -delete
+@end example
+
+Because @samp{-delete} turns on @samp{-depth}, the @samp{-prune}
+action has no effect and files in @file{dirname/foo} will be deleted
+too.
+
+
+@node Strange File Names
+@section Strange File Names
+
+@c Idea from:
+@c From: tmatimar@isgtec.com (Ted Timar)
+@c Newsgroups: comp.unix.questions,comp.unix.shell,comp.answers,news.answers
+@c Subject: Unix - Frequently Asked Questions (2/7) [Frequent posting]
+@c Subject: How do I remove a file with funny characters in the filename ?
+@c Date: Thu Mar 18 17:16:55 EST 1993
+@code{find} can help you remove or rename a file with strange
+characters in its name. People are sometimes stymied by files whose
+names contain characters such as spaces, tabs, control characters, or
+characters with the high bit set. The simplest way to remove such
+files is:
+
+@example
+rm -i @var{some*pattern*that*matches*the*problem*file}
+@end example
+
+@code{rm} asks you whether to remove each file matching the given
+pattern. If you are using an old shell, this approach might not work
+if the file name contains a character with the high bit set; the shell
+may strip it off. A more reliable way is:
+
+@example
+find . -maxdepth 1 @var{tests} -okdir rm '@{@}' \;
+@end example
+
+@noindent
+where @var{tests} uniquely identify the file. The @samp{-maxdepth 1}
+option prevents @code{find} from wasting time searching for the file
+in any subdirectories; if there are no subdirectories, you may omit
+it. A good way to uniquely identify the problem file is to figure out
+its inode number; use
+
+@example
+ls -i
+@end example
+
+Suppose you have a file whose name contains control characters, and
+you have found that its inode number is 12345. This command prompts
+you for whether to remove it:
+
+@example
+find . -maxdepth 1 -inum 12345 -okdir rm -f '@{@}' \;
+@end example
+
+If you don't want to be asked, perhaps because the file name may
+contain a strange character sequence that will mess up your screen
+when printed, then use @samp{-execdir} instead of @samp{-okdir}.
+
+If you want to rename the file instead, you can use @code{mv} instead
+of @code{rm}:
+
+@example
+find . -maxdepth 1 -inum 12345 -okdir mv '@{@}' @var{new-file-name} \;
+@end example
+
+@node Fixing Permissions
+@section Fixing Permissions
+
+Suppose you want to make sure that everyone can write to the
+directories in a certain directory tree. Here is a way to find
+directories lacking either user or group write permission (or both),
+and fix their permissions:
+
+@example
+find . -type d -not -perm -ug=w | xargs chmod ug+w
+@end example
+
+@noindent
+You could also reverse the operations, if you want to make sure that
+directories do @emph{not} have world write permission.
+
+@node Classifying Files
+@section Classifying Files
+
+@c Idea from:
+@c From: martin@mwtech.UUCP (Martin Weitzel)
+@c Newsgroups: comp.unix.wizards,comp.unix.questions
+@c Subject: Advanced usage of 'find' (Re: Unix security automating script)
+@c Date: 22 Mar 90 15:05:19 GMT
+If you want to classify a set of files into several groups based on
+different criteria, you can use the comma operator to perform multiple
+independent tests on the files. Here is an example:
+
+@example
+find / -type d \( -perm -o=w -fprint allwrite , \
+ -perm -o=x -fprint allexec \)
+
+echo "Directories that can be written to by everyone:"
+cat allwrite
+echo ""
+echo "Directories with search permissions for everyone:"
+cat allexec
+@end example
+
+@code{find} has only to make one scan through the directory tree
+(which is one of the most time consuming parts of its work).
+
+@node Worked Examples
+@chapter Worked Examples
+
+The tools in the findutils package, and in particular @code{find},
+have a large number of options. This means that quite often,
+there is more than one way to do things. Some of the options
+and facilities only exist for compatibility with other tools, and
+findutils provides improved ways of doing things.
+
+This chapter describes a number of useful tasks that are commonly
+performed, and compares the different ways of achieving them.
+
+@menu
+* Deleting Files::
+* Copying A Subset of Files::
+* Updating A Timestamp File::
+* Finding the Shallowest Instance::
+@end menu
+
+@node Deleting Files
+@section Deleting Files
+
+One of the most common tasks that @code{find} is used for is locating
+files that can be deleted. This might include:
+
+@itemize
+@item
+Files last modified more than 3 years ago which haven't been accessed
+for at least 2 years
+@item
+Files belonging to a certain user
+@item
+Temporary files which are no longer required
+@end itemize
+
+This example concentrates on the actual deletion task rather than on
+sophisticated ways of locating the files that need to be deleted.
+We'll assume that the files we want to delete are old files underneath
+@file{/var/tmp/stuff}.
+
+@subsection The Traditional Way
+
+The traditional way to delete files in @file{/var/tmp/stuff} that have
+not been modified in over 90 days would have been:
+
+@smallexample
+find /var/tmp/stuff -mtime +90 -exec /bin/rm @{@} \;
+@end smallexample
+
+The above command uses @samp{-exec} to run the @code{/bin/rm} command
+to remove each file. This approach works and in fact would have
+worked in Version 7 Unix in 1979. However, there are a number of
+problems with this approach.
+
+
+The most obvious problem with the approach above is that it causes
+@code{find} to fork every time it finds a file that needs to delete,
+and the child process then has to use the @code{exec} system call to
+launch @code{/bin/rm}. All this is quite inefficient. If we are
+going to use @code{/bin/rm} to do this job, it is better to make it
+delete more than one file at a time.
+
+The most obvious way of doing this is to use the shell's command
+expansion feature:
+
+@smallexample
+/bin/rm `find /var/tmp/stuff -mtime +90 -print`
+@end smallexample
+or you could use the more modern form
+@smallexample
+/bin/rm $(find /var/tmp/stuff -mtime +90 -print)
+@end smallexample
+
+The commands above are much more efficient than the first attempt.
+However, there is a problem with them. The shell has a maximum
+command length which is imposed by the operating system (the actual
+limit varies between systems). This means that while the command
+expansion technique will usually work, it will suddenly fail when
+there are lots of files to delete. Since the task is to delete
+unwanted files, this is precisely the time we don't want things to go
+wrong.
+
+@subsection Making Use of @code{xargs}
+
+So, is there a way to be more efficient in the use of @code{fork()}
+and @code{exec()} without running up against this limit?
+Yes, we can be almost optimally efficient by making use
+of the @code{xargs} command. The @code{xargs} command reads arguments
+from its standard input and builds them into command lines. We can
+use it like this:
+
+@smallexample
+find /var/tmp/stuff -mtime +90 -print | xargs /bin/rm
+@end smallexample
+
+For example if the files found by @code{find} are
+@file{/var/tmp/stuff/A},
+@file{/var/tmp/stuff/B} and
+@file{/var/tmp/stuff/C} then @code{xargs} might issue the commands
+
+@smallexample
+/bin/rm /var/tmp/stuff/A /var/tmp/stuff/B
+/bin/rm /var/tmp/stuff/C
+@end smallexample
+
+The above assumes that @code{xargs} has a very small maximum command
+line length. The real limit is much larger but the idea is that
+@code{xargs} will run @code{/bin/rm} as many times as necessary to get
+the job done, given the limits on command line length.
+
+This usage of @code{xargs} is pretty efficient, and the @code{xargs}
+command is widely implemented (all modern versions of Unix offer it).
+So far then, the news is all good. However, there is bad news too.
+
+@subsection Unusual characters in filenames
+
+Unix-like systems allow any characters to appear in file names with
+the exception of the ASCII NUL character and the slash.
+Slashes can occur in path names (as the directory separator) but
+not in the names of actual directory entries. This means that the
+list of files that @code{xargs} reads could in fact contain white space
+characters -- spaces, tabs and newline characters. Since by default,
+@code{xargs} assumes that the list of files it is reading uses white
+space as an argument separator, it cannot correctly handle the case
+where a filename actually includes white space. This makes the
+default behaviour of @code{xargs} almost useless for handling
+arbitrary data.
+
+To solve this problem, GNU findutils introduced the @samp{-print0}
+action for @code{find}. This uses the ASCII NUL character to separate
+the entries in the file list that it produces. This is the ideal
+choice of separator since it is the only character that cannot appear
+within a path name. The @samp{-0} option to @code{xargs} makes it
+assume that arguments are separated with ASCII NUL instead of white
+space. It also turns off another misfeature in the default behaviour
+of @code{xargs}, which is that it pays attention to quote characters
+in its input. Some versions of @code{xargs} also terminate when they
+see a lone @samp{_} in the input, but GNU @code{find} no longer does
+that (since it has become an optional behaviour in the Unix standard).
+
+So, putting @code{find -print0} together with @code{xargs -0} we get
+this command:
+
+@smallexample
+find /var/tmp/stuff -mtime +90 -print0 | xargs -0 /bin/rm
+@end smallexample
+
+The result is an efficient way of proceeding that
+correctly handles all the possible characters that could appear in the
+list of files to delete. This is good news. However, there is, as
+I'm sure you're expecting, also more bad news. The problem is that
+this is not a portable construct; although other versions of Unix
+(notably BSD-derived ones) support @samp{-print0}, it's not
+universal. So, is there a more universal mechanism?
+
+@subsection Going back to @code{-exec}
+
+There is indeed a more universal mechanism, which is a slight
+modification to the @samp{-exec} action. The normal @samp{-exec}
+action assumes that the command to run is terminated with a semicolon
+(the semicolon normally has to be quoted in order to protect it from
+interpretation as the shell command separator). The SVR4 edition of
+Unix introduced a slight variation, which involves terminating the
+command with @samp{+} instead:
+
+@smallexample
+find /var/tmp/stuff -mtime +90 -exec /bin/rm @{@} \+
+@end smallexample
+
+The above use of @samp{-exec} causes @code{find} to build up a long
+command line and then issue it. This can be less efficient than some
+uses of @code{xargs}; for example @code{xargs} allows new command
+lines to be built up while the previous command is still executing, and
+allows you to specify a number of commands to run in parallel.
+However, the @code{find @dots{} -exec @dots{} +} construct has the advantage
+of wide portability. GNU findutils did not support @samp{-exec @dots{} +}
+until version 4.2.12; one of the reasons for this is that it already
+had the @samp{-print0} action in any case.
+
+
+@subsection A more secure version of @code{-exec}
+
+The command above seems to be efficient and portable. However,
+within it lurks a security problem. The problem is shared with
+all the commands we've tried in this worked example so far, too. The
+security problem is a race condition; that is, if it is possible for
+somebody to manipulate the filesystem that you are searching while you
+are searching it, it is possible for them to persuade your @code{find}
+command to cause the deletion of a file that you can delete but they
+normally cannot.
+
+The problem occurs because the @samp{-exec} action is defined by the
+POSIX standard to invoke its command with the same working directory
+as @code{find} had when it was started. This means that the arguments
+which replace the @{@} include a relative path from @code{find}'s
+starting point down the file that needs to be deleted. For example,
+
+@smallexample
+find /var/tmp/stuff -mtime +90 -exec /bin/rm @{@} \+
+@end smallexample
+
+might actually issue the command:
+
+@smallexample
+/bin/rm /var/tmp/stuff/A /var/tmp/stuff/B /var/tmp/stuff/passwd
+@end smallexample
+
+Notice the file @file{/var/tmp/stuff/passwd}. Likewise, the command:
+
+@smallexample
+cd /var/tmp && find stuff -mtime +90 -exec /bin/rm @{@} \+
+@end smallexample
+
+might actually issue the command:
+
+@smallexample
+/bin/rm stuff/A stuff/B stuff/passwd
+@end smallexample
+
+If an attacker can rename @file{stuff} to something else (making use
+of their write permissions in @file{/var/tmp}) they can replace it
+with a symbolic link to @file{/etc}. That means that the
+@code{/bin/rm} command will be invoked on @file{/etc/passwd}. If you
+are running your @code{find} command as root, the attacker has just managed
+to delete a vital file. All they needed to do to achieve this was
+replace a subdirectory with a symbolic link at the vital moment.
+
+There is however, a simple solution to the problem. This is an action
+which works a lot like @code{-exec} but doesn't need to traverse a
+chain of directories to reach the file that it needs to work on. This
+is the @samp{-execdir} action, which was introduced by the BSD family
+of operating systems. The command,
+
+@smallexample
+find /var/tmp/stuff -mtime +90 -execdir /bin/rm @{@} \+
+@end smallexample
+
+might delete a set of files by performing these actions:
+
+@enumerate
+@item
+Change directory to /var/tmp/stuff/foo
+@item
+Invoke @code{/bin/rm ./file1 ./file2 ./file3}
+@item
+Change directory to /var/tmp/stuff/bar
+@item
+Invoke @code{/bin/rm ./file99 ./file100 ./file101}
+@end enumerate
+
+This is a much more secure method. We are no longer exposed to a race
+condition. For many typical uses of @code{find}, this is the best
+strategy. It's reasonably efficient, but the length of the command
+line is limited not just by the operating system limits, but also by
+how many files we actually need to delete from each directory.
+
+Is it possible to do any better? In the case of general file
+processing, no. However, in the specific case of deleting files it is
+indeed possible to do better.
+
+@subsection Using the @code{-delete} action
+
+The most efficient and secure method of solving this problem is to use
+the @samp{-delete} action:
+
+@smallexample
+find /var/tmp/stuff -mtime +90 -delete
+@end smallexample
+
+This alternative is more efficient than any of the @samp{-exec} or
+@samp{-execdir} actions, since it entirely avoids the overhead of
+forking a new process and using @code{exec} to run @code{/bin/rm}. It
+is also normally more efficient than @code{xargs} for the same
+reason. The file deletion is performed from the directory containing
+the entry to be deleted, so the @samp{-delete} action has the same
+security advantages as the @samp{-execdir} action has.
+
+The @samp{-delete} action was introduced by the BSD family of
+operating systems.
+
+@subsection Improving things still further
+
+Is it possible to improve things still further? Not without either
+modifying the system library to the operating system or having more specific
+knowledge of the layout of the filesystem and disk I/O subsystem, or
+both.
+
+The @code{find} command traverses the filesystem, reading
+directories. It then issues a separate system call for each file to
+be deleted. If we could modify the operating system, there are
+potential gains that could be made:
+
+@itemize
+@item
+We could have a system call to which we pass more than one filename
+for deletion
+@item
+Alternatively, we could pass in a list of inode numbers (on GNU/Linux
+systems, @code{readdir()} also returns the inode number of each
+directory entry) to be deleted.
+@end itemize
+
+The above possibilities sound interesting, but from the kernel's point
+of view it is difficult to enforce standard Unix access controls for
+such processing by inode number. Such a facility would probably
+need to be restricted to the superuser.
+
+Another way of improving performance would be to increase the
+parallelism of the process. For example if the directory hierarchy we
+are searching is actually spread across a number of disks, we might
+somehow be able to arrange for @code{find} to process each disk in
+parallel. In practice GNU @code{find} doesn't have such an intimate
+understanding of the system's filesystem layout and disk I/O
+subsystem.
+
+However, since the system administrator can have such an understanding
+they can take advantage of it like so:
+
+@smallexample
+find /var/tmp/stuff1 -mtime +90 -delete &
+find /var/tmp/stuff2 -mtime +90 -delete &
+find /var/tmp/stuff3 -mtime +90 -delete &
+find /var/tmp/stuff4 -mtime +90 -delete &
+wait
+@end smallexample
+
+In the example above, four separate instances of @code{find} are used
+to search four subdirectories in parallel. The @code{wait} command
+simply waits for all of these to complete. Whether this approach is
+more or less efficient than a single instance of @code{find} depends
+on a number of things:
+
+@itemize
+@item
+Are the directories being searched in parallel actually on separate
+disks? If not, this parallel search might just result in a lot of
+disk head movement and so the speed might even be slower.
+@item
+Other activity - are other programs also doing things on those disks?
+@end itemize
+
+
+@subsection Conclusion
+
+The fastest and most secure way to delete files with the help of
+@code{find} is to use @samp{-delete}. Using @code{xargs -0 -P N} can
+also make effective use of the disk, but it is not as secure.
+
+In the case where we're doing things other than deleting files, the
+most secure alternative is @samp{-execdir @dots{} +}, but this is not as
+portable as the insecure action @samp{-exec @dots{} +}.
+
+The @samp{-delete} action is not completely portable, but the only
+other possibility which is as secure (@samp{-execdir}) is no more
+portable. The most efficient portable alternative is @samp{-exec
+@dots{}+}, but this is insecure and isn't supported by versions of GNU
+findutils prior to 4.2.12.
+
+@node Copying A Subset of Files
+@section Copying A Subset of Files
+
+Suppose you want to copy some files from @file{/source-dir} to
+@file{/dest-dir}, but there are a small number of files in
+@file{/source-dir} you don't want to copy.
+
+One option of course is @code{cp /source-dir /dest-dir} followed by
+deletion of the unwanted material under @file{/dest-dir}. But often
+that can be inconvenient, because for example we would have copied a
+large amount of extraneous material, or because @file{/dest-dir} is
+too small. Naturally there are many other possible reasons why this
+strategy may be unsuitable.
+
+So we need to have some way of identifying which files we want to
+copy, and we need to have a way of copying that file list. The second
+part of this condition is met by @code{cpio -p}. Of course, we can
+identify the files we wish to copy by using @code{find}. Here is a
+command that solves our problem:
+
+@example
+cd /source-dir
+find . -name '.snapshot' -prune -o \( \! -name '*~' -print0 \) |
+cpio -pmd0 /dest-dir
+@end example
+
+The first part of the @code{find} command here identifies files or
+directories named @file{.snapshot} and tells @code{find} not to
+recurse into them (since they do not need to be copied). The
+combination @code{-name '.snapshot' -prune} yields false for anything
+that didn't get pruned, but it is exactly those files we want to
+copy. Therefore we need to use an OR (@samp{-o}) condition to
+introduce the rest of our expression. The remainder of the expression
+simply arranges for the name of any file not ending in @samp{~} to be
+printed.
+
+Using @code{-print0} ensures that white space characters in file names
+do not pose a problem. The @code{cpio} command does the actual work
+of copying files. The program as a whole fails if the @code{cpio}
+program returns nonzero. If the @code{find} command returns non-zero
+on the other hand, the Unix shell will not diagnose a problem (since
+@code{find} is not the last command in the pipeline).
+
+
+@node Updating A Timestamp File
+@section Updating A Timestamp File
+
+Suppose we have a directory full of files which is maintained with a
+set of automated tools; perhaps one set of tools updates them and
+another set of tools uses the result. In this situation, it might be
+useful for the second set of tools to know if the files have recently
+been changed. It might be useful, for example, to have a 'timestamp'
+file which gives the timestamp on the newest file in the collection.
+
+We can use @code{find} to achieve this, but there are several
+different ways to do it.
+
+@subsection Updating the Timestamp The Wrong Way
+
+The obvious but wrong answer is just to use @samp{-newer}:
+
+@smallexample
+find subdir -newer timestamp -exec touch -r @{@} timestamp \;
+@end smallexample
+
+This does the right sort of thing but has a bug. Suppose that two
+files in the subdirectory have been updated, and that these are called
+@file{file1} and @file{file2}. The command above will update
+@file{timestamp} with the modification time of @file{file1} or that of
+@file{file2}, but we don't know which one. Since the timestamps on
+@file{file1} and @file{file2} will in general be different, this could
+well be the wrong value.
+
+One solution to this problem is to modify @code{find} to recheck the
+modification time of @file{timestamp} every time a file is to be
+compared against it, but that will reduce the performance of
+@code{find}.
+
+@subsection Using the test utility to compare timestamps
+
+The @code{test} command can be used to compare timestamps:
+
+@smallexample
+find subdir -exec test @{@} -nt timestamp \; -exec touch -r @{@} timestamp \;
+@end smallexample
+
+This will ensure that any changes made to the modification time of
+@file{timestamp} that take place during the execution of @code{find}
+are taken into account. This resolves our earlier problem, but
+unfortunately this runs much more slowly.
+
+@subsection A combined approach
+
+We can of course still use @samp{-newer} to cut down on the number of
+calls to @code{test}:
+
+@smallexample
+find subdir -newer timestamp -and \
+ -exec test @{@} -nt timestamp \; -and \
+ -exec touch -r @{@} timestamp \;
+@end smallexample
+
+Here, the @samp{-newer} test excludes all the files which are
+definitely older than the timestamp, but all the files which are newer
+than the old value of the timestamp are compared against the current
+updated timestamp.
+
+This is indeed faster in general, but the speed difference will depend
+on how many updated files there are.
+
+@subsection Using @code{-printf} and @code{sort} to compare timestamps
+
+It is possible to use the @samp{-printf} action to abandon the use of
+@code{test} entirely:
+
+@smallexample
+newest=$(find subdir -newer timestamp -printf "%A@:%p\n" |
+ sort -n |
+ tail -1 |
+ cut -d: -f2- )
+touch -r "$@{newest:-timestamp@}" timestamp
+@end smallexample
+
+The command above works by generating a list of the timestamps and
+names of all the files which are newer than the timestamp. The
+@code{sort}, @code{tail} and @code{cut} commands simply pull out the
+name of the file with the largest timestamp value (that is, the latest
+file). The @code{touch} command is then used to update the timestamp,
+
+The @code{"$@{newest:-timestamp@}"} expression simply expands to the
+value of @code{$newest} if that variable is set, but to
+@file{timestamp} otherwise. This ensures that an argument is always
+given to the @samp{-r} option of the @code{touch} command.
+
+This approach seems quite efficient, but unfortunately it has a
+problem. Many operating systems now keep file modification time
+information at a granularity which is finer than one second.
+Findutils version 4.3.3 and later will print a fractional part with
+%A@@, but older versions will not.
+
+
+@subsection Solving the problem with @code{make}
+
+Another tool which often works with timestamps is @code{make}. We can
+use @code{find} to generate a @file{Makefile} file on the fly and then
+use @code{make} to update the timestamps:
+
+@smallexample
+makefile=$(mktemp)
+find subdir \
+ \( \! -xtype l \) \
+ -newer timestamp \
+ -printf "timestamp:: %p\n\ttouch -r %p timestamp\n\n" > "$makefile"
+make -f "$makefile"
+rm -f "$makefile"
+@end smallexample
+
+Unfortunately although the solution above is quite elegant, it fails
+to cope with white space within file names, and adjusting it to do so
+would require a rather complex shell script.
+
+
+@subsection Coping with odd filenames too
+
+We can fix both of these problems (looping and problems with white
+space), and do things more efficiently too. The following command
+works with newlines and doesn't need to sort the list of filenames.
+
+@smallexample
+find subdir -newer timestamp -printf "%A@@:%p\0" |
+ perl -0 newest.pl |
+ xargs --no-run-if-empty --null -i \
+ find @{@} -maxdepth 0 -newer timestamp -exec touch -r @{@} timestamp \;
+@end smallexample
+
+The first @code{find} command generates a list of files which are
+newer than the original timestamp file, and prints a list of them with
+their timestamps. The @file{newest.pl} script simply filters out all
+the filenames which have timestamps which are older than whatever the
+newest file is:
+
+@smallexample
+@verbatim
+#! /usr/bin/perl -0
+my @newest = ();
+my $latest_stamp = undef;
+while (<>) {
+ my ($stamp, $name) = split(/:/);
+ if (!defined($latest_stamp) || ($tstamp > $latest_stamp)) {
+ $latest_stamp = $stamp;
+ @newest = ();
+ }
+ if ($tstamp >= $latest_stamp) {
+ push @newest, $name;
+ }
+}
+print join("\0", @newest);
+@end verbatim
+@end smallexample
+
+This prints a list of zero or more files, all of which are newer than
+the original timestamp file, and which have the same timestamp as each
+other, to the nearest second. The second @code{find} command takes
+each resulting file one at a time, and if that is newer than the
+timestamp file, the timestamp is updated.
+
+@node Finding the Shallowest Instance
+@section Finding the Shallowest Instance
+
+Suppose you maintain local copies of sources from various projects,
+each with their own choice of directory organisation and source code
+management (SCM) tool. You need to periodically synchronize each
+project with its upstream tree. As the number local repositories
+grows, so does the work involved in maintaining synchronization. SCM
+utilities typically create some sort of administrative directory: .svn
+for Subversion, CVS for CVS, and so on. These directories can be used
+as a key to search for the bases of the project source trees. Suppose
+we have the following directory structure:
+
+@smallexample
+repo/project1/CVS
+repo/gnu/project2/.svn
+repo/gnu/project3/.svn
+repo/gnu/project3/src/.svn
+repo/gnu/project3/doc/.svn
+repo/project4/.git
+@end smallexample
+
+One would expect to update each of the @file{projectX} directories,
+but not their subdirectories (src, doc, etc.). To locate the project
+roots, we would need to find the least deeply nested directories
+containing an SCM-related subdirectory. The following command
+discovers those roots efficiently. It is efficient because it avoids
+searching subdirectories inside projects whose SCM directory we
+already found.
+
+@smallexample
+find repo/ \
+-exec test -d @{@}/.svn \; -or \
+-exec test -d @{@}/.git \; -or \
+-exec test -d @{@}/CVS \; -print -prune
+@end smallexample
+
+In this example, @command{test} is used to tell if we are currently
+examining a directory which appears to the a project's root directory
+(because it has an SCM subdirectory). When we find a project root,
+there is no need to search inside it, and @code{-prune} makes sure
+that we descend no further.
+
+For large, complex trees like the Linux kernel, this will prevent
+searching a large portion of the structure, saving a good deal of
+time.
+
+
+@node Security Considerations
+@chapter Security Considerations
+
+Security considerations are important if you are using @code{find} or
+@code{xargs} to search for or process files that don't belong to you
+or which other people have control. Security considerations
+relating to @code{locate} may also apply if you have files which you
+do not want others to see.
+
+The most severe forms of security problems affecting
+@code{find} and related programs are when third parties bring
+about a situation allowing them to do something
+they would normally not be able to accomplish. This is called @emph{privilege
+elevation}. This might include deleting files they would not normally
+be able to delete. It is common for the operating system to periodically
+invoke @code{find} for self-maintenance purposes. These invocations of
+@code{find} are particularly problematic from a security point of view
+as these are often invoked by the superuser and search the entire
+filesystem hierarchy. Generally, the severity of any associated problem depends
+on what the system is going to do with the files found by @code{find}.
+
+@menu
+* Levels of Risk:: What is your level of exposure to security problems?
+* Security Considerations for find:: Security problems with find
+* Security Considerations for xargs:: Security problems with xargs
+* Security Considerations for locate:: Security problems with locate
+* Security Summary:: That was all very complex, what does it boil down to?
+* Further Reading on Security::
+@end menu
+
+
+@node Levels of Risk
+@section Levels of Risk
+
+There are some security risks inherent in the use of @code{find},
+@code{xargs} and (to a lesser extent) @code{locate}. The severity of
+these risks depends on what sort of system you are using:
+
+@table @strong
+@item High risk
+Multi-user systems where you do not control (or trust) the other
+users, and on which you execute @code{find}, including areas where
+those other users can manipulate the filesystem (for example beneath
+@file{/home} or @file{/tmp}).
+
+@item Medium Risk
+Systems where the actions of other users can create file names chosen
+by them, but to which they don't have access while @code{find} is
+being run. This access might include leaving programs running (shell
+background jobs, @code{at} or @code{cron} tasks, for example). On
+these sorts of systems, carefully written commands (avoiding use of
+@samp{-print} for example) should not expose you to a high degree of
+risk. Most systems fall into this category.
+
+@item Low Risk
+Systems to which untrusted parties do not have access, cannot create
+file names of their own choice (even remotely) and which contain no
+security flaws which might enable an untrusted third party to gain
+access. Most systems do not fall into this category because there are
+many ways in which external parties can affect the names of files that
+are created on your system. The system on which I am writing this for
+example automatically downloads software updates from the Internet;
+the names of the files in which these updates exist are chosen by
+third parties@footnote{Of course, I trust these parties to a large
+extent anyway, because I install software provided by them; I choose
+to trust them in this way, and that's a deliberate choice}.
+@end table
+
+In the discussion above, ``risk'' denotes the likelihood that someone
+can cause @code{find}, @code{xargs}, @code{locate} or some other
+program which is controlled by them to do something you did not
+intend. The levels of risk suggested do not take any account of the
+consequences of this sort of event. That is, if you operate a ``low
+risk'' type system, but the consequences of a security problem are
+disastrous, then you should still give serious thought to all the
+possible security problems, many of which of course will not be
+discussed here -- this section of the manual is intended to be
+informative but not comprehensive or exhaustive.
+
+If you are responsible for the operation of a system where the
+consequences of a security problem could be very important, you should
+do two things:
+
+@enumerate
+@item Define a security policy which defines who is allowed to do what
+on your system.
+@item Seek competent advice on how to enforce your policy, detect
+breaches of that policy, and take account of any potential problems
+that might fall outside the scope of your policy.
+@end enumerate
+
+
+@node Security Considerations for find
+@section Security Considerations for @code{find}
+
+
+Some of the actions @code{find} might take have a direct effect;
+these include @code{-exec} and @code{-delete}. However, it is also
+common to use @code{-print} explicitly or implicitly, and so if
+@code{find} produces the wrong list of file names, that can also be a
+security problem; consider the case for example where @code{find} is
+producing a list of files to be deleted.
+
+We normally assume that the @code{find} command line expresses the
+file selection criteria and actions that the user had in mind -- that
+is, the command line is ``trusted'' data.
+
+From a security analysis point of view, the output of @code{find}
+should be correct; that is, the output should contain only the names
+of those files which meet the user's criteria specified on the command
+line. This applies for the @code{-exec} and @code{-delete} actions;
+one can consider these to be part of the output.
+
+On the other hand, the contents of the filesystem can be manipulated
+by other people, and hence we regard this as ``untrusted'' data. This
+implies that the @code{find} command line is a filter which converts
+the untrusted contents of the filesystem into a correct list of output
+files.
+
+The filesystem will in general change while @code{find} is searching
+it; in fact, most of the potential security problems with @code{find}
+relate to this issue in some way.
+
+@dfn{Race conditions} are a general class of security problem where the
+relative ordering of actions taken by @code{find} (for example) and
+something else are critically important in getting the correct and expected result@footnote{This is more or less the
+definition of the term ``race condition''} .
+
+For @code{find}, an attacker might move or rename files or directories in
+the hope that an action might be taken against a file which was not
+normally intended to be affected. Alternatively, this sort of attack
+might be intended to persuade @code{find} to search part of the
+filesystem which would not normally be included in the search
+(defeating the @code{-prune} action for example).
+
+@menu
+* Problems with -exec and filenames::
+* Changing the Current Working Directory::
+* Race Conditions with -exec::
+* Race Conditions with -print and -print0::
+@end menu
+
+@node Problems with -exec and filenames
+@subsection Problems with @code{-exec} and filenames
+
+It is safe in many cases to use the @samp{-execdir} action with any
+file name. Because @samp{-execdir} prefixes the arguments it passes
+to programs with @samp{./}, you will not accidentally pass an argument
+which is interpreted as an option. For example the file @file{-f}
+would be passed to @code{rm} as @file{./-f}, which is harmless.
+
+However, your degree of safety does depend on the nature of the
+program you are running. For example constructs such as these two commands
+
+@example
+# risky
+find -exec sh -c "something @{@}" \;
+find -execdir sh -c "something @{@}" \;
+@end example
+
+are very dangerous. The reason for this is that the @samp{@{@}} is
+expanded to a filename which might contain a semicolon or other
+characters special to the shell. If for example someone creates the
+file @file{/tmp/foo; rm -rf $HOME} then the two commands above could
+delete someone's home directory.
+
+So for this reason do not run any command which will pass untrusted
+data (such as the names of files) to commands which interpret
+arguments as commands to be further interpreted (for example
+@samp{sh}).
+
+In the case of the shell, there is a clever workaround for this
+problem:
+
+@example
+# safer
+find -exec sh -c 'something "$@@"' sh @{@} \;
+find -execdir sh -c 'something "$@@"' sh @{@} \;
+@end example
+
+This approach is not guaranteed to avoid every problem, but it is much
+safer than substituting data of an attacker's choice into the text of
+a shell command.
+
+@node Changing the Current Working Directory
+@subsection Changing the Current Working Directory
+
+As @code{find} searches the filesystem, it finds subdirectories and
+then searches within them by changing its working directory. First,
+@code{find} reaches and recognises a subdirectory. It then decides if that
+subdirectory meets the criteria for being searched; that is, any
+@samp{-xdev} or @samp{-prune} expressions are taken into account. The
+@code{find} program will then change working directory and proceed to
+search the directory.
+
+A race condition attack might take the form that once the checks
+relevant to @samp{-xdev} and @samp{-prune} have been done, an attacker
+might rename the directory that was being considered, and put in its
+place a symbolic link that actually points somewhere else.
+
+The idea behind this attack is to fool @code{find} into going into the
+wrong directory. This would leave @code{find} with a working
+directory chosen by an attacker, bypassing any protection apparently
+provided by @samp{-xdev} and @samp{-prune}, and any protection
+provided by being able to @emph{not} list particular directories on
+the @code{find} command line. This form of attack is particularly
+problematic if the attacker can predict when the @code{find} command
+will be run, as is the case with @code{cron} tasks for example.
+
+GNU @code{find} has specific safeguards to prevent this general class
+of problem. The exact form of these safeguards depends on the
+properties of your system.
+
+@menu
+* O_NOFOLLOW:: Safely changing directory using @code{fchdir}.
+* Systems without O_NOFOLLOW:: Checking for symbolic links after @code{chdir}.
+@end menu
+
+@node O_NOFOLLOW
+@subsubsection @code{O_NOFOLLOW}
+
+If your system supports the @code{O_NOFOLLOW} flag @footnote{GNU/Linux
+(kernel version 2.1.126 and later) and FreeBSD (3.0-CURRENT and later)
+support this} to the @code{open(2)} system call, @code{find} uses it
+to safely change directories. The target directory is first opened
+and then @code{find} changes working directory with the
+@code{fchdir()} system call. This ensures that symbolic links are not
+followed, preventing the sort of race condition attack in which use
+is made of symbolic links.
+
+If for any reason this approach does not work, @code{find} will fall
+back on the method which is normally used if @code{O_NOFOLLOW} is not
+supported.
+
+You can tell if your system supports @code{O_NOFOLLOW} by running
+
+@example
+find --version
+@end example
+
+This will tell you the version number and which features are enabled.
+For example, if I run this on my system now, this gives:
+@example
+find (GNU findutils) 4.5.11-git
+Copyright (C) 2012 Free Software Foundation, Inc.
+License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
+This is free software: you are free to change and redistribute it.
+There is NO WARRANTY, to the extent permitted by law.
+
+Written by Eric B. Decker, James Youngman, and Kevin Dalley.
+Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION FTS(FTS_CWDFD) CBO(level=2)
+@end example
+
+Here, you can see that I am running a version of @code{find} which was
+built from the development (git) code prior to the release of
+findutils-4.5.12, and that several features including @code{O_NOFOLLOW} are
+present. @code{O_NOFOLLOW} is qualified with ``enabled''. This simply means
+that the current system seems to support @code{O_NOFOLLOW}. This check is
+needed because it is possible to build @code{find} on a system that
+defines @code{O_NOFOLLOW} and then run it on a system that ignores the
+@code{O_NOFOLLOW} flag. We try to detect such cases at startup by checking
+the operating system and version number; when this happens you will
+see @samp{O_NOFOLLOW(disabled)} instead.
+
+@node Systems without O_NOFOLLOW
+@subsubsection Systems without @code{O_NOFOLLOW}
+
+The strategy for preventing this type of problem on systems that lack
+support for the @code{O_NOFOLLOW} flag is more complex. Each time
+@code{find} changes directory, it examines the directory it is about
+to move to, issues the @code{chdir()} system call, and then checks
+that it has ended up in the subdirectory it expected. If all is as
+expected, processing continues as normal. However, there are two main
+reasons why the directory might change: the use of an automounter and
+the someone removing the old directory and replacing it with something
+else while @code{find} is trying to descend into it.
+
+Where a filesystem ``automounter'' is in use it can be the case that
+the use of the @code{chdir()} system call can itself cause a new
+filesystem to be mounted at that point. On systems that do not
+support @code{O_NOFOLLOW}, this will cause @code{find}'s security check to
+fail.
+
+However, this does not normally represent a security problem, since
+the automounter configuration is normally set up by the system
+administrator. Therefore, if the @code{chdir()} sanity check fails,
+@code{find} will make one more attempt@footnote{This may not be the
+case for the fts-based executable}. If that succeeds, execution
+carries on as normal. This is the usual case for automounters.
+
+Where an attacker is trying to exploit a race condition, the problem
+may not have gone away on the second attempt. If this is the case,
+@code{find} will issue a warning message and then ignore that
+subdirectory. When this happens, actions such as @samp{-exec} or
+@samp{-print} may already have taken place for the problematic
+subdirectory. This is because @code{find} applies tests and actions
+to directories before searching within them (unless @samp{-depth} was
+specified).
+
+Because of the nature of the directory-change operation and security
+check, in the worst case the only things that @code{find} would have
+done with the directory are to move into it and back out to the
+original parent. No operations would have been performed within that
+directory.
+
+@node Race Conditions with -exec
+@subsection Race Conditions with @code{-exec}
+
+The @samp{-exec} action causes another program to be run. It passes
+to the program the name of the file which is being considered at the
+time. The invoked program will typically then perform some action
+on that file. Once again, there is a race condition which can be
+exploited here. We shall take as a specific example the command
+
+@example
+find /tmp -path /tmp/umsp/passwd -exec /bin/rm
+@end example
+
+In this simple example, we are identifying just one file to be deleted
+and invoking @code{/bin/rm} to delete it. A problem exists because
+there is a time gap between the point where @code{find} decides that
+it needs to process the @samp{-exec} action and the point where the
+@code{/bin/rm} command actually issues the @code{unlink()} system
+call to delete the file from the filesystem. Within this time period, an attacker can rename the
+@file{/tmp/umsp} directory, replacing it with a symbolic link to
+@file{/etc}. There is no way for @code{/bin/rm} to determine that it
+is working on the same file that @code{find} had in mind. Once the
+symbolic link is in place, the attacker has persuaded @code{find} to
+cause the deletion of the @file{/etc/passwd} file, which is not the
+effect intended by the command which was actually invoked.
+
+One possible defence against this type of attack is to modify the
+behaviour of @samp{-exec} so that the @code{/bin/rm} command is run
+with the argument @file{./passwd} and a suitable choice of working
+directory. This would allow the normal sanity check that @code{find}
+performs to protect against this form of attack too. Unfortunately,
+this strategy cannot be used as the POSIX standard specifies that the
+current working directory for commands invoked with @samp{-exec} must
+be the same as the current working directory from which @code{find}
+was invoked. This means that the @samp{-exec} action is inherently
+insecure and can't be fixed.
+
+GNU @code{find} implements a more secure variant of the @samp{-exec}
+action, @samp{-execdir}. The @samp{-execdir} action
+ensures that it is not necessary to dereference subdirectories to
+process target files. The current directory used to invoke programs
+is the same as the directory in which the file to be processed exists
+(@file{/tmp/umsp} in our example, and only the basename of the file to
+be processed is passed to the invoked command, with a @samp{./}
+prepended (giving @file{./passwd} in our example).
+
+The @samp{-execdir} action refuses to do anything if the current
+directory is included in the @var{$PATH} environment variable. This
+is necessary because @samp{-execdir} runs programs in the same
+directory in which it finds files -- in general, such a directory
+might be writable by untrusted users. For similar reasons,
+@samp{-execdir} does not allow @samp{@{@}} to appear in the name of
+the command to be run.
+
+@node Race Conditions with -print and -print0
+@subsection Race Conditions with @code{-print} and @code{-print0}
+
+The @samp{-print} and @samp{-print0} actions can be used to produce a
+list of files matching some criteria, which can then be used with some
+other command, perhaps with @code{xargs}. Unfortunately, this means
+that there is an unavoidable time gap between @code{find} deciding
+that one or more files meet its criteria and the relevant command
+being executed. For this reason, the @samp{-print} and @samp{-print0}
+actions are just as insecure as @samp{-exec}.
+
+In fact, since the construction
+
+@example
+find @dots{} -print | xargs @enddots{}
+@end example
+
+does not cope correctly with newlines or other ``white space'' in
+file names, and copes poorly with file names containing quotes, the
+@samp{-print} action is less secure even than @samp{-print0}.
+
+
+@comment node-name, next, previous, up
+@comment @node Security Considerations for xargs
+@node Security Considerations for xargs
+@section Security Considerations for @code{xargs}
+
+The description of the race conditions affecting the @samp{-print}
+action of @code{find} shows that @code{xargs} cannot be secure if it
+is possible for an attacker to modify a filesystem after @code{find}
+has started but before @code{xargs} has completed all its actions.
+
+However, there are other security issues that exist even if it is not
+possible for an attacker to have access to the filesystem in real
+time. Firstly, if it is possible for an attacker to create files with
+names of their choice on the filesystem, then @code{xargs} is
+insecure unless the @samp{-0} option is used. If a file with the name
+@file{/home/someuser/foo/bar\n/etc/passwd} exists (assume that
+@samp{\n} stands for a newline character), then @code{find @dots{} -print}
+can be persuaded to print three separate lines:
+
+@example
+/home/someuser/foo/bar
+
+/etc/passwd
+@end example
+
+If it finds a blank line in the input, @code{xargs} will ignore it.
+Therefore, if some action is to be taken on the basis of this list of
+files, the @file{/etc/passwd} file would be included even if this was
+not the intent of the person running find. There are circumstances in
+which an attacker can use this to their advantage. The same
+consideration applies to file names containing ordinary spaces rather
+than newlines, except that of course the list of file names will no
+longer contain an ``extra'' newline.
+
+This problem is an unavoidable consequence of the default behaviour of
+the @code{xargs} command, which is specified by the POSIX standard.
+The only ways to avoid this problem are either to avoid all use of
+@code{xargs} in favour for example of @samp{find -exec} or (where
+available) @samp{find -execdir}, or to use the @samp{-0} option, which
+ensures that @code{xargs} considers file names to be separated by
+ASCII NUL characters rather than whitespace. However, useful as this
+option is, the POSIX standard does not make it mandatory.
+
+POSIX also specifies that @code{xargs} interprets quoting and trailing
+whitespace specially in filenames, too. This means that using
+@code{find ... -print | xargs ...} can cause the commands run by
+@code{xargs} to receive a list of file names which is not the same as
+the list printed by @code{find}. The interpretation of quotes and
+trailing whitespace is turned off by the @samp{-0} argument to
+@code{xargs}, which is another reason to use that option.
+
+@comment node-name, next, previous, up
+@node Security Considerations for locate
+@section Security Considerations for @code{locate}
+
+@subsection Race Conditions
+It is fairly unusual for the output of @code{locate} to be fed into
+another command. However, if this were to be done, this would raise
+the same set of security issues as the use of @samp{find @dots{} -print}.
+Although the problems relating to whitespace in file names can be
+resolved by using @code{locate}'s @samp{-0} option, this still leaves
+the race condition problems associated with @samp{find @dots{} -print0}.
+There is no way to avoid these problems in the case of @code{locate}.
+
+@subsection Long File Name Bugs with Old-Format Databases
+Old versions of @code{locate} have a bug in the way that old-format
+databases are read. This bug affects the following versions of
+@code{locate}:
+
+@enumerate
+@item All releases prior to 4.2.31
+@item All 4.3.x releases prior to 4.3.7
+@end enumerate
+
+The affected versions of @code{locate} read file names into a
+fixed-length 1026 byte buffer, allocated on the heap. This buffer is
+not extended if file names are too long to fit into the buffer. No
+range checking on the length of the filename is performed. This could
+in theory lead to a privilege escalation attack. Findutils versions
+4.3.0 to 4.3.6 are also affected.
+
+On systems using the old database format and affected versions of
+@code{locate}, carefully-chosen long file names could in theory allow
+malicious users to run code of their choice as any user invoking
+locate.
+
+If remote users can choose the names of files stored on your system,
+and these files are indexed by @code{updatedb}, this may be a remote
+security vulnerability. Findutils version 4.2.31 and findutils
+version 4.3.7 include fixes for this problem. The @code{updatedb},
+@code{bigram} and @code{code} programs do no appear to be affected.
+
+If you are also using GNU coreutils, you can use the following command
+to determine the length of the longest file name on a given system:
+
+@example
+find / -print0 | tr -c '\0' 'x' | tr '\0' '\n' | wc -L
+@end example
+
+Although this problem is significant, the old database format is not
+the default, and use of the old database format is not common. Most
+installations and most users will not be affected by this problem.
+
+
+
+@node Security Summary
+@section Summary
+
+Where untrusted parties can create files on the system, or affect the
+names of files that are created, all uses for @code{find},
+@code{locate} and @code{xargs} have known security problems except the
+following:
+
+@table @asis
+@item Informational use only
+Uses where the programs are used to prepare lists of file names upon
+which no further action will ever be taken.
+
+@item @samp{-delete}
+Use of the @samp{-delete} action with @code{find} to delete files
+which meet specified criteria
+
+@item @samp{-execdir}
+Use of the @samp{-execdir} action with @code{find} where the
+@env{PATH} environment variable contains directories which contain
+only trusted programs.
+@end table
+
+
+@node Further Reading on Security
+@section Further Reading on Security
+
+While there are a number of books on computer security, there are also
+useful articles on the web that touch on the issues described above:
+
+@table @url
+@item http://goo.gl/DAvh
+@c https://www.securecoding.cert.org/confluence/display/seccode/MSC09-C.+Character+Encoding+-+Use+Subset+of+ASCII+for+Safety
+This article describes some of the unfortunate effects of allowing
+free choice of file names.
+@item http://cwe.mitre.org/data/definitions/78.html
+Describes OS Command Injection
+@item https://cwe.mitre.org/data/definitions/73.html
+Describes problems arising from allowing remote computers to send
+requests which specify file names of their choice
+@item http://cwe.mitre.org/data/definitions/116.html
+Describes problems relating to encoding file names and escaping
+characters. This article is relevant to findutils because for command
+lines processed via the shell, the encoding and escaping rules are
+already set by the shell. For example command lines like @code{find
+... -print | some-shell-script} require specific care.
+@item http://xkcd.com/327/
+A humorous and pithy summary of the broader problem.
+@end table
+
+@comment node-name, next, previous, up
+@node Error Messages
+@chapter Error Messages
+
+This section describes some of the error messages sometimes made by
+@code{find}, @code{xargs}, or @code{locate}, explains them and in some
+cases provides advice as to what you should do about this.
+
+This manual is written in English. The GNU findutils software
+features translations of error messages for many languages. For this
+reason the error messages produced by the programs are made to be as
+self-explanatory as possible. This approach avoids leaving people to
+figure out which test an English-language error message corresponds
+to. Error messages which are self-explanatory will not normally be
+mentioned in this document. For those messages mentioned in this
+document, only the English-language version of the message will be
+listed.
+
+@menu
+* Error Messages From find::
+* Error Messages From xargs::
+* Error Messages From locate::
+* Error Messages From updatedb::
+@end menu
+
+@node Error Messages From find
+@section Error Messages From @code{find}
+
+Most error messages produced by find are self-explanatory. Error
+messages sometimes include a filename. When this happens, the
+filename is quoted in order to prevent any unusual characters in the
+filename making unwanted changes in the state of the terminal.
+
+@table @samp
+@item invalid predicate `-foo'
+This means that the @code{find} command line included something that
+started with a dash or other special character. The @code{find}
+program tried to interpret this as a test, action or option, but
+didn't recognise it. If it was intended to be a test, check what was
+specified against the documentation. If, on the other hand, the
+string is the name of a file which has been expanded from a wildcard
+(for example because you have a @samp{*} on the command line),
+consider using @samp{./*} or just @samp{.} instead.
+
+@item unexpected extra predicate
+This usually happens if you have an extra bracket on the command line
+(for example @samp{find . -print \)}).
+
+@item Warning: filesystem /path/foo has recently been mounted
+@itemx Warning: filesystem /path/foo has recently been unmounted
+These messages might appear when @code{find} moves into a directory
+and finds that the device number and inode are different from what it
+expected them to be. If the directory @code{find} has moved into is
+on a network filesystem (NFS), it will not issue this message, because
+@code{automount} frequently mounts new filesystems on directories as
+you move into them (that is how it knows you want to use the
+filesystem). So, if you do see this message, be wary --
+@code{automount} may not have been responsible. Consider the
+possibility that someone else is manipulating the filesystem while
+@code{find} is running. Some people might do this in order to mislead
+@code{find} or persuade it to look at one set of files when it thought
+it was looking at another set.
+
+@item /path/foo changed during execution of find (old device number 12345, new device number 6789, filesystem type is <whatever>) [ref XXX]
+This message is issued when @code{find} moves into a directory and ends up
+somewhere it didn't expect to be. This happens in one of two
+circumstances. Firstly, this happens when @code{automount} intervenes
+on a system where @code{find} doesn't know how to determine what
+the current set of mounted filesystems is.
+
+Secondly, this can happen when the device number of a directory
+appears to change during a change of current directory, but
+@code{find} is moving up the filesystem hierarchy rather than down into it.
+In order to prevent @code{find} wandering off into some unexpected
+part of the filesystem, we stop it at this point.
+
+@item Don't know how to use getmntent() to read `/etc/mtab'. This is a bug.
+This message is issued when a problem similar to the above occurs on a
+system where @code{find} doesn't know how to figure out the current
+list of mount points. Ask for help on @email{bug-findutils@@gnu.org}.
+
+@item /path/foo/bar changed during execution of find (old inode number 12345, new inode number 67893, filesystem type is <whatever>) [ref XXX]"),
+This message is issued when @code{find} moves into a directory and
+discovers that the inode number of that directory
+is different from the inode number that it obtained when it examined the
+directory previously. This usually means that while
+@code{find} was deep in a directory hierarchy doing a
+time consuming operation, somebody has moved one of the parent directories to
+another location in the same filesystem. This may or may not have been done
+maliciously. In any case, @code{find} stops at this point
+to avoid traversing parts of the filesystem that it wasn't
+intended to. You can use @code{ls -li} or @code{find /path -inum
+12345 -o -inum 67893} to find out more about what has happened.
+
+@item sanity check of the fnmatch() library function failed.
+Please submit a bug report. You may well be asked questions about
+your system, and if you compiled the @code{findutils} code yourself,
+you should keep your copy of the build tree around. The likely
+explanation is that your system has a buggy implementation of
+@code{fnmatch} that looks enough like the GNU version to fool
+@code{configure}, but which doesn't work properly.
+
+@item cannot fork
+This normally happens if you use the @code{-exec} action or
+something similar (@code{-ok} and so forth) but the system has run out
+of free process slots. This is either because the system is very busy
+and the system has reached its maximum process limit, or because you
+have a resource limit in place and you've reached it. Check the
+system for runaway processes (with @code{ps}, if possible). Some process
+slots are normally reserved for use by @samp{root}.
+
+@item some-program terminated by signal 99
+Some program which was launched with @code{-exec} or similar was killed
+with a fatal signal. This is just an advisory message.
+@end table
+
+
+@node Error Messages From xargs
+@section Error Messages From @code{xargs}
+
+@table @samp
+@item environment is too large for exec
+This message means that you have so many environment variables set (or
+such large values for them) that there is no room within the
+system-imposed limits on program command line argument length to
+invoke any program. This is an unlikely situation and is more likely
+result of an attempt to test the limits of @code{xargs}, or break it.
+Please try unsetting some environment variables, or exiting the
+current shell. You can also use @samp{xargs --show-limits} to
+understand the relevant sizes.
+
+@item argument list too long
+You are using the @samp{-I} option and @code{xargs} doesn't have
+enough space to build a command line because it has read a really
+large item and it doesn't fit. You may be able to work around this
+problem with the @samp{-s} option, but the default size is pretty
+large. This is a rare situation and is more likely an attempt to test
+the limits of @code{xargs}, or break it. Otherwise, you will need to
+try to shorten the problematic argument or not use @code{xargs}.
+
+@item argument line too long
+You are using the @samp{-L} or @samp{-l} option and one of the input
+lines is too long. You may be able to work around this problem with
+the @samp{-s} option, but the default size is pretty large. If you
+can modify the your @code{xargs} command not to use @samp{-L} or
+@samp{-l}, that will be more likely to result in success.
+
+@item cannot fork
+See the description of the similar message for @code{find}.
+
+@item <program>: exited with status 255; aborting
+When a command run by @code{xargs} exits with status 255, @code{xargs}
+is supposed to stop. If this is not what you intended, wrap the
+program you are trying to invoke in a shell script which doesn't
+return status 255.
+
+@item <program>: terminated by signal 99
+See the description of the similar message for @code{find}.
+
+@item cannot set SIGUSR1 signal handler
+@code{xargs} is having trouble preparing for you to be able to send it
+signals to increase or decrease the parallelism of its processing.
+If you don't plan to send it those signals, this warning can be ignored
+(though if you're a programmer, you may want to help us figure out
+why @code{xargs} is confused by your operating system).
+@end table
+
+@node Error Messages From locate
+@section Error Messages From @code{locate}
+
+@table @samp
+@item warning: database @file{@value{LOCATE_DB}} is more than 8 days old
+The @code{locate} program relies on a database which is periodically
+built by the @code{updatedb} program. That hasn't happened in a long
+time. To fix this problem, run @code{updatedb} manually. This can
+often happen on systems that are generally not left on, so the
+periodic ``cron'' task which normally does this doesn't get a chance
+to run.
+
+@item locate database @file{@value{LOCATE_DB}} is corrupt or invalid
+This should not happen. Re-run @code{updatedb}. If that works, but
+@code{locate} still produces this error, run @code{locate --version}
+and @code{updatedb --version}. These should produce the same output.
+If not, you are using a mixed toolset; check your @samp{$PATH}
+environment variable and your shell aliases (if you have any). If
+both programs claim to be GNU versions, this is a bug; all versions of
+these programs should interoperate without problem. Ask for help on
+@email{bug-findutils@@gnu.org}.
+@end table
+
+
+@node Error Messages From updatedb
+@section Error Messages From @code{updatedb}
+
+The @code{updatedb} program (and the programs it invokes) do issue
+error messages, but none seem to be candidates for guidance. If
+you are having a problem understanding one of these, ask for help on
+@email{bug-findutils@@gnu.org}.
+
+@node GNU Free Documentation License
+@appendix GNU Free Documentation License
+@include fdl.texi
+
+@node Primary Index
+@unnumbered @code{find} Primary Index
+
+This is a list of all of the primaries (tests, actions, and options)
+that make up @code{find} expressions for selecting files. @xref{find
+Expressions}, for more information on expressions.
+
+@printindex fn
+
+@bye
+
+@comment texi related words used by Emacs' spell checker ispell.el
+
+@comment LocalWords: texinfo setfilename settitle setchapternewpage
+@comment LocalWords: iftex finalout ifinfo DIR titlepage vskip pt
+@comment LocalWords: filll dir samp dfn noindent xref pxref
+@comment LocalWords: var deffn texi deffnx itemx emph asis
+@comment LocalWords: findex smallexample subsubsection cindex
+@comment LocalWords: dircategory direntry itemize
+
+@comment other words used by Emacs' spell checker ispell.el
+@comment LocalWords: README fred updatedb xargs Plett Rendell akefile
+@comment LocalWords: args grep Filesystems fo foo fOo wildcards iname
+@comment LocalWords: ipath regex iregex expr fubar regexps
+@comment LocalWords: metacharacters macs sr sc inode lname ilname
+@comment LocalWords: sysdep noleaf ls inum xdev filesystems usr atime
+@comment LocalWords: ctime mtime amin cmin mmin al daystart Sladkey rm
+@comment LocalWords: anewer cnewer bckw rf xtype uname gname uid gid
+@comment LocalWords: nouser nogroup chown chgrp perm ch maxdepth
+@comment LocalWords: mindepth cpio src CD AFS statted stat fstype ufs
+@comment LocalWords: nfs tmp mfs printf fprint dils rw djm Nov lwall
+@comment LocalWords: POSIXLY fls fprintf strftime locale's EDT GMT AP
+@comment LocalWords: EST diff perl backquotes sprintf Falstad Oct cron
+@comment LocalWords: eg vmunix mkdir afs allexec allwrite ARG bigram
+@comment LocalWords: bigrams cd chmod comp crc CVS dbfile eof
+@comment LocalWords: fileserver filesystem fn frcode Ghazi Hnewc iXX
+@comment LocalWords: joeuser Kaveh localpaths localuser LOGNAME
+@comment LocalWords: Meyering mv netpaths netuser nonblank nonblanks
+@comment LocalWords: ois ok Pinard printindex proc procs prunefs
+@comment LocalWords: prunepaths pwd RFS rmadillo rmdir rsh sbins str
+@comment LocalWords: su Timar ubins ug unstripped vf VM Weitzel
+@comment LocalWords: wildcard zlogout basename execdir wholename iwholename
+@comment LocalWords: timestamp timestamps Solaris FreeBSD OpenBSD POSIX
diff --git a/doc/mdate-sh b/doc/mdate-sh
new file mode 100755
index 0000000..7072ea9
--- /dev/null
+++ b/doc/mdate-sh
@@ -0,0 +1,224 @@
+#!/bin/sh
+# Get modification time of a file or directory and pretty-print it.
+
+scriptversion=2010-08-21.06; # UTC
+
+# Copyright (C) 1995-2013 Free Software Foundation, Inc.
+# written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, June 1995
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+fi
+
+case $1 in
+ '')
+ echo "$0: No file. Try '$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
+ -h | --h*)
+ cat <<\EOF
+Usage: mdate-sh [--help] [--version] FILE
+
+Pretty-print the modification day of FILE, in the format:
+1 January 1970
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit $?
+ ;;
+ -v | --v*)
+ echo "mdate-sh $scriptversion"
+ exit $?
+ ;;
+esac
+
+error ()
+{
+ echo "$0: $1" >&2
+ exit 1
+}
+
+
+# Prevent date giving response in another language.
+LANG=C
+export LANG
+LC_ALL=C
+export LC_ALL
+LC_TIME=C
+export LC_TIME
+
+# GNU ls changes its time format in response to the TIME_STYLE
+# variable. Since we cannot assume 'unset' works, revert this
+# variable to its documented default.
+if test "${TIME_STYLE+set}" = set; then
+ TIME_STYLE=posix-long-iso
+ export TIME_STYLE
+fi
+
+save_arg1=$1
+
+# Find out how to get the extended ls output of a file or directory.
+if ls -L /dev/null 1>/dev/null 2>&1; then
+ ls_command='ls -L -l -d'
+else
+ ls_command='ls -l -d'
+fi
+# Avoid user/group names that might have spaces, when possible.
+if ls -n /dev/null 1>/dev/null 2>&1; then
+ ls_command="$ls_command -n"
+fi
+
+# A 'ls -l' line looks as follows on OS/2.
+# drwxrwx--- 0 Aug 11 2001 foo
+# This differs from Unix, which adds ownership information.
+# drwxrwx--- 2 root root 4096 Aug 11 2001 foo
+#
+# To find the date, we split the line on spaces and iterate on words
+# until we find a month. This cannot work with files whose owner is a
+# user named "Jan", or "Feb", etc. However, it's unlikely that '/'
+# will be owned by a user whose name is a month. So we first look at
+# the extended ls output of the root directory to decide how many
+# words should be skipped to get the date.
+
+# On HPUX /bin/sh, "set" interprets "-rw-r--r--" as options, so the "x" below.
+set x`$ls_command /`
+
+# Find which argument is the month.
+month=
+command=
+until test $month
+do
+ test $# -gt 0 || error "failed parsing '$ls_command /' output"
+ shift
+ # Add another shift to the command.
+ command="$command shift;"
+ case $1 in
+ Jan) month=January; nummonth=1;;
+ Feb) month=February; nummonth=2;;
+ Mar) month=March; nummonth=3;;
+ Apr) month=April; nummonth=4;;
+ May) month=May; nummonth=5;;
+ Jun) month=June; nummonth=6;;
+ Jul) month=July; nummonth=7;;
+ Aug) month=August; nummonth=8;;
+ Sep) month=September; nummonth=9;;
+ Oct) month=October; nummonth=10;;
+ Nov) month=November; nummonth=11;;
+ Dec) month=December; nummonth=12;;
+ esac
+done
+
+test -n "$month" || error "failed parsing '$ls_command /' output"
+
+# Get the extended ls output of the file or directory.
+set dummy x`eval "$ls_command \"\\\$save_arg1\""`
+
+# Remove all preceding arguments
+eval $command
+
+# Because of the dummy argument above, month is in $2.
+#
+# On a POSIX system, we should have
+#
+# $# = 5
+# $1 = file size
+# $2 = month
+# $3 = day
+# $4 = year or time
+# $5 = filename
+#
+# On Darwin 7.7.0 and 7.6.0, we have
+#
+# $# = 4
+# $1 = day
+# $2 = month
+# $3 = year or time
+# $4 = filename
+
+# Get the month.
+case $2 in
+ Jan) month=January; nummonth=1;;
+ Feb) month=February; nummonth=2;;
+ Mar) month=March; nummonth=3;;
+ Apr) month=April; nummonth=4;;
+ May) month=May; nummonth=5;;
+ Jun) month=June; nummonth=6;;
+ Jul) month=July; nummonth=7;;
+ Aug) month=August; nummonth=8;;
+ Sep) month=September; nummonth=9;;
+ Oct) month=October; nummonth=10;;
+ Nov) month=November; nummonth=11;;
+ Dec) month=December; nummonth=12;;
+esac
+
+case $3 in
+ ???*) day=$1;;
+ *) day=$3; shift;;
+esac
+
+# Here we have to deal with the problem that the ls output gives either
+# the time of day or the year.
+case $3 in
+ *:*) set `date`; eval year=\$$#
+ case $2 in
+ Jan) nummonthtod=1;;
+ Feb) nummonthtod=2;;
+ Mar) nummonthtod=3;;
+ Apr) nummonthtod=4;;
+ May) nummonthtod=5;;
+ Jun) nummonthtod=6;;
+ Jul) nummonthtod=7;;
+ Aug) nummonthtod=8;;
+ Sep) nummonthtod=9;;
+ Oct) nummonthtod=10;;
+ Nov) nummonthtod=11;;
+ Dec) nummonthtod=12;;
+ esac
+ # For the first six month of the year the time notation can also
+ # be used for files modified in the last year.
+ if (expr $nummonth \> $nummonthtod) > /dev/null;
+ then
+ year=`expr $year - 1`
+ fi;;
+ *) year=$3;;
+esac
+
+# The result.
+echo $day $month $year
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/doc/parse-datetime.texi b/doc/parse-datetime.texi
new file mode 100644
index 0000000..1083924
--- /dev/null
+++ b/doc/parse-datetime.texi
@@ -0,0 +1,594 @@
+@c GNU date syntax documentation
+
+@c Copyright (C) 1994-2006, 2009-2015 Free Software Foundation, Inc.
+
+@c Permission is granted to copy, distribute and/or modify this document
+@c under the terms of the GNU Free Documentation License, Version 1.3 or
+@c any later version published by the Free Software Foundation; with no
+@c Invariant Sections, no Front-Cover Texts, and no Back-Cover
+@c Texts. A copy of the license is included in the ``GNU Free
+@c Documentation License'' file as part of this distribution.
+
+@node Date input formats
+@chapter Date input formats
+
+@cindex date input formats
+@findex parse_datetime
+
+First, a quote:
+
+@quotation
+Our units of temporal measurement, from seconds on up to months, are so
+complicated, asymmetrical and disjunctive so as to make coherent mental
+reckoning in time all but impossible. Indeed, had some tyrannical god
+contrived to enslave our minds to time, to make it all but impossible
+for us to escape subjection to sodden routines and unpleasant surprises,
+he could hardly have done better than handing down our present system.
+It is like a set of trapezoidal building blocks, with no vertical or
+horizontal surfaces, like a language in which the simplest thought
+demands ornate constructions, useless particles and lengthy
+circumlocutions. Unlike the more successful patterns of language and
+science, which enable us to face experience boldly or at least
+level-headedly, our system of temporal calculation silently and
+persistently encourages our terror of time.
+
+@dots{} It is as though architects had to measure length in feet, width
+in meters and height in ells; as though basic instruction manuals
+demanded a knowledge of five different languages. It is no wonder then
+that we often look into our own immediate past or future, last Tuesday
+or a week from Sunday, with feelings of helpless confusion. @dots{}
+
+---Robert Grudin, @cite{Time and the Art of Living}.
+@end quotation
+
+This section describes the textual date representations that GNU
+programs accept. These are the strings you, as a user, can supply as
+arguments to the various programs. The C interface (via the
+@code{parse_datetime} function) is not described here.
+
+@menu
+* General date syntax:: Common rules.
+* Calendar date items:: 19 Dec 1994.
+* Time of day items:: 9:20pm.
+* Time zone items:: EST, PDT, UTC, @dots{}
+* Combined date and time of day items:: 1972-09-24T20:02:00,000000-0500.
+* Day of week items:: Monday and others.
+* Relative items in date strings:: next tuesday, 2 years ago.
+* Pure numbers in date strings:: 19931219, 1440.
+* Seconds since the Epoch:: @@1078100502.
+* Specifying time zone rules:: TZ="America/New_York", TZ="UTC0".
+* Authors of parse_datetime:: Bellovin, Eggert, Salz, Berets, et al.
+@end menu
+
+
+@node General date syntax
+@section General date syntax
+
+@cindex general date syntax
+
+@cindex items in date strings
+A @dfn{date} is a string, possibly empty, containing many items
+separated by whitespace. The whitespace may be omitted when no
+ambiguity arises. The empty string means the beginning of today (i.e.,
+midnight). Order of the items is immaterial. A date string may contain
+many flavors of items:
+
+@itemize @bullet
+@item calendar date items
+@item time of day items
+@item time zone items
+@item combined date and time of day items
+@item day of the week items
+@item relative items
+@item pure numbers.
+@end itemize
+
+@noindent We describe each of these item types in turn, below.
+
+@cindex numbers, written-out
+@cindex ordinal numbers
+@findex first @r{in date strings}
+@findex next @r{in date strings}
+@findex last @r{in date strings}
+A few ordinal numbers may be written out in words in some contexts. This is
+most useful for specifying day of the week items or relative items (see
+below). Among the most commonly used ordinal numbers, the word
+@samp{last} stands for @math{-1}, @samp{this} stands for 0, and
+@samp{first} and @samp{next} both stand for 1. Because the word
+@samp{second} stands for the unit of time there is no way to write the
+ordinal number 2, but for convenience @samp{third} stands for 3,
+@samp{fourth} for 4, @samp{fifth} for 5,
+@samp{sixth} for 6, @samp{seventh} for 7, @samp{eighth} for 8,
+@samp{ninth} for 9, @samp{tenth} for 10, @samp{eleventh} for 11 and
+@samp{twelfth} for 12.
+
+@cindex months, written-out
+When a month is written this way, it is still considered to be written
+numerically, instead of being ``spelled in full''; this changes the
+allowed strings.
+
+@cindex language, in dates
+In the current implementation, only English is supported for words and
+abbreviations like @samp{AM}, @samp{DST}, @samp{EST}, @samp{first},
+@samp{January}, @samp{Sunday}, @samp{tomorrow}, and @samp{year}.
+
+@cindex language, in dates
+@cindex time zone item
+The output of the @command{date} command
+is not always acceptable as a date string,
+not only because of the language problem, but also because there is no
+standard meaning for time zone items like @samp{IST}@. When using
+@command{date} to generate a date string intended to be parsed later,
+specify a date format that is independent of language and that does not
+use time zone items other than @samp{UTC} and @samp{Z}@. Here are some
+ways to do this:
+
+@example
+$ LC_ALL=C TZ=UTC0 date
+Mon Mar 1 00:21:42 UTC 2004
+$ TZ=UTC0 date +'%Y-%m-%d %H:%M:%SZ'
+2004-03-01 00:21:42Z
+$ date --rfc-3339=ns # --rfc-3339 is a GNU extension.
+2004-02-29 16:21:42.692722128-08:00
+$ date --rfc-2822 # a GNU extension
+Sun, 29 Feb 2004 16:21:42 -0800
+$ date +'%Y-%m-%d %H:%M:%S %z' # %z is a GNU extension.
+2004-02-29 16:21:42 -0800
+$ date +'@@%s.%N' # %s and %N are GNU extensions.
+@@1078100502.692722128
+@end example
+
+@cindex case, ignored in dates
+@cindex comments, in dates
+Alphabetic case is completely ignored in dates. Comments may be introduced
+between round parentheses, as long as included parentheses are properly
+nested. Hyphens not followed by a digit are currently ignored. Leading
+zeros on numbers are ignored.
+
+@cindex leap seconds
+Invalid dates like @samp{2005-02-29} or times like @samp{24:00} are
+rejected. In the typical case of a host that does not support leap
+seconds, a time like @samp{23:59:60} is rejected even if it
+corresponds to a valid leap second.
+
+
+@node Calendar date items
+@section Calendar date items
+
+@cindex calendar date item
+
+A @dfn{calendar date item} specifies a day of the year. It is
+specified differently, depending on whether the month is specified
+numerically or literally. All these strings specify the same calendar date:
+
+@example
+1972-09-24 # ISO 8601.
+72-9-24 # Assume 19xx for 69 through 99,
+ # 20xx for 00 through 68.
+72-09-24 # Leading zeros are ignored.
+9/24/72 # Common U.S. writing.
+24 September 1972
+24 Sept 72 # September has a special abbreviation.
+24 Sep 72 # Three-letter abbreviations always allowed.
+Sep 24, 1972
+24-sep-72
+24sep72
+@end example
+
+The year can also be omitted. In this case, the last specified year is
+used, or the current year if none. For example:
+
+@example
+9/24
+sep 24
+@end example
+
+Here are the rules.
+
+@cindex ISO 8601 date format
+@cindex date format, ISO 8601
+For numeric months, the ISO 8601 format
+@samp{@var{year}-@var{month}-@var{day}} is allowed, where @var{year} is
+any positive number, @var{month} is a number between 01 and 12, and
+@var{day} is a number between 01 and 31. A leading zero must be present
+if a number is less than ten. If @var{year} is 68 or smaller, then 2000
+is added to it; otherwise, if @var{year} is less than 100,
+then 1900 is added to it. The construct
+@samp{@var{month}/@var{day}/@var{year}}, popular in the United States,
+is accepted. Also @samp{@var{month}/@var{day}}, omitting the year.
+
+@cindex month names in date strings
+@cindex abbreviations for months
+Literal months may be spelled out in full: @samp{January},
+@samp{February}, @samp{March}, @samp{April}, @samp{May}, @samp{June},
+@samp{July}, @samp{August}, @samp{September}, @samp{October},
+@samp{November} or @samp{December}. Literal months may be abbreviated
+to their first three letters, possibly followed by an abbreviating dot.
+It is also permitted to write @samp{Sept} instead of @samp{September}.
+
+When months are written literally, the calendar date may be given as any
+of the following:
+
+@example
+@var{day} @var{month} @var{year}
+@var{day} @var{month}
+@var{month} @var{day} @var{year}
+@var{day}-@var{month}-@var{year}
+@end example
+
+Or, omitting the year:
+
+@example
+@var{month} @var{day}
+@end example
+
+
+@node Time of day items
+@section Time of day items
+
+@cindex time of day item
+
+A @dfn{time of day item} in date strings specifies the time on a given
+day. Here are some examples, all of which represent the same time:
+
+@example
+20:02:00.000000
+20:02
+8:02pm
+20:02-0500 # In EST (U.S. Eastern Standard Time).
+@end example
+
+@cindex leap seconds
+More generally, the time of day may be given as
+@samp{@var{hour}:@var{minute}:@var{second}}, where @var{hour} is
+a number between 0 and 23, @var{minute} is a number between 0 and
+59, and @var{second} is a number between 0 and 59 possibly followed by
+@samp{.} or @samp{,} and a fraction containing one or more digits.
+Alternatively,
+@samp{:@var{second}} can be omitted, in which case it is taken to
+be zero. On the rare hosts that support leap seconds, @var{second}
+may be 60.
+
+@findex am @r{in date strings}
+@findex pm @r{in date strings}
+@findex midnight @r{in date strings}
+@findex noon @r{in date strings}
+If the time is followed by @samp{am} or @samp{pm} (or @samp{a.m.}
+or @samp{p.m.}), @var{hour} is restricted to run from 1 to 12, and
+@samp{:@var{minute}} may be omitted (taken to be zero). @samp{am}
+indicates the first half of the day, @samp{pm} indicates the second
+half of the day. In this notation, 12 is the predecessor of 1:
+midnight is @samp{12am} while noon is @samp{12pm}.
+(This is the zero-oriented interpretation of @samp{12am} and @samp{12pm},
+as opposed to the old tradition derived from Latin
+which uses @samp{12m} for noon and @samp{12pm} for midnight.)
+
+@cindex time zone correction
+@cindex minutes, time zone correction by
+The time may alternatively be followed by a time zone correction,
+expressed as @samp{@var{s}@var{hh}@var{mm}}, where @var{s} is @samp{+}
+or @samp{-}, @var{hh} is a number of zone hours and @var{mm} is a number
+of zone minutes.
+The zone minutes term, @var{mm}, may be omitted, in which case
+the one- or two-digit correction is interpreted as a number of hours.
+You can also separate @var{hh} from @var{mm} with a colon.
+When a time zone correction is given this way, it
+forces interpretation of the time relative to
+Coordinated Universal Time (UTC), overriding any previous
+specification for the time zone or the local time zone. For example,
+@samp{+0530} and @samp{+05:30} both stand for the time zone 5.5 hours
+ahead of UTC (e.g., India).
+This is the best way to
+specify a time zone correction by fractional parts of an hour.
+The maximum zone correction is 24 hours.
+
+Either @samp{am}/@samp{pm} or a time zone correction may be specified,
+but not both.
+
+
+@node Time zone items
+@section Time zone items
+
+@cindex time zone item
+
+A @dfn{time zone item} specifies an international time zone, indicated
+by a small set of letters, e.g., @samp{UTC} or @samp{Z}
+for Coordinated Universal
+Time. Any included periods are ignored. By following a
+non-daylight-saving time zone by the string @samp{DST} in a separate
+word (that is, separated by some white space), the corresponding
+daylight saving time zone may be specified.
+Alternatively, a non-daylight-saving time zone can be followed by a
+time zone correction, to add the two values. This is normally done
+only for @samp{UTC}; for example, @samp{UTC+05:30} is equivalent to
+@samp{+05:30}.
+
+Time zone items other than @samp{UTC} and @samp{Z}
+are obsolescent and are not recommended, because they
+are ambiguous; for example, @samp{EST} has a different meaning in
+Australia than in the United States. Instead, it's better to use
+unambiguous numeric time zone corrections like @samp{-0500}, as
+described in the previous section.
+
+If neither a time zone item nor a time zone correction is supplied,
+time stamps are interpreted using the rules of the default time zone
+(@pxref{Specifying time zone rules}).
+
+
+@node Combined date and time of day items
+@section Combined date and time of day items
+
+@cindex combined date and time of day item
+@cindex ISO 8601 date and time of day format
+@cindex date and time of day format, ISO 8601
+
+The ISO 8601 date and time of day extended format consists of an ISO
+8601 date, a @samp{T} character separator, and an ISO 8601 time of
+day. This format is also recognized if the @samp{T} is replaced by a
+space.
+
+In this format, the time of day should use 24-hour notation.
+Fractional seconds are allowed, with either comma or period preceding
+the fraction. ISO 8601 fractional minutes and hours are not
+supported. Typically, hosts support nanosecond timestamp resolution;
+excess precision is silently discarded.
+
+Here are some examples:
+
+@example
+2012-09-24T20:02:00.052-05:00
+2012-12-31T23:59:59,999999999+11:00
+1970-01-01 00:00Z
+@end example
+
+@node Day of week items
+@section Day of week items
+
+@cindex day of week item
+
+The explicit mention of a day of the week will forward the date
+(only if necessary) to reach that day of the week in the future.
+
+Days of the week may be spelled out in full: @samp{Sunday},
+@samp{Monday}, @samp{Tuesday}, @samp{Wednesday}, @samp{Thursday},
+@samp{Friday} or @samp{Saturday}. Days may be abbreviated to their
+first three letters, optionally followed by a period. The special
+abbreviations @samp{Tues} for @samp{Tuesday}, @samp{Wednes} for
+@samp{Wednesday} and @samp{Thur} or @samp{Thurs} for @samp{Thursday} are
+also allowed.
+
+@findex next @var{day}
+@findex last @var{day}
+A number may precede a day of the week item to move forward
+supplementary weeks. It is best used in expression like @samp{third
+monday}. In this context, @samp{last @var{day}} or @samp{next
+@var{day}} is also acceptable; they move one week before or after
+the day that @var{day} by itself would represent.
+
+A comma following a day of the week item is ignored.
+
+
+@node Relative items in date strings
+@section Relative items in date strings
+
+@cindex relative items in date strings
+@cindex displacement of dates
+
+@dfn{Relative items} adjust a date (or the current date if none) forward
+or backward. The effects of relative items accumulate. Here are some
+examples:
+
+@example
+1 year
+1 year ago
+3 years
+2 days
+@end example
+
+@findex year @r{in date strings}
+@findex month @r{in date strings}
+@findex fortnight @r{in date strings}
+@findex week @r{in date strings}
+@findex day @r{in date strings}
+@findex hour @r{in date strings}
+@findex minute @r{in date strings}
+The unit of time displacement may be selected by the string @samp{year}
+or @samp{month} for moving by whole years or months. These are fuzzy
+units, as years and months are not all of equal duration. More precise
+units are @samp{fortnight} which is worth 14 days, @samp{week} worth 7
+days, @samp{day} worth 24 hours, @samp{hour} worth 60 minutes,
+@samp{minute} or @samp{min} worth 60 seconds, and @samp{second} or
+@samp{sec} worth one second. An @samp{s} suffix on these units is
+accepted and ignored.
+
+@findex ago @r{in date strings}
+The unit of time may be preceded by a multiplier, given as an optionally
+signed number. Unsigned numbers are taken as positively signed. No
+number at all implies 1 for a multiplier. Following a relative item by
+the string @samp{ago} is equivalent to preceding the unit by a
+multiplier with value @math{-1}.
+
+@findex day @r{in date strings}
+@findex tomorrow @r{in date strings}
+@findex yesterday @r{in date strings}
+The string @samp{tomorrow} is worth one day in the future (equivalent
+to @samp{day}), the string @samp{yesterday} is worth
+one day in the past (equivalent to @samp{day ago}).
+
+@findex now @r{in date strings}
+@findex today @r{in date strings}
+@findex this @r{in date strings}
+The strings @samp{now} or @samp{today} are relative items corresponding
+to zero-valued time displacement, these strings come from the fact
+a zero-valued time displacement represents the current time when not
+otherwise changed by previous items. They may be used to stress other
+items, like in @samp{12:00 today}. The string @samp{this} also has
+the meaning of a zero-valued time displacement, but is preferred in
+date strings like @samp{this thursday}.
+
+When a relative item causes the resulting date to cross a boundary
+where the clocks were adjusted, typically for daylight saving time,
+the resulting date and time are adjusted accordingly.
+
+The fuzz in units can cause problems with relative items. For
+example, @samp{2003-07-31 -1 month} might evaluate to 2003-07-01,
+because 2003-06-31 is an invalid date. To determine the previous
+month more reliably, you can ask for the month before the 15th of the
+current month. For example:
+
+@example
+$ date -R
+Thu, 31 Jul 2003 13:02:39 -0700
+$ date --date='-1 month' +'Last month was %B?'
+Last month was July?
+$ date --date="$(date +%Y-%m-15) -1 month" +'Last month was %B!'
+Last month was June!
+@end example
+
+Also, take care when manipulating dates around clock changes such as
+daylight saving leaps. In a few cases these have added or subtracted
+as much as 24 hours from the clock, so it is often wise to adopt
+universal time by setting the @env{TZ} environment variable to
+@samp{UTC0} before embarking on calendrical calculations.
+
+@node Pure numbers in date strings
+@section Pure numbers in date strings
+
+@cindex pure numbers in date strings
+
+The precise interpretation of a pure decimal number depends
+on the context in the date string.
+
+If the decimal number is of the form @var{yyyy}@var{mm}@var{dd} and no
+other calendar date item (@pxref{Calendar date items}) appears before it
+in the date string, then @var{yyyy} is read as the year, @var{mm} as the
+month number and @var{dd} as the day of the month, for the specified
+calendar date.
+
+If the decimal number is of the form @var{hh}@var{mm} and no other time
+of day item appears before it in the date string, then @var{hh} is read
+as the hour of the day and @var{mm} as the minute of the hour, for the
+specified time of day. @var{mm} can also be omitted.
+
+If both a calendar date and a time of day appear to the left of a number
+in the date string, but no relative item, then the number overrides the
+year.
+
+
+@node Seconds since the Epoch
+@section Seconds since the Epoch
+
+If you precede a number with @samp{@@}, it represents an internal time
+stamp as a count of seconds. The number can contain an internal
+decimal point (either @samp{.} or @samp{,}); any excess precision not
+supported by the internal representation is truncated toward minus
+infinity. Such a number cannot be combined with any other date
+item, as it specifies a complete time stamp.
+
+@cindex beginning of time, for POSIX
+@cindex epoch, for POSIX
+Internally, computer times are represented as a count of seconds since
+an epoch---a well-defined point of time. On GNU and
+POSIX systems, the epoch is 1970-01-01 00:00:00 UTC, so
+@samp{@@0} represents this time, @samp{@@1} represents 1970-01-01
+00:00:01 UTC, and so forth. GNU and most other
+POSIX-compliant systems support such times as an extension
+to POSIX, using negative counts, so that @samp{@@-1}
+represents 1969-12-31 23:59:59 UTC.
+
+Traditional Unix systems count seconds with 32-bit two's-complement
+integers and can represent times from 1901-12-13 20:45:52 through
+2038-01-19 03:14:07 UTC@. More modern systems use 64-bit counts
+of seconds with nanosecond subcounts, and can represent all the times
+in the known lifetime of the universe to a resolution of 1 nanosecond.
+
+@cindex leap seconds
+On most hosts, these counts ignore the presence of leap seconds.
+For example, on most hosts @samp{@@915148799} represents 1998-12-31
+23:59:59 UTC, @samp{@@915148800} represents 1999-01-01 00:00:00
+UTC, and there is no way to represent the intervening leap second
+1998-12-31 23:59:60 UTC.
+
+@node Specifying time zone rules
+@section Specifying time zone rules
+
+@vindex TZ
+Normally, dates are interpreted using the rules of the current time
+zone, which in turn are specified by the @env{TZ} environment
+variable, or by a system default if @env{TZ} is not set. To specify a
+different set of default time zone rules that apply just to one date,
+start the date with a string of the form @samp{TZ="@var{rule}"}. The
+two quote characters (@samp{"}) must be present in the date, and any
+quotes or backslashes within @var{rule} must be escaped by a
+backslash.
+
+For example, with the GNU @command{date} command you can
+answer the question ``What time is it in New York when a Paris clock
+shows 6:30am on October 31, 2004?'' by using a date beginning with
+@samp{TZ="Europe/Paris"} as shown in the following shell transcript:
+
+@example
+$ export TZ="America/New_York"
+$ date --date='TZ="Europe/Paris" 2004-10-31 06:30'
+Sun Oct 31 01:30:00 EDT 2004
+@end example
+
+In this example, the @option{--date} operand begins with its own
+@env{TZ} setting, so the rest of that operand is processed according
+to @samp{Europe/Paris} rules, treating the string @samp{2004-10-31
+06:30} as if it were in Paris. However, since the output of the
+@command{date} command is processed according to the overall time zone
+rules, it uses New York time. (Paris was normally six hours ahead of
+New York in 2004, but this example refers to a brief Halloween period
+when the gap was five hours.)
+
+A @env{TZ} value is a rule that typically names a location in the
+@uref{http://www.twinsun.com/tz/tz-link.htm, @samp{tz} database}.
+A recent catalog of location names appears in the
+@uref{http://twiki.org/cgi-bin/xtra/tzdate, TWiki Date and Time
+Gateway}. A few non-GNU hosts require a colon before a
+location name in a @env{TZ} setting, e.g.,
+@samp{TZ=":America/New_York"}.
+
+The @samp{tz} database includes a wide variety of locations ranging
+from @samp{Arctic/Longyearbyen} to @samp{Antarctica/South_Pole}, but
+if you are at sea and have your own private time zone, or if you are
+using a non-GNU host that does not support the @samp{tz}
+database, you may need to use a POSIX rule instead. Simple
+POSIX rules like @samp{UTC0} specify a time zone without
+daylight saving time; other rules can specify simple daylight saving
+regimes. @xref{TZ Variable,, Specifying the Time Zone with @code{TZ},
+libc, The GNU C Library}.
+
+@node Authors of parse_datetime
+@section Authors of @code{parse_datetime}
+@c the anchor keeps the old node name, to try to avoid breaking links
+@anchor{Authors of get_date}
+
+@cindex authors of @code{parse_datetime}
+
+@cindex Bellovin, Steven M.
+@cindex Salz, Rich
+@cindex Berets, Jim
+@cindex MacKenzie, David
+@cindex Meyering, Jim
+@cindex Eggert, Paul
+@code{parse_datetime} started life as @code{getdate}, as originally
+implemented by Steven M. Bellovin
+(@email{smb@@research.att.com}) while at the University of North Carolina
+at Chapel Hill. The code was later tweaked by a couple of people on
+Usenet, then completely overhauled by Rich $alz (@email{rsalz@@bbn.com})
+and Jim Berets (@email{jberets@@bbn.com}) in August, 1990. Various
+revisions for the GNU system were made by David MacKenzie, Jim Meyering,
+Paul Eggert and others, including renaming it to @code{get_date} to
+avoid a conflict with the alternative Posix function @code{getdate},
+and a later rename to @code{parse_datetime}. The Posix function
+@code{getdate} can parse more locale-specific dates using
+@code{strptime}, but relies on an environment variable and external
+file, and lacks the thread-safety of @code{parse_datetime}.
+
+@cindex Pinard, F.
+@cindex Berry, K.
+This chapter was originally produced by Fran@,{c}ois Pinard
+(@email{pinard@@iro.umontreal.ca}) from the @file{parse_datetime.y} source code,
+and then edited by K. Berry (@email{kb@@cs.umb.edu}).
diff --git a/doc/perm.texi b/doc/perm.texi
new file mode 100644
index 0000000..41b24f6
--- /dev/null
+++ b/doc/perm.texi
@@ -0,0 +1,508 @@
+Each file has a set of @dfn{permissions} that control the kinds of
+access that users have to that file. The permissions for a file are
+also called its @dfn{access mode}. They can be represented either in
+symbolic form or as an octal number.
+
+@menu
+* Mode Structure:: Structure of file permissions.
+* Symbolic Modes:: Mnemonic permissions representation.
+* Numeric Modes:: Permissions as octal numbers.
+@end menu
+
+@node Mode Structure
+@section Structure of File Permissions
+
+There are three kinds of permissions that a user can have for a file:
+
+@enumerate
+@item
+@cindex read permission
+permission to read the file. For directories, this means permission to
+list the contents of the directory.
+@item
+@cindex write permission
+permission to write to (change) the file. For directories, this means
+permission to create and remove files in the directory.
+@item
+@cindex execute permission
+permission to execute the file (run it as a program). For directories,
+this means permission to access files in the directory.
+@end enumerate
+
+There are three categories of users who may have different permissions
+to perform any of the above operations on a file:
+
+@enumerate
+@item
+the file's owner;
+@item
+other users who are in the file's group;
+@item
+everyone else.
+@end enumerate
+
+@cindex owner, default
+@cindex group owner, default
+Files are given an owner and group when they are created. Usually the
+owner is the current user and the group is the group of the directory
+the file is in, but this varies with the operating system, the
+file system the file is created on, and the way the file is created. You
+can change the owner and group of a file by using the @command{chown} and
+@command{chgrp} commands.
+
+In addition to the three sets of three permissions listed above, a
+file's permissions have three special components, which affect only
+executable files (programs) and, on some systems, directories:
+
+@enumerate
+@item
+@cindex setuid
+Set the process's effective user ID to that of the file upon execution
+(called the @dfn{setuid bit}). No effect on directories.
+@item
+@cindex setgid
+Set the process's effective group ID to that of the file upon execution
+(called the @dfn{setgid bit}). For directories on some systems, put
+files created in the directory into the same group as the directory, no
+matter what group the user who creates them is in.
+@item
+@cindex sticky
+@cindex swap space, saving text image in
+@cindex text image, saving in swap space
+@cindex restricted deletion flag
+prevent users from removing or renaming a file in a directory
+unless they own the file or the directory; this is called the
+@dfn{restricted deletion flag} for the directory.
+For regular files on some systems, save the program's text image on the
+swap device so it will load more quickly when run; this is called the
+@dfn{sticky bit}.
+@end enumerate
+
+In addition to the permissions listed above, there may be file attributes
+specific to the file system, e.g: access control lists (ACLs), whether a
+file is compressed, whether a file can be modified (immutability), whether
+a file can be dumped. These are usually set using programs
+specific to the file system. For example:
+@c should probably say a lot more about ACLs... someday
+
+@table @asis
+@item ext2
+On @acronym{GNU} and @acronym{GNU}/Linux the file permissions
+(``attributes'') specific to
+the ext2 file system are set using @command{chattr}.
+
+@item FFS
+On FreeBSD the file permissions (``flags'') specific to the FFS
+file system are set using @command{chrflags}.
+@end table
+
+Although a file's permission ``bits'' allow an operation on that file,
+that operation may still fail, because:
+
+@itemize
+@item
+the file-system-specific permissions do not permit it;
+
+@item
+the file system is mounted as read-only.
+@end itemize
+
+For example, if the immutable attribute is set on a file,
+it cannot be modified, regardless of the fact that you
+may have just run @code{chmod a+w FILE}.
+
+@node Symbolic Modes
+@section Symbolic Modes
+
+@cindex symbolic modes
+@dfn{Symbolic modes} represent changes to files' permissions as
+operations on single-character symbols. They allow you to modify either
+all or selected parts of files' permissions, optionally based on
+their previous values, and perhaps on the current @code{umask} as well
+(@pxref{Umask and Protection}).
+
+The format of symbolic modes is:
+
+@example
+@r{[}ugoa@dots{}@r{][}+-=@r{]}@var{perms}@dots{}@r{[},@dots{}@r{]}
+@end example
+
+@noindent
+where @var{perms} is either zero or more letters from the set
+@samp{rwxXst}, or a single letter from the set @samp{ugo}.
+
+The following sections describe the operators and other details of
+symbolic modes.
+
+@menu
+* Setting Permissions:: Basic operations on permissions.
+* Copying Permissions:: Copying existing permissions.
+* Changing Special Permissions:: Special permissions.
+* Conditional Executability:: Conditionally affecting executability.
+* Multiple Changes:: Making multiple changes.
+* Umask and Protection:: The effect of the umask.
+@end menu
+
+@node Setting Permissions
+@subsection Setting Permissions
+
+The basic symbolic operations on a file's permissions are adding,
+removing, and setting the permission that certain users have to read,
+write, and execute the file. These operations have the following
+format:
+
+@example
+@var{users} @var{operation} @var{permissions}
+@end example
+
+@noindent
+The spaces between the three parts above are shown for readability only;
+symbolic modes cannot contain spaces.
+
+The @var{users} part tells which users' access to the file is changed.
+It consists of one or more of the following letters (or it can be empty;
+@pxref{Umask and Protection}, for a description of what happens then). When
+more than one of these letters is given, the order that they are in does
+not matter.
+
+@table @code
+@item u
+@cindex owner of file, permissions for
+the user who owns the file;
+@item g
+@cindex group, permissions for
+other users who are in the file's group;
+@item o
+@cindex other permissions
+all other users;
+@item a
+all users; the same as @samp{ugo}.
+@end table
+
+The @var{operation} part tells how to change the affected users' access
+to the file, and is one of the following symbols:
+
+@table @code
+@item +
+@cindex adding permissions
+to add the @var{permissions} to whatever permissions the @var{users}
+already have for the file;
+@item -
+@cindex removing permissions
+@cindex subtracting permissions
+to remove the @var{permissions} from whatever permissions the
+@var{users} already have for the file;
+@item =
+@cindex setting permissions
+to make the @var{permissions} the only permissions that the @var{users}
+have for the file.
+@end table
+
+The @var{permissions} part tells what kind of access to the file should
+be changed; it is normally zero or more of the following letters. As with the
+@var{users} part, the order does not matter when more than one letter is
+given. Omitting the @var{permissions} part is useful only with the
+@samp{=} operation, where it gives the specified @var{users} no access
+at all to the file.
+
+@table @code
+@item r
+@cindex read permission, symbolic
+the permission the @var{users} have to read the file;
+@item w
+@cindex write permission, symbolic
+the permission the @var{users} have to write to the file;
+@item x
+@cindex execute permission, symbolic
+the permission the @var{users} have to execute the file.
+@end table
+
+For example, to give everyone permission to read and write a file,
+but not to execute it, use:
+
+@example
+a=rw
+@end example
+
+To remove write permission for all users other than the file's
+owner, use:
+
+@example
+go-w
+@end example
+
+@noindent
+The above command does not affect the access that the owner of
+the file has to it, nor does it affect whether other users can
+read or execute the file.
+
+To give everyone except a file's owner no permission to do anything with
+that file, use the mode below. Other users could still remove the file,
+if they have write permission on the directory it is in.
+
+@example
+go=
+@end example
+
+@noindent
+Another way to specify the same thing is:
+
+@example
+og-rwx
+@end example
+
+@node Copying Permissions
+@subsection Copying Existing Permissions
+
+@cindex copying existing permissions
+@cindex permissions, copying existing
+You can base a file's permissions on its existing permissions. To do
+this, instead of using a series of @samp{r}, @samp{w}, or @samp{x}
+letters after the
+operator, you use the letter @samp{u}, @samp{g}, or @samp{o}. For
+example, the mode
+
+@example
+o+g
+@end example
+
+@noindent
+adds the permissions for users who are in a file's group to the
+permissions that other users have for the file. Thus, if the file
+started out as mode 664 (@samp{rw-rw-r--}), the above mode would change
+it to mode 666 (@samp{rw-rw-rw-}). If the file had started out as mode
+741 (@samp{rwxr----x}), the above mode would change it to mode 745
+(@samp{rwxr--r-x}). The @samp{-} and @samp{=} operations work
+analogously.
+
+@node Changing Special Permissions
+@subsection Changing Special Permissions
+
+@cindex changing special permissions
+In addition to changing a file's read, write, and execute permissions,
+you can change its special permissions. @xref{Mode Structure}, for a
+summary of these permissions.
+
+To change a file's permission to set the user ID on execution, use
+@samp{u} in the @var{users} part of the symbolic mode and
+@samp{s} in the @var{permissions} part.
+
+To change a file's permission to set the group ID on execution, use
+@samp{g} in the @var{users} part of the symbolic mode and
+@samp{s} in the @var{permissions} part.
+
+To change a file's permission to set the restricted deletion flag or sticky bit,
+omit the @var{users} part of the symbolic mode (or use @samp{a}) and put
+@samp{t} in the @var{permissions} part.
+
+For example, to add set-user-ID permission to a program,
+you can use the mode:
+
+@example
+u+s
+@end example
+
+To remove both set-user-ID and set-group-ID permission from
+it, you can use the mode:
+
+@example
+ug-s
+@end example
+
+To set the restricted deletion flag or sticky bit, you can use
+the mode:
+
+@example
++t
+@end example
+
+The combination @samp{o+s} has no effect. On @acronym{GNU} systems
+the combinations @samp{u+t} and @samp{g+t} have no effect, and
+@samp{o+t} acts like plain @samp{+t}.
+
+The @samp{=} operator is not very useful with special permissions; for
+example, the mode:
+
+@example
+o=t
+@end example
+
+@noindent
+does set the restricted deletion flag or sticky bit, but it also
+removes all read, write, and execute permissions that users not in the
+file's group might have had for it.
+
+@node Conditional Executability
+@subsection Conditional Executability
+
+@cindex conditional executability
+There is one more special type of symbolic permission: if you use
+@samp{X} instead of @samp{x}, execute permission is affected only if the
+file is a directory or already had execute permission.
+
+For example, this mode:
+
+@example
+a+X
+@end example
+
+@noindent
+gives all users permission to search directories, or to execute files if
+anyone could execute them before.
+
+@node Multiple Changes
+@subsection Making Multiple Changes
+
+@cindex multiple changes to permissions
+The format of symbolic modes is actually more complex than described
+above (@pxref{Setting Permissions}). It provides two ways to make
+multiple changes to files' permissions.
+
+The first way is to specify multiple @var{operation} and
+@var{permissions} parts after a @var{users} part in the symbolic mode.
+
+For example, the mode:
+
+@example
+og+rX-w
+@end example
+
+@noindent
+gives users other than the owner of the file read permission and, if
+it is a directory or if someone already had execute permission
+to it, gives them execute permission; and it also denies them write
+permission to the file. It does not affect the permission that the
+owner of the file has for it. The above mode is equivalent to
+the two modes:
+
+@example
+og+rX
+og-w
+@end example
+
+The second way to make multiple changes is to specify more than one
+simple symbolic mode, separated by commas. For example, the mode:
+
+@example
+a+r,go-w
+@end example
+
+@noindent
+gives everyone permission to read the file and removes write
+permission on it for all users except its owner. Another example:
+
+@example
+u=rwx,g=rx,o=
+@end example
+
+@noindent
+sets all of the non-special permissions for the file explicitly. (It
+gives users who are not in the file's group no permission at all for
+it.)
+
+The two methods can be combined. The mode:
+
+@example
+a+r,g+x-w
+@end example
+
+@noindent
+gives all users permission to read the file, and gives users who are in
+the file's group permission to execute it, as well, but not permission
+to write to it. The above mode could be written in several different
+ways; another is:
+
+@example
+u+r,g+rx,o+r,g-w
+@end example
+
+@node Umask and Protection
+@subsection The Umask and Protection
+
+@cindex umask and modes
+@cindex modes and umask
+If the @var{users} part of a symbolic mode is omitted, it defaults to
+@samp{a} (affect all users), except that any permissions that are
+@emph{set} in the system variable @code{umask} are @emph{not affected}.
+The value of @code{umask} can be set using the
+@code{umask} command. Its default value varies from system to system.
+
+@cindex giving away permissions
+Omitting the @var{users} part of a symbolic mode is generally not useful
+with operations other than @samp{+}. It is useful with @samp{+} because
+it allows you to use @code{umask} as an easily customizable protection
+against giving away more permission to files than you intended to.
+
+As an example, if @code{umask} has the value 2, which removes write
+permission for users who are not in the file's group, then the mode:
+
+@example
++w
+@end example
+
+@noindent
+adds permission to write to the file to its owner and to other users who
+are in the file's group, but @emph{not} to other users. In contrast,
+the mode:
+
+@example
+a+w
+@end example
+
+@noindent
+ignores @code{umask}, and @emph{does} give write permission for
+the file to all users.
+
+@node Numeric Modes
+@section Numeric Modes
+
+@cindex numeric modes
+@cindex file permissions, numeric
+@cindex octal numbers for file modes
+As an
+alternative to giving a symbolic mode, you can give an octal (base 8)
+number that represents the new mode.
+This number is always interpreted in octal; you do not have to add a
+leading 0, as you do in C. Mode 0055 is the same as mode 55.
+
+A numeric mode is usually shorter than the corresponding symbolic
+mode, but it is limited in that it cannot take into account a file's
+previous permissions; it can only set them absolutely.
+
+The permissions granted to the user,
+to other users in the file's group,
+and to other users not in the file's group each require three
+bits, which are represented as one octal digit. The three special
+permissions also require one bit each, and they are as a group
+represented as another octal digit. Here is how the bits are arranged,
+starting with the lowest valued bit:
+
+@example
+Value in Corresponding
+Mode Permission
+
+ Other users not in the file's group:
+ 1 Execute
+ 2 Write
+ 4 Read
+
+ Other users in the file's group:
+ 10 Execute
+ 20 Write
+ 40 Read
+
+ The file's owner:
+ 100 Execute
+ 200 Write
+ 400 Read
+
+ Special permissions:
+1000 Restricted deletion flag or sticky bit
+2000 Set group ID on execution
+4000 Set user ID on execution
+@end example
+
+For example, numeric mode 4755 corresponds to symbolic mode
+@samp{u=rwxs,go=rx}, and numeric mode 664 corresponds to symbolic mode
+@samp{ug=rw,o=r}. Numeric mode 0 corresponds to symbolic mode
+@samp{a=}.
diff --git a/doc/regexprops.texi b/doc/regexprops.texi
new file mode 100644
index 0000000..537b64e
--- /dev/null
+++ b/doc/regexprops.texi
@@ -0,0 +1,592 @@
+@c Copyright (C) 1994, 1996, 1998, 2000, 2001, 2003, 2004, 2005, 2006,
+@c 2007, 2009, 2010, 2011 Free Software Foundation, Inc.
+@c
+@c Permission is granted to copy, distribute and/or modify this document
+@c under the terms of the GNU Free Documentation License, Version 1.3 or
+@c any later version published by the Free Software Foundation; with no
+@c Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
+@c A copy of the license is included in the ``GNU Free
+@c Documentation License'' file as part of this distribution.
+
+@c this regular expression description is for: findutils
+
+@menu
+* findutils-default regular expression syntax::
+* awk regular expression syntax::
+* egrep regular expression syntax::
+* emacs regular expression syntax::
+* gnu-awk regular expression syntax::
+* grep regular expression syntax::
+* posix-awk regular expression syntax::
+* posix-basic regular expression syntax::
+* posix-egrep regular expression syntax::
+* posix-extended regular expression syntax::
+@end menu
+
+@node findutils-default regular expression syntax
+@subsection @samp{findutils-default} regular expression syntax
+
+
+The character @samp{.} matches any single character.
+
+
+@table @samp
+
+@item +
+indicates that the regular expression should match one or more occurrences of the previous atom or regexp.
+@item ?
+indicates that the regular expression should match zero or one occurrence of the previous atom or regexp.
+@item \+
+matches a @samp{+}
+@item \?
+matches a @samp{?}.
+@end table
+
+
+Bracket expressions are used to match ranges of characters. Bracket expressions where the range is backward, for example @samp{[z-a]}, are ignored. Within square brackets, @samp{\} is taken literally. Character classes are not supported, so for example you would need to use @samp{[0-9]} instead of @samp{[[:digit:]]}.
+
+GNU extensions are supported:
+@enumerate
+
+@item @samp{\w} matches a character within a word
+
+@item @samp{\W} matches a character which is not within a word
+
+@item @samp{\<} matches the beginning of a word
+
+@item @samp{\>} matches the end of a word
+
+@item @samp{\b} matches a word boundary
+
+@item @samp{\B} matches characters which are not a word boundary
+
+@item @samp{\`} matches the beginning of the whole input
+
+@item @samp{\'} matches the end of the whole input
+
+@end enumerate
+
+
+Grouping is performed with backslashes followed by parentheses @samp{\(}, @samp{\)}. A backslash followed by a digit acts as a back-reference and matches the same thing as the previous grouped expression indicated by that number. For example @samp{\2} matches the second group expression. The order of group expressions is determined by the position of their opening parenthesis @samp{\(}.
+
+The alternation operator is @samp{\|}.
+
+The character @samp{^} only represents the beginning of a string when it appears:
+@enumerate
+
+@item
+At the beginning of a regular expression
+
+@item After an open-group, signified by
+@samp{\(}
+
+@item After the alternation operator @samp{\|}
+
+@end enumerate
+
+
+The character @samp{$} only represents the end of a string when it appears:
+@enumerate
+
+@item At the end of a regular expression
+
+@item Before a close-group, signified by
+@samp{\)}
+@item Before the alternation operator @samp{\|}
+
+@end enumerate
+
+
+@samp{*}, @samp{+} and @samp{?} are special at any point in a regular expression except:
+@enumerate
+
+@item At the beginning of a regular expression
+
+@item After an open-group, signified by
+@samp{\(}
+@item After the alternation operator @samp{\|}
+
+@end enumerate
+
+
+
+
+The longest possible match is returned; this applies to the regular expression as a whole and (subject to this constraint) to subexpressions within groups.
+
+
+@node awk regular expression syntax
+@subsection @samp{awk} regular expression syntax
+
+
+The character @samp{.} matches any single character except the null character.
+
+
+@table @samp
+
+@item +
+indicates that the regular expression should match one or more occurrences of the previous atom or regexp.
+@item ?
+indicates that the regular expression should match zero or one occurrence of the previous atom or regexp.
+@item \+
+matches a @samp{+}
+@item \?
+matches a @samp{?}.
+@end table
+
+
+Bracket expressions are used to match ranges of characters. Bracket expressions where the range is backward, for example @samp{[z-a]}, are invalid. Within square brackets, @samp{\} can be used to quote the following character. Character classes are supported; for example @samp{[[:digit:]]} will match a single decimal digit.
+
+GNU extensions are not supported and so @samp{\w}, @samp{\W}, @samp{\<}, @samp{\>}, @samp{\b}, @samp{\B}, @samp{\`}, and @samp{\'} match @samp{w}, @samp{W}, @samp{<}, @samp{>}, @samp{b}, @samp{B}, @samp{`}, and @samp{'} respectively.
+
+Grouping is performed with parentheses @samp{()}. An unmatched @samp{)} matches just itself. A backslash followed by a digit matches that digit.
+
+The alternation operator is @samp{|}.
+
+The characters @samp{^} and @samp{$} always represent the beginning and end of a string respectively, except within square brackets. Within brackets, @samp{^} can be used to invert the membership of the character class being specified.
+
+@samp{*}, @samp{+} and @samp{?} are special at any point in a regular expression except:
+@enumerate
+
+@item At the beginning of a regular expression
+
+@item After an open-group, signified by
+@samp{(}
+@item After the alternation operator @samp{|}
+
+@end enumerate
+
+
+
+
+The longest possible match is returned; this applies to the regular expression as a whole and (subject to this constraint) to subexpressions within groups.
+
+
+@node egrep regular expression syntax
+@subsection @samp{egrep} regular expression syntax
+
+
+The character @samp{.} matches any single character.
+
+
+@table @samp
+
+@item +
+indicates that the regular expression should match one or more occurrences of the previous atom or regexp.
+@item ?
+indicates that the regular expression should match zero or one occurrence of the previous atom or regexp.
+@item \+
+matches a @samp{+}
+@item \?
+matches a @samp{?}.
+@end table
+
+
+Bracket expressions are used to match ranges of characters. Bracket expressions where the range is backward, for example @samp{[z-a]}, are invalid. Within square brackets, @samp{\} is taken literally. Character classes are supported; for example @samp{[[:digit:]]} will match a single decimal digit.
+
+GNU extensions are supported:
+@enumerate
+
+@item @samp{\w} matches a character within a word
+
+@item @samp{\W} matches a character which is not within a word
+
+@item @samp{\<} matches the beginning of a word
+
+@item @samp{\>} matches the end of a word
+
+@item @samp{\b} matches a word boundary
+
+@item @samp{\B} matches characters which are not a word boundary
+
+@item @samp{\`} matches the beginning of the whole input
+
+@item @samp{\'} matches the end of the whole input
+
+@end enumerate
+
+
+Grouping is performed with parentheses @samp{()}. An unmatched @samp{)} matches just itself. A backslash followed by a digit acts as a back-reference and matches the same thing as the previous grouped expression indicated by that number. For example @samp{\2} matches the second group expression. The order of group expressions is determined by the position of their opening parenthesis @samp{(}.
+
+The alternation operator is @samp{|}.
+
+The characters @samp{^} and @samp{$} always represent the beginning and end of a string respectively, except within square brackets. Within brackets, @samp{^} can be used to invert the membership of the character class being specified.
+
+The characters @samp{*}, @samp{+} and @samp{?} are special anywhere in a regular expression.
+
+Intervals are specified by @samp{@{} and @samp{@}}. Invalid intervals are treated as literals, for example @samp{a@{1} is treated as @samp{a\@{1}
+
+The longest possible match is returned; this applies to the regular expression as a whole and (subject to this constraint) to subexpressions within groups.
+
+
+@node emacs regular expression syntax
+@subsection @samp{emacs} regular expression syntax
+
+
+The character @samp{.} matches any single character except newline.
+
+
+@table @samp
+
+@item +
+indicates that the regular expression should match one or more occurrences of the previous atom or regexp.
+@item ?
+indicates that the regular expression should match zero or one occurrence of the previous atom or regexp.
+@item \+
+matches a @samp{+}
+@item \?
+matches a @samp{?}.
+@end table
+
+
+Bracket expressions are used to match ranges of characters. Bracket expressions where the range is backward, for example @samp{[z-a]}, are ignored. Within square brackets, @samp{\} is taken literally. Character classes are not supported, so for example you would need to use @samp{[0-9]} instead of @samp{[[:digit:]]}.
+
+GNU extensions are supported:
+@enumerate
+
+@item @samp{\w} matches a character within a word
+
+@item @samp{\W} matches a character which is not within a word
+
+@item @samp{\<} matches the beginning of a word
+
+@item @samp{\>} matches the end of a word
+
+@item @samp{\b} matches a word boundary
+
+@item @samp{\B} matches characters which are not a word boundary
+
+@item @samp{\`} matches the beginning of the whole input
+
+@item @samp{\'} matches the end of the whole input
+
+@end enumerate
+
+
+Grouping is performed with backslashes followed by parentheses @samp{\(}, @samp{\)}. A backslash followed by a digit acts as a back-reference and matches the same thing as the previous grouped expression indicated by that number. For example @samp{\2} matches the second group expression. The order of group expressions is determined by the position of their opening parenthesis @samp{\(}.
+
+The alternation operator is @samp{\|}.
+
+The character @samp{^} only represents the beginning of a string when it appears:
+@enumerate
+
+@item
+At the beginning of a regular expression
+
+@item After an open-group, signified by
+@samp{\(}
+
+@item After the alternation operator @samp{\|}
+
+@end enumerate
+
+
+The character @samp{$} only represents the end of a string when it appears:
+@enumerate
+
+@item At the end of a regular expression
+
+@item Before a close-group, signified by
+@samp{\)}
+@item Before the alternation operator @samp{\|}
+
+@end enumerate
+
+
+@samp{*}, @samp{+} and @samp{?} are special at any point in a regular expression except:
+@enumerate
+
+@item At the beginning of a regular expression
+
+@item After an open-group, signified by
+@samp{\(}
+@item After the alternation operator @samp{\|}
+
+@end enumerate
+
+
+
+
+The longest possible match is returned; this applies to the regular expression as a whole and (subject to this constraint) to subexpressions within groups.
+
+
+@node gnu-awk regular expression syntax
+@subsection @samp{gnu-awk} regular expression syntax
+
+
+The character @samp{.} matches any single character.
+
+
+@table @samp
+
+@item +
+indicates that the regular expression should match one or more occurrences of the previous atom or regexp.
+@item ?
+indicates that the regular expression should match zero or one occurrence of the previous atom or regexp.
+@item \+
+matches a @samp{+}
+@item \?
+matches a @samp{?}.
+@end table
+
+
+Bracket expressions are used to match ranges of characters. Bracket expressions where the range is backward, for example @samp{[z-a]}, are invalid. Within square brackets, @samp{\} can be used to quote the following character. Character classes are supported; for example @samp{[[:digit:]]} will match a single decimal digit.
+
+GNU extensions are supported:
+@enumerate
+
+@item @samp{\w} matches a character within a word
+
+@item @samp{\W} matches a character which is not within a word
+
+@item @samp{\<} matches the beginning of a word
+
+@item @samp{\>} matches the end of a word
+
+@item @samp{\b} matches a word boundary
+
+@item @samp{\B} matches characters which are not a word boundary
+
+@item @samp{\`} matches the beginning of the whole input
+
+@item @samp{\'} matches the end of the whole input
+
+@end enumerate
+
+
+Grouping is performed with parentheses @samp{()}. An unmatched @samp{)} matches just itself. A backslash followed by a digit acts as a back-reference and matches the same thing as the previous grouped expression indicated by that number. For example @samp{\2} matches the second group expression. The order of group expressions is determined by the position of their opening parenthesis @samp{(}.
+
+The alternation operator is @samp{|}.
+
+The characters @samp{^} and @samp{$} always represent the beginning and end of a string respectively, except within square brackets. Within brackets, @samp{^} can be used to invert the membership of the character class being specified.
+
+@samp{*}, @samp{+} and @samp{?} are special at any point in a regular expression except:
+@enumerate
+
+@item At the beginning of a regular expression
+
+@item After an open-group, signified by
+@samp{(}
+@item After the alternation operator @samp{|}
+
+@end enumerate
+
+
+Intervals are specified by @samp{@{} and @samp{@}}. Invalid intervals are treated as literals, for example @samp{a@{1} is treated as @samp{a\@{1}
+
+The longest possible match is returned; this applies to the regular expression as a whole and (subject to this constraint) to subexpressions within groups.
+
+
+@node grep regular expression syntax
+@subsection @samp{grep} regular expression syntax
+
+
+The character @samp{.} matches any single character.
+
+
+@table @samp
+
+@item \+
+indicates that the regular expression should match one or more occurrences of the previous atom or regexp.
+@item \?
+indicates that the regular expression should match zero or one occurrence of the previous atom or regexp.
+@item + and ?
+match themselves.
+@end table
+
+
+Bracket expressions are used to match ranges of characters. Bracket expressions where the range is backward, for example @samp{[z-a]}, are invalid. Within square brackets, @samp{\} is taken literally. Character classes are supported; for example @samp{[[:digit:]]} will match a single decimal digit.
+
+GNU extensions are supported:
+@enumerate
+
+@item @samp{\w} matches a character within a word
+
+@item @samp{\W} matches a character which is not within a word
+
+@item @samp{\<} matches the beginning of a word
+
+@item @samp{\>} matches the end of a word
+
+@item @samp{\b} matches a word boundary
+
+@item @samp{\B} matches characters which are not a word boundary
+
+@item @samp{\`} matches the beginning of the whole input
+
+@item @samp{\'} matches the end of the whole input
+
+@end enumerate
+
+
+Grouping is performed with backslashes followed by parentheses @samp{\(}, @samp{\)}. A backslash followed by a digit acts as a back-reference and matches the same thing as the previous grouped expression indicated by that number. For example @samp{\2} matches the second group expression. The order of group expressions is determined by the position of their opening parenthesis @samp{\(}.
+
+The alternation operator is @samp{\|}.
+
+The character @samp{^} only represents the beginning of a string when it appears:
+@enumerate
+
+@item
+At the beginning of a regular expression
+
+@item After an open-group, signified by
+@samp{\(}
+
+@item After a newline
+
+@item After the alternation operator @samp{\|}
+
+@end enumerate
+
+
+The character @samp{$} only represents the end of a string when it appears:
+@enumerate
+
+@item At the end of a regular expression
+
+@item Before a close-group, signified by
+@samp{\)}
+@item Before a newline
+
+@item Before the alternation operator @samp{\|}
+
+@end enumerate
+
+
+@samp{\*}, @samp{\+} and @samp{\?} are special at any point in a regular expression except:
+@enumerate
+
+@item At the beginning of a regular expression
+
+@item After an open-group, signified by
+@samp{\(}
+@item After a newline
+
+@item After the alternation operator @samp{\|}
+
+@end enumerate
+
+
+Intervals are specified by @samp{\@{} and @samp{\@}}. Invalid intervals such as @samp{a\@{1z} are not accepted.
+
+The longest possible match is returned; this applies to the regular expression as a whole and (subject to this constraint) to subexpressions within groups.
+
+
+@node posix-awk regular expression syntax
+@subsection @samp{posix-awk} regular expression syntax
+
+
+The character @samp{.} matches any single character except the null character.
+
+
+@table @samp
+
+@item +
+indicates that the regular expression should match one or more occurrences of the previous atom or regexp.
+@item ?
+indicates that the regular expression should match zero or one occurrence of the previous atom or regexp.
+@item \+
+matches a @samp{+}
+@item \?
+matches a @samp{?}.
+@end table
+
+
+Bracket expressions are used to match ranges of characters. Bracket expressions where the range is backward, for example @samp{[z-a]}, are invalid. Within square brackets, @samp{\} can be used to quote the following character. Character classes are supported; for example @samp{[[:digit:]]} will match a single decimal digit.
+
+GNU extensions are not supported and so @samp{\w}, @samp{\W}, @samp{\<}, @samp{\>}, @samp{\b}, @samp{\B}, @samp{\`}, and @samp{\'} match @samp{w}, @samp{W}, @samp{<}, @samp{>}, @samp{b}, @samp{B}, @samp{`}, and @samp{'} respectively.
+
+Grouping is performed with parentheses @samp{()}. An unmatched @samp{)} matches just itself. A backslash followed by a digit acts as a back-reference and matches the same thing as the previous grouped expression indicated by that number. For example @samp{\2} matches the second group expression. The order of group expressions is determined by the position of their opening parenthesis @samp{(}.
+
+The alternation operator is @samp{|}.
+
+The characters @samp{^} and @samp{$} always represent the beginning and end of a string respectively, except within square brackets. Within brackets, @samp{^} can be used to invert the membership of the character class being specified.
+
+@samp{*}, @samp{+} and @samp{?} are special at any point in a regular expression except the following places, where they are not allowed:
+@enumerate
+
+@item At the beginning of a regular expression
+
+@item After an open-group, signified by
+@samp{(}
+@item After the alternation operator @samp{|}
+
+@end enumerate
+
+
+Intervals are specified by @samp{@{} and @samp{@}}. Invalid intervals are treated as literals, for example @samp{a@{1} is treated as @samp{a\@{1}
+
+The longest possible match is returned; this applies to the regular expression as a whole and (subject to this constraint) to subexpressions within groups.
+
+
+@node posix-basic regular expression syntax
+@subsection @samp{posix-basic} regular expression syntax
+This is a synonym for ed.
+@node posix-egrep regular expression syntax
+@subsection @samp{posix-egrep} regular expression syntax
+This is a synonym for egrep.
+@node posix-extended regular expression syntax
+@subsection @samp{posix-extended} regular expression syntax
+
+
+The character @samp{.} matches any single character except the null character.
+
+
+@table @samp
+
+@item +
+indicates that the regular expression should match one or more occurrences of the previous atom or regexp.
+@item ?
+indicates that the regular expression should match zero or one occurrence of the previous atom or regexp.
+@item \+
+matches a @samp{+}
+@item \?
+matches a @samp{?}.
+@end table
+
+
+Bracket expressions are used to match ranges of characters. Bracket expressions where the range is backward, for example @samp{[z-a]}, are invalid. Within square brackets, @samp{\} is taken literally. Character classes are supported; for example @samp{[[:digit:]]} will match a single decimal digit.
+
+GNU extensions are supported:
+@enumerate
+
+@item @samp{\w} matches a character within a word
+
+@item @samp{\W} matches a character which is not within a word
+
+@item @samp{\<} matches the beginning of a word
+
+@item @samp{\>} matches the end of a word
+
+@item @samp{\b} matches a word boundary
+
+@item @samp{\B} matches characters which are not a word boundary
+
+@item @samp{\`} matches the beginning of the whole input
+
+@item @samp{\'} matches the end of the whole input
+
+@end enumerate
+
+
+Grouping is performed with parentheses @samp{()}. An unmatched @samp{)} matches just itself. A backslash followed by a digit acts as a back-reference and matches the same thing as the previous grouped expression indicated by that number. For example @samp{\2} matches the second group expression. The order of group expressions is determined by the position of their opening parenthesis @samp{(}.
+
+The alternation operator is @samp{|}.
+
+The characters @samp{^} and @samp{$} always represent the beginning and end of a string respectively, except within square brackets. Within brackets, @samp{^} can be used to invert the membership of the character class being specified.
+
+@samp{*}, @samp{+} and @samp{?} are special at any point in a regular expression except the following places, where they are not allowed:
+@enumerate
+
+@item At the beginning of a regular expression
+
+@item After an open-group, signified by
+@samp{(}
+@item After the alternation operator @samp{|}
+
+@end enumerate
+
+
+Intervals are specified by @samp{@{} and @samp{@}}. Invalid intervals such as @samp{a@{1z} are not accepted.
+
+The longest possible match is returned; this applies to the regular expression as a whole and (subject to this constraint) to subexpressions within groups.
+
diff --git a/doc/stamp-1 b/doc/stamp-1
new file mode 100644
index 0000000..5d0c32b
--- /dev/null
+++ b/doc/stamp-1
@@ -0,0 +1,4 @@
+@set UPDATED 28 December 2015
+@set UPDATED-MONTH December 2015
+@set EDITION 4.6.0
+@set VERSION 4.6.0
diff --git a/doc/stamp-vti b/doc/stamp-vti
new file mode 100644
index 0000000..5d0c32b
--- /dev/null
+++ b/doc/stamp-vti
@@ -0,0 +1,4 @@
+@set UPDATED 28 December 2015
+@set UPDATED-MONTH December 2015
+@set EDITION 4.6.0
+@set VERSION 4.6.0
diff --git a/doc/texinfo.tex b/doc/texinfo.tex
new file mode 100644
index 0000000..cfb5c56
--- /dev/null
+++ b/doc/texinfo.tex
@@ -0,0 +1,10174 @@
+% texinfo.tex -- TeX macros to handle Texinfo files.
+%
+% Load plain if necessary, i.e., if running under initex.
+\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
+%
+\def\texinfoversion{2014-05-05.10}
+%
+% Copyright 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995,
+% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+% 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Free Software Foundation, Inc.
+%
+% This texinfo.tex file is free software: you can redistribute it and/or
+% modify it under the terms of the GNU General Public License as
+% published by the Free Software Foundation, either version 3 of the
+% License, or (at your option) any later version.
+%
+% This texinfo.tex file is distributed in the hope that it will be
+% useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+% of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+% General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this program. If not, see <http://www.gnu.org/licenses/>.
+%
+% As a special exception, when this file is read by TeX when processing
+% a Texinfo source document, you may use the result without
+% restriction. This Exception is an additional permission under section 7
+% of the GNU General Public License, version 3 ("GPLv3").
+%
+% Please try the latest version of texinfo.tex before submitting bug
+% reports; you can get the latest version from:
+% http://ftp.gnu.org/gnu/texinfo/ (the Texinfo release area), or
+% http://ftpmirror.gnu.org/texinfo/ (same, via a mirror), or
+% http://www.gnu.org/software/texinfo/ (the Texinfo home page)
+% The texinfo.tex in any given distribution could well be out
+% of date, so if that's what you're using, please check.
+%
+% Send bug reports to bug-texinfo@gnu.org. Please include including a
+% complete document in each bug report with which we can reproduce the
+% problem. Patches are, of course, greatly appreciated.
+%
+% To process a Texinfo manual with TeX, it's most reliable to use the
+% texi2dvi shell script that comes with the distribution. For a simple
+% manual foo.texi, however, you can get away with this:
+% tex foo.texi
+% texindex foo.??
+% tex foo.texi
+% tex foo.texi
+% dvips foo.dvi -o # or whatever; this makes foo.ps.
+% The extra TeX runs get the cross-reference information correct.
+% Sometimes one run after texindex suffices, and sometimes you need more
+% than two; texi2dvi does it as many times as necessary.
+%
+% It is possible to adapt texinfo.tex for other languages, to some
+% extent. You can get the existing language-specific files from the
+% full Texinfo distribution.
+%
+% The GNU Texinfo home page is http://www.gnu.org/software/texinfo.
+
+
+\message{Loading texinfo [version \texinfoversion]:}
+
+% If in a .fmt file, print the version number
+% and turn on active characters that we couldn't do earlier because
+% they might have appeared in the input file name.
+\everyjob{\message{[Texinfo version \texinfoversion]}%
+ \catcode`+=\active \catcode`\_=\active}
+
+\chardef\other=12
+
+% We never want plain's \outer definition of \+ in Texinfo.
+% For @tex, we can use \tabalign.
+\let\+ = \relax
+
+% Save some plain tex macros whose names we will redefine.
+\let\ptexb=\b
+\let\ptexbullet=\bullet
+\let\ptexc=\c
+\let\ptexcomma=\,
+\let\ptexdot=\.
+\let\ptexdots=\dots
+\let\ptexend=\end
+\let\ptexequiv=\equiv
+\let\ptexexclam=\!
+\let\ptexfootnote=\footnote
+\let\ptexgtr=>
+\let\ptexhat=^
+\let\ptexi=\i
+\let\ptexindent=\indent
+\let\ptexinsert=\insert
+\let\ptexlbrace=\{
+\let\ptexless=<
+\let\ptexnewwrite\newwrite
+\let\ptexnoindent=\noindent
+\let\ptexplus=+
+\let\ptexraggedright=\raggedright
+\let\ptexrbrace=\}
+\let\ptexslash=\/
+\let\ptexstar=\*
+\let\ptext=\t
+\let\ptextop=\top
+{\catcode`\'=\active \global\let\ptexquoteright'}% active in plain's math mode
+
+% If this character appears in an error message or help string, it
+% starts a new line in the output.
+\newlinechar = `^^J
+
+% Use TeX 3.0's \inputlineno to get the line number, for better error
+% messages, but if we're using an old version of TeX, don't do anything.
+%
+\ifx\inputlineno\thisisundefined
+ \let\linenumber = \empty % Pre-3.0.
+\else
+ \def\linenumber{l.\the\inputlineno:\space}
+\fi
+
+% Set up fixed words for English if not already set.
+\ifx\putwordAppendix\undefined \gdef\putwordAppendix{Appendix}\fi
+\ifx\putwordChapter\undefined \gdef\putwordChapter{Chapter}\fi
+\ifx\putworderror\undefined \gdef\putworderror{error}\fi
+\ifx\putwordfile\undefined \gdef\putwordfile{file}\fi
+\ifx\putwordin\undefined \gdef\putwordin{in}\fi
+\ifx\putwordIndexIsEmpty\undefined \gdef\putwordIndexIsEmpty{(Index is empty)}\fi
+\ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi
+\ifx\putwordInfo\undefined \gdef\putwordInfo{Info}\fi
+\ifx\putwordInstanceVariableof\undefined \gdef\putwordInstanceVariableof{Instance Variable of}\fi
+\ifx\putwordMethodon\undefined \gdef\putwordMethodon{Method on}\fi
+\ifx\putwordNoTitle\undefined \gdef\putwordNoTitle{No Title}\fi
+\ifx\putwordof\undefined \gdef\putwordof{of}\fi
+\ifx\putwordon\undefined \gdef\putwordon{on}\fi
+\ifx\putwordpage\undefined \gdef\putwordpage{page}\fi
+\ifx\putwordsection\undefined \gdef\putwordsection{section}\fi
+\ifx\putwordSection\undefined \gdef\putwordSection{Section}\fi
+\ifx\putwordsee\undefined \gdef\putwordsee{see}\fi
+\ifx\putwordSee\undefined \gdef\putwordSee{See}\fi
+\ifx\putwordShortTOC\undefined \gdef\putwordShortTOC{Short Contents}\fi
+\ifx\putwordTOC\undefined \gdef\putwordTOC{Table of Contents}\fi
+%
+\ifx\putwordMJan\undefined \gdef\putwordMJan{January}\fi
+\ifx\putwordMFeb\undefined \gdef\putwordMFeb{February}\fi
+\ifx\putwordMMar\undefined \gdef\putwordMMar{March}\fi
+\ifx\putwordMApr\undefined \gdef\putwordMApr{April}\fi
+\ifx\putwordMMay\undefined \gdef\putwordMMay{May}\fi
+\ifx\putwordMJun\undefined \gdef\putwordMJun{June}\fi
+\ifx\putwordMJul\undefined \gdef\putwordMJul{July}\fi
+\ifx\putwordMAug\undefined \gdef\putwordMAug{August}\fi
+\ifx\putwordMSep\undefined \gdef\putwordMSep{September}\fi
+\ifx\putwordMOct\undefined \gdef\putwordMOct{October}\fi
+\ifx\putwordMNov\undefined \gdef\putwordMNov{November}\fi
+\ifx\putwordMDec\undefined \gdef\putwordMDec{December}\fi
+%
+\ifx\putwordDefmac\undefined \gdef\putwordDefmac{Macro}\fi
+\ifx\putwordDefspec\undefined \gdef\putwordDefspec{Special Form}\fi
+\ifx\putwordDefvar\undefined \gdef\putwordDefvar{Variable}\fi
+\ifx\putwordDefopt\undefined \gdef\putwordDefopt{User Option}\fi
+\ifx\putwordDeffunc\undefined \gdef\putwordDeffunc{Function}\fi
+
+% Since the category of space is not known, we have to be careful.
+\chardef\spacecat = 10
+\def\spaceisspace{\catcode`\ =\spacecat}
+
+% sometimes characters are active, so we need control sequences.
+\chardef\ampChar = `\&
+\chardef\colonChar = `\:
+\chardef\commaChar = `\,
+\chardef\dashChar = `\-
+\chardef\dotChar = `\.
+\chardef\exclamChar= `\!
+\chardef\hashChar = `\#
+\chardef\lquoteChar= `\`
+\chardef\questChar = `\?
+\chardef\rquoteChar= `\'
+\chardef\semiChar = `\;
+\chardef\slashChar = `\/
+\chardef\underChar = `\_
+
+% Ignore a token.
+%
+\def\gobble#1{}
+
+% The following is used inside several \edef's.
+\def\makecsname#1{\expandafter\noexpand\csname#1\endcsname}
+
+% Hyphenation fixes.
+\hyphenation{
+ Flor-i-da Ghost-script Ghost-view Mac-OS Post-Script
+ ap-pen-dix bit-map bit-maps
+ data-base data-bases eshell fall-ing half-way long-est man-u-script
+ man-u-scripts mini-buf-fer mini-buf-fers over-view par-a-digm
+ par-a-digms rath-er rec-tan-gu-lar ro-bot-ics se-vere-ly set-up spa-ces
+ spell-ing spell-ings
+ stand-alone strong-est time-stamp time-stamps which-ever white-space
+ wide-spread wrap-around
+}
+
+% Margin to add to right of even pages, to left of odd pages.
+\newdimen\bindingoffset
+\newdimen\normaloffset
+\newdimen\pagewidth \newdimen\pageheight
+
+% For a final copy, take out the rectangles
+% that mark overfull boxes (in case you have decided
+% that the text looks ok even though it passes the margin).
+%
+\def\finalout{\overfullrule=0pt }
+
+% Sometimes it is convenient to have everything in the transcript file
+% and nothing on the terminal. We don't just call \tracingall here,
+% since that produces some useless output on the terminal. We also make
+% some effort to order the tracing commands to reduce output in the log
+% file; cf. trace.sty in LaTeX.
+%
+\def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}%
+\def\loggingall{%
+ \tracingstats2
+ \tracingpages1
+ \tracinglostchars2 % 2 gives us more in etex
+ \tracingparagraphs1
+ \tracingoutput1
+ \tracingmacros2
+ \tracingrestores1
+ \showboxbreadth\maxdimen \showboxdepth\maxdimen
+ \ifx\eTeXversion\thisisundefined\else % etex gives us more logging
+ \tracingscantokens1
+ \tracingifs1
+ \tracinggroups1
+ \tracingnesting2
+ \tracingassigns1
+ \fi
+ \tracingcommands3 % 3 gives us more in etex
+ \errorcontextlines16
+}%
+
+% @errormsg{MSG}. Do the index-like expansions on MSG, but if things
+% aren't perfect, it's not the end of the world, being an error message,
+% after all.
+%
+\def\errormsg{\begingroup \indexnofonts \doerrormsg}
+\def\doerrormsg#1{\errmessage{#1}}
+
+% add check for \lastpenalty to plain's definitions. If the last thing
+% we did was a \nobreak, we don't want to insert more space.
+%
+\def\smallbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\smallskipamount
+ \removelastskip\penalty-50\smallskip\fi\fi}
+\def\medbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\medskipamount
+ \removelastskip\penalty-100\medskip\fi\fi}
+\def\bigbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\bigskipamount
+ \removelastskip\penalty-200\bigskip\fi\fi}
+
+% Do @cropmarks to get crop marks.
+%
+\newif\ifcropmarks
+\let\cropmarks = \cropmarkstrue
+%
+% Dimensions to add cropmarks at corners.
+% Added by P. A. MacKay, 12 Nov. 1986
+%
+\newdimen\outerhsize \newdimen\outervsize % set by the paper size routines
+\newdimen\cornerlong \cornerlong=1pc
+\newdimen\cornerthick \cornerthick=.3pt
+\newdimen\topandbottommargin \topandbottommargin=.75in
+
+% Output a mark which sets \thischapter, \thissection and \thiscolor.
+% We dump everything together because we only have one kind of mark.
+% This works because we only use \botmark / \topmark, not \firstmark.
+%
+% A mark contains a subexpression of the \ifcase ... \fi construct.
+% \get*marks macros below extract the needed part using \ifcase.
+%
+% Another complication is to let the user choose whether \thischapter
+% (\thissection) refers to the chapter (section) in effect at the top
+% of a page, or that at the bottom of a page. The solution is
+% described on page 260 of The TeXbook. It involves outputting two
+% marks for the sectioning macros, one before the section break, and
+% one after. I won't pretend I can describe this better than DEK...
+\def\domark{%
+ \toks0=\expandafter{\lastchapterdefs}%
+ \toks2=\expandafter{\lastsectiondefs}%
+ \toks4=\expandafter{\prevchapterdefs}%
+ \toks6=\expandafter{\prevsectiondefs}%
+ \toks8=\expandafter{\lastcolordefs}%
+ \mark{%
+ \the\toks0 \the\toks2 % 0: top marks (\last...)
+ \noexpand\or \the\toks4 \the\toks6 % 1: bottom marks (default, \prev...)
+ \noexpand\else \the\toks8 % 2: color marks
+ }%
+}
+% \topmark doesn't work for the very first chapter (after the title
+% page or the contents), so we use \firstmark there -- this gets us
+% the mark with the chapter defs, unless the user sneaks in, e.g.,
+% @setcolor (or @url, or @link, etc.) between @contents and the very
+% first @chapter.
+\def\gettopheadingmarks{%
+ \ifcase0\topmark\fi
+ \ifx\thischapter\empty \ifcase0\firstmark\fi \fi
+}
+\def\getbottomheadingmarks{\ifcase1\botmark\fi}
+\def\getcolormarks{\ifcase2\topmark\fi}
+
+% Avoid "undefined control sequence" errors.
+\def\lastchapterdefs{}
+\def\lastsectiondefs{}
+\def\prevchapterdefs{}
+\def\prevsectiondefs{}
+\def\lastcolordefs{}
+
+% Main output routine.
+\chardef\PAGE = 255
+\output = {\onepageout{\pagecontents\PAGE}}
+
+\newbox\headlinebox
+\newbox\footlinebox
+
+% \onepageout takes a vbox as an argument. Note that \pagecontents
+% does insertions, but you have to call it yourself.
+\def\onepageout#1{%
+ \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi
+ %
+ \ifodd\pageno \advance\hoffset by \bindingoffset
+ \else \advance\hoffset by -\bindingoffset\fi
+ %
+ % Do this outside of the \shipout so @code etc. will be expanded in
+ % the headline as they should be, not taken literally (outputting ''code).
+ \def\commmonheadfootline{\let\hsize=\pagewidth \texinfochars}
+ %
+ \ifodd\pageno \getoddheadingmarks \else \getevenheadingmarks \fi
+ \global\setbox\headlinebox = \vbox{\commmonheadfootline \makeheadline}%
+ %
+ \ifodd\pageno \getoddfootingmarks \else \getevenfootingmarks \fi
+ \global\setbox\footlinebox = \vbox{\commmonheadfootline \makefootline}%
+ %
+ {%
+ % Have to do this stuff outside the \shipout because we want it to
+ % take effect in \write's, yet the group defined by the \vbox ends
+ % before the \shipout runs.
+ %
+ \indexdummies % don't expand commands in the output.
+ \normalturnoffactive % \ in index entries must not stay \, e.g., if
+ % the page break happens to be in the middle of an example.
+ % We don't want .vr (or whatever) entries like this:
+ % \entry{{\tt \indexbackslash }acronym}{32}{\code {\acronym}}
+ % "\acronym" won't work when it's read back in;
+ % it needs to be
+ % {\code {{\tt \backslashcurfont }acronym}
+ \shipout\vbox{%
+ % Do this early so pdf references go to the beginning of the page.
+ \ifpdfmakepagedest \pdfdest name{\the\pageno} xyz\fi
+ %
+ \ifcropmarks \vbox to \outervsize\bgroup
+ \hsize = \outerhsize
+ \vskip-\topandbottommargin
+ \vtop to0pt{%
+ \line{\ewtop\hfil\ewtop}%
+ \nointerlineskip
+ \line{%
+ \vbox{\moveleft\cornerthick\nstop}%
+ \hfill
+ \vbox{\moveright\cornerthick\nstop}%
+ }%
+ \vss}%
+ \vskip\topandbottommargin
+ \line\bgroup
+ \hfil % center the page within the outer (page) hsize.
+ \ifodd\pageno\hskip\bindingoffset\fi
+ \vbox\bgroup
+ \fi
+ %
+ \unvbox\headlinebox
+ \pagebody{#1}%
+ \ifdim\ht\footlinebox > 0pt
+ % Only leave this space if the footline is nonempty.
+ % (We lessened \vsize for it in \oddfootingyyy.)
+ % The \baselineskip=24pt in plain's \makefootline has no effect.
+ \vskip 24pt
+ \unvbox\footlinebox
+ \fi
+ %
+ \ifcropmarks
+ \egroup % end of \vbox\bgroup
+ \hfil\egroup % end of (centering) \line\bgroup
+ \vskip\topandbottommargin plus1fill minus1fill
+ \boxmaxdepth = \cornerthick
+ \vbox to0pt{\vss
+ \line{%
+ \vbox{\moveleft\cornerthick\nsbot}%
+ \hfill
+ \vbox{\moveright\cornerthick\nsbot}%
+ }%
+ \nointerlineskip
+ \line{\ewbot\hfil\ewbot}%
+ }%
+ \egroup % \vbox from first cropmarks clause
+ \fi
+ }% end of \shipout\vbox
+ }% end of group with \indexdummies
+ \advancepageno
+ \ifnum\outputpenalty>-20000 \else\dosupereject\fi
+}
+
+\newinsert\margin \dimen\margin=\maxdimen
+
+\def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}}
+{\catcode`\@ =11
+\gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi
+% marginal hacks, juha@viisa.uucp (Juha Takala)
+\ifvoid\margin\else % marginal info is present
+ \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi
+\dimen@=\dp#1\relax \unvbox#1\relax
+\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi
+\ifr@ggedbottom \kern-\dimen@ \vfil \fi}
+}
+
+% Here are the rules for the cropmarks. Note that they are
+% offset so that the space between them is truly \outerhsize or \outervsize
+% (P. A. MacKay, 12 November, 1986)
+%
+\def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong}
+\def\nstop{\vbox
+ {\hrule height\cornerthick depth\cornerlong width\cornerthick}}
+\def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong}
+\def\nsbot{\vbox
+ {\hrule height\cornerlong depth\cornerthick width\cornerthick}}
+
+% Parse an argument, then pass it to #1. The argument is the rest of
+% the input line (except we remove a trailing comment). #1 should be a
+% macro which expects an ordinary undelimited TeX argument.
+%
+\def\parsearg{\parseargusing{}}
+\def\parseargusing#1#2{%
+ \def\argtorun{#2}%
+ \begingroup
+ \obeylines
+ \spaceisspace
+ #1%
+ \parseargline\empty% Insert the \empty token, see \finishparsearg below.
+}
+
+{\obeylines %
+ \gdef\parseargline#1^^M{%
+ \endgroup % End of the group started in \parsearg.
+ \argremovecomment #1\comment\ArgTerm%
+ }%
+}
+
+% First remove any @comment, then any @c comment.
+\def\argremovecomment#1\comment#2\ArgTerm{\argremovec #1\c\ArgTerm}
+\def\argremovec#1\c#2\ArgTerm{\argcheckspaces#1\^^M\ArgTerm}
+
+% Each occurrence of `\^^M' or `<space>\^^M' is replaced by a single space.
+%
+% \argremovec might leave us with trailing space, e.g.,
+% @end itemize @c foo
+% This space token undergoes the same procedure and is eventually removed
+% by \finishparsearg.
+%
+\def\argcheckspaces#1\^^M{\argcheckspacesX#1\^^M \^^M}
+\def\argcheckspacesX#1 \^^M{\argcheckspacesY#1\^^M}
+\def\argcheckspacesY#1\^^M#2\^^M#3\ArgTerm{%
+ \def\temp{#3}%
+ \ifx\temp\empty
+ % Do not use \next, perhaps the caller of \parsearg uses it; reuse \temp:
+ \let\temp\finishparsearg
+ \else
+ \let\temp\argcheckspaces
+ \fi
+ % Put the space token in:
+ \temp#1 #3\ArgTerm
+}
+
+% If a _delimited_ argument is enclosed in braces, they get stripped; so
+% to get _exactly_ the rest of the line, we had to prevent such situation.
+% We prepended an \empty token at the very beginning and we expand it now,
+% just before passing the control to \argtorun.
+% (Similarly, we have to think about #3 of \argcheckspacesY above: it is
+% either the null string, or it ends with \^^M---thus there is no danger
+% that a pair of braces would be stripped.
+%
+% But first, we have to remove the trailing space token.
+%
+\def\finishparsearg#1 \ArgTerm{\expandafter\argtorun\expandafter{#1}}
+
+% \parseargdef\foo{...}
+% is roughly equivalent to
+% \def\foo{\parsearg\Xfoo}
+% \def\Xfoo#1{...}
+%
+% Actually, I use \csname\string\foo\endcsname, ie. \\foo, as it is my
+% favourite TeX trick. --kasal, 16nov03
+
+\def\parseargdef#1{%
+ \expandafter \doparseargdef \csname\string#1\endcsname #1%
+}
+\def\doparseargdef#1#2{%
+ \def#2{\parsearg#1}%
+ \def#1##1%
+}
+
+% Several utility definitions with active space:
+{
+ \obeyspaces
+ \gdef\obeyedspace{ }
+
+ % Make each space character in the input produce a normal interword
+ % space in the output. Don't allow a line break at this space, as this
+ % is used only in environments like @example, where each line of input
+ % should produce a line of output anyway.
+ %
+ \gdef\sepspaces{\obeyspaces\let =\tie}
+
+ % If an index command is used in an @example environment, any spaces
+ % therein should become regular spaces in the raw index file, not the
+ % expansion of \tie (\leavevmode \penalty \@M \ ).
+ \gdef\unsepspaces{\let =\space}
+}
+
+
+\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next}
+
+% Define the framework for environments in texinfo.tex. It's used like this:
+%
+% \envdef\foo{...}
+% \def\Efoo{...}
+%
+% It's the responsibility of \envdef to insert \begingroup before the
+% actual body; @end closes the group after calling \Efoo. \envdef also
+% defines \thisenv, so the current environment is known; @end checks
+% whether the environment name matches. The \checkenv macro can also be
+% used to check whether the current environment is the one expected.
+%
+% Non-false conditionals (@iftex, @ifset) don't fit into this, so they
+% are not treated as environments; they don't open a group. (The
+% implementation of @end takes care not to call \endgroup in this
+% special case.)
+
+
+% At run-time, environments start with this:
+\def\startenvironment#1{\begingroup\def\thisenv{#1}}
+% initialize
+\let\thisenv\empty
+
+% ... but they get defined via ``\envdef\foo{...}'':
+\long\def\envdef#1#2{\def#1{\startenvironment#1#2}}
+\def\envparseargdef#1#2{\parseargdef#1{\startenvironment#1#2}}
+
+% Check whether we're in the right environment:
+\def\checkenv#1{%
+ \def\temp{#1}%
+ \ifx\thisenv\temp
+ \else
+ \badenverr
+ \fi
+}
+
+% Environment mismatch, #1 expected:
+\def\badenverr{%
+ \errhelp = \EMsimple
+ \errmessage{This command can appear only \inenvironment\temp,
+ not \inenvironment\thisenv}%
+}
+\def\inenvironment#1{%
+ \ifx#1\empty
+ outside of any environment%
+ \else
+ in environment \expandafter\string#1%
+ \fi
+}
+
+% @end foo executes the definition of \Efoo.
+% But first, it executes a specialized version of \checkenv
+%
+\parseargdef\end{%
+ \if 1\csname iscond.#1\endcsname
+ \else
+ % The general wording of \badenverr may not be ideal.
+ \expandafter\checkenv\csname#1\endcsname
+ \csname E#1\endcsname
+ \endgroup
+ \fi
+}
+
+\newhelp\EMsimple{Press RETURN to continue.}
+
+
+% Be sure we're in horizontal mode when doing a tie, since we make space
+% equivalent to this in @example-like environments. Otherwise, a space
+% at the beginning of a line will start with \penalty -- and
+% since \penalty is valid in vertical mode, we'd end up putting the
+% penalty on the vertical list instead of in the new paragraph.
+{\catcode`@ = 11
+ % Avoid using \@M directly, because that causes trouble
+ % if the definition is written into an index file.
+ \global\let\tiepenalty = \@M
+ \gdef\tie{\leavevmode\penalty\tiepenalty\ }
+}
+
+% @: forces normal size whitespace following.
+\def\:{\spacefactor=1000 }
+
+% @* forces a line break.
+\def\*{\unskip\hfil\break\hbox{}\ignorespaces}
+
+% @/ allows a line break.
+\let\/=\allowbreak
+
+% @. is an end-of-sentence period.
+\def\.{.\spacefactor=\endofsentencespacefactor\space}
+
+% @! is an end-of-sentence bang.
+\def\!{!\spacefactor=\endofsentencespacefactor\space}
+
+% @? is an end-of-sentence query.
+\def\?{?\spacefactor=\endofsentencespacefactor\space}
+
+% @frenchspacing on|off says whether to put extra space after punctuation.
+%
+\def\onword{on}
+\def\offword{off}
+%
+\parseargdef\frenchspacing{%
+ \def\temp{#1}%
+ \ifx\temp\onword \plainfrenchspacing
+ \else\ifx\temp\offword \plainnonfrenchspacing
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @frenchspacing option `\temp', must be on|off}%
+ \fi\fi
+}
+
+% @w prevents a word break. Without the \leavevmode, @w at the
+% beginning of a paragraph, when TeX is still in vertical mode, would
+% produce a whole line of output instead of starting the paragraph.
+\def\w#1{\leavevmode\hbox{#1}}
+
+% @group ... @end group forces ... to be all on one page, by enclosing
+% it in a TeX vbox. We use \vtop instead of \vbox to construct the box
+% to keep its height that of a normal line. According to the rules for
+% \topskip (p.114 of the TeXbook), the glue inserted is
+% max (\topskip - \ht (first item), 0). If that height is large,
+% therefore, no glue is inserted, and the space between the headline and
+% the text is small, which looks bad.
+%
+% Another complication is that the group might be very large. This can
+% cause the glue on the previous page to be unduly stretched, because it
+% does not have much material. In this case, it's better to add an
+% explicit \vfill so that the extra space is at the bottom. The
+% threshold for doing this is if the group is more than \vfilllimit
+% percent of a page (\vfilllimit can be changed inside of @tex).
+%
+\newbox\groupbox
+\def\vfilllimit{0.7}
+%
+\envdef\group{%
+ \ifnum\catcode`\^^M=\active \else
+ \errhelp = \groupinvalidhelp
+ \errmessage{@group invalid in context where filling is enabled}%
+ \fi
+ \startsavinginserts
+ %
+ \setbox\groupbox = \vtop\bgroup
+ % Do @comment since we are called inside an environment such as
+ % @example, where each end-of-line in the input causes an
+ % end-of-line in the output. We don't want the end-of-line after
+ % the `@group' to put extra space in the output. Since @group
+ % should appear on a line by itself (according to the Texinfo
+ % manual), we don't worry about eating any user text.
+ \comment
+}
+%
+% The \vtop produces a box with normal height and large depth; thus, TeX puts
+% \baselineskip glue before it, and (when the next line of text is done)
+% \lineskip glue after it. Thus, space below is not quite equal to space
+% above. But it's pretty close.
+\def\Egroup{%
+ % To get correct interline space between the last line of the group
+ % and the first line afterwards, we have to propagate \prevdepth.
+ \endgraf % Not \par, as it may have been set to \lisppar.
+ \global\dimen1 = \prevdepth
+ \egroup % End the \vtop.
+ % \dimen0 is the vertical size of the group's box.
+ \dimen0 = \ht\groupbox \advance\dimen0 by \dp\groupbox
+ % \dimen2 is how much space is left on the page (more or less).
+ \dimen2 = \pageheight \advance\dimen2 by -\pagetotal
+ % if the group doesn't fit on the current page, and it's a big big
+ % group, force a page break.
+ \ifdim \dimen0 > \dimen2
+ \ifdim \pagetotal < \vfilllimit\pageheight
+ \page
+ \fi
+ \fi
+ \box\groupbox
+ \prevdepth = \dimen1
+ \checkinserts
+}
+%
+% TeX puts in an \escapechar (i.e., `@') at the beginning of the help
+% message, so this ends up printing `@group can only ...'.
+%
+\newhelp\groupinvalidhelp{%
+group can only be used in environments such as @example,^^J%
+where each line of input produces a line of output.}
+
+% @need space-in-mils
+% forces a page break if there is not space-in-mils remaining.
+
+\newdimen\mil \mil=0.001in
+
+\parseargdef\need{%
+ % Ensure vertical mode, so we don't make a big box in the middle of a
+ % paragraph.
+ \par
+ %
+ % If the @need value is less than one line space, it's useless.
+ \dimen0 = #1\mil
+ \dimen2 = \ht\strutbox
+ \advance\dimen2 by \dp\strutbox
+ \ifdim\dimen0 > \dimen2
+ %
+ % Do a \strut just to make the height of this box be normal, so the
+ % normal leading is inserted relative to the preceding line.
+ % And a page break here is fine.
+ \vtop to #1\mil{\strut\vfil}%
+ %
+ % TeX does not even consider page breaks if a penalty added to the
+ % main vertical list is 10000 or more. But in order to see if the
+ % empty box we just added fits on the page, we must make it consider
+ % page breaks. On the other hand, we don't want to actually break the
+ % page after the empty box. So we use a penalty of 9999.
+ %
+ % There is an extremely small chance that TeX will actually break the
+ % page at this \penalty, if there are no other feasible breakpoints in
+ % sight. (If the user is using lots of big @group commands, which
+ % almost-but-not-quite fill up a page, TeX will have a hard time doing
+ % good page breaking, for example.) However, I could not construct an
+ % example where a page broke at this \penalty; if it happens in a real
+ % document, then we can reconsider our strategy.
+ \penalty9999
+ %
+ % Back up by the size of the box, whether we did a page break or not.
+ \kern -#1\mil
+ %
+ % Do not allow a page break right after this kern.
+ \nobreak
+ \fi
+}
+
+% @br forces paragraph break (and is undocumented).
+
+\let\br = \par
+
+% @page forces the start of a new page.
+%
+\def\page{\par\vfill\supereject}
+
+% @exdent text....
+% outputs text on separate line in roman font, starting at standard page margin
+
+% This records the amount of indent in the innermost environment.
+% That's how much \exdent should take out.
+\newskip\exdentamount
+
+% This defn is used inside fill environments such as @defun.
+\parseargdef\exdent{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}
+
+% This defn is used inside nofill environments such as @example.
+\parseargdef\nofillexdent{{\advance \leftskip by -\exdentamount
+ \leftline{\hskip\leftskip{\rm#1}}}}
+
+% @inmargin{WHICH}{TEXT} puts TEXT in the WHICH margin next to the current
+% paragraph. For more general purposes, use the \margin insertion
+% class. WHICH is `l' or `r'. Not documented, written for gawk manual.
+%
+\newskip\inmarginspacing \inmarginspacing=1cm
+\def\strutdepth{\dp\strutbox}
+%
+\def\doinmargin#1#2{\strut\vadjust{%
+ \nobreak
+ \kern-\strutdepth
+ \vtop to \strutdepth{%
+ \baselineskip=\strutdepth
+ \vss
+ % if you have multiple lines of stuff to put here, you'll need to
+ % make the vbox yourself of the appropriate size.
+ \ifx#1l%
+ \llap{\ignorespaces #2\hskip\inmarginspacing}%
+ \else
+ \rlap{\hskip\hsize \hskip\inmarginspacing \ignorespaces #2}%
+ \fi
+ \null
+ }%
+}}
+\def\inleftmargin{\doinmargin l}
+\def\inrightmargin{\doinmargin r}
+%
+% @inmargin{TEXT [, RIGHT-TEXT]}
+% (if RIGHT-TEXT is given, use TEXT for left page, RIGHT-TEXT for right;
+% else use TEXT for both).
+%
+\def\inmargin#1{\parseinmargin #1,,\finish}
+\def\parseinmargin#1,#2,#3\finish{% not perfect, but better than nothing.
+ \setbox0 = \hbox{\ignorespaces #2}%
+ \ifdim\wd0 > 0pt
+ \def\lefttext{#1}% have both texts
+ \def\righttext{#2}%
+ \else
+ \def\lefttext{#1}% have only one text
+ \def\righttext{#1}%
+ \fi
+ %
+ \ifodd\pageno
+ \def\temp{\inrightmargin\righttext}% odd page -> outside is right margin
+ \else
+ \def\temp{\inleftmargin\lefttext}%
+ \fi
+ \temp
+}
+
+% @| inserts a changebar to the left of the current line. It should
+% surround any changed text. This approach does *not* work if the
+% change spans more than two lines of output. To handle that, we would
+% have adopt a much more difficult approach (putting marks into the main
+% vertical list for the beginning and end of each change). This command
+% is not documented, not supported, and doesn't work.
+%
+\def\|{%
+ % \vadjust can only be used in horizontal mode.
+ \leavevmode
+ %
+ % Append this vertical mode material after the current line in the output.
+ \vadjust{%
+ % We want to insert a rule with the height and depth of the current
+ % leading; that is exactly what \strutbox is supposed to record.
+ \vskip-\baselineskip
+ %
+ % \vadjust-items are inserted at the left edge of the type. So
+ % the \llap here moves out into the left-hand margin.
+ \llap{%
+ %
+ % For a thicker or thinner bar, change the `1pt'.
+ \vrule height\baselineskip width1pt
+ %
+ % This is the space between the bar and the text.
+ \hskip 12pt
+ }%
+ }%
+}
+
+% @include FILE -- \input text of FILE.
+%
+\def\include{\parseargusing\filenamecatcodes\includezzz}
+\def\includezzz#1{%
+ \pushthisfilestack
+ \def\thisfile{#1}%
+ {%
+ \makevalueexpandable % we want to expand any @value in FILE.
+ \turnoffactive % and allow special characters in the expansion
+ \indexnofonts % Allow `@@' and other weird things in file names.
+ \wlog{texinfo.tex: doing @include of #1^^J}%
+ \edef\temp{\noexpand\input #1 }%
+ %
+ % This trickery is to read FILE outside of a group, in case it makes
+ % definitions, etc.
+ \expandafter
+ }\temp
+ \popthisfilestack
+}
+\def\filenamecatcodes{%
+ \catcode`\\=\other
+ \catcode`~=\other
+ \catcode`^=\other
+ \catcode`_=\other
+ \catcode`|=\other
+ \catcode`<=\other
+ \catcode`>=\other
+ \catcode`+=\other
+ \catcode`-=\other
+ \catcode`\`=\other
+ \catcode`\'=\other
+}
+
+\def\pushthisfilestack{%
+ \expandafter\pushthisfilestackX\popthisfilestack\StackTerm
+}
+\def\pushthisfilestackX{%
+ \expandafter\pushthisfilestackY\thisfile\StackTerm
+}
+\def\pushthisfilestackY #1\StackTerm #2\StackTerm {%
+ \gdef\popthisfilestack{\gdef\thisfile{#1}\gdef\popthisfilestack{#2}}%
+}
+
+\def\popthisfilestack{\errthisfilestackempty}
+\def\errthisfilestackempty{\errmessage{Internal error:
+ the stack of filenames is empty.}}
+%
+\def\thisfile{}
+
+% @center line
+% outputs that line, centered.
+%
+\parseargdef\center{%
+ \ifhmode
+ \let\centersub\centerH
+ \else
+ \let\centersub\centerV
+ \fi
+ \centersub{\hfil \ignorespaces#1\unskip \hfil}%
+ \let\centersub\relax % don't let the definition persist, just in case
+}
+\def\centerH#1{{%
+ \hfil\break
+ \advance\hsize by -\leftskip
+ \advance\hsize by -\rightskip
+ \line{#1}%
+ \break
+}}
+%
+\newcount\centerpenalty
+\def\centerV#1{%
+ % The idea here is the same as in \startdefun, \cartouche, etc.: if
+ % @center is the first thing after a section heading, we need to wipe
+ % out the negative parskip inserted by \sectionheading, but still
+ % prevent a page break here.
+ \centerpenalty = \lastpenalty
+ \ifnum\centerpenalty>10000 \vskip\parskip \fi
+ \ifnum\centerpenalty>9999 \penalty\centerpenalty \fi
+ \line{\kern\leftskip #1\kern\rightskip}%
+}
+
+% @sp n outputs n lines of vertical space
+%
+\parseargdef\sp{\vskip #1\baselineskip}
+
+% @comment ...line which is ignored...
+% @c is the same as @comment
+% @ignore ... @end ignore is another way to write a comment
+%
+\def\comment{\begingroup \catcode`\^^M=\other%
+\catcode`\@=\other \catcode`\{=\other \catcode`\}=\other%
+\commentxxx}
+{\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}}
+%
+\let\c=\comment
+
+% @paragraphindent NCHARS
+% We'll use ems for NCHARS, close enough.
+% NCHARS can also be the word `asis' or `none'.
+% We cannot feasibly implement @paragraphindent asis, though.
+%
+\def\asisword{asis} % no translation, these are keywords
+\def\noneword{none}
+%
+\parseargdef\paragraphindent{%
+ \def\temp{#1}%
+ \ifx\temp\asisword
+ \else
+ \ifx\temp\noneword
+ \defaultparindent = 0pt
+ \else
+ \defaultparindent = #1em
+ \fi
+ \fi
+ \parindent = \defaultparindent
+}
+
+% @exampleindent NCHARS
+% We'll use ems for NCHARS like @paragraphindent.
+% It seems @exampleindent asis isn't necessary, but
+% I preserve it to make it similar to @paragraphindent.
+\parseargdef\exampleindent{%
+ \def\temp{#1}%
+ \ifx\temp\asisword
+ \else
+ \ifx\temp\noneword
+ \lispnarrowing = 0pt
+ \else
+ \lispnarrowing = #1em
+ \fi
+ \fi
+}
+
+% @firstparagraphindent WORD
+% If WORD is `none', then suppress indentation of the first paragraph
+% after a section heading. If WORD is `insert', then do indent at such
+% paragraphs.
+%
+% The paragraph indentation is suppressed or not by calling
+% \suppressfirstparagraphindent, which the sectioning commands do.
+% We switch the definition of this back and forth according to WORD.
+% By default, we suppress indentation.
+%
+\def\suppressfirstparagraphindent{\dosuppressfirstparagraphindent}
+\def\insertword{insert}
+%
+\parseargdef\firstparagraphindent{%
+ \def\temp{#1}%
+ \ifx\temp\noneword
+ \let\suppressfirstparagraphindent = \dosuppressfirstparagraphindent
+ \else\ifx\temp\insertword
+ \let\suppressfirstparagraphindent = \relax
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @firstparagraphindent option `\temp'}%
+ \fi\fi
+}
+
+% Here is how we actually suppress indentation. Redefine \everypar to
+% \kern backwards by \parindent, and then reset itself to empty.
+%
+% We also make \indent itself not actually do anything until the next
+% paragraph.
+%
+\gdef\dosuppressfirstparagraphindent{%
+ \gdef\indent{%
+ \restorefirstparagraphindent
+ \indent
+ }%
+ \gdef\noindent{%
+ \restorefirstparagraphindent
+ \noindent
+ }%
+ \global\everypar = {%
+ \kern -\parindent
+ \restorefirstparagraphindent
+ }%
+}
+
+\gdef\restorefirstparagraphindent{%
+ \global \let \indent = \ptexindent
+ \global \let \noindent = \ptexnoindent
+ \global \everypar = {}%
+}
+
+
+% @refill is a no-op.
+\let\refill=\relax
+
+% If working on a large document in chapters, it is convenient to
+% be able to disable indexing, cross-referencing, and contents, for test runs.
+% This is done with @novalidate (before @setfilename).
+%
+\newif\iflinks \linkstrue % by default we want the aux files.
+\let\novalidate = \linksfalse
+
+% @setfilename is done at the beginning of every texinfo file.
+% So open here the files we need to have open while reading the input.
+% This makes it possible to make a .fmt file for texinfo.
+\def\setfilename{%
+ \fixbackslash % Turn off hack to swallow `\input texinfo'.
+ \iflinks
+ \tryauxfile
+ % Open the new aux file. TeX will close it automatically at exit.
+ \immediate\openout\auxfile=\jobname.aux
+ \fi % \openindices needs to do some work in any case.
+ \openindices
+ \let\setfilename=\comment % Ignore extra @setfilename cmds.
+ %
+ % If texinfo.cnf is present on the system, read it.
+ % Useful for site-wide @afourpaper, etc.
+ \openin 1 texinfo.cnf
+ \ifeof 1 \else \input texinfo.cnf \fi
+ \closein 1
+ %
+ \comment % Ignore the actual filename.
+}
+
+% Called from \setfilename.
+%
+\def\openindices{%
+ \newindex{cp}%
+ \newcodeindex{fn}%
+ \newcodeindex{vr}%
+ \newcodeindex{tp}%
+ \newcodeindex{ky}%
+ \newcodeindex{pg}%
+}
+
+% @bye.
+\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend}
+
+
+\message{pdf,}
+% adobe `portable' document format
+\newcount\tempnum
+\newcount\lnkcount
+\newtoks\filename
+\newcount\filenamelength
+\newcount\pgn
+\newtoks\toksA
+\newtoks\toksB
+\newtoks\toksC
+\newtoks\toksD
+\newbox\boxA
+\newcount\countA
+\newif\ifpdf
+\newif\ifpdfmakepagedest
+
+% when pdftex is run in dvi mode, \pdfoutput is defined (so \pdfoutput=1
+% can be set). So we test for \relax and 0 as well as being undefined.
+\ifx\pdfoutput\thisisundefined
+\else
+ \ifx\pdfoutput\relax
+ \else
+ \ifcase\pdfoutput
+ \else
+ \pdftrue
+ \fi
+ \fi
+\fi
+
+% PDF uses PostScript string constants for the names of xref targets,
+% for display in the outlines, and in other places. Thus, we have to
+% double any backslashes. Otherwise, a name like "\node" will be
+% interpreted as a newline (\n), followed by o, d, e. Not good.
+%
+% See http://www.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html and
+% related messages. The final outcome is that it is up to the TeX user
+% to double the backslashes and otherwise make the string valid, so
+% that's what we do. pdftex 1.30.0 (ca.2005) introduced a primitive to
+% do this reliably, so we use it.
+
+% #1 is a control sequence in which to do the replacements,
+% which we \xdef.
+\def\txiescapepdf#1{%
+ \ifx\pdfescapestring\thisisundefined
+ % No primitive available; should we give a warning or log?
+ % Many times it won't matter.
+ \else
+ % The expandable \pdfescapestring primitive escapes parentheses,
+ % backslashes, and other special chars.
+ \xdef#1{\pdfescapestring{#1}}%
+ \fi
+}
+
+\newhelp\nopdfimagehelp{Texinfo supports .png, .jpg, .jpeg, and .pdf images
+with PDF output, and none of those formats could be found. (.eps cannot
+be supported due to the design of the PDF format; use regular TeX (DVI
+output) for that.)}
+
+\ifpdf
+ %
+ % Color manipulation macros using ideas from pdfcolor.tex,
+ % except using rgb instead of cmyk; the latter is said to render as a
+ % very dark gray on-screen and a very dark halftone in print, instead
+ % of actual black. The dark red here is dark enough to print on paper as
+ % nearly black, but still distinguishable for online viewing. We use
+ % black by default, though.
+ \def\rgbDarkRed{0.50 0.09 0.12}
+ \def\rgbBlack{0 0 0}
+ %
+ % k sets the color for filling (usual text, etc.);
+ % K sets the color for stroking (thin rules, e.g., normal _'s).
+ \def\pdfsetcolor#1{\pdfliteral{#1 rg #1 RG}}
+ %
+ % Set color, and create a mark which defines \thiscolor accordingly,
+ % so that \makeheadline knows which color to restore.
+ \def\setcolor#1{%
+ \xdef\lastcolordefs{\gdef\noexpand\thiscolor{#1}}%
+ \domark
+ \pdfsetcolor{#1}%
+ }
+ %
+ \def\maincolor{\rgbBlack}
+ \pdfsetcolor{\maincolor}
+ \edef\thiscolor{\maincolor}
+ \def\lastcolordefs{}
+ %
+ \def\makefootline{%
+ \baselineskip24pt
+ \line{\pdfsetcolor{\maincolor}\the\footline}%
+ }
+ %
+ \def\makeheadline{%
+ \vbox to 0pt{%
+ \vskip-22.5pt
+ \line{%
+ \vbox to8.5pt{}%
+ % Extract \thiscolor definition from the marks.
+ \getcolormarks
+ % Typeset the headline with \maincolor, then restore the color.
+ \pdfsetcolor{\maincolor}\the\headline\pdfsetcolor{\thiscolor}%
+ }%
+ \vss
+ }%
+ \nointerlineskip
+ }
+ %
+ %
+ \pdfcatalog{/PageMode /UseOutlines}
+ %
+ % #1 is image name, #2 width (might be empty/whitespace), #3 height (ditto).
+ \def\dopdfimage#1#2#3{%
+ \def\pdfimagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}%
+ \def\pdfimageheight{#3}\setbox2 = \hbox{\ignorespaces #3}%
+ %
+ % pdftex (and the PDF format) support .pdf, .png, .jpg (among
+ % others). Let's try in that order, PDF first since if
+ % someone has a scalable image, presumably better to use that than a
+ % bitmap.
+ \let\pdfimgext=\empty
+ \begingroup
+ \openin 1 #1.pdf \ifeof 1
+ \openin 1 #1.PDF \ifeof 1
+ \openin 1 #1.png \ifeof 1
+ \openin 1 #1.jpg \ifeof 1
+ \openin 1 #1.jpeg \ifeof 1
+ \openin 1 #1.JPG \ifeof 1
+ \errhelp = \nopdfimagehelp
+ \errmessage{Could not find image file #1 for pdf}%
+ \else \gdef\pdfimgext{JPG}%
+ \fi
+ \else \gdef\pdfimgext{jpeg}%
+ \fi
+ \else \gdef\pdfimgext{jpg}%
+ \fi
+ \else \gdef\pdfimgext{png}%
+ \fi
+ \else \gdef\pdfimgext{PDF}%
+ \fi
+ \else \gdef\pdfimgext{pdf}%
+ \fi
+ \closein 1
+ \endgroup
+ %
+ % without \immediate, ancient pdftex seg faults when the same image is
+ % included twice. (Version 3.14159-pre-1.0-unofficial-20010704.)
+ \ifnum\pdftexversion < 14
+ \immediate\pdfimage
+ \else
+ \immediate\pdfximage
+ \fi
+ \ifdim \wd0 >0pt width \pdfimagewidth \fi
+ \ifdim \wd2 >0pt height \pdfimageheight \fi
+ \ifnum\pdftexversion<13
+ #1.\pdfimgext
+ \else
+ {#1.\pdfimgext}%
+ \fi
+ \ifnum\pdftexversion < 14 \else
+ \pdfrefximage \pdflastximage
+ \fi}
+ %
+ \def\pdfmkdest#1{{%
+ % We have to set dummies so commands such as @code, and characters
+ % such as \, aren't expanded when present in a section title.
+ \indexnofonts
+ \turnoffactive
+ \makevalueexpandable
+ \def\pdfdestname{#1}%
+ \txiescapepdf\pdfdestname
+ \safewhatsit{\pdfdest name{\pdfdestname} xyz}%
+ }}
+ %
+ % used to mark target names; must be expandable.
+ \def\pdfmkpgn#1{#1}
+ %
+ % by default, use black for everything.
+ \def\urlcolor{\rgbBlack}
+ \def\linkcolor{\rgbBlack}
+ \def\endlink{\setcolor{\maincolor}\pdfendlink}
+ %
+ % Adding outlines to PDF; macros for calculating structure of outlines
+ % come from Petr Olsak
+ \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0%
+ \else \csname#1\endcsname \fi}
+ \def\advancenumber#1{\tempnum=\expnumber{#1}\relax
+ \advance\tempnum by 1
+ \expandafter\xdef\csname#1\endcsname{\the\tempnum}}
+ %
+ % #1 is the section text, which is what will be displayed in the
+ % outline by the pdf viewer. #2 is the pdf expression for the number
+ % of subentries (or empty, for subsubsections). #3 is the node text,
+ % which might be empty if this toc entry had no corresponding node.
+ % #4 is the page number
+ %
+ \def\dopdfoutline#1#2#3#4{%
+ % Generate a link to the node text if that exists; else, use the
+ % page number. We could generate a destination for the section
+ % text in the case where a section has no node, but it doesn't
+ % seem worth the trouble, since most documents are normally structured.
+ \edef\pdfoutlinedest{#3}%
+ \ifx\pdfoutlinedest\empty
+ \def\pdfoutlinedest{#4}%
+ \else
+ \txiescapepdf\pdfoutlinedest
+ \fi
+ %
+ % Also escape PDF chars in the display string.
+ \edef\pdfoutlinetext{#1}%
+ \txiescapepdf\pdfoutlinetext
+ %
+ \pdfoutline goto name{\pdfmkpgn{\pdfoutlinedest}}#2{\pdfoutlinetext}%
+ }
+ %
+ \def\pdfmakeoutlines{%
+ \begingroup
+ % Read toc silently, to get counts of subentries for \pdfoutline.
+ \def\partentry##1##2##3##4{}% ignore parts in the outlines
+ \def\numchapentry##1##2##3##4{%
+ \def\thischapnum{##2}%
+ \def\thissecnum{0}%
+ \def\thissubsecnum{0}%
+ }%
+ \def\numsecentry##1##2##3##4{%
+ \advancenumber{chap\thischapnum}%
+ \def\thissecnum{##2}%
+ \def\thissubsecnum{0}%
+ }%
+ \def\numsubsecentry##1##2##3##4{%
+ \advancenumber{sec\thissecnum}%
+ \def\thissubsecnum{##2}%
+ }%
+ \def\numsubsubsecentry##1##2##3##4{%
+ \advancenumber{subsec\thissubsecnum}%
+ }%
+ \def\thischapnum{0}%
+ \def\thissecnum{0}%
+ \def\thissubsecnum{0}%
+ %
+ % use \def rather than \let here because we redefine \chapentry et
+ % al. a second time, below.
+ \def\appentry{\numchapentry}%
+ \def\appsecentry{\numsecentry}%
+ \def\appsubsecentry{\numsubsecentry}%
+ \def\appsubsubsecentry{\numsubsubsecentry}%
+ \def\unnchapentry{\numchapentry}%
+ \def\unnsecentry{\numsecentry}%
+ \def\unnsubsecentry{\numsubsecentry}%
+ \def\unnsubsubsecentry{\numsubsubsecentry}%
+ \readdatafile{toc}%
+ %
+ % Read toc second time, this time actually producing the outlines.
+ % The `-' means take the \expnumber as the absolute number of
+ % subentries, which we calculated on our first read of the .toc above.
+ %
+ % We use the node names as the destinations.
+ \def\numchapentry##1##2##3##4{%
+ \dopdfoutline{##1}{count-\expnumber{chap##2}}{##3}{##4}}%
+ \def\numsecentry##1##2##3##4{%
+ \dopdfoutline{##1}{count-\expnumber{sec##2}}{##3}{##4}}%
+ \def\numsubsecentry##1##2##3##4{%
+ \dopdfoutline{##1}{count-\expnumber{subsec##2}}{##3}{##4}}%
+ \def\numsubsubsecentry##1##2##3##4{% count is always zero
+ \dopdfoutline{##1}{}{##3}{##4}}%
+ %
+ % PDF outlines are displayed using system fonts, instead of
+ % document fonts. Therefore we cannot use special characters,
+ % since the encoding is unknown. For example, the eogonek from
+ % Latin 2 (0xea) gets translated to a | character. Info from
+ % Staszek Wawrykiewicz, 19 Jan 2004 04:09:24 +0100.
+ %
+ % TODO this right, we have to translate 8-bit characters to
+ % their "best" equivalent, based on the @documentencoding. Too
+ % much work for too little return. Just use the ASCII equivalents
+ % we use for the index sort strings.
+ %
+ \indexnofonts
+ \setupdatafile
+ % We can have normal brace characters in the PDF outlines, unlike
+ % Texinfo index files. So set that up.
+ \def\{{\lbracecharliteral}%
+ \def\}{\rbracecharliteral}%
+ \catcode`\\=\active \otherbackslash
+ \input \tocreadfilename
+ \endgroup
+ }
+ {\catcode`[=1 \catcode`]=2
+ \catcode`{=\other \catcode`}=\other
+ \gdef\lbracecharliteral[{]%
+ \gdef\rbracecharliteral[}]%
+ ]
+ %
+ \def\skipspaces#1{\def\PP{#1}\def\D{|}%
+ \ifx\PP\D\let\nextsp\relax
+ \else\let\nextsp\skipspaces
+ \addtokens{\filename}{\PP}%
+ \advance\filenamelength by 1
+ \fi
+ \nextsp}
+ \def\getfilename#1{%
+ \filenamelength=0
+ % If we don't expand the argument now, \skipspaces will get
+ % snagged on things like "@value{foo}".
+ \edef\temp{#1}%
+ \expandafter\skipspaces\temp|\relax
+ }
+ \ifnum\pdftexversion < 14
+ \let \startlink \pdfannotlink
+ \else
+ \let \startlink \pdfstartlink
+ \fi
+ % make a live url in pdf output.
+ \def\pdfurl#1{%
+ \begingroup
+ % it seems we really need yet another set of dummies; have not
+ % tried to figure out what each command should do in the context
+ % of @url. for now, just make @/ a no-op, that's the only one
+ % people have actually reported a problem with.
+ %
+ \normalturnoffactive
+ \def\@{@}%
+ \let\/=\empty
+ \makevalueexpandable
+ % do we want to go so far as to use \indexnofonts instead of just
+ % special-casing \var here?
+ \def\var##1{##1}%
+ %
+ \leavevmode\setcolor{\urlcolor}%
+ \startlink attr{/Border [0 0 0]}%
+ user{/Subtype /Link /A << /S /URI /URI (#1) >>}%
+ \endgroup}
+ \def\pdfgettoks#1.{\setbox\boxA=\hbox{\toksA={#1.}\toksB={}\maketoks}}
+ \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks}
+ \def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks}
+ \def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}}
+ \def\maketoks{%
+ \expandafter\poptoks\the\toksA|ENDTOKS|\relax
+ \ifx\first0\adn0
+ \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3
+ \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6
+ \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9
+ \else
+ \ifnum0=\countA\else\makelink\fi
+ \ifx\first.\let\next=\done\else
+ \let\next=\maketoks
+ \addtokens{\toksB}{\the\toksD}
+ \ifx\first,\addtokens{\toksB}{\space}\fi
+ \fi
+ \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+ \next}
+ \def\makelink{\addtokens{\toksB}%
+ {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0}
+ \def\pdflink#1{%
+ \startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{#1}}
+ \setcolor{\linkcolor}#1\endlink}
+ \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st}
+\else
+ % non-pdf mode
+ \let\pdfmkdest = \gobble
+ \let\pdfurl = \gobble
+ \let\endlink = \relax
+ \let\setcolor = \gobble
+ \let\pdfsetcolor = \gobble
+ \let\pdfmakeoutlines = \relax
+\fi % \ifx\pdfoutput
+
+
+\message{fonts,}
+
+% Change the current font style to #1, remembering it in \curfontstyle.
+% For now, we do not accumulate font styles: @b{@i{foo}} prints foo in
+% italics, not bold italics.
+%
+\def\setfontstyle#1{%
+ \def\curfontstyle{#1}% not as a control sequence, because we are \edef'd.
+ \csname ten#1\endcsname % change the current font
+}
+
+% Select #1 fonts with the current style.
+%
+\def\selectfonts#1{\csname #1fonts\endcsname \csname\curfontstyle\endcsname}
+
+\def\rm{\fam=0 \setfontstyle{rm}}
+\def\it{\fam=\itfam \setfontstyle{it}}
+\def\sl{\fam=\slfam \setfontstyle{sl}}
+\def\bf{\fam=\bffam \setfontstyle{bf}}\def\bfstylename{bf}
+\def\tt{\fam=\ttfam \setfontstyle{tt}}
+
+% Unfortunately, we have to override this for titles and the like, since
+% in those cases "rm" is bold. Sigh.
+\def\rmisbold{\rm\def\curfontstyle{bf}}
+
+% Texinfo sort of supports the sans serif font style, which plain TeX does not.
+% So we set up a \sf.
+\newfam\sffam
+\def\sf{\fam=\sffam \setfontstyle{sf}}
+\let\li = \sf % Sometimes we call it \li, not \sf.
+
+% We don't need math for this font style.
+\def\ttsl{\setfontstyle{ttsl}}
+
+
+% Set the baselineskip to #1, and the lineskip and strut size
+% correspondingly. There is no deep meaning behind these magic numbers
+% used as factors; they just match (closely enough) what Knuth defined.
+%
+\def\lineskipfactor{.08333}
+\def\strutheightpercent{.70833}
+\def\strutdepthpercent {.29167}
+%
+% can get a sort of poor man's double spacing by redefining this.
+\def\baselinefactor{1}
+%
+\newdimen\textleading
+\def\setleading#1{%
+ \dimen0 = #1\relax
+ \normalbaselineskip = \baselinefactor\dimen0
+ \normallineskip = \lineskipfactor\normalbaselineskip
+ \normalbaselines
+ \setbox\strutbox =\hbox{%
+ \vrule width0pt height\strutheightpercent\baselineskip
+ depth \strutdepthpercent \baselineskip
+ }%
+}
+
+% PDF CMaps. See also LaTeX's t1.cmap.
+%
+% do nothing with this by default.
+\expandafter\let\csname cmapOT1\endcsname\gobble
+\expandafter\let\csname cmapOT1IT\endcsname\gobble
+\expandafter\let\csname cmapOT1TT\endcsname\gobble
+
+% if we are producing pdf, and we have \pdffontattr, then define cmaps.
+% (\pdffontattr was introduced many years ago, but people still run
+% older pdftex's; it's easy to conditionalize, so we do.)
+\ifpdf \ifx\pdffontattr\thisisundefined \else
+ \begingroup
+ \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char.
+ \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap
+%%DocumentNeededResources: ProcSet (CIDInit)
+%%IncludeResource: ProcSet (CIDInit)
+%%BeginResource: CMap (TeX-OT1-0)
+%%Title: (TeX-OT1-0 TeX OT1 0)
+%%Version: 1.000
+%%EndComments
+/CIDInit /ProcSet findresource begin
+12 dict begin
+begincmap
+/CIDSystemInfo
+<< /Registry (TeX)
+/Ordering (OT1)
+/Supplement 0
+>> def
+/CMapName /TeX-OT1-0 def
+/CMapType 2 def
+1 begincodespacerange
+<00> <7F>
+endcodespacerange
+8 beginbfrange
+<00> <01> <0393>
+<09> <0A> <03A8>
+<23> <26> <0023>
+<28> <3B> <0028>
+<3F> <5B> <003F>
+<5D> <5E> <005D>
+<61> <7A> <0061>
+<7B> <7C> <2013>
+endbfrange
+40 beginbfchar
+<02> <0398>
+<03> <039B>
+<04> <039E>
+<05> <03A0>
+<06> <03A3>
+<07> <03D2>
+<08> <03A6>
+<0B> <00660066>
+<0C> <00660069>
+<0D> <0066006C>
+<0E> <006600660069>
+<0F> <00660066006C>
+<10> <0131>
+<11> <0237>
+<12> <0060>
+<13> <00B4>
+<14> <02C7>
+<15> <02D8>
+<16> <00AF>
+<17> <02DA>
+<18> <00B8>
+<19> <00DF>
+<1A> <00E6>
+<1B> <0153>
+<1C> <00F8>
+<1D> <00C6>
+<1E> <0152>
+<1F> <00D8>
+<21> <0021>
+<22> <201D>
+<27> <2019>
+<3C> <00A1>
+<3D> <003D>
+<3E> <00BF>
+<5C> <201C>
+<5F> <02D9>
+<60> <2018>
+<7D> <02DD>
+<7E> <007E>
+<7F> <00A8>
+endbfchar
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+%%EndResource
+%%EOF
+ }\endgroup
+ \expandafter\edef\csname cmapOT1\endcsname#1{%
+ \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}%
+ }%
+%
+% \cmapOT1IT
+ \begingroup
+ \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char.
+ \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap
+%%DocumentNeededResources: ProcSet (CIDInit)
+%%IncludeResource: ProcSet (CIDInit)
+%%BeginResource: CMap (TeX-OT1IT-0)
+%%Title: (TeX-OT1IT-0 TeX OT1IT 0)
+%%Version: 1.000
+%%EndComments
+/CIDInit /ProcSet findresource begin
+12 dict begin
+begincmap
+/CIDSystemInfo
+<< /Registry (TeX)
+/Ordering (OT1IT)
+/Supplement 0
+>> def
+/CMapName /TeX-OT1IT-0 def
+/CMapType 2 def
+1 begincodespacerange
+<00> <7F>
+endcodespacerange
+8 beginbfrange
+<00> <01> <0393>
+<09> <0A> <03A8>
+<25> <26> <0025>
+<28> <3B> <0028>
+<3F> <5B> <003F>
+<5D> <5E> <005D>
+<61> <7A> <0061>
+<7B> <7C> <2013>
+endbfrange
+42 beginbfchar
+<02> <0398>
+<03> <039B>
+<04> <039E>
+<05> <03A0>
+<06> <03A3>
+<07> <03D2>
+<08> <03A6>
+<0B> <00660066>
+<0C> <00660069>
+<0D> <0066006C>
+<0E> <006600660069>
+<0F> <00660066006C>
+<10> <0131>
+<11> <0237>
+<12> <0060>
+<13> <00B4>
+<14> <02C7>
+<15> <02D8>
+<16> <00AF>
+<17> <02DA>
+<18> <00B8>
+<19> <00DF>
+<1A> <00E6>
+<1B> <0153>
+<1C> <00F8>
+<1D> <00C6>
+<1E> <0152>
+<1F> <00D8>
+<21> <0021>
+<22> <201D>
+<23> <0023>
+<24> <00A3>
+<27> <2019>
+<3C> <00A1>
+<3D> <003D>
+<3E> <00BF>
+<5C> <201C>
+<5F> <02D9>
+<60> <2018>
+<7D> <02DD>
+<7E> <007E>
+<7F> <00A8>
+endbfchar
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+%%EndResource
+%%EOF
+ }\endgroup
+ \expandafter\edef\csname cmapOT1IT\endcsname#1{%
+ \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}%
+ }%
+%
+% \cmapOT1TT
+ \begingroup
+ \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char.
+ \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap
+%%DocumentNeededResources: ProcSet (CIDInit)
+%%IncludeResource: ProcSet (CIDInit)
+%%BeginResource: CMap (TeX-OT1TT-0)
+%%Title: (TeX-OT1TT-0 TeX OT1TT 0)
+%%Version: 1.000
+%%EndComments
+/CIDInit /ProcSet findresource begin
+12 dict begin
+begincmap
+/CIDSystemInfo
+<< /Registry (TeX)
+/Ordering (OT1TT)
+/Supplement 0
+>> def
+/CMapName /TeX-OT1TT-0 def
+/CMapType 2 def
+1 begincodespacerange
+<00> <7F>
+endcodespacerange
+5 beginbfrange
+<00> <01> <0393>
+<09> <0A> <03A8>
+<21> <26> <0021>
+<28> <5F> <0028>
+<61> <7E> <0061>
+endbfrange
+32 beginbfchar
+<02> <0398>
+<03> <039B>
+<04> <039E>
+<05> <03A0>
+<06> <03A3>
+<07> <03D2>
+<08> <03A6>
+<0B> <2191>
+<0C> <2193>
+<0D> <0027>
+<0E> <00A1>
+<0F> <00BF>
+<10> <0131>
+<11> <0237>
+<12> <0060>
+<13> <00B4>
+<14> <02C7>
+<15> <02D8>
+<16> <00AF>
+<17> <02DA>
+<18> <00B8>
+<19> <00DF>
+<1A> <00E6>
+<1B> <0153>
+<1C> <00F8>
+<1D> <00C6>
+<1E> <0152>
+<1F> <00D8>
+<20> <2423>
+<27> <2019>
+<60> <2018>
+<7F> <00A8>
+endbfchar
+endcmap
+CMapName currentdict /CMap defineresource pop
+end
+end
+%%EndResource
+%%EOF
+ }\endgroup
+ \expandafter\edef\csname cmapOT1TT\endcsname#1{%
+ \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}%
+ }%
+\fi\fi
+
+
+% Set the font macro #1 to the font named \fontprefix#2.
+% #3 is the font's design size, #4 is a scale factor, #5 is the CMap
+% encoding (only OT1, OT1IT and OT1TT are allowed, or empty to omit).
+% Example:
+% #1 = \textrm
+% #2 = \rmshape
+% #3 = 10
+% #4 = \mainmagstep
+% #5 = OT1
+%
+\def\setfont#1#2#3#4#5{%
+ \font#1=\fontprefix#2#3 scaled #4
+ \csname cmap#5\endcsname#1%
+}
+% This is what gets called when #5 of \setfont is empty.
+\let\cmap\gobble
+%
+% (end of cmaps)
+
+% Use cm as the default font prefix.
+% To specify the font prefix, you must define \fontprefix
+% before you read in texinfo.tex.
+\ifx\fontprefix\thisisundefined
+\def\fontprefix{cm}
+\fi
+% Support font families that don't use the same naming scheme as CM.
+\def\rmshape{r}
+\def\rmbshape{bx} % where the normal face is bold
+\def\bfshape{b}
+\def\bxshape{bx}
+\def\ttshape{tt}
+\def\ttbshape{tt}
+\def\ttslshape{sltt}
+\def\itshape{ti}
+\def\itbshape{bxti}
+\def\slshape{sl}
+\def\slbshape{bxsl}
+\def\sfshape{ss}
+\def\sfbshape{ss}
+\def\scshape{csc}
+\def\scbshape{csc}
+
+% Definitions for a main text size of 11pt. (The default in Texinfo.)
+%
+\def\definetextfontsizexi{%
+% Text fonts (11.2pt, magstep1).
+\def\textnominalsize{11pt}
+\edef\mainmagstep{\magstephalf}
+\setfont\textrm\rmshape{10}{\mainmagstep}{OT1}
+\setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT}
+\setfont\textbf\bfshape{10}{\mainmagstep}{OT1}
+\setfont\textit\itshape{10}{\mainmagstep}{OT1IT}
+\setfont\textsl\slshape{10}{\mainmagstep}{OT1}
+\setfont\textsf\sfshape{10}{\mainmagstep}{OT1}
+\setfont\textsc\scshape{10}{\mainmagstep}{OT1}
+\setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT}
+\font\texti=cmmi10 scaled \mainmagstep
+\font\textsy=cmsy10 scaled \mainmagstep
+\def\textecsize{1095}
+
+% A few fonts for @defun names and args.
+\setfont\defbf\bfshape{10}{\magstep1}{OT1}
+\setfont\deftt\ttshape{10}{\magstep1}{OT1TT}
+\setfont\defttsl\ttslshape{10}{\magstep1}{OT1TT}
+\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf}
+
+% Fonts for indices, footnotes, small examples (9pt).
+\def\smallnominalsize{9pt}
+\setfont\smallrm\rmshape{9}{1000}{OT1}
+\setfont\smalltt\ttshape{9}{1000}{OT1TT}
+\setfont\smallbf\bfshape{10}{900}{OT1}
+\setfont\smallit\itshape{9}{1000}{OT1IT}
+\setfont\smallsl\slshape{9}{1000}{OT1}
+\setfont\smallsf\sfshape{9}{1000}{OT1}
+\setfont\smallsc\scshape{10}{900}{OT1}
+\setfont\smallttsl\ttslshape{10}{900}{OT1TT}
+\font\smalli=cmmi9
+\font\smallsy=cmsy9
+\def\smallecsize{0900}
+
+% Fonts for small examples (8pt).
+\def\smallernominalsize{8pt}
+\setfont\smallerrm\rmshape{8}{1000}{OT1}
+\setfont\smallertt\ttshape{8}{1000}{OT1TT}
+\setfont\smallerbf\bfshape{10}{800}{OT1}
+\setfont\smallerit\itshape{8}{1000}{OT1IT}
+\setfont\smallersl\slshape{8}{1000}{OT1}
+\setfont\smallersf\sfshape{8}{1000}{OT1}
+\setfont\smallersc\scshape{10}{800}{OT1}
+\setfont\smallerttsl\ttslshape{10}{800}{OT1TT}
+\font\smalleri=cmmi8
+\font\smallersy=cmsy8
+\def\smallerecsize{0800}
+
+% Fonts for title page (20.4pt):
+\def\titlenominalsize{20pt}
+\setfont\titlerm\rmbshape{12}{\magstep3}{OT1}
+\setfont\titleit\itbshape{10}{\magstep4}{OT1IT}
+\setfont\titlesl\slbshape{10}{\magstep4}{OT1}
+\setfont\titlett\ttbshape{12}{\magstep3}{OT1TT}
+\setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT}
+\setfont\titlesf\sfbshape{17}{\magstep1}{OT1}
+\let\titlebf=\titlerm
+\setfont\titlesc\scbshape{10}{\magstep4}{OT1}
+\font\titlei=cmmi12 scaled \magstep3
+\font\titlesy=cmsy10 scaled \magstep4
+\def\titleecsize{2074}
+
+% Chapter (and unnumbered) fonts (17.28pt).
+\def\chapnominalsize{17pt}
+\setfont\chaprm\rmbshape{12}{\magstep2}{OT1}
+\setfont\chapit\itbshape{10}{\magstep3}{OT1IT}
+\setfont\chapsl\slbshape{10}{\magstep3}{OT1}
+\setfont\chaptt\ttbshape{12}{\magstep2}{OT1TT}
+\setfont\chapttsl\ttslshape{10}{\magstep3}{OT1TT}
+\setfont\chapsf\sfbshape{17}{1000}{OT1}
+\let\chapbf=\chaprm
+\setfont\chapsc\scbshape{10}{\magstep3}{OT1}
+\font\chapi=cmmi12 scaled \magstep2
+\font\chapsy=cmsy10 scaled \magstep3
+\def\chapecsize{1728}
+
+% Section fonts (14.4pt).
+\def\secnominalsize{14pt}
+\setfont\secrm\rmbshape{12}{\magstep1}{OT1}
+\setfont\secit\itbshape{10}{\magstep2}{OT1IT}
+\setfont\secsl\slbshape{10}{\magstep2}{OT1}
+\setfont\sectt\ttbshape{12}{\magstep1}{OT1TT}
+\setfont\secttsl\ttslshape{10}{\magstep2}{OT1TT}
+\setfont\secsf\sfbshape{12}{\magstep1}{OT1}
+\let\secbf\secrm
+\setfont\secsc\scbshape{10}{\magstep2}{OT1}
+\font\seci=cmmi12 scaled \magstep1
+\font\secsy=cmsy10 scaled \magstep2
+\def\sececsize{1440}
+
+% Subsection fonts (13.15pt).
+\def\ssecnominalsize{13pt}
+\setfont\ssecrm\rmbshape{12}{\magstephalf}{OT1}
+\setfont\ssecit\itbshape{10}{1315}{OT1IT}
+\setfont\ssecsl\slbshape{10}{1315}{OT1}
+\setfont\ssectt\ttbshape{12}{\magstephalf}{OT1TT}
+\setfont\ssecttsl\ttslshape{10}{1315}{OT1TT}
+\setfont\ssecsf\sfbshape{12}{\magstephalf}{OT1}
+\let\ssecbf\ssecrm
+\setfont\ssecsc\scbshape{10}{1315}{OT1}
+\font\sseci=cmmi12 scaled \magstephalf
+\font\ssecsy=cmsy10 scaled 1315
+\def\ssececsize{1200}
+
+% Reduced fonts for @acro in text (10pt).
+\def\reducednominalsize{10pt}
+\setfont\reducedrm\rmshape{10}{1000}{OT1}
+\setfont\reducedtt\ttshape{10}{1000}{OT1TT}
+\setfont\reducedbf\bfshape{10}{1000}{OT1}
+\setfont\reducedit\itshape{10}{1000}{OT1IT}
+\setfont\reducedsl\slshape{10}{1000}{OT1}
+\setfont\reducedsf\sfshape{10}{1000}{OT1}
+\setfont\reducedsc\scshape{10}{1000}{OT1}
+\setfont\reducedttsl\ttslshape{10}{1000}{OT1TT}
+\font\reducedi=cmmi10
+\font\reducedsy=cmsy10
+\def\reducedecsize{1000}
+
+\textleading = 13.2pt % line spacing for 11pt CM
+\textfonts % reset the current fonts
+\rm
+} % end of 11pt text font size definitions, \definetextfontsizexi
+
+
+% Definitions to make the main text be 10pt Computer Modern, with
+% section, chapter, etc., sizes following suit. This is for the GNU
+% Press printing of the Emacs 22 manual. Maybe other manuals in the
+% future. Used with @smallbook, which sets the leading to 12pt.
+%
+\def\definetextfontsizex{%
+% Text fonts (10pt).
+\def\textnominalsize{10pt}
+\edef\mainmagstep{1000}
+\setfont\textrm\rmshape{10}{\mainmagstep}{OT1}
+\setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT}
+\setfont\textbf\bfshape{10}{\mainmagstep}{OT1}
+\setfont\textit\itshape{10}{\mainmagstep}{OT1IT}
+\setfont\textsl\slshape{10}{\mainmagstep}{OT1}
+\setfont\textsf\sfshape{10}{\mainmagstep}{OT1}
+\setfont\textsc\scshape{10}{\mainmagstep}{OT1}
+\setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT}
+\font\texti=cmmi10 scaled \mainmagstep
+\font\textsy=cmsy10 scaled \mainmagstep
+\def\textecsize{1000}
+
+% A few fonts for @defun names and args.
+\setfont\defbf\bfshape{10}{\magstephalf}{OT1}
+\setfont\deftt\ttshape{10}{\magstephalf}{OT1TT}
+\setfont\defttsl\ttslshape{10}{\magstephalf}{OT1TT}
+\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf}
+
+% Fonts for indices, footnotes, small examples (9pt).
+\def\smallnominalsize{9pt}
+\setfont\smallrm\rmshape{9}{1000}{OT1}
+\setfont\smalltt\ttshape{9}{1000}{OT1TT}
+\setfont\smallbf\bfshape{10}{900}{OT1}
+\setfont\smallit\itshape{9}{1000}{OT1IT}
+\setfont\smallsl\slshape{9}{1000}{OT1}
+\setfont\smallsf\sfshape{9}{1000}{OT1}
+\setfont\smallsc\scshape{10}{900}{OT1}
+\setfont\smallttsl\ttslshape{10}{900}{OT1TT}
+\font\smalli=cmmi9
+\font\smallsy=cmsy9
+\def\smallecsize{0900}
+
+% Fonts for small examples (8pt).
+\def\smallernominalsize{8pt}
+\setfont\smallerrm\rmshape{8}{1000}{OT1}
+\setfont\smallertt\ttshape{8}{1000}{OT1TT}
+\setfont\smallerbf\bfshape{10}{800}{OT1}
+\setfont\smallerit\itshape{8}{1000}{OT1IT}
+\setfont\smallersl\slshape{8}{1000}{OT1}
+\setfont\smallersf\sfshape{8}{1000}{OT1}
+\setfont\smallersc\scshape{10}{800}{OT1}
+\setfont\smallerttsl\ttslshape{10}{800}{OT1TT}
+\font\smalleri=cmmi8
+\font\smallersy=cmsy8
+\def\smallerecsize{0800}
+
+% Fonts for title page (20.4pt):
+\def\titlenominalsize{20pt}
+\setfont\titlerm\rmbshape{12}{\magstep3}{OT1}
+\setfont\titleit\itbshape{10}{\magstep4}{OT1IT}
+\setfont\titlesl\slbshape{10}{\magstep4}{OT1}
+\setfont\titlett\ttbshape{12}{\magstep3}{OT1TT}
+\setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT}
+\setfont\titlesf\sfbshape{17}{\magstep1}{OT1}
+\let\titlebf=\titlerm
+\setfont\titlesc\scbshape{10}{\magstep4}{OT1}
+\font\titlei=cmmi12 scaled \magstep3
+\font\titlesy=cmsy10 scaled \magstep4
+\def\titleecsize{2074}
+
+% Chapter fonts (14.4pt).
+\def\chapnominalsize{14pt}
+\setfont\chaprm\rmbshape{12}{\magstep1}{OT1}
+\setfont\chapit\itbshape{10}{\magstep2}{OT1IT}
+\setfont\chapsl\slbshape{10}{\magstep2}{OT1}
+\setfont\chaptt\ttbshape{12}{\magstep1}{OT1TT}
+\setfont\chapttsl\ttslshape{10}{\magstep2}{OT1TT}
+\setfont\chapsf\sfbshape{12}{\magstep1}{OT1}
+\let\chapbf\chaprm
+\setfont\chapsc\scbshape{10}{\magstep2}{OT1}
+\font\chapi=cmmi12 scaled \magstep1
+\font\chapsy=cmsy10 scaled \magstep2
+\def\chapecsize{1440}
+
+% Section fonts (12pt).
+\def\secnominalsize{12pt}
+\setfont\secrm\rmbshape{12}{1000}{OT1}
+\setfont\secit\itbshape{10}{\magstep1}{OT1IT}
+\setfont\secsl\slbshape{10}{\magstep1}{OT1}
+\setfont\sectt\ttbshape{12}{1000}{OT1TT}
+\setfont\secttsl\ttslshape{10}{\magstep1}{OT1TT}
+\setfont\secsf\sfbshape{12}{1000}{OT1}
+\let\secbf\secrm
+\setfont\secsc\scbshape{10}{\magstep1}{OT1}
+\font\seci=cmmi12
+\font\secsy=cmsy10 scaled \magstep1
+\def\sececsize{1200}
+
+% Subsection fonts (10pt).
+\def\ssecnominalsize{10pt}
+\setfont\ssecrm\rmbshape{10}{1000}{OT1}
+\setfont\ssecit\itbshape{10}{1000}{OT1IT}
+\setfont\ssecsl\slbshape{10}{1000}{OT1}
+\setfont\ssectt\ttbshape{10}{1000}{OT1TT}
+\setfont\ssecttsl\ttslshape{10}{1000}{OT1TT}
+\setfont\ssecsf\sfbshape{10}{1000}{OT1}
+\let\ssecbf\ssecrm
+\setfont\ssecsc\scbshape{10}{1000}{OT1}
+\font\sseci=cmmi10
+\font\ssecsy=cmsy10
+\def\ssececsize{1000}
+
+% Reduced fonts for @acro in text (9pt).
+\def\reducednominalsize{9pt}
+\setfont\reducedrm\rmshape{9}{1000}{OT1}
+\setfont\reducedtt\ttshape{9}{1000}{OT1TT}
+\setfont\reducedbf\bfshape{10}{900}{OT1}
+\setfont\reducedit\itshape{9}{1000}{OT1IT}
+\setfont\reducedsl\slshape{9}{1000}{OT1}
+\setfont\reducedsf\sfshape{9}{1000}{OT1}
+\setfont\reducedsc\scshape{10}{900}{OT1}
+\setfont\reducedttsl\ttslshape{10}{900}{OT1TT}
+\font\reducedi=cmmi9
+\font\reducedsy=cmsy9
+\def\reducedecsize{0900}
+
+\divide\parskip by 2 % reduce space between paragraphs
+\textleading = 12pt % line spacing for 10pt CM
+\textfonts % reset the current fonts
+\rm
+} % end of 10pt text font size definitions, \definetextfontsizex
+
+
+% We provide the user-level command
+% @fonttextsize 10
+% (or 11) to redefine the text font size. pt is assumed.
+%
+\def\xiword{11}
+\def\xword{10}
+\def\xwordpt{10pt}
+%
+\parseargdef\fonttextsize{%
+ \def\textsizearg{#1}%
+ %\wlog{doing @fonttextsize \textsizearg}%
+ %
+ % Set \globaldefs so that documents can use this inside @tex, since
+ % makeinfo 4.8 does not support it, but we need it nonetheless.
+ %
+ \begingroup \globaldefs=1
+ \ifx\textsizearg\xword \definetextfontsizex
+ \else \ifx\textsizearg\xiword \definetextfontsizexi
+ \else
+ \errhelp=\EMsimple
+ \errmessage{@fonttextsize only supports `10' or `11', not `\textsizearg'}
+ \fi\fi
+ \endgroup
+}
+
+
+% In order for the font changes to affect most math symbols and letters,
+% we have to define the \textfont of the standard families. Since
+% texinfo doesn't allow for producing subscripts and superscripts except
+% in the main text, we don't bother to reset \scriptfont and
+% \scriptscriptfont (which would also require loading a lot more fonts).
+%
+\def\resetmathfonts{%
+ \textfont0=\tenrm \textfont1=\teni \textfont2=\tensy
+ \textfont\itfam=\tenit \textfont\slfam=\tensl \textfont\bffam=\tenbf
+ \textfont\ttfam=\tentt \textfont\sffam=\tensf
+}
+
+% The font-changing commands redefine the meanings of \tenSTYLE, instead
+% of just \STYLE. We do this because \STYLE needs to also set the
+% current \fam for math mode. Our \STYLE (e.g., \rm) commands hardwire
+% \tenSTYLE to set the current font.
+%
+% Each font-changing command also sets the names \lsize (one size lower)
+% and \lllsize (three sizes lower). These relative commands are used in
+% the LaTeX logo and acronyms.
+%
+% This all needs generalizing, badly.
+%
+\def\textfonts{%
+ \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl
+ \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc
+ \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy
+ \let\tenttsl=\textttsl
+ \def\curfontsize{text}%
+ \def\lsize{reduced}\def\lllsize{smaller}%
+ \resetmathfonts \setleading{\textleading}}
+\def\titlefonts{%
+ \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl
+ \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc
+ \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy
+ \let\tenttsl=\titlettsl
+ \def\curfontsize{title}%
+ \def\lsize{chap}\def\lllsize{subsec}%
+ \resetmathfonts \setleading{27pt}}
+\def\titlefont#1{{\titlefonts\rmisbold #1}}
+\def\chapfonts{%
+ \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl
+ \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc
+ \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy
+ \let\tenttsl=\chapttsl
+ \def\curfontsize{chap}%
+ \def\lsize{sec}\def\lllsize{text}%
+ \resetmathfonts \setleading{19pt}}
+\def\secfonts{%
+ \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl
+ \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc
+ \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy
+ \let\tenttsl=\secttsl
+ \def\curfontsize{sec}%
+ \def\lsize{subsec}\def\lllsize{reduced}%
+ \resetmathfonts \setleading{17pt}}
+\def\subsecfonts{%
+ \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl
+ \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc
+ \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy
+ \let\tenttsl=\ssecttsl
+ \def\curfontsize{ssec}%
+ \def\lsize{text}\def\lllsize{small}%
+ \resetmathfonts \setleading{15pt}}
+\let\subsubsecfonts = \subsecfonts
+\def\reducedfonts{%
+ \let\tenrm=\reducedrm \let\tenit=\reducedit \let\tensl=\reducedsl
+ \let\tenbf=\reducedbf \let\tentt=\reducedtt \let\reducedcaps=\reducedsc
+ \let\tensf=\reducedsf \let\teni=\reducedi \let\tensy=\reducedsy
+ \let\tenttsl=\reducedttsl
+ \def\curfontsize{reduced}%
+ \def\lsize{small}\def\lllsize{smaller}%
+ \resetmathfonts \setleading{10.5pt}}
+\def\smallfonts{%
+ \let\tenrm=\smallrm \let\tenit=\smallit \let\tensl=\smallsl
+ \let\tenbf=\smallbf \let\tentt=\smalltt \let\smallcaps=\smallsc
+ \let\tensf=\smallsf \let\teni=\smalli \let\tensy=\smallsy
+ \let\tenttsl=\smallttsl
+ \def\curfontsize{small}%
+ \def\lsize{smaller}\def\lllsize{smaller}%
+ \resetmathfonts \setleading{10.5pt}}
+\def\smallerfonts{%
+ \let\tenrm=\smallerrm \let\tenit=\smallerit \let\tensl=\smallersl
+ \let\tenbf=\smallerbf \let\tentt=\smallertt \let\smallcaps=\smallersc
+ \let\tensf=\smallersf \let\teni=\smalleri \let\tensy=\smallersy
+ \let\tenttsl=\smallerttsl
+ \def\curfontsize{smaller}%
+ \def\lsize{smaller}\def\lllsize{smaller}%
+ \resetmathfonts \setleading{9.5pt}}
+
+% Fonts for short table of contents.
+\setfont\shortcontrm\rmshape{12}{1000}{OT1}
+\setfont\shortcontbf\bfshape{10}{\magstep1}{OT1} % no cmb12
+\setfont\shortcontsl\slshape{12}{1000}{OT1}
+\setfont\shortconttt\ttshape{12}{1000}{OT1TT}
+
+% Define these just so they can be easily changed for other fonts.
+\def\angleleft{$\langle$}
+\def\angleright{$\rangle$}
+
+% Set the fonts to use with the @small... environments.
+\let\smallexamplefonts = \smallfonts
+
+% About \smallexamplefonts. If we use \smallfonts (9pt), @smallexample
+% can fit this many characters:
+% 8.5x11=86 smallbook=72 a4=90 a5=69
+% If we use \scriptfonts (8pt), then we can fit this many characters:
+% 8.5x11=90+ smallbook=80 a4=90+ a5=77
+% For me, subjectively, the few extra characters that fit aren't worth
+% the additional smallness of 8pt. So I'm making the default 9pt.
+%
+% By the way, for comparison, here's what fits with @example (10pt):
+% 8.5x11=71 smallbook=60 a4=75 a5=58
+% --karl, 24jan03.
+
+% Set up the default fonts, so we can use them for creating boxes.
+%
+\definetextfontsizexi
+
+
+\message{markup,}
+
+% Check if we are currently using a typewriter font. Since all the
+% Computer Modern typewriter fonts have zero interword stretch (and
+% shrink), and it is reasonable to expect all typewriter fonts to have
+% this property, we can check that font parameter.
+%
+\def\ifmonospace{\ifdim\fontdimen3\font=0pt }
+
+% Markup style infrastructure. \defmarkupstylesetup\INITMACRO will
+% define and register \INITMACRO to be called on markup style changes.
+% \INITMACRO can check \currentmarkupstyle for the innermost
+% style and the set of \ifmarkupSTYLE switches for all styles
+% currently in effect.
+\newif\ifmarkupvar
+\newif\ifmarkupsamp
+\newif\ifmarkupkey
+%\newif\ifmarkupfile % @file == @samp.
+%\newif\ifmarkupoption % @option == @samp.
+\newif\ifmarkupcode
+\newif\ifmarkupkbd
+%\newif\ifmarkupenv % @env == @code.
+%\newif\ifmarkupcommand % @command == @code.
+\newif\ifmarkuptex % @tex (and part of @math, for now).
+\newif\ifmarkupexample
+\newif\ifmarkupverb
+\newif\ifmarkupverbatim
+
+\let\currentmarkupstyle\empty
+
+\def\setupmarkupstyle#1{%
+ \csname markup#1true\endcsname
+ \def\currentmarkupstyle{#1}%
+ \markupstylesetup
+}
+
+\let\markupstylesetup\empty
+
+\def\defmarkupstylesetup#1{%
+ \expandafter\def\expandafter\markupstylesetup
+ \expandafter{\markupstylesetup #1}%
+ \def#1%
+}
+
+% Markup style setup for left and right quotes.
+\defmarkupstylesetup\markupsetuplq{%
+ \expandafter\let\expandafter \temp
+ \csname markupsetuplq\currentmarkupstyle\endcsname
+ \ifx\temp\relax \markupsetuplqdefault \else \temp \fi
+}
+
+\defmarkupstylesetup\markupsetuprq{%
+ \expandafter\let\expandafter \temp
+ \csname markupsetuprq\currentmarkupstyle\endcsname
+ \ifx\temp\relax \markupsetuprqdefault \else \temp \fi
+}
+
+{
+\catcode`\'=\active
+\catcode`\`=\active
+
+\gdef\markupsetuplqdefault{\let`\lq}
+\gdef\markupsetuprqdefault{\let'\rq}
+
+\gdef\markupsetcodequoteleft{\let`\codequoteleft}
+\gdef\markupsetcodequoteright{\let'\codequoteright}
+}
+
+\let\markupsetuplqcode \markupsetcodequoteleft
+\let\markupsetuprqcode \markupsetcodequoteright
+%
+\let\markupsetuplqexample \markupsetcodequoteleft
+\let\markupsetuprqexample \markupsetcodequoteright
+%
+\let\markupsetuplqkbd \markupsetcodequoteleft
+\let\markupsetuprqkbd \markupsetcodequoteright
+%
+\let\markupsetuplqsamp \markupsetcodequoteleft
+\let\markupsetuprqsamp \markupsetcodequoteright
+%
+\let\markupsetuplqverb \markupsetcodequoteleft
+\let\markupsetuprqverb \markupsetcodequoteright
+%
+\let\markupsetuplqverbatim \markupsetcodequoteleft
+\let\markupsetuprqverbatim \markupsetcodequoteright
+
+% Allow an option to not use regular directed right quote/apostrophe
+% (char 0x27), but instead the undirected quote from cmtt (char 0x0d).
+% The undirected quote is ugly, so don't make it the default, but it
+% works for pasting with more pdf viewers (at least evince), the
+% lilypond developers report. xpdf does work with the regular 0x27.
+%
+\def\codequoteright{%
+ \expandafter\ifx\csname SETtxicodequoteundirected\endcsname\relax
+ \expandafter\ifx\csname SETcodequoteundirected\endcsname\relax
+ '%
+ \else \char'15 \fi
+ \else \char'15 \fi
+}
+%
+% and a similar option for the left quote char vs. a grave accent.
+% Modern fonts display ASCII 0x60 as a grave accent, so some people like
+% the code environments to do likewise.
+%
+\def\codequoteleft{%
+ \expandafter\ifx\csname SETtxicodequotebacktick\endcsname\relax
+ \expandafter\ifx\csname SETcodequotebacktick\endcsname\relax
+ % [Knuth] pp. 380,381,391
+ % \relax disables Spanish ligatures ?` and !` of \tt font.
+ \relax`%
+ \else \char'22 \fi
+ \else \char'22 \fi
+}
+
+% Commands to set the quote options.
+%
+\parseargdef\codequoteundirected{%
+ \def\temp{#1}%
+ \ifx\temp\onword
+ \expandafter\let\csname SETtxicodequoteundirected\endcsname
+ = t%
+ \else\ifx\temp\offword
+ \expandafter\let\csname SETtxicodequoteundirected\endcsname
+ = \relax
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @codequoteundirected value `\temp', must be on|off}%
+ \fi\fi
+}
+%
+\parseargdef\codequotebacktick{%
+ \def\temp{#1}%
+ \ifx\temp\onword
+ \expandafter\let\csname SETtxicodequotebacktick\endcsname
+ = t%
+ \else\ifx\temp\offword
+ \expandafter\let\csname SETtxicodequotebacktick\endcsname
+ = \relax
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @codequotebacktick value `\temp', must be on|off}%
+ \fi\fi
+}
+
+% [Knuth] pp. 380,381,391, disable Spanish ligatures ?` and !` of \tt font.
+\def\noligaturesquoteleft{\relax\lq}
+
+% Count depth in font-changes, for error checks
+\newcount\fontdepth \fontdepth=0
+
+% Font commands.
+
+% #1 is the font command (\sl or \it), #2 is the text to slant.
+% If we are in a monospaced environment, however, 1) always use \ttsl,
+% and 2) do not add an italic correction.
+\def\dosmartslant#1#2{%
+ \ifusingtt
+ {{\ttsl #2}\let\next=\relax}%
+ {\def\next{{#1#2}\futurelet\next\smartitaliccorrection}}%
+ \next
+}
+\def\smartslanted{\dosmartslant\sl}
+\def\smartitalic{\dosmartslant\it}
+
+% Output an italic correction unless \next (presumed to be the following
+% character) is such as not to need one.
+\def\smartitaliccorrection{%
+ \ifx\next,%
+ \else\ifx\next-%
+ \else\ifx\next.%
+ \else\ifx\next\.%
+ \else\ifx\next\comma%
+ \else\ptexslash
+ \fi\fi\fi\fi\fi
+ \aftersmartic
+}
+
+% Unconditional use \ttsl, and no ic. @var is set to this for defuns.
+\def\ttslanted#1{{\ttsl #1}}
+
+% @cite is like \smartslanted except unconditionally use \sl. We never want
+% ttsl for book titles, do we?
+\def\cite#1{{\sl #1}\futurelet\next\smartitaliccorrection}
+
+\def\aftersmartic{}
+\def\var#1{%
+ \let\saveaftersmartic = \aftersmartic
+ \def\aftersmartic{\null\let\aftersmartic=\saveaftersmartic}%
+ \smartslanted{#1}%
+}
+
+\let\i=\smartitalic
+\let\slanted=\smartslanted
+\let\dfn=\smartslanted
+\let\emph=\smartitalic
+
+% Explicit font changes: @r, @sc, undocumented @ii.
+\def\r#1{{\rm #1}} % roman font
+\def\sc#1{{\smallcaps#1}} % smallcaps font
+\def\ii#1{{\it #1}} % italic font
+
+% @b, explicit bold. Also @strong.
+\def\b#1{{\bf #1}}
+\let\strong=\b
+
+% @sansserif, explicit sans.
+\def\sansserif#1{{\sf #1}}
+
+% We can't just use \exhyphenpenalty, because that only has effect at
+% the end of a paragraph. Restore normal hyphenation at the end of the
+% group within which \nohyphenation is presumably called.
+%
+\def\nohyphenation{\hyphenchar\font = -1 \aftergroup\restorehyphenation}
+\def\restorehyphenation{\hyphenchar\font = `- }
+
+% Set sfcode to normal for the chars that usually have another value.
+% Can't use plain's \frenchspacing because it uses the `\x notation, and
+% sometimes \x has an active definition that messes things up.
+%
+\catcode`@=11
+ \def\plainfrenchspacing{%
+ \sfcode\dotChar =\@m \sfcode\questChar=\@m \sfcode\exclamChar=\@m
+ \sfcode\colonChar=\@m \sfcode\semiChar =\@m \sfcode\commaChar =\@m
+ \def\endofsentencespacefactor{1000}% for @. and friends
+ }
+ \def\plainnonfrenchspacing{%
+ \sfcode`\.3000\sfcode`\?3000\sfcode`\!3000
+ \sfcode`\:2000\sfcode`\;1500\sfcode`\,1250
+ \def\endofsentencespacefactor{3000}% for @. and friends
+ }
+\catcode`@=\other
+\def\endofsentencespacefactor{3000}% default
+
+% @t, explicit typewriter.
+\def\t#1{%
+ {\tt \rawbackslash \plainfrenchspacing #1}%
+ \null
+}
+
+% @samp.
+\def\samp#1{{\setupmarkupstyle{samp}\lq\tclose{#1}\rq\null}}
+
+% @indicateurl is \samp, that is, with quotes.
+\let\indicateurl=\samp
+
+% @code (and similar) prints in typewriter, but with spaces the same
+% size as normal in the surrounding text, without hyphenation, etc.
+% This is a subroutine for that.
+\def\tclose#1{%
+ {%
+ % Change normal interword space to be same as for the current font.
+ \spaceskip = \fontdimen2\font
+ %
+ % Switch to typewriter.
+ \tt
+ %
+ % But `\ ' produces the large typewriter interword space.
+ \def\ {{\spaceskip = 0pt{} }}%
+ %
+ % Turn off hyphenation.
+ \nohyphenation
+ %
+ \rawbackslash
+ \plainfrenchspacing
+ #1%
+ }%
+ \null % reset spacefactor to 1000
+}
+
+% We *must* turn on hyphenation at `-' and `_' in @code.
+% (But see \codedashfinish below.)
+% Otherwise, it is too hard to avoid overfull hboxes
+% in the Emacs manual, the Library manual, etc.
+%
+% Unfortunately, TeX uses one parameter (\hyphenchar) to control
+% both hyphenation at - and hyphenation within words.
+% We must therefore turn them both off (\tclose does that)
+% and arrange explicitly to hyphenate at a dash. -- rms.
+{
+ \catcode`\-=\active \catcode`\_=\active
+ \catcode`\'=\active \catcode`\`=\active
+ \global\let'=\rq \global\let`=\lq % default definitions
+ %
+ \global\def\code{\begingroup
+ \setupmarkupstyle{code}%
+ % The following should really be moved into \setupmarkupstyle handlers.
+ \catcode\dashChar=\active \catcode\underChar=\active
+ \ifallowcodebreaks
+ \let-\codedash
+ \let_\codeunder
+ \else
+ \let-\normaldash
+ \let_\realunder
+ \fi
+ % Given -foo (with a single dash), we do not want to allow a break
+ % after the hyphen.
+ \global\let\codedashprev=\codedash
+ %
+ \codex
+ }
+ %
+ \gdef\codedash{\futurelet\next\codedashfinish}
+ \gdef\codedashfinish{%
+ \normaldash % always output the dash character itself.
+ %
+ % Now, output a discretionary to allow a line break, unless
+ % (a) the next character is a -, or
+ % (b) the preceding character is a -.
+ % E.g., given --posix, we do not want to allow a break after either -.
+ % Given --foo-bar, we do want to allow a break between the - and the b.
+ \ifx\next\codedash \else
+ \ifx\codedashprev\codedash
+ \else \discretionary{}{}{}\fi
+ \fi
+ % we need the space after the = for the case when \next itself is a
+ % space token; it would get swallowed otherwise. As in @code{- a}.
+ \global\let\codedashprev= \next
+ }
+}
+\def\normaldash{-}
+%
+\def\codex #1{\tclose{#1}\endgroup}
+
+\def\codeunder{%
+ % this is all so @math{@code{var_name}+1} can work. In math mode, _
+ % is "active" (mathcode"8000) and \normalunderscore (or \char95, etc.)
+ % will therefore expand the active definition of _, which is us
+ % (inside @code that is), therefore an endless loop.
+ \ifusingtt{\ifmmode
+ \mathchar"075F % class 0=ordinary, family 7=ttfam, pos 0x5F=_.
+ \else\normalunderscore \fi
+ \discretionary{}{}{}}%
+ {\_}%
+}
+
+% An additional complication: the above will allow breaks after, e.g.,
+% each of the four underscores in __typeof__. This is bad.
+% @allowcodebreaks provides a document-level way to turn breaking at -
+% and _ on and off.
+%
+\newif\ifallowcodebreaks \allowcodebreakstrue
+
+\def\keywordtrue{true}
+\def\keywordfalse{false}
+
+\parseargdef\allowcodebreaks{%
+ \def\txiarg{#1}%
+ \ifx\txiarg\keywordtrue
+ \allowcodebreakstrue
+ \else\ifx\txiarg\keywordfalse
+ \allowcodebreaksfalse
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @allowcodebreaks option `\txiarg', must be true|false}%
+ \fi\fi
+}
+
+% For @command, @env, @file, @option quotes seem unnecessary,
+% so use \code rather than \samp.
+\let\command=\code
+\let\env=\code
+\let\file=\code
+\let\option=\code
+
+% @uref (abbreviation for `urlref') aka @url takes an optional
+% (comma-separated) second argument specifying the text to display and
+% an optional third arg as text to display instead of (rather than in
+% addition to) the url itself. First (mandatory) arg is the url.
+
+% TeX-only option to allow changing PDF output to show only the second
+% arg (if given), and not the url (which is then just the link target).
+\newif\ifurefurlonlylink
+
+% The main macro is \urefbreak, which allows breaking at expected
+% places within the url. (There used to be another version, which
+% didn't support automatic breaking.)
+\def\urefbreak{\begingroup \urefcatcodes \dourefbreak}
+\let\uref=\urefbreak
+%
+\def\dourefbreak#1{\urefbreakfinish #1,,,\finish}
+\def\urefbreakfinish#1,#2,#3,#4\finish{% doesn't work in @example
+ \unsepspaces
+ \pdfurl{#1}%
+ \setbox0 = \hbox{\ignorespaces #3}%
+ \ifdim\wd0 > 0pt
+ \unhbox0 % third arg given, show only that
+ \else
+ \setbox0 = \hbox{\ignorespaces #2}% look for second arg
+ \ifdim\wd0 > 0pt
+ \ifpdf
+ \ifurefurlonlylink
+ % PDF plus option to not display url, show just arg
+ \unhbox0
+ \else
+ % PDF, normally display both arg and url for consistency,
+ % visibility, if the pdf is eventually used to print, etc.
+ \unhbox0\ (\urefcode{#1})%
+ \fi
+ \else
+ \unhbox0\ (\urefcode{#1})% DVI, always show arg and url
+ \fi
+ \else
+ \urefcode{#1}% only url given, so show it
+ \fi
+ \fi
+ \endlink
+\endgroup}
+
+% Allow line breaks around only a few characters (only).
+\def\urefcatcodes{%
+ \catcode\ampChar=\active \catcode\dotChar=\active
+ \catcode\hashChar=\active \catcode\questChar=\active
+ \catcode\slashChar=\active
+}
+{
+ \urefcatcodes
+ %
+ \global\def\urefcode{\begingroup
+ \setupmarkupstyle{code}%
+ \urefcatcodes
+ \let&\urefcodeamp
+ \let.\urefcodedot
+ \let#\urefcodehash
+ \let?\urefcodequest
+ \let/\urefcodeslash
+ \codex
+ }
+ %
+ % By default, they are just regular characters.
+ \global\def&{\normalamp}
+ \global\def.{\normaldot}
+ \global\def#{\normalhash}
+ \global\def?{\normalquest}
+ \global\def/{\normalslash}
+}
+
+% we put a little stretch before and after the breakable chars, to help
+% line breaking of long url's. The unequal skips make look better in
+% cmtt at least, especially for dots.
+\def\urefprestretchamount{.13em}
+\def\urefpoststretchamount{.1em}
+\def\urefprestretch{\urefprebreak \hskip0pt plus\urefprestretchamount\relax}
+\def\urefpoststretch{\urefpostbreak \hskip0pt plus\urefprestretchamount\relax}
+%
+\def\urefcodeamp{\urefprestretch \&\urefpoststretch}
+\def\urefcodedot{\urefprestretch .\urefpoststretch}
+\def\urefcodehash{\urefprestretch \#\urefpoststretch}
+\def\urefcodequest{\urefprestretch ?\urefpoststretch}
+\def\urefcodeslash{\futurelet\next\urefcodeslashfinish}
+{
+ \catcode`\/=\active
+ \global\def\urefcodeslashfinish{%
+ \urefprestretch \slashChar
+ % Allow line break only after the final / in a sequence of
+ % slashes, to avoid line break between the slashes in http://.
+ \ifx\next/\else \urefpoststretch \fi
+ }
+}
+
+% One more complication: by default we'll break after the special
+% characters, but some people like to break before the special chars, so
+% allow that. Also allow no breaking at all, for manual control.
+%
+\parseargdef\urefbreakstyle{%
+ \def\txiarg{#1}%
+ \ifx\txiarg\wordnone
+ \def\urefprebreak{\nobreak}\def\urefpostbreak{\nobreak}
+ \else\ifx\txiarg\wordbefore
+ \def\urefprebreak{\allowbreak}\def\urefpostbreak{\nobreak}
+ \else\ifx\txiarg\wordafter
+ \def\urefprebreak{\nobreak}\def\urefpostbreak{\allowbreak}
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @urefbreakstyle setting `\txiarg'}%
+ \fi\fi\fi
+}
+\def\wordafter{after}
+\def\wordbefore{before}
+\def\wordnone{none}
+
+\urefbreakstyle after
+
+% @url synonym for @uref, since that's how everyone uses it.
+%
+\let\url=\uref
+
+% rms does not like angle brackets --karl, 17may97.
+% So now @email is just like @uref, unless we are pdf.
+%
+%\def\email#1{\angleleft{\tt #1}\angleright}
+\ifpdf
+ \def\email#1{\doemail#1,,\finish}
+ \def\doemail#1,#2,#3\finish{\begingroup
+ \unsepspaces
+ \pdfurl{mailto:#1}%
+ \setbox0 = \hbox{\ignorespaces #2}%
+ \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi
+ \endlink
+ \endgroup}
+\else
+ \let\email=\uref
+\fi
+
+% @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always),
+% `example' (@kbd uses ttsl only inside of @example and friends),
+% or `code' (@kbd uses normal tty font always).
+\parseargdef\kbdinputstyle{%
+ \def\txiarg{#1}%
+ \ifx\txiarg\worddistinct
+ \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}%
+ \else\ifx\txiarg\wordexample
+ \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}%
+ \else\ifx\txiarg\wordcode
+ \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}%
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @kbdinputstyle setting `\txiarg'}%
+ \fi\fi\fi
+}
+\def\worddistinct{distinct}
+\def\wordexample{example}
+\def\wordcode{code}
+
+% Default is `distinct'.
+\kbdinputstyle distinct
+
+% @kbd is like @code, except that if the argument is just one @key command,
+% then @kbd has no effect.
+\def\kbd#1{{\def\look{#1}\expandafter\kbdsub\look??\par}}
+
+\def\xkey{\key}
+\def\kbdsub#1#2#3\par{%
+ \def\one{#1}\def\three{#3}\def\threex{??}%
+ \ifx\one\xkey\ifx\threex\three \key{#2}%
+ \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi
+ \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi
+}
+
+% definition of @key that produces a lozenge. Doesn't adjust to text size.
+%\setfont\keyrm\rmshape{8}{1000}{OT1}
+%\font\keysy=cmsy9
+%\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{%
+% \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{%
+% \vbox{\hrule\kern-0.4pt
+% \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}%
+% \kern-0.4pt\hrule}%
+% \kern-.06em\raise0.4pt\hbox{\angleright}}}}
+
+% definition of @key with no lozenge. If the current font is already
+% monospace, don't change it; that way, we respect @kbdinputstyle. But
+% if it isn't monospace, then use \tt.
+%
+\def\key#1{{\setupmarkupstyle{key}%
+ \nohyphenation
+ \ifmonospace\else\tt\fi
+ #1}\null}
+
+% @clicksequence{File @click{} Open ...}
+\def\clicksequence#1{\begingroup #1\endgroup}
+
+% @clickstyle @arrow (by default)
+\parseargdef\clickstyle{\def\click{#1}}
+\def\click{\arrow}
+
+% Typeset a dimension, e.g., `in' or `pt'. The only reason for the
+% argument is to make the input look right: @dmn{pt} instead of @dmn{}pt.
+%
+\def\dmn#1{\thinspace #1}
+
+% @l was never documented to mean ``switch to the Lisp font'',
+% and it is not used as such in any manual I can find. We need it for
+% Polish suppressed-l. --karl, 22sep96.
+%\def\l#1{{\li #1}\null}
+
+% @acronym for "FBI", "NATO", and the like.
+% We print this one point size smaller, since it's intended for
+% all-uppercase.
+%
+\def\acronym#1{\doacronym #1,,\finish}
+\def\doacronym#1,#2,#3\finish{%
+ {\selectfonts\lsize #1}%
+ \def\temp{#2}%
+ \ifx\temp\empty \else
+ \space ({\unsepspaces \ignorespaces \temp \unskip})%
+ \fi
+ \null % reset \spacefactor=1000
+}
+
+% @abbr for "Comput. J." and the like.
+% No font change, but don't do end-of-sentence spacing.
+%
+\def\abbr#1{\doabbr #1,,\finish}
+\def\doabbr#1,#2,#3\finish{%
+ {\plainfrenchspacing #1}%
+ \def\temp{#2}%
+ \ifx\temp\empty \else
+ \space ({\unsepspaces \ignorespaces \temp \unskip})%
+ \fi
+ \null % reset \spacefactor=1000
+}
+
+% @asis just yields its argument. Used with @table, for example.
+%
+\def\asis#1{#1}
+
+% @math outputs its argument in math mode.
+%
+% One complication: _ usually means subscripts, but it could also mean
+% an actual _ character, as in @math{@var{some_variable} + 1}. So make
+% _ active, and distinguish by seeing if the current family is \slfam,
+% which is what @var uses.
+{
+ \catcode`\_ = \active
+ \gdef\mathunderscore{%
+ \catcode`\_=\active
+ \def_{\ifnum\fam=\slfam \_\else\sb\fi}%
+ }
+}
+% Another complication: we want \\ (and @\) to output a math (or tt) \.
+% FYI, plain.tex uses \\ as a temporary control sequence (for no
+% particular reason), but this is not advertised and we don't care.
+%
+% The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\.
+\def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi}
+%
+\def\math{%
+ \tex
+ \mathunderscore
+ \let\\ = \mathbackslash
+ \mathactive
+ % make the texinfo accent commands work in math mode
+ \let\"=\ddot
+ \let\'=\acute
+ \let\==\bar
+ \let\^=\hat
+ \let\`=\grave
+ \let\u=\breve
+ \let\v=\check
+ \let\~=\tilde
+ \let\dotaccent=\dot
+ $\finishmath
+}
+\def\finishmath#1{#1$\endgroup} % Close the group opened by \tex.
+
+% Some active characters (such as <) are spaced differently in math.
+% We have to reset their definitions in case the @math was an argument
+% to a command which sets the catcodes (such as @item or @section).
+%
+{
+ \catcode`^ = \active
+ \catcode`< = \active
+ \catcode`> = \active
+ \catcode`+ = \active
+ \catcode`' = \active
+ \gdef\mathactive{%
+ \let^ = \ptexhat
+ \let< = \ptexless
+ \let> = \ptexgtr
+ \let+ = \ptexplus
+ \let' = \ptexquoteright
+ }
+}
+
+% ctrl is no longer a Texinfo command, but leave this definition for fun.
+\def\ctrl #1{{\tt \rawbackslash \hat}#1}
+
+% @inlinefmt{FMTNAME,PROCESSED-TEXT} and @inlineraw{FMTNAME,RAW-TEXT}.
+% Ignore unless FMTNAME == tex; then it is like @iftex and @tex,
+% except specified as a normal braced arg, so no newlines to worry about.
+%
+\def\outfmtnametex{tex}
+%
+\long\def\inlinefmt#1{\doinlinefmt #1,\finish}
+\long\def\doinlinefmt#1,#2,\finish{%
+ \def\inlinefmtname{#1}%
+ \ifx\inlinefmtname\outfmtnametex \ignorespaces #2\fi
+}
+%
+% @inlinefmtifelse{FMTNAME,THEN-TEXT,ELSE-TEXT} expands THEN-TEXT if
+% FMTNAME is tex, else ELSE-TEXT.
+\long\def\inlinefmtifelse#1{\doinlinefmtifelse #1,,,\finish}
+\long\def\doinlinefmtifelse#1,#2,#3,#4,\finish{%
+ \def\inlinefmtname{#1}%
+ \ifx\inlinefmtname\outfmtnametex \ignorespaces #2\else \ignorespaces #3\fi
+}
+%
+% For raw, must switch into @tex before parsing the argument, to avoid
+% setting catcodes prematurely. Doing it this way means that, for
+% example, @inlineraw{html, foo{bar} gets a parse error instead of being
+% ignored. But this isn't important because if people want a literal
+% *right* brace they would have to use a command anyway, so they may as
+% well use a command to get a left brace too. We could re-use the
+% delimiter character idea from \verb, but it seems like overkill.
+%
+\long\def\inlineraw{\tex \doinlineraw}
+\long\def\doinlineraw#1{\doinlinerawtwo #1,\finish}
+\def\doinlinerawtwo#1,#2,\finish{%
+ \def\inlinerawname{#1}%
+ \ifx\inlinerawname\outfmtnametex \ignorespaces #2\fi
+ \endgroup % close group opened by \tex.
+}
+
+% @inlineifset{VAR, TEXT} expands TEXT if VAR is @set.
+%
+\long\def\inlineifset#1{\doinlineifset #1,\finish}
+\long\def\doinlineifset#1,#2,\finish{%
+ \def\inlinevarname{#1}%
+ \expandafter\ifx\csname SET\inlinevarname\endcsname\relax
+ \else\ignorespaces#2\fi
+}
+
+% @inlineifclear{VAR, TEXT} expands TEXT if VAR is not @set.
+%
+\long\def\inlineifclear#1{\doinlineifclear #1,\finish}
+\long\def\doinlineifclear#1,#2,\finish{%
+ \def\inlinevarname{#1}%
+ \expandafter\ifx\csname SET\inlinevarname\endcsname\relax \ignorespaces#2\fi
+}
+
+
+\message{glyphs,}
+% and logos.
+
+% @@ prints an @, as does @atchar{}.
+\def\@{\char64 }
+\let\atchar=\@
+
+% @{ @} @lbracechar{} @rbracechar{} all generate brace characters.
+% Unless we're in typewriter, use \ecfont because the CM text fonts do
+% not have braces, and we don't want to switch into math.
+\def\mylbrace{{\ifmonospace\else\ecfont\fi \char123}}
+\def\myrbrace{{\ifmonospace\else\ecfont\fi \char125}}
+\let\{=\mylbrace \let\lbracechar=\{
+\let\}=\myrbrace \let\rbracechar=\}
+\begingroup
+ % Definitions to produce \{ and \} commands for indices,
+ % and @{ and @} for the aux/toc files.
+ \catcode`\{ = \other \catcode`\} = \other
+ \catcode`\[ = 1 \catcode`\] = 2
+ \catcode`\! = 0 \catcode`\\ = \other
+ !gdef!lbracecmd[\{]%
+ !gdef!rbracecmd[\}]%
+ !gdef!lbraceatcmd[@{]%
+ !gdef!rbraceatcmd[@}]%
+!endgroup
+
+% @comma{} to avoid , parsing problems.
+\let\comma = ,
+
+% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent
+% Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H.
+\let\, = \ptexc
+\let\dotaccent = \ptexdot
+\def\ringaccent#1{{\accent23 #1}}
+\let\tieaccent = \ptext
+\let\ubaraccent = \ptexb
+\let\udotaccent = \d
+
+% Other special characters: @questiondown @exclamdown @ordf @ordm
+% Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss.
+\def\questiondown{?`}
+\def\exclamdown{!`}
+\def\ordf{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{a}}}
+\def\ordm{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{o}}}
+
+% Dotless i and dotless j, used for accents.
+\def\imacro{i}
+\def\jmacro{j}
+\def\dotless#1{%
+ \def\temp{#1}%
+ \ifx\temp\imacro \ifmmode\imath \else\ptexi \fi
+ \else\ifx\temp\jmacro \ifmmode\jmath \else\j \fi
+ \else \errmessage{@dotless can be used only with i or j}%
+ \fi\fi
+}
+
+% The \TeX{} logo, as in plain, but resetting the spacing so that a
+% period following counts as ending a sentence. (Idea found in latex.)
+%
+\edef\TeX{\TeX \spacefactor=1000 }
+
+% @LaTeX{} logo. Not quite the same results as the definition in
+% latex.ltx, since we use a different font for the raised A; it's most
+% convenient for us to use an explicitly smaller font, rather than using
+% the \scriptstyle font (since we don't reset \scriptstyle and
+% \scriptscriptstyle).
+%
+\def\LaTeX{%
+ L\kern-.36em
+ {\setbox0=\hbox{T}%
+ \vbox to \ht0{\hbox{%
+ \ifx\textnominalsize\xwordpt
+ % for 10pt running text, \lllsize (8pt) is too small for the A in LaTeX.
+ % Revert to plain's \scriptsize, which is 7pt.
+ \count255=\the\fam $\fam\count255 \scriptstyle A$%
+ \else
+ % For 11pt, we can use our lllsize.
+ \selectfonts\lllsize A%
+ \fi
+ }%
+ \vss
+ }}%
+ \kern-.15em
+ \TeX
+}
+
+% Some math mode symbols.
+\def\bullet{$\ptexbullet$}
+\def\geq{\ifmmode \ge\else $\ge$\fi}
+\def\leq{\ifmmode \le\else $\le$\fi}
+\def\minus{\ifmmode -\else $-$\fi}
+
+% @dots{} outputs an ellipsis using the current font.
+% We do .5em per period so that it has the same spacing in the cm
+% typewriter fonts as three actual period characters; on the other hand,
+% in other typewriter fonts three periods are wider than 1.5em. So do
+% whichever is larger.
+%
+\def\dots{%
+ \leavevmode
+ \setbox0=\hbox{...}% get width of three periods
+ \ifdim\wd0 > 1.5em
+ \dimen0 = \wd0
+ \else
+ \dimen0 = 1.5em
+ \fi
+ \hbox to \dimen0{%
+ \hskip 0pt plus.25fil
+ .\hskip 0pt plus1fil
+ .\hskip 0pt plus1fil
+ .\hskip 0pt plus.5fil
+ }%
+}
+
+% @enddots{} is an end-of-sentence ellipsis.
+%
+\def\enddots{%
+ \dots
+ \spacefactor=\endofsentencespacefactor
+}
+
+% @point{}, @result{}, @expansion{}, @print{}, @equiv{}.
+%
+% Since these characters are used in examples, they should be an even number of
+% \tt widths. Each \tt character is 1en, so two makes it 1em.
+%
+\def\point{$\star$}
+\def\arrow{\leavevmode\raise.05ex\hbox to 1em{\hfil$\rightarrow$\hfil}}
+\def\result{\leavevmode\raise.05ex\hbox to 1em{\hfil$\Rightarrow$\hfil}}
+\def\expansion{\leavevmode\hbox to 1em{\hfil$\mapsto$\hfil}}
+\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}}
+\def\equiv{\leavevmode\hbox to 1em{\hfil$\ptexequiv$\hfil}}
+
+% The @error{} command.
+% Adapted from the TeXbook's \boxit.
+%
+\newbox\errorbox
+%
+{\tentt \global\dimen0 = 3em}% Width of the box.
+\dimen2 = .55pt % Thickness of rules
+% The text. (`r' is open on the right, `e' somewhat less so on the left.)
+\setbox0 = \hbox{\kern-.75pt \reducedsf \putworderror\kern-1.5pt}
+%
+\setbox\errorbox=\hbox to \dimen0{\hfil
+ \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right.
+ \advance\hsize by -2\dimen2 % Rules.
+ \vbox{%
+ \hrule height\dimen2
+ \hbox{\vrule width\dimen2 \kern3pt % Space to left of text.
+ \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below.
+ \kern3pt\vrule width\dimen2}% Space to right.
+ \hrule height\dimen2}
+ \hfil}
+%
+\def\error{\leavevmode\lower.7ex\copy\errorbox}
+
+% @pounds{} is a sterling sign, which Knuth put in the CM italic font.
+%
+\def\pounds{{\it\$}}
+
+% @euro{} comes from a separate font, depending on the current style.
+% We use the free feym* fonts from the eurosym package by Henrik
+% Theiling, which support regular, slanted, bold and bold slanted (and
+% "outlined" (blackboard board, sort of) versions, which we don't need).
+% It is available from http://www.ctan.org/tex-archive/fonts/eurosym.
+%
+% Although only regular is the truly official Euro symbol, we ignore
+% that. The Euro is designed to be slightly taller than the regular
+% font height.
+%
+% feymr - regular
+% feymo - slanted
+% feybr - bold
+% feybo - bold slanted
+%
+% There is no good (free) typewriter version, to my knowledge.
+% A feymr10 euro is ~7.3pt wide, while a normal cmtt10 char is ~5.25pt wide.
+% Hmm.
+%
+% Also doesn't work in math. Do we need to do math with euro symbols?
+% Hope not.
+%
+%
+\def\euro{{\eurofont e}}
+\def\eurofont{%
+ % We set the font at each command, rather than predefining it in
+ % \textfonts and the other font-switching commands, so that
+ % installations which never need the symbol don't have to have the
+ % font installed.
+ %
+ % There is only one designed size (nominal 10pt), so we always scale
+ % that to the current nominal size.
+ %
+ % By the way, simply using "at 1em" works for cmr10 and the like, but
+ % does not work for cmbx10 and other extended/shrunken fonts.
+ %
+ \def\eurosize{\csname\curfontsize nominalsize\endcsname}%
+ %
+ \ifx\curfontstyle\bfstylename
+ % bold:
+ \font\thiseurofont = \ifusingit{feybo10}{feybr10} at \eurosize
+ \else
+ % regular:
+ \font\thiseurofont = \ifusingit{feymo10}{feymr10} at \eurosize
+ \fi
+ \thiseurofont
+}
+
+% Glyphs from the EC fonts. We don't use \let for the aliases, because
+% sometimes we redefine the original macro, and the alias should reflect
+% the redefinition.
+%
+% Use LaTeX names for the Icelandic letters.
+\def\DH{{\ecfont \char"D0}} % Eth
+\def\dh{{\ecfont \char"F0}} % eth
+\def\TH{{\ecfont \char"DE}} % Thorn
+\def\th{{\ecfont \char"FE}} % thorn
+%
+\def\guillemetleft{{\ecfont \char"13}}
+\def\guillemotleft{\guillemetleft}
+\def\guillemetright{{\ecfont \char"14}}
+\def\guillemotright{\guillemetright}
+\def\guilsinglleft{{\ecfont \char"0E}}
+\def\guilsinglright{{\ecfont \char"0F}}
+\def\quotedblbase{{\ecfont \char"12}}
+\def\quotesinglbase{{\ecfont \char"0D}}
+%
+% This positioning is not perfect (see the ogonek LaTeX package), but
+% we have the precomposed glyphs for the most common cases. We put the
+% tests to use those glyphs in the single \ogonek macro so we have fewer
+% dummy definitions to worry about for index entries, etc.
+%
+% ogonek is also used with other letters in Lithuanian (IOU), but using
+% the precomposed glyphs for those is not so easy since they aren't in
+% the same EC font.
+\def\ogonek#1{{%
+ \def\temp{#1}%
+ \ifx\temp\macrocharA\Aogonek
+ \else\ifx\temp\macrochara\aogonek
+ \else\ifx\temp\macrocharE\Eogonek
+ \else\ifx\temp\macrochare\eogonek
+ \else
+ \ecfont \setbox0=\hbox{#1}%
+ \ifdim\ht0=1ex\accent"0C #1%
+ \else\ooalign{\unhbox0\crcr\hidewidth\char"0C \hidewidth}%
+ \fi
+ \fi\fi\fi\fi
+ }%
+}
+\def\Aogonek{{\ecfont \char"81}}\def\macrocharA{A}
+\def\aogonek{{\ecfont \char"A1}}\def\macrochara{a}
+\def\Eogonek{{\ecfont \char"86}}\def\macrocharE{E}
+\def\eogonek{{\ecfont \char"A6}}\def\macrochare{e}
+%
+% Use the ec* fonts (cm-super in outline format) for non-CM glyphs.
+\def\ecfont{%
+ % We can't distinguish serif/sans and italic/slanted, but this
+ % is used for crude hacks anyway (like adding French and German
+ % quotes to documents typeset with CM, where we lose kerning), so
+ % hopefully nobody will notice/care.
+ \edef\ecsize{\csname\curfontsize ecsize\endcsname}%
+ \edef\nominalsize{\csname\curfontsize nominalsize\endcsname}%
+ \ifmonospace
+ % typewriter:
+ \font\thisecfont = ectt\ecsize \space at \nominalsize
+ \else
+ \ifx\curfontstyle\bfstylename
+ % bold:
+ \font\thisecfont = ecb\ifusingit{i}{x}\ecsize \space at \nominalsize
+ \else
+ % regular:
+ \font\thisecfont = ec\ifusingit{ti}{rm}\ecsize \space at \nominalsize
+ \fi
+ \fi
+ \thisecfont
+}
+
+% @registeredsymbol - R in a circle. The font for the R should really
+% be smaller yet, but lllsize is the best we can do for now.
+% Adapted from the plain.tex definition of \copyright.
+%
+\def\registeredsymbol{%
+ $^{{\ooalign{\hfil\raise.07ex\hbox{\selectfonts\lllsize R}%
+ \hfil\crcr\Orb}}%
+ }$%
+}
+
+% @textdegree - the normal degrees sign.
+%
+\def\textdegree{$^\circ$}
+
+% Laurent Siebenmann reports \Orb undefined with:
+% Textures 1.7.7 (preloaded format=plain 93.10.14) (68K) 16 APR 2004 02:38
+% so we'll define it if necessary.
+%
+\ifx\Orb\thisisundefined
+\def\Orb{\mathhexbox20D}
+\fi
+
+% Quotes.
+\chardef\quotedblleft="5C
+\chardef\quotedblright=`\"
+\chardef\quoteleft=`\`
+\chardef\quoteright=`\'
+
+
+\message{page headings,}
+
+\newskip\titlepagetopglue \titlepagetopglue = 1.5in
+\newskip\titlepagebottomglue \titlepagebottomglue = 2pc
+
+% First the title page. Must do @settitle before @titlepage.
+\newif\ifseenauthor
+\newif\iffinishedtitlepage
+
+% Do an implicit @contents or @shortcontents after @end titlepage if the
+% user says @setcontentsaftertitlepage or @setshortcontentsaftertitlepage.
+%
+\newif\ifsetcontentsaftertitlepage
+ \let\setcontentsaftertitlepage = \setcontentsaftertitlepagetrue
+\newif\ifsetshortcontentsaftertitlepage
+ \let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue
+
+\parseargdef\shorttitlepage{%
+ \begingroup \hbox{}\vskip 1.5in \chaprm \centerline{#1}%
+ \endgroup\page\hbox{}\page}
+
+\envdef\titlepage{%
+ % Open one extra group, as we want to close it in the middle of \Etitlepage.
+ \begingroup
+ \parindent=0pt \textfonts
+ % Leave some space at the very top of the page.
+ \vglue\titlepagetopglue
+ % No rule at page bottom unless we print one at the top with @title.
+ \finishedtitlepagetrue
+ %
+ % Most title ``pages'' are actually two pages long, with space
+ % at the top of the second. We don't want the ragged left on the second.
+ \let\oldpage = \page
+ \def\page{%
+ \iffinishedtitlepage\else
+ \finishtitlepage
+ \fi
+ \let\page = \oldpage
+ \page
+ \null
+ }%
+}
+
+\def\Etitlepage{%
+ \iffinishedtitlepage\else
+ \finishtitlepage
+ \fi
+ % It is important to do the page break before ending the group,
+ % because the headline and footline are only empty inside the group.
+ % If we use the new definition of \page, we always get a blank page
+ % after the title page, which we certainly don't want.
+ \oldpage
+ \endgroup
+ %
+ % Need this before the \...aftertitlepage checks so that if they are
+ % in effect the toc pages will come out with page numbers.
+ \HEADINGSon
+ %
+ % If they want short, they certainly want long too.
+ \ifsetshortcontentsaftertitlepage
+ \shortcontents
+ \contents
+ \global\let\shortcontents = \relax
+ \global\let\contents = \relax
+ \fi
+ %
+ \ifsetcontentsaftertitlepage
+ \contents
+ \global\let\contents = \relax
+ \global\let\shortcontents = \relax
+ \fi
+}
+
+\def\finishtitlepage{%
+ \vskip4pt \hrule height 2pt width \hsize
+ \vskip\titlepagebottomglue
+ \finishedtitlepagetrue
+}
+
+% Settings used for typesetting titles: no hyphenation, no indentation,
+% don't worry much about spacing, ragged right. This should be used
+% inside a \vbox, and fonts need to be set appropriately first. Because
+% it is always used for titles, nothing else, we call \rmisbold. \par
+% should be specified before the end of the \vbox, since a vbox is a group.
+%
+\def\raggedtitlesettings{%
+ \rmisbold
+ \hyphenpenalty=10000
+ \parindent=0pt
+ \tolerance=5000
+ \ptexraggedright
+}
+
+% Macros to be used within @titlepage:
+
+\let\subtitlerm=\tenrm
+\def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}
+
+\parseargdef\title{%
+ \checkenv\titlepage
+ \vbox{\titlefonts \raggedtitlesettings #1\par}%
+ % print a rule at the page bottom also.
+ \finishedtitlepagefalse
+ \vskip4pt \hrule height 4pt width \hsize \vskip4pt
+}
+
+\parseargdef\subtitle{%
+ \checkenv\titlepage
+ {\subtitlefont \rightline{#1}}%
+}
+
+% @author should come last, but may come many times.
+% It can also be used inside @quotation.
+%
+\parseargdef\author{%
+ \def\temp{\quotation}%
+ \ifx\thisenv\temp
+ \def\quotationauthor{#1}% printed in \Equotation.
+ \else
+ \checkenv\titlepage
+ \ifseenauthor\else \vskip 0pt plus 1filll \seenauthortrue \fi
+ {\secfonts\rmisbold \leftline{#1}}%
+ \fi
+}
+
+
+% Set up page headings and footings.
+
+\let\thispage=\folio
+
+\newtoks\evenheadline % headline on even pages
+\newtoks\oddheadline % headline on odd pages
+\newtoks\evenfootline % footline on even pages
+\newtoks\oddfootline % footline on odd pages
+
+% Now make TeX use those variables
+\headline={{\textfonts\rm \ifodd\pageno \the\oddheadline
+ \else \the\evenheadline \fi}}
+\footline={{\textfonts\rm \ifodd\pageno \the\oddfootline
+ \else \the\evenfootline \fi}\HEADINGShook}
+\let\HEADINGShook=\relax
+
+% Commands to set those variables.
+% For example, this is what @headings on does
+% @evenheading @thistitle|@thispage|@thischapter
+% @oddheading @thischapter|@thispage|@thistitle
+% @evenfooting @thisfile||
+% @oddfooting ||@thisfile
+
+
+\def\evenheading{\parsearg\evenheadingxxx}
+\def\evenheadingxxx #1{\evenheadingyyy #1\|\|\|\|\finish}
+\def\evenheadingyyy #1\|#2\|#3\|#4\finish{%
+\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\def\oddheading{\parsearg\oddheadingxxx}
+\def\oddheadingxxx #1{\oddheadingyyy #1\|\|\|\|\finish}
+\def\oddheadingyyy #1\|#2\|#3\|#4\finish{%
+\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\parseargdef\everyheading{\oddheadingxxx{#1}\evenheadingxxx{#1}}%
+
+\def\evenfooting{\parsearg\evenfootingxxx}
+\def\evenfootingxxx #1{\evenfootingyyy #1\|\|\|\|\finish}
+\def\evenfootingyyy #1\|#2\|#3\|#4\finish{%
+\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\def\oddfooting{\parsearg\oddfootingxxx}
+\def\oddfootingxxx #1{\oddfootingyyy #1\|\|\|\|\finish}
+\def\oddfootingyyy #1\|#2\|#3\|#4\finish{%
+ \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}%
+ %
+ % Leave some space for the footline. Hopefully ok to assume
+ % @evenfooting will not be used by itself.
+ \global\advance\pageheight by -12pt
+ \global\advance\vsize by -12pt
+}
+
+\parseargdef\everyfooting{\oddfootingxxx{#1}\evenfootingxxx{#1}}
+
+% @evenheadingmarks top \thischapter <- chapter at the top of a page
+% @evenheadingmarks bottom \thischapter <- chapter at the bottom of a page
+%
+% The same set of arguments for:
+%
+% @oddheadingmarks
+% @evenfootingmarks
+% @oddfootingmarks
+% @everyheadingmarks
+% @everyfootingmarks
+
+\def\evenheadingmarks{\headingmarks{even}{heading}}
+\def\oddheadingmarks{\headingmarks{odd}{heading}}
+\def\evenfootingmarks{\headingmarks{even}{footing}}
+\def\oddfootingmarks{\headingmarks{odd}{footing}}
+\def\everyheadingmarks#1 {\headingmarks{even}{heading}{#1}
+ \headingmarks{odd}{heading}{#1} }
+\def\everyfootingmarks#1 {\headingmarks{even}{footing}{#1}
+ \headingmarks{odd}{footing}{#1} }
+% #1 = even/odd, #2 = heading/footing, #3 = top/bottom.
+\def\headingmarks#1#2#3 {%
+ \expandafter\let\expandafter\temp \csname get#3headingmarks\endcsname
+ \global\expandafter\let\csname get#1#2marks\endcsname \temp
+}
+
+\everyheadingmarks bottom
+\everyfootingmarks bottom
+
+% @headings double turns headings on for double-sided printing.
+% @headings single turns headings on for single-sided printing.
+% @headings off turns them off.
+% @headings on same as @headings double, retained for compatibility.
+% @headings after turns on double-sided headings after this page.
+% @headings doubleafter turns on double-sided headings after this page.
+% @headings singleafter turns on single-sided headings after this page.
+% By default, they are off at the start of a document,
+% and turned `on' after @end titlepage.
+
+\def\headings #1 {\csname HEADINGS#1\endcsname}
+
+\def\headingsoff{% non-global headings elimination
+ \evenheadline={\hfil}\evenfootline={\hfil}%
+ \oddheadline={\hfil}\oddfootline={\hfil}%
+}
+
+\def\HEADINGSoff{{\globaldefs=1 \headingsoff}} % global setting
+\HEADINGSoff % it's the default
+
+% When we turn headings on, set the page number to 1.
+% For double-sided printing, put current file name in lower left corner,
+% chapter name on inside top of right hand pages, document
+% title on inside top of left hand pages, and page numbers on outside top
+% edge of all pages.
+\def\HEADINGSdouble{%
+\global\pageno=1
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\folio\hfil\thistitle}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chapoddpage
+}
+\let\contentsalignmacro = \chappager
+
+% For single-sided printing, chapter title goes across top left of page,
+% page number on top right.
+\def\HEADINGSsingle{%
+\global\pageno=1
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\thischapter\hfil\folio}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chappager
+}
+\def\HEADINGSon{\HEADINGSdouble}
+
+\def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex}
+\let\HEADINGSdoubleafter=\HEADINGSafter
+\def\HEADINGSdoublex{%
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\folio\hfil\thistitle}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chapoddpage
+}
+
+\def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex}
+\def\HEADINGSsinglex{%
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\thischapter\hfil\folio}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chappager
+}
+
+% Subroutines used in generating headings
+% This produces Day Month Year style of output.
+% Only define if not already defined, in case a txi-??.tex file has set
+% up a different format (e.g., txi-cs.tex does this).
+\ifx\today\thisisundefined
+\def\today{%
+ \number\day\space
+ \ifcase\month
+ \or\putwordMJan\or\putwordMFeb\or\putwordMMar\or\putwordMApr
+ \or\putwordMMay\or\putwordMJun\or\putwordMJul\or\putwordMAug
+ \or\putwordMSep\or\putwordMOct\or\putwordMNov\or\putwordMDec
+ \fi
+ \space\number\year}
+\fi
+
+% @settitle line... specifies the title of the document, for headings.
+% It generates no output of its own.
+\def\thistitle{\putwordNoTitle}
+\def\settitle{\parsearg{\gdef\thistitle}}
+
+
+\message{tables,}
+% Tables -- @table, @ftable, @vtable, @item(x).
+
+% default indentation of table text
+\newdimen\tableindent \tableindent=.8in
+% default indentation of @itemize and @enumerate text
+\newdimen\itemindent \itemindent=.3in
+% margin between end of table item and start of table text.
+\newdimen\itemmargin \itemmargin=.1in
+
+% used internally for \itemindent minus \itemmargin
+\newdimen\itemmax
+
+% Note @table, @ftable, and @vtable define @item, @itemx, etc., with
+% these defs.
+% They also define \itemindex
+% to index the item name in whatever manner is desired (perhaps none).
+
+\newif\ifitemxneedsnegativevskip
+
+\def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi}
+
+\def\internalBitem{\smallbreak \parsearg\itemzzz}
+\def\internalBitemx{\itemxpar \parsearg\itemzzz}
+
+\def\itemzzz #1{\begingroup %
+ \advance\hsize by -\rightskip
+ \advance\hsize by -\tableindent
+ \setbox0=\hbox{\itemindicate{#1}}%
+ \itemindex{#1}%
+ \nobreak % This prevents a break before @itemx.
+ %
+ % If the item text does not fit in the space we have, put it on a line
+ % by itself, and do not allow a page break either before or after that
+ % line. We do not start a paragraph here because then if the next
+ % command is, e.g., @kindex, the whatsit would get put into the
+ % horizontal list on a line by itself, resulting in extra blank space.
+ \ifdim \wd0>\itemmax
+ %
+ % Make this a paragraph so we get the \parskip glue and wrapping,
+ % but leave it ragged-right.
+ \begingroup
+ \advance\leftskip by-\tableindent
+ \advance\hsize by\tableindent
+ \advance\rightskip by0pt plus1fil\relax
+ \leavevmode\unhbox0\par
+ \endgroup
+ %
+ % We're going to be starting a paragraph, but we don't want the
+ % \parskip glue -- logically it's part of the @item we just started.
+ \nobreak \vskip-\parskip
+ %
+ % Stop a page break at the \parskip glue coming up. However, if
+ % what follows is an environment such as @example, there will be no
+ % \parskip glue; then the negative vskip we just inserted would
+ % cause the example and the item to crash together. So we use this
+ % bizarre value of 10001 as a signal to \aboveenvbreak to insert
+ % \parskip glue after all. Section titles are handled this way also.
+ %
+ \penalty 10001
+ \endgroup
+ \itemxneedsnegativevskipfalse
+ \else
+ % The item text fits into the space. Start a paragraph, so that the
+ % following text (if any) will end up on the same line.
+ \noindent
+ % Do this with kerns and \unhbox so that if there is a footnote in
+ % the item text, it can migrate to the main vertical list and
+ % eventually be printed.
+ \nobreak\kern-\tableindent
+ \dimen0 = \itemmax \advance\dimen0 by \itemmargin \advance\dimen0 by -\wd0
+ \unhbox0
+ \nobreak\kern\dimen0
+ \endgroup
+ \itemxneedsnegativevskiptrue
+ \fi
+}
+
+\def\item{\errmessage{@item while not in a list environment}}
+\def\itemx{\errmessage{@itemx while not in a list environment}}
+
+% @table, @ftable, @vtable.
+\envdef\table{%
+ \let\itemindex\gobble
+ \tablecheck{table}%
+}
+\envdef\ftable{%
+ \def\itemindex ##1{\doind {fn}{\code{##1}}}%
+ \tablecheck{ftable}%
+}
+\envdef\vtable{%
+ \def\itemindex ##1{\doind {vr}{\code{##1}}}%
+ \tablecheck{vtable}%
+}
+\def\tablecheck#1{%
+ \ifnum \the\catcode`\^^M=\active
+ \endgroup
+ \errmessage{This command won't work in this context; perhaps the problem is
+ that we are \inenvironment\thisenv}%
+ \def\next{\doignore{#1}}%
+ \else
+ \let\next\tablex
+ \fi
+ \next
+}
+\def\tablex#1{%
+ \def\itemindicate{#1}%
+ \parsearg\tabley
+}
+\def\tabley#1{%
+ {%
+ \makevalueexpandable
+ \edef\temp{\noexpand\tablez #1\space\space\space}%
+ \expandafter
+ }\temp \endtablez
+}
+\def\tablez #1 #2 #3 #4\endtablez{%
+ \aboveenvbreak
+ \ifnum 0#1>0 \advance \leftskip by #1\mil \fi
+ \ifnum 0#2>0 \tableindent=#2\mil \fi
+ \ifnum 0#3>0 \advance \rightskip by #3\mil \fi
+ \itemmax=\tableindent
+ \advance \itemmax by -\itemmargin
+ \advance \leftskip by \tableindent
+ \exdentamount=\tableindent
+ \parindent = 0pt
+ \parskip = \smallskipamount
+ \ifdim \parskip=0pt \parskip=2pt \fi
+ \let\item = \internalBitem
+ \let\itemx = \internalBitemx
+}
+\def\Etable{\endgraf\afterenvbreak}
+\let\Eftable\Etable
+\let\Evtable\Etable
+\let\Eitemize\Etable
+\let\Eenumerate\Etable
+
+% This is the counter used by @enumerate, which is really @itemize
+
+\newcount \itemno
+
+\envdef\itemize{\parsearg\doitemize}
+
+\def\doitemize#1{%
+ \aboveenvbreak
+ \itemmax=\itemindent
+ \advance\itemmax by -\itemmargin
+ \advance\leftskip by \itemindent
+ \exdentamount=\itemindent
+ \parindent=0pt
+ \parskip=\smallskipamount
+ \ifdim\parskip=0pt \parskip=2pt \fi
+ %
+ % Try typesetting the item mark so that if the document erroneously says
+ % something like @itemize @samp (intending @table), there's an error
+ % right away at the @itemize. It's not the best error message in the
+ % world, but it's better than leaving it to the @item. This means if
+ % the user wants an empty mark, they have to say @w{} not just @w.
+ \def\itemcontents{#1}%
+ \setbox0 = \hbox{\itemcontents}%
+ %
+ % @itemize with no arg is equivalent to @itemize @bullet.
+ \ifx\itemcontents\empty\def\itemcontents{\bullet}\fi
+ %
+ \let\item=\itemizeitem
+}
+
+% Definition of @item while inside @itemize and @enumerate.
+%
+\def\itemizeitem{%
+ \advance\itemno by 1 % for enumerations
+ {\let\par=\endgraf \smallbreak}% reasonable place to break
+ {%
+ % If the document has an @itemize directly after a section title, a
+ % \nobreak will be last on the list, and \sectionheading will have
+ % done a \vskip-\parskip. In that case, we don't want to zero
+ % parskip, or the item text will crash with the heading. On the
+ % other hand, when there is normal text preceding the item (as there
+ % usually is), we do want to zero parskip, or there would be too much
+ % space. In that case, we won't have a \nobreak before. At least
+ % that's the theory.
+ \ifnum\lastpenalty<10000 \parskip=0in \fi
+ \noindent
+ \hbox to 0pt{\hss \itemcontents \kern\itemmargin}%
+ %
+ \vadjust{\penalty 1200}}% not good to break after first line of item.
+ \flushcr
+}
+
+% \splitoff TOKENS\endmark defines \first to be the first token in
+% TOKENS, and \rest to be the remainder.
+%
+\def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}%
+
+% Allow an optional argument of an uppercase letter, lowercase letter,
+% or number, to specify the first label in the enumerated list. No
+% argument is the same as `1'.
+%
+\envparseargdef\enumerate{\enumeratey #1 \endenumeratey}
+\def\enumeratey #1 #2\endenumeratey{%
+ % If we were given no argument, pretend we were given `1'.
+ \def\thearg{#1}%
+ \ifx\thearg\empty \def\thearg{1}\fi
+ %
+ % Detect if the argument is a single token. If so, it might be a
+ % letter. Otherwise, the only valid thing it can be is a number.
+ % (We will always have one token, because of the test we just made.
+ % This is a good thing, since \splitoff doesn't work given nothing at
+ % all -- the first parameter is undelimited.)
+ \expandafter\splitoff\thearg\endmark
+ \ifx\rest\empty
+ % Only one token in the argument. It could still be anything.
+ % A ``lowercase letter'' is one whose \lccode is nonzero.
+ % An ``uppercase letter'' is one whose \lccode is both nonzero, and
+ % not equal to itself.
+ % Otherwise, we assume it's a number.
+ %
+ % We need the \relax at the end of the \ifnum lines to stop TeX from
+ % continuing to look for a <number>.
+ %
+ \ifnum\lccode\expandafter`\thearg=0\relax
+ \numericenumerate % a number (we hope)
+ \else
+ % It's a letter.
+ \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax
+ \lowercaseenumerate % lowercase letter
+ \else
+ \uppercaseenumerate % uppercase letter
+ \fi
+ \fi
+ \else
+ % Multiple tokens in the argument. We hope it's a number.
+ \numericenumerate
+ \fi
+}
+
+% An @enumerate whose labels are integers. The starting integer is
+% given in \thearg.
+%
+\def\numericenumerate{%
+ \itemno = \thearg
+ \startenumeration{\the\itemno}%
+}
+
+% The starting (lowercase) letter is in \thearg.
+\def\lowercaseenumerate{%
+ \itemno = \expandafter`\thearg
+ \startenumeration{%
+ % Be sure we're not beyond the end of the alphabet.
+ \ifnum\itemno=0
+ \errmessage{No more lowercase letters in @enumerate; get a bigger
+ alphabet}%
+ \fi
+ \char\lccode\itemno
+ }%
+}
+
+% The starting (uppercase) letter is in \thearg.
+\def\uppercaseenumerate{%
+ \itemno = \expandafter`\thearg
+ \startenumeration{%
+ % Be sure we're not beyond the end of the alphabet.
+ \ifnum\itemno=0
+ \errmessage{No more uppercase letters in @enumerate; get a bigger
+ alphabet}
+ \fi
+ \char\uccode\itemno
+ }%
+}
+
+% Call \doitemize, adding a period to the first argument and supplying the
+% common last two arguments. Also subtract one from the initial value in
+% \itemno, since @item increments \itemno.
+%
+\def\startenumeration#1{%
+ \advance\itemno by -1
+ \doitemize{#1.}\flushcr
+}
+
+% @alphaenumerate and @capsenumerate are abbreviations for giving an arg
+% to @enumerate.
+%
+\def\alphaenumerate{\enumerate{a}}
+\def\capsenumerate{\enumerate{A}}
+\def\Ealphaenumerate{\Eenumerate}
+\def\Ecapsenumerate{\Eenumerate}
+
+
+% @multitable macros
+% Amy Hendrickson, 8/18/94, 3/6/96
+%
+% @multitable ... @end multitable will make as many columns as desired.
+% Contents of each column will wrap at width given in preamble. Width
+% can be specified either with sample text given in a template line,
+% or in percent of \hsize, the current width of text on page.
+
+% Table can continue over pages but will only break between lines.
+
+% To make preamble:
+%
+% Either define widths of columns in terms of percent of \hsize:
+% @multitable @columnfractions .25 .3 .45
+% @item ...
+%
+% Numbers following @columnfractions are the percent of the total
+% current hsize to be used for each column. You may use as many
+% columns as desired.
+
+
+% Or use a template:
+% @multitable {Column 1 template} {Column 2 template} {Column 3 template}
+% @item ...
+% using the widest term desired in each column.
+
+% Each new table line starts with @item, each subsequent new column
+% starts with @tab. Empty columns may be produced by supplying @tab's
+% with nothing between them for as many times as empty columns are needed,
+% ie, @tab@tab@tab will produce two empty columns.
+
+% @item, @tab do not need to be on their own lines, but it will not hurt
+% if they are.
+
+% Sample multitable:
+
+% @multitable {Column 1 template} {Column 2 template} {Column 3 template}
+% @item first col stuff @tab second col stuff @tab third col
+% @item
+% first col stuff
+% @tab
+% second col stuff
+% @tab
+% third col
+% @item first col stuff @tab second col stuff
+% @tab Many paragraphs of text may be used in any column.
+%
+% They will wrap at the width determined by the template.
+% @item@tab@tab This will be in third column.
+% @end multitable
+
+% Default dimensions may be reset by user.
+% @multitableparskip is vertical space between paragraphs in table.
+% @multitableparindent is paragraph indent in table.
+% @multitablecolmargin is horizontal space to be left between columns.
+% @multitablelinespace is space to leave between table items, baseline
+% to baseline.
+% 0pt means it depends on current normal line spacing.
+%
+\newskip\multitableparskip
+\newskip\multitableparindent
+\newdimen\multitablecolspace
+\newskip\multitablelinespace
+\multitableparskip=0pt
+\multitableparindent=6pt
+\multitablecolspace=12pt
+\multitablelinespace=0pt
+
+% Macros used to set up halign preamble:
+%
+\let\endsetuptable\relax
+\def\xendsetuptable{\endsetuptable}
+\let\columnfractions\relax
+\def\xcolumnfractions{\columnfractions}
+\newif\ifsetpercent
+
+% #1 is the @columnfraction, usually a decimal number like .5, but might
+% be just 1. We just use it, whatever it is.
+%
+\def\pickupwholefraction#1 {%
+ \global\advance\colcount by 1
+ \expandafter\xdef\csname col\the\colcount\endcsname{#1\hsize}%
+ \setuptable
+}
+
+\newcount\colcount
+\def\setuptable#1{%
+ \def\firstarg{#1}%
+ \ifx\firstarg\xendsetuptable
+ \let\go = \relax
+ \else
+ \ifx\firstarg\xcolumnfractions
+ \global\setpercenttrue
+ \else
+ \ifsetpercent
+ \let\go\pickupwholefraction
+ \else
+ \global\advance\colcount by 1
+ \setbox0=\hbox{#1\unskip\space}% Add a normal word space as a
+ % separator; typically that is always in the input, anyway.
+ \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}%
+ \fi
+ \fi
+ \ifx\go\pickupwholefraction
+ % Put the argument back for the \pickupwholefraction call, so
+ % we'll always have a period there to be parsed.
+ \def\go{\pickupwholefraction#1}%
+ \else
+ \let\go = \setuptable
+ \fi%
+ \fi
+ \go
+}
+
+% multitable-only commands.
+%
+% @headitem starts a heading row, which we typeset in bold. Assignments
+% have to be global since we are inside the implicit group of an
+% alignment entry. \everycr below resets \everytab so we don't have to
+% undo it ourselves.
+\def\headitemfont{\b}% for people to use in the template row; not changeable
+\def\headitem{%
+ \checkenv\multitable
+ \crcr
+ \gdef\headitemcrhook{\nobreak}% attempt to avoid page break after headings
+ \global\everytab={\bf}% can't use \headitemfont since the parsing differs
+ \the\everytab % for the first item
+}%
+%
+% default for tables with no headings.
+\let\headitemcrhook=\relax
+%
+% A \tab used to include \hskip1sp. But then the space in a template
+% line is not enough. That is bad. So let's go back to just `&' until
+% we again encounter the problem the 1sp was intended to solve.
+% --karl, nathan@acm.org, 20apr99.
+\def\tab{\checkenv\multitable &\the\everytab}%
+
+% @multitable ... @end multitable definitions:
+%
+\newtoks\everytab % insert after every tab.
+%
+\envdef\multitable{%
+ \vskip\parskip
+ \startsavinginserts
+ %
+ % @item within a multitable starts a normal row.
+ % We use \def instead of \let so that if one of the multitable entries
+ % contains an @itemize, we don't choke on the \item (seen as \crcr aka
+ % \endtemplate) expanding \doitemize.
+ \def\item{\crcr}%
+ %
+ \tolerance=9500
+ \hbadness=9500
+ \setmultitablespacing
+ \parskip=\multitableparskip
+ \parindent=\multitableparindent
+ \overfullrule=0pt
+ \global\colcount=0
+ %
+ \everycr = {%
+ \noalign{%
+ \global\everytab={}% Reset from possible headitem.
+ \global\colcount=0 % Reset the column counter.
+ %
+ % Check for saved footnotes, etc.:
+ \checkinserts
+ %
+ % Perhaps a \nobreak, then reset:
+ \headitemcrhook
+ \global\let\headitemcrhook=\relax
+ }%
+ }%
+ %
+ \parsearg\domultitable
+}
+\def\domultitable#1{%
+ % To parse everything between @multitable and @item:
+ \setuptable#1 \endsetuptable
+ %
+ % This preamble sets up a generic column definition, which will
+ % be used as many times as user calls for columns.
+ % \vtop will set a single line and will also let text wrap and
+ % continue for many paragraphs if desired.
+ \halign\bgroup &%
+ \global\advance\colcount by 1
+ \multistrut
+ \vtop{%
+ % Use the current \colcount to find the correct column width:
+ \hsize=\expandafter\csname col\the\colcount\endcsname
+ %
+ % In order to keep entries from bumping into each other
+ % we will add a \leftskip of \multitablecolspace to all columns after
+ % the first one.
+ %
+ % If a template has been used, we will add \multitablecolspace
+ % to the width of each template entry.
+ %
+ % If the user has set preamble in terms of percent of \hsize we will
+ % use that dimension as the width of the column, and the \leftskip
+ % will keep entries from bumping into each other. Table will start at
+ % left margin and final column will justify at right margin.
+ %
+ % Make sure we don't inherit \rightskip from the outer environment.
+ \rightskip=0pt
+ \ifnum\colcount=1
+ % The first column will be indented with the surrounding text.
+ \advance\hsize by\leftskip
+ \else
+ \ifsetpercent \else
+ % If user has not set preamble in terms of percent of \hsize
+ % we will advance \hsize by \multitablecolspace.
+ \advance\hsize by \multitablecolspace
+ \fi
+ % In either case we will make \leftskip=\multitablecolspace:
+ \leftskip=\multitablecolspace
+ \fi
+ % Ignoring space at the beginning and end avoids an occasional spurious
+ % blank line, when TeX decides to break the line at the space before the
+ % box from the multistrut, so the strut ends up on a line by itself.
+ % For example:
+ % @multitable @columnfractions .11 .89
+ % @item @code{#}
+ % @tab Legal holiday which is valid in major parts of the whole country.
+ % Is automatically provided with highlighting sequences respectively
+ % marking characters.
+ \noindent\ignorespaces##\unskip\multistrut
+ }\cr
+}
+\def\Emultitable{%
+ \crcr
+ \egroup % end the \halign
+ \global\setpercentfalse
+}
+
+\def\setmultitablespacing{%
+ \def\multistrut{\strut}% just use the standard line spacing
+ %
+ % Compute \multitablelinespace (if not defined by user) for use in
+ % \multitableparskip calculation. We used define \multistrut based on
+ % this, but (ironically) that caused the spacing to be off.
+ % See bug-texinfo report from Werner Lemberg, 31 Oct 2004 12:52:20 +0100.
+\ifdim\multitablelinespace=0pt
+\setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip
+\global\advance\multitablelinespace by-\ht0
+\fi
+% Test to see if parskip is larger than space between lines of
+% table. If not, do nothing.
+% If so, set to same dimension as multitablelinespace.
+\ifdim\multitableparskip>\multitablelinespace
+\global\multitableparskip=\multitablelinespace
+\global\advance\multitableparskip-7pt % to keep parskip somewhat smaller
+ % than skip between lines in the table.
+\fi%
+\ifdim\multitableparskip=0pt
+\global\multitableparskip=\multitablelinespace
+\global\advance\multitableparskip-7pt % to keep parskip somewhat smaller
+ % than skip between lines in the table.
+\fi}
+
+
+\message{conditionals,}
+
+% @iftex, @ifnotdocbook, @ifnothtml, @ifnotinfo, @ifnotplaintext,
+% @ifnotxml always succeed. They currently do nothing; we don't
+% attempt to check whether the conditionals are properly nested. But we
+% have to remember that they are conditionals, so that @end doesn't
+% attempt to close an environment group.
+%
+\def\makecond#1{%
+ \expandafter\let\csname #1\endcsname = \relax
+ \expandafter\let\csname iscond.#1\endcsname = 1
+}
+\makecond{iftex}
+\makecond{ifnotdocbook}
+\makecond{ifnothtml}
+\makecond{ifnotinfo}
+\makecond{ifnotplaintext}
+\makecond{ifnotxml}
+
+% Ignore @ignore, @ifhtml, @ifinfo, and the like.
+%
+\def\direntry{\doignore{direntry}}
+\def\documentdescription{\doignore{documentdescription}}
+\def\docbook{\doignore{docbook}}
+\def\html{\doignore{html}}
+\def\ifdocbook{\doignore{ifdocbook}}
+\def\ifhtml{\doignore{ifhtml}}
+\def\ifinfo{\doignore{ifinfo}}
+\def\ifnottex{\doignore{ifnottex}}
+\def\ifplaintext{\doignore{ifplaintext}}
+\def\ifxml{\doignore{ifxml}}
+\def\ignore{\doignore{ignore}}
+\def\menu{\doignore{menu}}
+\def\xml{\doignore{xml}}
+
+% Ignore text until a line `@end #1', keeping track of nested conditionals.
+%
+% A count to remember the depth of nesting.
+\newcount\doignorecount
+
+\def\doignore#1{\begingroup
+ % Scan in ``verbatim'' mode:
+ \obeylines
+ \catcode`\@ = \other
+ \catcode`\{ = \other
+ \catcode`\} = \other
+ %
+ % Make sure that spaces turn into tokens that match what \doignoretext wants.
+ \spaceisspace
+ %
+ % Count number of #1's that we've seen.
+ \doignorecount = 0
+ %
+ % Swallow text until we reach the matching `@end #1'.
+ \dodoignore{#1}%
+}
+
+{ \catcode`_=11 % We want to use \_STOP_ which cannot appear in texinfo source.
+ \obeylines %
+ %
+ \gdef\dodoignore#1{%
+ % #1 contains the command name as a string, e.g., `ifinfo'.
+ %
+ % Define a command to find the next `@end #1'.
+ \long\def\doignoretext##1^^M@end #1{%
+ \doignoretextyyy##1^^M@#1\_STOP_}%
+ %
+ % And this command to find another #1 command, at the beginning of a
+ % line. (Otherwise, we would consider a line `@c @ifset', for
+ % example, to count as an @ifset for nesting.)
+ \long\def\doignoretextyyy##1^^M@#1##2\_STOP_{\doignoreyyy{##2}\_STOP_}%
+ %
+ % And now expand that command.
+ \doignoretext ^^M%
+ }%
+}
+
+\def\doignoreyyy#1{%
+ \def\temp{#1}%
+ \ifx\temp\empty % Nothing found.
+ \let\next\doignoretextzzz
+ \else % Found a nested condition, ...
+ \advance\doignorecount by 1
+ \let\next\doignoretextyyy % ..., look for another.
+ % If we're here, #1 ends with ^^M\ifinfo (for example).
+ \fi
+ \next #1% the token \_STOP_ is present just after this macro.
+}
+
+% We have to swallow the remaining "\_STOP_".
+%
+\def\doignoretextzzz#1{%
+ \ifnum\doignorecount = 0 % We have just found the outermost @end.
+ \let\next\enddoignore
+ \else % Still inside a nested condition.
+ \advance\doignorecount by -1
+ \let\next\doignoretext % Look for the next @end.
+ \fi
+ \next
+}
+
+% Finish off ignored text.
+{ \obeylines%
+ % Ignore anything after the last `@end #1'; this matters in verbatim
+ % environments, where otherwise the newline after an ignored conditional
+ % would result in a blank line in the output.
+ \gdef\enddoignore#1^^M{\endgroup\ignorespaces}%
+}
+
+
+% @set VAR sets the variable VAR to an empty value.
+% @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE.
+%
+% Since we want to separate VAR from REST-OF-LINE (which might be
+% empty), we can't just use \parsearg; we have to insert a space of our
+% own to delimit the rest of the line, and then take it out again if we
+% didn't need it.
+% We rely on the fact that \parsearg sets \catcode`\ =10.
+%
+\parseargdef\set{\setyyy#1 \endsetyyy}
+\def\setyyy#1 #2\endsetyyy{%
+ {%
+ \makevalueexpandable
+ \def\temp{#2}%
+ \edef\next{\gdef\makecsname{SET#1}}%
+ \ifx\temp\empty
+ \next{}%
+ \else
+ \setzzz#2\endsetzzz
+ \fi
+ }%
+}
+% Remove the trailing space \setxxx inserted.
+\def\setzzz#1 \endsetzzz{\next{#1}}
+
+% @clear VAR clears (i.e., unsets) the variable VAR.
+%
+\parseargdef\clear{%
+ {%
+ \makevalueexpandable
+ \global\expandafter\let\csname SET#1\endcsname=\relax
+ }%
+}
+
+% @value{foo} gets the text saved in variable foo.
+\def\value{\begingroup\makevalueexpandable\valuexxx}
+\def\valuexxx#1{\expandablevalue{#1}\endgroup}
+{
+ \catcode`\-=\active \catcode`\_=\active
+ %
+ \gdef\makevalueexpandable{%
+ \let\value = \expandablevalue
+ % We don't want these characters active, ...
+ \catcode`\-=\other \catcode`\_=\other
+ % ..., but we might end up with active ones in the argument if
+ % we're called from @code, as @code{@value{foo-bar_}}, though.
+ % So \let them to their normal equivalents.
+ \let-\normaldash \let_\normalunderscore
+ }
+}
+
+% We have this subroutine so that we can handle at least some @value's
+% properly in indexes (we call \makevalueexpandable in \indexdummies).
+% The command has to be fully expandable (if the variable is set), since
+% the result winds up in the index file. This means that if the
+% variable's value contains other Texinfo commands, it's almost certain
+% it will fail (although perhaps we could fix that with sufficient work
+% to do a one-level expansion on the result, instead of complete).
+%
+% Unfortunately, this has the consequence that when _ is in the *value*
+% of an @set, it does not print properly in the roman fonts (get the cmr
+% dot accent at position 126 instead). No fix comes to mind, and it's
+% been this way since 2003 or earlier, so just ignore it.
+%
+\def\expandablevalue#1{%
+ \expandafter\ifx\csname SET#1\endcsname\relax
+ {[No value for ``#1'']}%
+ \message{Variable `#1', used in @value, is not set.}%
+ \else
+ \csname SET#1\endcsname
+ \fi
+}
+
+% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined
+% with @set.
+%
+% To get the special treatment we need for `@end ifset,' we call
+% \makecond and then redefine.
+%
+\makecond{ifset}
+\def\ifset{\parsearg{\doifset{\let\next=\ifsetfail}}}
+\def\doifset#1#2{%
+ {%
+ \makevalueexpandable
+ \let\next=\empty
+ \expandafter\ifx\csname SET#2\endcsname\relax
+ #1% If not set, redefine \next.
+ \fi
+ \expandafter
+ }\next
+}
+\def\ifsetfail{\doignore{ifset}}
+
+% @ifclear VAR ... @end executes the `...' iff VAR has never been
+% defined with @set, or has been undefined with @clear.
+%
+% The `\else' inside the `\doifset' parameter is a trick to reuse the
+% above code: if the variable is not set, do nothing, if it is set,
+% then redefine \next to \ifclearfail.
+%
+\makecond{ifclear}
+\def\ifclear{\parsearg{\doifset{\else \let\next=\ifclearfail}}}
+\def\ifclearfail{\doignore{ifclear}}
+
+% @ifcommandisdefined CMD ... @end executes the `...' if CMD (written
+% without the @) is in fact defined. We can only feasibly check at the
+% TeX level, so something like `mathcode' is going to considered
+% defined even though it is not a Texinfo command.
+%
+\makecond{ifcommanddefined}
+\def\ifcommanddefined{\parsearg{\doifcmddefined{\let\next=\ifcmddefinedfail}}}
+%
+\def\doifcmddefined#1#2{{%
+ \makevalueexpandable
+ \let\next=\empty
+ \expandafter\ifx\csname #2\endcsname\relax
+ #1% If not defined, \let\next as above.
+ \fi
+ \expandafter
+ }\next
+}
+\def\ifcmddefinedfail{\doignore{ifcommanddefined}}
+
+% @ifcommandnotdefined CMD ... handled similar to @ifclear above.
+\makecond{ifcommandnotdefined}
+\def\ifcommandnotdefined{%
+ \parsearg{\doifcmddefined{\else \let\next=\ifcmdnotdefinedfail}}}
+\def\ifcmdnotdefinedfail{\doignore{ifcommandnotdefined}}
+
+% Set the `txicommandconditionals' variable, so documents have a way to
+% test if the @ifcommand...defined conditionals are available.
+\set txicommandconditionals
+
+% @dircategory CATEGORY -- specify a category of the dir file
+% which this file should belong to. Ignore this in TeX.
+\let\dircategory=\comment
+
+% @defininfoenclose.
+\let\definfoenclose=\comment
+
+
+\message{indexing,}
+% Index generation facilities
+
+% Define \newwrite to be identical to plain tex's \newwrite
+% except not \outer, so it can be used within macros and \if's.
+\edef\newwrite{\makecsname{ptexnewwrite}}
+
+% \newindex {foo} defines an index named foo.
+% It automatically defines \fooindex such that
+% \fooindex ...rest of line... puts an entry in the index foo.
+% It also defines \fooindfile to be the number of the output channel for
+% the file that accumulates this index. The file's extension is foo.
+% The name of an index should be no more than 2 characters long
+% for the sake of vms.
+%
+\def\newindex#1{%
+ \iflinks
+ \expandafter\newwrite \csname#1indfile\endcsname
+ \openout \csname#1indfile\endcsname \jobname.#1 % Open the file
+ \fi
+ \expandafter\xdef\csname#1index\endcsname{% % Define @#1index
+ \noexpand\doindex{#1}}
+}
+
+% @defindex foo == \newindex{foo}
+%
+\def\defindex{\parsearg\newindex}
+
+% Define @defcodeindex, like @defindex except put all entries in @code.
+%
+\def\defcodeindex{\parsearg\newcodeindex}
+%
+\def\newcodeindex#1{%
+ \iflinks
+ \expandafter\newwrite \csname#1indfile\endcsname
+ \openout \csname#1indfile\endcsname \jobname.#1
+ \fi
+ \expandafter\xdef\csname#1index\endcsname{%
+ \noexpand\docodeindex{#1}}%
+}
+
+
+% @synindex foo bar makes index foo feed into index bar.
+% Do this instead of @defindex foo if you don't want it as a separate index.
+%
+% @syncodeindex foo bar similar, but put all entries made for index foo
+% inside @code.
+%
+\def\synindex#1 #2 {\dosynindex\doindex{#1}{#2}}
+\def\syncodeindex#1 #2 {\dosynindex\docodeindex{#1}{#2}}
+
+% #1 is \doindex or \docodeindex, #2 the index getting redefined (foo),
+% #3 the target index (bar).
+\def\dosynindex#1#2#3{%
+ % Only do \closeout if we haven't already done it, else we'll end up
+ % closing the target index.
+ \expandafter \ifx\csname donesynindex#2\endcsname \relax
+ % The \closeout helps reduce unnecessary open files; the limit on the
+ % Acorn RISC OS is a mere 16 files.
+ \expandafter\closeout\csname#2indfile\endcsname
+ \expandafter\let\csname donesynindex#2\endcsname = 1
+ \fi
+ % redefine \fooindfile:
+ \expandafter\let\expandafter\temp\expandafter=\csname#3indfile\endcsname
+ \expandafter\let\csname#2indfile\endcsname=\temp
+ % redefine \fooindex:
+ \expandafter\xdef\csname#2index\endcsname{\noexpand#1{#3}}%
+}
+
+% Define \doindex, the driver for all \fooindex macros.
+% Argument #1 is generated by the calling \fooindex macro,
+% and it is "foo", the name of the index.
+
+% \doindex just uses \parsearg; it calls \doind for the actual work.
+% This is because \doind is more useful to call from other macros.
+
+% There is also \dosubind {index}{topic}{subtopic}
+% which makes an entry in a two-level index such as the operation index.
+
+\def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer}
+\def\singleindexer #1{\doind{\indexname}{#1}}
+
+% like the previous two, but they put @code around the argument.
+\def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer}
+\def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}}
+
+% Take care of Texinfo commands that can appear in an index entry.
+% Since there are some commands we want to expand, and others we don't,
+% we have to laboriously prevent expansion for those that we don't.
+%
+\def\indexdummies{%
+ \escapechar = `\\ % use backslash in output files.
+ \def\@{@}% change to @@ when we switch to @ as escape char in index files.
+ \def\ {\realbackslash\space }%
+ %
+ % Need these unexpandable (because we define \tt as a dummy)
+ % definitions when @{ or @} appear in index entry text. Also, more
+ % complicated, when \tex is in effect and \{ is a \delimiter again.
+ % We can't use \lbracecmd and \rbracecmd because texindex assumes
+ % braces and backslashes are used only as delimiters. Perhaps we
+ % should use @lbracechar and @rbracechar?
+ \def\{{{\tt\char123}}%
+ \def\}{{\tt\char125}}%
+ %
+ % I don't entirely understand this, but when an index entry is
+ % generated from a macro call, the \endinput which \scanmacro inserts
+ % causes processing to be prematurely terminated. This is,
+ % apparently, because \indexsorttmp is fully expanded, and \endinput
+ % is an expandable command. The redefinition below makes \endinput
+ % disappear altogether for that purpose -- although logging shows that
+ % processing continues to some further point. On the other hand, it
+ % seems \endinput does not hurt in the printed index arg, since that
+ % is still getting written without apparent harm.
+ %
+ % Sample source (mac-idx3.tex, reported by Graham Percival to
+ % help-texinfo, 22may06):
+ % @macro funindex {WORD}
+ % @findex xyz
+ % @end macro
+ % ...
+ % @funindex commtest
+ % This is not enough to reproduce the bug, but it gives the flavor.
+ %
+ % Sample whatsit resulting:
+ % .@write3{\entry{xyz}{@folio }{@code {xyz@endinput }}}
+ %
+ % So:
+ \let\endinput = \empty
+ %
+ % Do the redefinitions.
+ \commondummies
+}
+
+% For the aux and toc files, @ is the escape character. So we want to
+% redefine everything using @ as the escape character (instead of
+% \realbackslash, still used for index files). When everything uses @,
+% this will be simpler.
+%
+\def\atdummies{%
+ \def\@{@@}%
+ \def\ {@ }%
+ \let\{ = \lbraceatcmd
+ \let\} = \rbraceatcmd
+ %
+ % Do the redefinitions.
+ \commondummies
+ \otherbackslash
+}
+
+% Called from \indexdummies and \atdummies.
+%
+\def\commondummies{%
+ %
+ % \definedummyword defines \#1 as \string\#1\space, thus effectively
+ % preventing its expansion. This is used only for control words,
+ % not control letters, because the \space would be incorrect for
+ % control characters, but is needed to separate the control word
+ % from whatever follows.
+ %
+ % For control letters, we have \definedummyletter, which omits the
+ % space.
+ %
+ % These can be used both for control words that take an argument and
+ % those that do not. If it is followed by {arg} in the input, then
+ % that will dutifully get written to the index (or wherever).
+ %
+ \def\definedummyword ##1{\def##1{\string##1\space}}%
+ \def\definedummyletter##1{\def##1{\string##1}}%
+ \let\definedummyaccent\definedummyletter
+ %
+ \commondummiesnofonts
+ %
+ \definedummyletter\_%
+ \definedummyletter\-%
+ %
+ % Non-English letters.
+ \definedummyword\AA
+ \definedummyword\AE
+ \definedummyword\DH
+ \definedummyword\L
+ \definedummyword\O
+ \definedummyword\OE
+ \definedummyword\TH
+ \definedummyword\aa
+ \definedummyword\ae
+ \definedummyword\dh
+ \definedummyword\exclamdown
+ \definedummyword\l
+ \definedummyword\o
+ \definedummyword\oe
+ \definedummyword\ordf
+ \definedummyword\ordm
+ \definedummyword\questiondown
+ \definedummyword\ss
+ \definedummyword\th
+ %
+ % Although these internal commands shouldn't show up, sometimes they do.
+ \definedummyword\bf
+ \definedummyword\gtr
+ \definedummyword\hat
+ \definedummyword\less
+ \definedummyword\sf
+ \definedummyword\sl
+ \definedummyword\tclose
+ \definedummyword\tt
+ %
+ \definedummyword\LaTeX
+ \definedummyword\TeX
+ %
+ % Assorted special characters.
+ \definedummyword\arrow
+ \definedummyword\bullet
+ \definedummyword\comma
+ \definedummyword\copyright
+ \definedummyword\registeredsymbol
+ \definedummyword\dots
+ \definedummyword\enddots
+ \definedummyword\entrybreak
+ \definedummyword\equiv
+ \definedummyword\error
+ \definedummyword\euro
+ \definedummyword\expansion
+ \definedummyword\geq
+ \definedummyword\guillemetleft
+ \definedummyword\guillemetright
+ \definedummyword\guilsinglleft
+ \definedummyword\guilsinglright
+ \definedummyword\lbracechar
+ \definedummyword\leq
+ \definedummyword\minus
+ \definedummyword\ogonek
+ \definedummyword\pounds
+ \definedummyword\point
+ \definedummyword\print
+ \definedummyword\quotedblbase
+ \definedummyword\quotedblleft
+ \definedummyword\quotedblright
+ \definedummyword\quoteleft
+ \definedummyword\quoteright
+ \definedummyword\quotesinglbase
+ \definedummyword\rbracechar
+ \definedummyword\result
+ \definedummyword\textdegree
+ %
+ % We want to disable all macros so that they are not expanded by \write.
+ \macrolist
+ %
+ \normalturnoffactive
+ %
+ % Handle some cases of @value -- where it does not contain any
+ % (non-fully-expandable) commands.
+ \makevalueexpandable
+}
+
+% \commondummiesnofonts: common to \commondummies and \indexnofonts.
+%
+\def\commondummiesnofonts{%
+ % Control letters and accents.
+ \definedummyletter\!%
+ \definedummyaccent\"%
+ \definedummyaccent\'%
+ \definedummyletter\*%
+ \definedummyaccent\,%
+ \definedummyletter\.%
+ \definedummyletter\/%
+ \definedummyletter\:%
+ \definedummyaccent\=%
+ \definedummyletter\?%
+ \definedummyaccent\^%
+ \definedummyaccent\`%
+ \definedummyaccent\~%
+ \definedummyword\u
+ \definedummyword\v
+ \definedummyword\H
+ \definedummyword\dotaccent
+ \definedummyword\ogonek
+ \definedummyword\ringaccent
+ \definedummyword\tieaccent
+ \definedummyword\ubaraccent
+ \definedummyword\udotaccent
+ \definedummyword\dotless
+ %
+ % Texinfo font commands.
+ \definedummyword\b
+ \definedummyword\i
+ \definedummyword\r
+ \definedummyword\sansserif
+ \definedummyword\sc
+ \definedummyword\slanted
+ \definedummyword\t
+ %
+ % Commands that take arguments.
+ \definedummyword\abbr
+ \definedummyword\acronym
+ \definedummyword\anchor
+ \definedummyword\cite
+ \definedummyword\code
+ \definedummyword\command
+ \definedummyword\dfn
+ \definedummyword\dmn
+ \definedummyword\email
+ \definedummyword\emph
+ \definedummyword\env
+ \definedummyword\file
+ \definedummyword\image
+ \definedummyword\indicateurl
+ \definedummyword\inforef
+ \definedummyword\kbd
+ \definedummyword\key
+ \definedummyword\math
+ \definedummyword\option
+ \definedummyword\pxref
+ \definedummyword\ref
+ \definedummyword\samp
+ \definedummyword\strong
+ \definedummyword\tie
+ \definedummyword\uref
+ \definedummyword\url
+ \definedummyword\var
+ \definedummyword\verb
+ \definedummyword\w
+ \definedummyword\xref
+ %
+ % Consider:
+ % @macro mkind{arg1,arg2}
+ % @cindex \arg2\
+ % @end macro
+ % @mkind{foo, bar}
+ % The space after the comma will end up in the temporary definition
+ % that we make for arg2 (see \parsemargdef ff.). We want all this to be
+ % expanded for the sake of the index, so we end up just seeing "bar".
+ \let\xeatspaces = \eatspaces
+}
+
+% For testing: output @{ and @} in index sort strings as \{ and \}.
+\newif\ifusebracesinindexes
+
+% \indexnofonts is used when outputting the strings to sort the index
+% by, and when constructing control sequence names. It eliminates all
+% control sequences and just writes whatever the best ASCII sort string
+% would be for a given command (usually its argument).
+%
+\def\indexnofonts{%
+ % Accent commands should become @asis.
+ \def\definedummyaccent##1{\let##1\asis}%
+ % We can just ignore other control letters.
+ \def\definedummyletter##1{\let##1\empty}%
+ % All control words become @asis by default; overrides below.
+ \let\definedummyword\definedummyaccent
+ %
+ \commondummiesnofonts
+ %
+ % Don't no-op \tt, since it isn't a user-level command
+ % and is used in the definitions of the active chars like <, >, |, etc.
+ % Likewise with the other plain tex font commands.
+ %\let\tt=\asis
+ %
+ \def\ { }%
+ \def\@{@}%
+ \def\_{\normalunderscore}%
+ \def\-{}% @- shouldn't affect sorting
+ %
+ % Unfortunately, texindex is not prepared to handle braces in the
+ % content at all. So for index sorting, we map @{ and @} to strings
+ % starting with |, since that ASCII character is between ASCII { and }.
+ \ifusebracesinindexes
+ \def\lbracechar{\lbracecmd}%
+ \def\rbracechar{\rbracecmd}%
+ \else
+ \def\lbracechar{|a}%
+ \def\rbracechar{|b}%
+ \fi
+ \let\{=\lbracechar
+ \let\}=\rbracechar
+ %
+ %
+ % Non-English letters.
+ \def\AA{AA}%
+ \def\AE{AE}%
+ \def\DH{DZZ}%
+ \def\L{L}%
+ \def\OE{OE}%
+ \def\O{O}%
+ \def\TH{ZZZ}%
+ \def\aa{aa}%
+ \def\ae{ae}%
+ \def\dh{dzz}%
+ \def\exclamdown{!}%
+ \def\l{l}%
+ \def\oe{oe}%
+ \def\ordf{a}%
+ \def\ordm{o}%
+ \def\o{o}%
+ \def\questiondown{?}%
+ \def\ss{ss}%
+ \def\th{zzz}%
+ %
+ \def\LaTeX{LaTeX}%
+ \def\TeX{TeX}%
+ %
+ % Assorted special characters.
+ % (The following {} will end up in the sort string, but that's ok.)
+ \def\arrow{->}%
+ \def\bullet{bullet}%
+ \def\comma{,}%
+ \def\copyright{copyright}%
+ \def\dots{...}%
+ \def\enddots{...}%
+ \def\equiv{==}%
+ \def\error{error}%
+ \def\euro{euro}%
+ \def\expansion{==>}%
+ \def\geq{>=}%
+ \def\guillemetleft{<<}%
+ \def\guillemetright{>>}%
+ \def\guilsinglleft{<}%
+ \def\guilsinglright{>}%
+ \def\leq{<=}%
+ \def\minus{-}%
+ \def\point{.}%
+ \def\pounds{pounds}%
+ \def\print{-|}%
+ \def\quotedblbase{"}%
+ \def\quotedblleft{"}%
+ \def\quotedblright{"}%
+ \def\quoteleft{`}%
+ \def\quoteright{'}%
+ \def\quotesinglbase{,}%
+ \def\registeredsymbol{R}%
+ \def\result{=>}%
+ \def\textdegree{o}%
+ %
+ \expandafter\ifx\csname SETtxiindexlquoteignore\endcsname\relax
+ \else \indexlquoteignore \fi
+ %
+ % We need to get rid of all macros, leaving only the arguments (if present).
+ % Of course this is not nearly correct, but it is the best we can do for now.
+ % makeinfo does not expand macros in the argument to @deffn, which ends up
+ % writing an index entry, and texindex isn't prepared for an index sort entry
+ % that starts with \.
+ %
+ % Since macro invocations are followed by braces, we can just redefine them
+ % to take a single TeX argument. The case of a macro invocation that
+ % goes to end-of-line is not handled.
+ %
+ \macrolist
+}
+
+% Undocumented (for FSFS 2nd ed.): @set txiindexlquoteignore makes us
+% ignore left quotes in the sort term.
+{\catcode`\`=\active
+ \gdef\indexlquoteignore{\let`=\empty}}
+
+\let\indexbackslash=0 %overridden during \printindex.
+\let\SETmarginindex=\relax % put index entries in margin (undocumented)?
+
+% Most index entries go through here, but \dosubind is the general case.
+% #1 is the index name, #2 is the entry text.
+\def\doind#1#2{\dosubind{#1}{#2}{}}
+
+% Workhorse for all \fooindexes.
+% #1 is name of index, #2 is stuff to put there, #3 is subentry --
+% empty if called from \doind, as we usually are (the main exception
+% is with most defuns, which call us directly).
+%
+\def\dosubind#1#2#3{%
+ \iflinks
+ {%
+ % Store the main index entry text (including the third arg).
+ \toks0 = {#2}%
+ % If third arg is present, precede it with a space.
+ \def\thirdarg{#3}%
+ \ifx\thirdarg\empty \else
+ \toks0 = \expandafter{\the\toks0 \space #3}%
+ \fi
+ %
+ \edef\writeto{\csname#1indfile\endcsname}%
+ %
+ \safewhatsit\dosubindwrite
+ }%
+ \fi
+}
+
+% Write the entry in \toks0 to the index file:
+%
+\def\dosubindwrite{%
+ % Put the index entry in the margin if desired.
+ \ifx\SETmarginindex\relax\else
+ \insert\margin{\hbox{\vrule height8pt depth3pt width0pt \the\toks0}}%
+ \fi
+ %
+ % Remember, we are within a group.
+ \indexdummies % Must do this here, since \bf, etc expand at this stage
+ \def\backslashcurfont{\indexbackslash}% \indexbackslash isn't defined now
+ % so it will be output as is; and it will print as backslash.
+ %
+ % Process the index entry with all font commands turned off, to
+ % get the string to sort by.
+ {\indexnofonts
+ \edef\temp{\the\toks0}% need full expansion
+ \xdef\indexsorttmp{\temp}%
+ }%
+ %
+ % Set up the complete index entry, with both the sort key and
+ % the original text, including any font commands. We write
+ % three arguments to \entry to the .?? file (four in the
+ % subentry case), texindex reduces to two when writing the .??s
+ % sorted result.
+ \edef\temp{%
+ \write\writeto{%
+ \string\entry{\indexsorttmp}{\noexpand\folio}{\the\toks0}}%
+ }%
+ \temp
+}
+
+% Take care of unwanted page breaks/skips around a whatsit:
+%
+% If a skip is the last thing on the list now, preserve it
+% by backing up by \lastskip, doing the \write, then inserting
+% the skip again. Otherwise, the whatsit generated by the
+% \write or \pdfdest will make \lastskip zero. The result is that
+% sequences like this:
+% @end defun
+% @tindex whatever
+% @defun ...
+% will have extra space inserted, because the \medbreak in the
+% start of the @defun won't see the skip inserted by the @end of
+% the previous defun.
+%
+% But don't do any of this if we're not in vertical mode. We
+% don't want to do a \vskip and prematurely end a paragraph.
+%
+% Avoid page breaks due to these extra skips, too.
+%
+% But wait, there is a catch there:
+% We'll have to check whether \lastskip is zero skip. \ifdim is not
+% sufficient for this purpose, as it ignores stretch and shrink parts
+% of the skip. The only way seems to be to check the textual
+% representation of the skip.
+%
+% The following is almost like \def\zeroskipmacro{0.0pt} except that
+% the ``p'' and ``t'' characters have catcode \other, not 11 (letter).
+%
+\edef\zeroskipmacro{\expandafter\the\csname z@skip\endcsname}
+%
+\newskip\whatsitskip
+\newcount\whatsitpenalty
+%
+% ..., ready, GO:
+%
+\def\safewhatsit#1{\ifhmode
+ #1%
+ \else
+ % \lastskip and \lastpenalty cannot both be nonzero simultaneously.
+ \whatsitskip = \lastskip
+ \edef\lastskipmacro{\the\lastskip}%
+ \whatsitpenalty = \lastpenalty
+ %
+ % If \lastskip is nonzero, that means the last item was a
+ % skip. And since a skip is discardable, that means this
+ % -\whatsitskip glue we're inserting is preceded by a
+ % non-discardable item, therefore it is not a potential
+ % breakpoint, therefore no \nobreak needed.
+ \ifx\lastskipmacro\zeroskipmacro
+ \else
+ \vskip-\whatsitskip
+ \fi
+ %
+ #1%
+ %
+ \ifx\lastskipmacro\zeroskipmacro
+ % If \lastskip was zero, perhaps the last item was a penalty, and
+ % perhaps it was >=10000, e.g., a \nobreak. In that case, we want
+ % to re-insert the same penalty (values >10000 are used for various
+ % signals); since we just inserted a non-discardable item, any
+ % following glue (such as a \parskip) would be a breakpoint. For example:
+ % @deffn deffn-whatever
+ % @vindex index-whatever
+ % Description.
+ % would allow a break between the index-whatever whatsit
+ % and the "Description." paragraph.
+ \ifnum\whatsitpenalty>9999 \penalty\whatsitpenalty \fi
+ \else
+ % On the other hand, if we had a nonzero \lastskip,
+ % this make-up glue would be preceded by a non-discardable item
+ % (the whatsit from the \write), so we must insert a \nobreak.
+ \nobreak\vskip\whatsitskip
+ \fi
+\fi}
+
+% The index entry written in the file actually looks like
+% \entry {sortstring}{page}{topic}
+% or
+% \entry {sortstring}{page}{topic}{subtopic}
+% The texindex program reads in these files and writes files
+% containing these kinds of lines:
+% \initial {c}
+% before the first topic whose initial is c
+% \entry {topic}{pagelist}
+% for a topic that is used without subtopics
+% \primary {topic}
+% for the beginning of a topic that is used with subtopics
+% \secondary {subtopic}{pagelist}
+% for each subtopic.
+
+% Define the user-accessible indexing commands
+% @findex, @vindex, @kindex, @cindex.
+
+\def\findex {\fnindex}
+\def\kindex {\kyindex}
+\def\cindex {\cpindex}
+\def\vindex {\vrindex}
+\def\tindex {\tpindex}
+\def\pindex {\pgindex}
+
+\def\cindexsub {\begingroup\obeylines\cindexsub}
+{\obeylines %
+\gdef\cindexsub "#1" #2^^M{\endgroup %
+\dosubind{cp}{#2}{#1}}}
+
+% Define the macros used in formatting output of the sorted index material.
+
+% @printindex causes a particular index (the ??s file) to get printed.
+% It does not print any chapter heading (usually an @unnumbered).
+%
+\parseargdef\printindex{\begingroup
+ \dobreak \chapheadingskip{10000}%
+ %
+ \smallfonts \rm
+ \tolerance = 9500
+ \plainfrenchspacing
+ \everypar = {}% don't want the \kern\-parindent from indentation suppression.
+ %
+ % See if the index file exists and is nonempty.
+ % Change catcode of @ here so that if the index file contains
+ % \initial {@}
+ % as its first line, TeX doesn't complain about mismatched braces
+ % (because it thinks @} is a control sequence).
+ \catcode`\@ = 11
+ \openin 1 \jobname.#1s
+ \ifeof 1
+ % \enddoublecolumns gets confused if there is no text in the index,
+ % and it loses the chapter title and the aux file entries for the
+ % index. The easiest way to prevent this problem is to make sure
+ % there is some text.
+ \putwordIndexNonexistent
+ \else
+ %
+ % If the index file exists but is empty, then \openin leaves \ifeof
+ % false. We have to make TeX try to read something from the file, so
+ % it can discover if there is anything in it.
+ \read 1 to \temp
+ \ifeof 1
+ \putwordIndexIsEmpty
+ \else
+ % Index files are almost Texinfo source, but we use \ as the escape
+ % character. It would be better to use @, but that's too big a change
+ % to make right now.
+ \def\indexbackslash{\backslashcurfont}%
+ \catcode`\\ = 0
+ \escapechar = `\\
+ \begindoublecolumns
+ \input \jobname.#1s
+ \enddoublecolumns
+ \fi
+ \fi
+ \closein 1
+\endgroup}
+
+% These macros are used by the sorted index file itself.
+% Change them to control the appearance of the index.
+
+\def\initial#1{{%
+ % Some minor font changes for the special characters.
+ \let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt
+ %
+ % Remove any glue we may have, we'll be inserting our own.
+ \removelastskip
+ %
+ % We like breaks before the index initials, so insert a bonus.
+ \nobreak
+ \vskip 0pt plus 3\baselineskip
+ \penalty 0
+ \vskip 0pt plus -3\baselineskip
+ %
+ % Typeset the initial. Making this add up to a whole number of
+ % baselineskips increases the chance of the dots lining up from column
+ % to column. It still won't often be perfect, because of the stretch
+ % we need before each entry, but it's better.
+ %
+ % No shrink because it confuses \balancecolumns.
+ \vskip 1.67\baselineskip plus .5\baselineskip
+ \leftline{\secbf #1}%
+ % Do our best not to break after the initial.
+ \nobreak
+ \vskip .33\baselineskip plus .1\baselineskip
+}}
+
+% \entry typesets a paragraph consisting of the text (#1), dot leaders, and
+% then page number (#2) flushed to the right margin. It is used for index
+% and table of contents entries. The paragraph is indented by \leftskip.
+%
+% A straightforward implementation would start like this:
+% \def\entry#1#2{...
+% But this freezes the catcodes in the argument, and can cause problems to
+% @code, which sets - active. This problem was fixed by a kludge---
+% ``-'' was active throughout whole index, but this isn't really right.
+% The right solution is to prevent \entry from swallowing the whole text.
+% --kasal, 21nov03
+\def\entry{%
+ \begingroup
+ %
+ % Start a new paragraph if necessary, so our assignments below can't
+ % affect previous text.
+ \par
+ %
+ % Do not fill out the last line with white space.
+ \parfillskip = 0in
+ %
+ % No extra space above this paragraph.
+ \parskip = 0in
+ %
+ % Do not prefer a separate line ending with a hyphen to fewer lines.
+ \finalhyphendemerits = 0
+ %
+ % \hangindent is only relevant when the entry text and page number
+ % don't both fit on one line. In that case, bob suggests starting the
+ % dots pretty far over on the line. Unfortunately, a large
+ % indentation looks wrong when the entry text itself is broken across
+ % lines. So we use a small indentation and put up with long leaders.
+ %
+ % \hangafter is reset to 1 (which is the value we want) at the start
+ % of each paragraph, so we need not do anything with that.
+ \hangindent = 2em
+ %
+ % When the entry text needs to be broken, just fill out the first line
+ % with blank space.
+ \rightskip = 0pt plus1fil
+ %
+ % A bit of stretch before each entry for the benefit of balancing
+ % columns.
+ \vskip 0pt plus1pt
+ %
+ % When reading the text of entry, convert explicit line breaks
+ % from @* into spaces. The user might give these in long section
+ % titles, for instance.
+ \def\*{\unskip\space\ignorespaces}%
+ \def\entrybreak{\hfil\break}%
+ %
+ % Swallow the left brace of the text (first parameter):
+ \afterassignment\doentry
+ \let\temp =
+}
+\def\entrybreak{\unskip\space\ignorespaces}%
+\def\doentry{%
+ \bgroup % Instead of the swallowed brace.
+ \noindent
+ \aftergroup\finishentry
+ % And now comes the text of the entry.
+}
+\def\finishentry#1{%
+ % #1 is the page number.
+ %
+ % The following is kludged to not output a line of dots in the index if
+ % there are no page numbers. The next person who breaks this will be
+ % cursed by a Unix daemon.
+ \setbox\boxA = \hbox{#1}%
+ \ifdim\wd\boxA = 0pt
+ \ %
+ \else
+ %
+ % If we must, put the page number on a line of its own, and fill out
+ % this line with blank space. (The \hfil is overwhelmed with the
+ % fill leaders glue in \indexdotfill if the page number does fit.)
+ \hfil\penalty50
+ \null\nobreak\indexdotfill % Have leaders before the page number.
+ %
+ % The `\ ' here is removed by the implicit \unskip that TeX does as
+ % part of (the primitive) \par. Without it, a spurious underfull
+ % \hbox ensues.
+ \ifpdf
+ \pdfgettoks#1.%
+ \ \the\toksA
+ \else
+ \ #1%
+ \fi
+ \fi
+ \par
+ \endgroup
+}
+
+% Like plain.tex's \dotfill, except uses up at least 1 em.
+\def\indexdotfill{\cleaders
+ \hbox{$\mathsurround=0pt \mkern1.5mu.\mkern1.5mu$}\hskip 1em plus 1fill}
+
+\def\primary #1{\line{#1\hfil}}
+
+\newskip\secondaryindent \secondaryindent=0.5cm
+\def\secondary#1#2{{%
+ \parfillskip=0in
+ \parskip=0in
+ \hangindent=1in
+ \hangafter=1
+ \noindent\hskip\secondaryindent\hbox{#1}\indexdotfill
+ \ifpdf
+ \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph.
+ \else
+ #2
+ \fi
+ \par
+}}
+
+% Define two-column mode, which we use to typeset indexes.
+% Adapted from the TeXbook, page 416, which is to say,
+% the manmac.tex format used to print the TeXbook itself.
+\catcode`\@=11
+
+\newbox\partialpage
+\newdimen\doublecolumnhsize
+
+\def\begindoublecolumns{\begingroup % ended by \enddoublecolumns
+ % Grab any single-column material above us.
+ \output = {%
+ %
+ % Here is a possibility not foreseen in manmac: if we accumulate a
+ % whole lot of material, we might end up calling this \output
+ % routine twice in a row (see the doublecol-lose test, which is
+ % essentially a couple of indexes with @setchapternewpage off). In
+ % that case we just ship out what is in \partialpage with the normal
+ % output routine. Generally, \partialpage will be empty when this
+ % runs and this will be a no-op. See the indexspread.tex test case.
+ \ifvoid\partialpage \else
+ \onepageout{\pagecontents\partialpage}%
+ \fi
+ %
+ \global\setbox\partialpage = \vbox{%
+ % Unvbox the main output page.
+ \unvbox\PAGE
+ \kern-\topskip \kern\baselineskip
+ }%
+ }%
+ \eject % run that output routine to set \partialpage
+ %
+ % Use the double-column output routine for subsequent pages.
+ \output = {\doublecolumnout}%
+ %
+ % Change the page size parameters. We could do this once outside this
+ % routine, in each of @smallbook, @afourpaper, and the default 8.5x11
+ % format, but then we repeat the same computation. Repeating a couple
+ % of assignments once per index is clearly meaningless for the
+ % execution time, so we may as well do it in one place.
+ %
+ % First we halve the line length, less a little for the gutter between
+ % the columns. We compute the gutter based on the line length, so it
+ % changes automatically with the paper format. The magic constant
+ % below is chosen so that the gutter has the same value (well, +-<1pt)
+ % as it did when we hard-coded it.
+ %
+ % We put the result in a separate register, \doublecolumhsize, so we
+ % can restore it in \pagesofar, after \hsize itself has (potentially)
+ % been clobbered.
+ %
+ \doublecolumnhsize = \hsize
+ \advance\doublecolumnhsize by -.04154\hsize
+ \divide\doublecolumnhsize by 2
+ \hsize = \doublecolumnhsize
+ %
+ % Double the \vsize as well. (We don't need a separate register here,
+ % since nobody clobbers \vsize.)
+ \vsize = 2\vsize
+}
+
+% The double-column output routine for all double-column pages except
+% the last.
+%
+\def\doublecolumnout{%
+ \splittopskip=\topskip \splitmaxdepth=\maxdepth
+ % Get the available space for the double columns -- the normal
+ % (undoubled) page height minus any material left over from the
+ % previous page.
+ \dimen@ = \vsize
+ \divide\dimen@ by 2
+ \advance\dimen@ by -\ht\partialpage
+ %
+ % box0 will be the left-hand column, box2 the right.
+ \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@
+ \onepageout\pagesofar
+ \unvbox255
+ \penalty\outputpenalty
+}
+%
+% Re-output the contents of the output page -- any previous material,
+% followed by the two boxes we just split, in box0 and box2.
+\def\pagesofar{%
+ \unvbox\partialpage
+ %
+ \hsize = \doublecolumnhsize
+ \wd0=\hsize \wd2=\hsize
+ \hbox to\pagewidth{\box0\hfil\box2}%
+}
+%
+% All done with double columns.
+\def\enddoublecolumns{%
+ % The following penalty ensures that the page builder is exercised
+ % _before_ we change the output routine. This is necessary in the
+ % following situation:
+ %
+ % The last section of the index consists only of a single entry.
+ % Before this section, \pagetotal is less than \pagegoal, so no
+ % break occurs before the last section starts. However, the last
+ % section, consisting of \initial and the single \entry, does not
+ % fit on the page and has to be broken off. Without the following
+ % penalty the page builder will not be exercised until \eject
+ % below, and by that time we'll already have changed the output
+ % routine to the \balancecolumns version, so the next-to-last
+ % double-column page will be processed with \balancecolumns, which
+ % is wrong: The two columns will go to the main vertical list, with
+ % the broken-off section in the recent contributions. As soon as
+ % the output routine finishes, TeX starts reconsidering the page
+ % break. The two columns and the broken-off section both fit on the
+ % page, because the two columns now take up only half of the page
+ % goal. When TeX sees \eject from below which follows the final
+ % section, it invokes the new output routine that we've set after
+ % \balancecolumns below; \onepageout will try to fit the two columns
+ % and the final section into the vbox of \pageheight (see
+ % \pagebody), causing an overfull box.
+ %
+ % Note that glue won't work here, because glue does not exercise the
+ % page builder, unlike penalties (see The TeXbook, pp. 280-281).
+ \penalty0
+ %
+ \output = {%
+ % Split the last of the double-column material. Leave it on the
+ % current page, no automatic page break.
+ \balancecolumns
+ %
+ % If we end up splitting too much material for the current page,
+ % though, there will be another page break right after this \output
+ % invocation ends. Having called \balancecolumns once, we do not
+ % want to call it again. Therefore, reset \output to its normal
+ % definition right away. (We hope \balancecolumns will never be
+ % called on to balance too much material, but if it is, this makes
+ % the output somewhat more palatable.)
+ \global\output = {\onepageout{\pagecontents\PAGE}}%
+ }%
+ \eject
+ \endgroup % started in \begindoublecolumns
+ %
+ % \pagegoal was set to the doubled \vsize above, since we restarted
+ % the current page. We're now back to normal single-column
+ % typesetting, so reset \pagegoal to the normal \vsize (after the
+ % \endgroup where \vsize got restored).
+ \pagegoal = \vsize
+}
+%
+% Called at the end of the double column material.
+\def\balancecolumns{%
+ \setbox0 = \vbox{\unvbox255}% like \box255 but more efficient, see p.120.
+ \dimen@ = \ht0
+ \advance\dimen@ by \topskip
+ \advance\dimen@ by-\baselineskip
+ \divide\dimen@ by 2 % target to split to
+ %debug\message{final 2-column material height=\the\ht0, target=\the\dimen@.}%
+ \splittopskip = \topskip
+ % Loop until we get a decent breakpoint.
+ {%
+ \vbadness = 10000
+ \loop
+ \global\setbox3 = \copy0
+ \global\setbox1 = \vsplit3 to \dimen@
+ \ifdim\ht3>\dimen@
+ \global\advance\dimen@ by 1pt
+ \repeat
+ }%
+ %debug\message{split to \the\dimen@, column heights: \the\ht1, \the\ht3.}%
+ \setbox0=\vbox to\dimen@{\unvbox1}%
+ \setbox2=\vbox to\dimen@{\unvbox3}%
+ %
+ \pagesofar
+}
+\catcode`\@ = \other
+
+
+\message{sectioning,}
+% Chapters, sections, etc.
+
+% Let's start with @part.
+\outer\parseargdef\part{\partzzz{#1}}
+\def\partzzz#1{%
+ \chapoddpage
+ \null
+ \vskip.3\vsize % move it down on the page a bit
+ \begingroup
+ \noindent \titlefonts\rmisbold #1\par % the text
+ \let\lastnode=\empty % no node to associate with
+ \writetocentry{part}{#1}{}% but put it in the toc
+ \headingsoff % no headline or footline on the part page
+ \chapoddpage
+ \endgroup
+}
+
+% \unnumberedno is an oxymoron. But we count the unnumbered
+% sections so that we can refer to them unambiguously in the pdf
+% outlines by their "section number". We avoid collisions with chapter
+% numbers by starting them at 10000. (If a document ever has 10000
+% chapters, we're in trouble anyway, I'm sure.)
+\newcount\unnumberedno \unnumberedno = 10000
+\newcount\chapno
+\newcount\secno \secno=0
+\newcount\subsecno \subsecno=0
+\newcount\subsubsecno \subsubsecno=0
+
+% This counter is funny since it counts through charcodes of letters A, B, ...
+\newcount\appendixno \appendixno = `\@
+%
+% \def\appendixletter{\char\the\appendixno}
+% We do the following ugly conditional instead of the above simple
+% construct for the sake of pdftex, which needs the actual
+% letter in the expansion, not just typeset.
+%
+\def\appendixletter{%
+ \ifnum\appendixno=`A A%
+ \else\ifnum\appendixno=`B B%
+ \else\ifnum\appendixno=`C C%
+ \else\ifnum\appendixno=`D D%
+ \else\ifnum\appendixno=`E E%
+ \else\ifnum\appendixno=`F F%
+ \else\ifnum\appendixno=`G G%
+ \else\ifnum\appendixno=`H H%
+ \else\ifnum\appendixno=`I I%
+ \else\ifnum\appendixno=`J J%
+ \else\ifnum\appendixno=`K K%
+ \else\ifnum\appendixno=`L L%
+ \else\ifnum\appendixno=`M M%
+ \else\ifnum\appendixno=`N N%
+ \else\ifnum\appendixno=`O O%
+ \else\ifnum\appendixno=`P P%
+ \else\ifnum\appendixno=`Q Q%
+ \else\ifnum\appendixno=`R R%
+ \else\ifnum\appendixno=`S S%
+ \else\ifnum\appendixno=`T T%
+ \else\ifnum\appendixno=`U U%
+ \else\ifnum\appendixno=`V V%
+ \else\ifnum\appendixno=`W W%
+ \else\ifnum\appendixno=`X X%
+ \else\ifnum\appendixno=`Y Y%
+ \else\ifnum\appendixno=`Z Z%
+ % The \the is necessary, despite appearances, because \appendixletter is
+ % expanded while writing the .toc file. \char\appendixno is not
+ % expandable, thus it is written literally, thus all appendixes come out
+ % with the same letter (or @) in the toc without it.
+ \else\char\the\appendixno
+ \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+ \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi}
+
+% Each @chapter defines these (using marks) as the number+name, number
+% and name of the chapter. Page headings and footings can use
+% these. @section does likewise.
+\def\thischapter{}
+\def\thischapternum{}
+\def\thischaptername{}
+\def\thissection{}
+\def\thissectionnum{}
+\def\thissectionname{}
+
+\newcount\absseclevel % used to calculate proper heading level
+\newcount\secbase\secbase=0 % @raisesections/@lowersections modify this count
+
+% @raisesections: treat @section as chapter, @subsection as section, etc.
+\def\raisesections{\global\advance\secbase by -1}
+\let\up=\raisesections % original BFox name
+
+% @lowersections: treat @chapter as section, @section as subsection, etc.
+\def\lowersections{\global\advance\secbase by 1}
+\let\down=\lowersections % original BFox name
+
+% we only have subsub.
+\chardef\maxseclevel = 3
+%
+% A numbered section within an unnumbered changes to unnumbered too.
+% To achieve this, remember the "biggest" unnum. sec. we are currently in:
+\chardef\unnlevel = \maxseclevel
+%
+% Trace whether the current chapter is an appendix or not:
+% \chapheadtype is "N" or "A", unnumbered chapters are ignored.
+\def\chapheadtype{N}
+
+% Choose a heading macro
+% #1 is heading type
+% #2 is heading level
+% #3 is text for heading
+\def\genhead#1#2#3{%
+ % Compute the abs. sec. level:
+ \absseclevel=#2
+ \advance\absseclevel by \secbase
+ % Make sure \absseclevel doesn't fall outside the range:
+ \ifnum \absseclevel < 0
+ \absseclevel = 0
+ \else
+ \ifnum \absseclevel > 3
+ \absseclevel = 3
+ \fi
+ \fi
+ % The heading type:
+ \def\headtype{#1}%
+ \if \headtype U%
+ \ifnum \absseclevel < \unnlevel
+ \chardef\unnlevel = \absseclevel
+ \fi
+ \else
+ % Check for appendix sections:
+ \ifnum \absseclevel = 0
+ \edef\chapheadtype{\headtype}%
+ \else
+ \if \headtype A\if \chapheadtype N%
+ \errmessage{@appendix... within a non-appendix chapter}%
+ \fi\fi
+ \fi
+ % Check for numbered within unnumbered:
+ \ifnum \absseclevel > \unnlevel
+ \def\headtype{U}%
+ \else
+ \chardef\unnlevel = 3
+ \fi
+ \fi
+ % Now print the heading:
+ \if \headtype U%
+ \ifcase\absseclevel
+ \unnumberedzzz{#3}%
+ \or \unnumberedseczzz{#3}%
+ \or \unnumberedsubseczzz{#3}%
+ \or \unnumberedsubsubseczzz{#3}%
+ \fi
+ \else
+ \if \headtype A%
+ \ifcase\absseclevel
+ \appendixzzz{#3}%
+ \or \appendixsectionzzz{#3}%
+ \or \appendixsubseczzz{#3}%
+ \or \appendixsubsubseczzz{#3}%
+ \fi
+ \else
+ \ifcase\absseclevel
+ \chapterzzz{#3}%
+ \or \seczzz{#3}%
+ \or \numberedsubseczzz{#3}%
+ \or \numberedsubsubseczzz{#3}%
+ \fi
+ \fi
+ \fi
+ \suppressfirstparagraphindent
+}
+
+% an interface:
+\def\numhead{\genhead N}
+\def\apphead{\genhead A}
+\def\unnmhead{\genhead U}
+
+% @chapter, @appendix, @unnumbered. Increment top-level counter, reset
+% all lower-level sectioning counters to zero.
+%
+% Also set \chaplevelprefix, which we prepend to @float sequence numbers
+% (e.g., figures), q.v. By default (before any chapter), that is empty.
+\let\chaplevelprefix = \empty
+%
+\outer\parseargdef\chapter{\numhead0{#1}} % normally numhead0 calls chapterzzz
+\def\chapterzzz#1{%
+ % section resetting is \global in case the chapter is in a group, such
+ % as an @include file.
+ \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+ \global\advance\chapno by 1
+ %
+ % Used for \float.
+ \gdef\chaplevelprefix{\the\chapno.}%
+ \resetallfloatnos
+ %
+ % \putwordChapter can contain complex things in translations.
+ \toks0=\expandafter{\putwordChapter}%
+ \message{\the\toks0 \space \the\chapno}%
+ %
+ % Write the actual heading.
+ \chapmacro{#1}{Ynumbered}{\the\chapno}%
+ %
+ % So @section and the like are numbered underneath this chapter.
+ \global\let\section = \numberedsec
+ \global\let\subsection = \numberedsubsec
+ \global\let\subsubsection = \numberedsubsubsec
+}
+
+\outer\parseargdef\appendix{\apphead0{#1}} % normally calls appendixzzz
+%
+\def\appendixzzz#1{%
+ \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+ \global\advance\appendixno by 1
+ \gdef\chaplevelprefix{\appendixletter.}%
+ \resetallfloatnos
+ %
+ % \putwordAppendix can contain complex things in translations.
+ \toks0=\expandafter{\putwordAppendix}%
+ \message{\the\toks0 \space \appendixletter}%
+ %
+ \chapmacro{#1}{Yappendix}{\appendixletter}%
+ %
+ \global\let\section = \appendixsec
+ \global\let\subsection = \appendixsubsec
+ \global\let\subsubsection = \appendixsubsubsec
+}
+
+% normally unnmhead0 calls unnumberedzzz:
+\outer\parseargdef\unnumbered{\unnmhead0{#1}}
+\def\unnumberedzzz#1{%
+ \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+ \global\advance\unnumberedno by 1
+ %
+ % Since an unnumbered has no number, no prefix for figures.
+ \global\let\chaplevelprefix = \empty
+ \resetallfloatnos
+ %
+ % This used to be simply \message{#1}, but TeX fully expands the
+ % argument to \message. Therefore, if #1 contained @-commands, TeX
+ % expanded them. For example, in `@unnumbered The @cite{Book}', TeX
+ % expanded @cite (which turns out to cause errors because \cite is meant
+ % to be executed, not expanded).
+ %
+ % Anyway, we don't want the fully-expanded definition of @cite to appear
+ % as a result of the \message, we just want `@cite' itself. We use
+ % \the<toks register> to achieve this: TeX expands \the<toks> only once,
+ % simply yielding the contents of <toks register>. (We also do this for
+ % the toc entries.)
+ \toks0 = {#1}%
+ \message{(\the\toks0)}%
+ %
+ \chapmacro{#1}{Ynothing}{\the\unnumberedno}%
+ %
+ \global\let\section = \unnumberedsec
+ \global\let\subsection = \unnumberedsubsec
+ \global\let\subsubsection = \unnumberedsubsubsec
+}
+
+% @centerchap is like @unnumbered, but the heading is centered.
+\outer\parseargdef\centerchap{%
+ % Well, we could do the following in a group, but that would break
+ % an assumption that \chapmacro is called at the outermost level.
+ % Thus we are safer this way: --kasal, 24feb04
+ \let\centerparametersmaybe = \centerparameters
+ \unnmhead0{#1}%
+ \let\centerparametersmaybe = \relax
+}
+
+% @top is like @unnumbered.
+\let\top\unnumbered
+
+% Sections.
+%
+\outer\parseargdef\numberedsec{\numhead1{#1}} % normally calls seczzz
+\def\seczzz#1{%
+ \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1
+ \sectionheading{#1}{sec}{Ynumbered}{\the\chapno.\the\secno}%
+}
+
+% normally calls appendixsectionzzz:
+\outer\parseargdef\appendixsection{\apphead1{#1}}
+\def\appendixsectionzzz#1{%
+ \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1
+ \sectionheading{#1}{sec}{Yappendix}{\appendixletter.\the\secno}%
+}
+\let\appendixsec\appendixsection
+
+% normally calls unnumberedseczzz:
+\outer\parseargdef\unnumberedsec{\unnmhead1{#1}}
+\def\unnumberedseczzz#1{%
+ \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1
+ \sectionheading{#1}{sec}{Ynothing}{\the\unnumberedno.\the\secno}%
+}
+
+% Subsections.
+%
+% normally calls numberedsubseczzz:
+\outer\parseargdef\numberedsubsec{\numhead2{#1}}
+\def\numberedsubseczzz#1{%
+ \global\subsubsecno=0 \global\advance\subsecno by 1
+ \sectionheading{#1}{subsec}{Ynumbered}{\the\chapno.\the\secno.\the\subsecno}%
+}
+
+% normally calls appendixsubseczzz:
+\outer\parseargdef\appendixsubsec{\apphead2{#1}}
+\def\appendixsubseczzz#1{%
+ \global\subsubsecno=0 \global\advance\subsecno by 1
+ \sectionheading{#1}{subsec}{Yappendix}%
+ {\appendixletter.\the\secno.\the\subsecno}%
+}
+
+% normally calls unnumberedsubseczzz:
+\outer\parseargdef\unnumberedsubsec{\unnmhead2{#1}}
+\def\unnumberedsubseczzz#1{%
+ \global\subsubsecno=0 \global\advance\subsecno by 1
+ \sectionheading{#1}{subsec}{Ynothing}%
+ {\the\unnumberedno.\the\secno.\the\subsecno}%
+}
+
+% Subsubsections.
+%
+% normally numberedsubsubseczzz:
+\outer\parseargdef\numberedsubsubsec{\numhead3{#1}}
+\def\numberedsubsubseczzz#1{%
+ \global\advance\subsubsecno by 1
+ \sectionheading{#1}{subsubsec}{Ynumbered}%
+ {\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno}%
+}
+
+% normally appendixsubsubseczzz:
+\outer\parseargdef\appendixsubsubsec{\apphead3{#1}}
+\def\appendixsubsubseczzz#1{%
+ \global\advance\subsubsecno by 1
+ \sectionheading{#1}{subsubsec}{Yappendix}%
+ {\appendixletter.\the\secno.\the\subsecno.\the\subsubsecno}%
+}
+
+% normally unnumberedsubsubseczzz:
+\outer\parseargdef\unnumberedsubsubsec{\unnmhead3{#1}}
+\def\unnumberedsubsubseczzz#1{%
+ \global\advance\subsubsecno by 1
+ \sectionheading{#1}{subsubsec}{Ynothing}%
+ {\the\unnumberedno.\the\secno.\the\subsecno.\the\subsubsecno}%
+}
+
+% These macros control what the section commands do, according
+% to what kind of chapter we are in (ordinary, appendix, or unnumbered).
+% Define them by default for a numbered chapter.
+\let\section = \numberedsec
+\let\subsection = \numberedsubsec
+\let\subsubsection = \numberedsubsubsec
+
+% Define @majorheading, @heading and @subheading
+
+\def\majorheading{%
+ {\advance\chapheadingskip by 10pt \chapbreak }%
+ \parsearg\chapheadingzzz
+}
+
+\def\chapheading{\chapbreak \parsearg\chapheadingzzz}
+\def\chapheadingzzz#1{%
+ \vbox{\chapfonts \raggedtitlesettings #1\par}%
+ \nobreak\bigskip \nobreak
+ \suppressfirstparagraphindent
+}
+
+% @heading, @subheading, @subsubheading.
+\parseargdef\heading{\sectionheading{#1}{sec}{Yomitfromtoc}{}
+ \suppressfirstparagraphindent}
+\parseargdef\subheading{\sectionheading{#1}{subsec}{Yomitfromtoc}{}
+ \suppressfirstparagraphindent}
+\parseargdef\subsubheading{\sectionheading{#1}{subsubsec}{Yomitfromtoc}{}
+ \suppressfirstparagraphindent}
+
+% These macros generate a chapter, section, etc. heading only
+% (including whitespace, linebreaking, etc. around it),
+% given all the information in convenient, parsed form.
+
+% Args are the skip and penalty (usually negative)
+\def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi}
+
+% Parameter controlling skip before chapter headings (if needed)
+\newskip\chapheadingskip
+
+% Define plain chapter starts, and page on/off switching for it.
+\def\chapbreak{\dobreak \chapheadingskip {-4000}}
+\def\chappager{\par\vfill\supereject}
+% Because \domark is called before \chapoddpage, the filler page will
+% get the headings for the next chapter, which is wrong. But we don't
+% care -- we just disable all headings on the filler page.
+\def\chapoddpage{%
+ \chappager
+ \ifodd\pageno \else
+ \begingroup
+ \headingsoff
+ \null
+ \chappager
+ \endgroup
+ \fi
+}
+
+\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname}
+
+\def\CHAPPAGoff{%
+\global\let\contentsalignmacro = \chappager
+\global\let\pchapsepmacro=\chapbreak
+\global\let\pagealignmacro=\chappager}
+
+\def\CHAPPAGon{%
+\global\let\contentsalignmacro = \chappager
+\global\let\pchapsepmacro=\chappager
+\global\let\pagealignmacro=\chappager
+\global\def\HEADINGSon{\HEADINGSsingle}}
+
+\def\CHAPPAGodd{%
+\global\let\contentsalignmacro = \chapoddpage
+\global\let\pchapsepmacro=\chapoddpage
+\global\let\pagealignmacro=\chapoddpage
+\global\def\HEADINGSon{\HEADINGSdouble}}
+
+\CHAPPAGon
+
+% Chapter opening.
+%
+% #1 is the text, #2 is the section type (Ynumbered, Ynothing,
+% Yappendix, Yomitfromtoc), #3 the chapter number.
+%
+% To test against our argument.
+\def\Ynothingkeyword{Ynothing}
+\def\Yomitfromtockeyword{Yomitfromtoc}
+\def\Yappendixkeyword{Yappendix}
+%
+\def\chapmacro#1#2#3{%
+ % Insert the first mark before the heading break (see notes for \domark).
+ \let\prevchapterdefs=\lastchapterdefs
+ \let\prevsectiondefs=\lastsectiondefs
+ \gdef\lastsectiondefs{\gdef\thissectionname{}\gdef\thissectionnum{}%
+ \gdef\thissection{}}%
+ %
+ \def\temptype{#2}%
+ \ifx\temptype\Ynothingkeyword
+ \gdef\lastchapterdefs{\gdef\thischaptername{#1}\gdef\thischapternum{}%
+ \gdef\thischapter{\thischaptername}}%
+ \else\ifx\temptype\Yomitfromtockeyword
+ \gdef\lastchapterdefs{\gdef\thischaptername{#1}\gdef\thischapternum{}%
+ \gdef\thischapter{}}%
+ \else\ifx\temptype\Yappendixkeyword
+ \toks0={#1}%
+ \xdef\lastchapterdefs{%
+ \gdef\noexpand\thischaptername{\the\toks0}%
+ \gdef\noexpand\thischapternum{\appendixletter}%
+ % \noexpand\putwordAppendix avoids expanding indigestible
+ % commands in some of the translations.
+ \gdef\noexpand\thischapter{\noexpand\putwordAppendix{}
+ \noexpand\thischapternum:
+ \noexpand\thischaptername}%
+ }%
+ \else
+ \toks0={#1}%
+ \xdef\lastchapterdefs{%
+ \gdef\noexpand\thischaptername{\the\toks0}%
+ \gdef\noexpand\thischapternum{\the\chapno}%
+ % \noexpand\putwordChapter avoids expanding indigestible
+ % commands in some of the translations.
+ \gdef\noexpand\thischapter{\noexpand\putwordChapter{}
+ \noexpand\thischapternum:
+ \noexpand\thischaptername}%
+ }%
+ \fi\fi\fi
+ %
+ % Output the mark. Pass it through \safewhatsit, to take care of
+ % the preceding space.
+ \safewhatsit\domark
+ %
+ % Insert the chapter heading break.
+ \pchapsepmacro
+ %
+ % Now the second mark, after the heading break. No break points
+ % between here and the heading.
+ \let\prevchapterdefs=\lastchapterdefs
+ \let\prevsectiondefs=\lastsectiondefs
+ \domark
+ %
+ {%
+ \chapfonts \rmisbold
+ %
+ % Have to define \lastsection before calling \donoderef, because the
+ % xref code eventually uses it. On the other hand, it has to be called
+ % after \pchapsepmacro, or the headline will change too soon.
+ \gdef\lastsection{#1}%
+ %
+ % Only insert the separating space if we have a chapter/appendix
+ % number, and don't print the unnumbered ``number''.
+ \ifx\temptype\Ynothingkeyword
+ \setbox0 = \hbox{}%
+ \def\toctype{unnchap}%
+ \else\ifx\temptype\Yomitfromtockeyword
+ \setbox0 = \hbox{}% contents like unnumbered, but no toc entry
+ \def\toctype{omit}%
+ \else\ifx\temptype\Yappendixkeyword
+ \setbox0 = \hbox{\putwordAppendix{} #3\enspace}%
+ \def\toctype{app}%
+ \else
+ \setbox0 = \hbox{#3\enspace}%
+ \def\toctype{numchap}%
+ \fi\fi\fi
+ %
+ % Write the toc entry for this chapter. Must come before the
+ % \donoderef, because we include the current node name in the toc
+ % entry, and \donoderef resets it to empty.
+ \writetocentry{\toctype}{#1}{#3}%
+ %
+ % For pdftex, we have to write out the node definition (aka, make
+ % the pdfdest) after any page break, but before the actual text has
+ % been typeset. If the destination for the pdf outline is after the
+ % text, then jumping from the outline may wind up with the text not
+ % being visible, for instance under high magnification.
+ \donoderef{#2}%
+ %
+ % Typeset the actual heading.
+ \nobreak % Avoid page breaks at the interline glue.
+ \vbox{\raggedtitlesettings \hangindent=\wd0 \centerparametersmaybe
+ \unhbox0 #1\par}%
+ }%
+ \nobreak\bigskip % no page break after a chapter title
+ \nobreak
+}
+
+% @centerchap -- centered and unnumbered.
+\let\centerparametersmaybe = \relax
+\def\centerparameters{%
+ \advance\rightskip by 3\rightskip
+ \leftskip = \rightskip
+ \parfillskip = 0pt
+}
+
+
+% I don't think this chapter style is supported any more, so I'm not
+% updating it with the new noderef stuff. We'll see. --karl, 11aug03.
+%
+\def\setchapterstyle #1 {\csname CHAPF#1\endcsname}
+%
+\def\unnchfopen #1{%
+ \chapoddpage
+ \vbox{\chapfonts \raggedtitlesettings #1\par}%
+ \nobreak\bigskip\nobreak
+}
+\def\chfopen #1#2{\chapoddpage {\chapfonts
+\vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}%
+\par\penalty 5000 %
+}
+\def\centerchfopen #1{%
+ \chapoddpage
+ \vbox{\chapfonts \raggedtitlesettings \hfill #1\hfill}%
+ \nobreak\bigskip \nobreak
+}
+\def\CHAPFopen{%
+ \global\let\chapmacro=\chfopen
+ \global\let\centerchapmacro=\centerchfopen}
+
+
+% Section titles. These macros combine the section number parts and
+% call the generic \sectionheading to do the printing.
+%
+\newskip\secheadingskip
+\def\secheadingbreak{\dobreak \secheadingskip{-1000}}
+
+% Subsection titles.
+\newskip\subsecheadingskip
+\def\subsecheadingbreak{\dobreak \subsecheadingskip{-500}}
+
+% Subsubsection titles.
+\def\subsubsecheadingskip{\subsecheadingskip}
+\def\subsubsecheadingbreak{\subsecheadingbreak}
+
+
+% Print any size, any type, section title.
+%
+% #1 is the text, #2 is the section level (sec/subsec/subsubsec), #3 is
+% the section type for xrefs (Ynumbered, Ynothing, Yappendix), #4 is the
+% section number.
+%
+\def\seckeyword{sec}
+%
+\def\sectionheading#1#2#3#4{%
+ {%
+ \checkenv{}% should not be in an environment.
+ %
+ % Switch to the right set of fonts.
+ \csname #2fonts\endcsname \rmisbold
+ %
+ \def\sectionlevel{#2}%
+ \def\temptype{#3}%
+ %
+ % Insert first mark before the heading break (see notes for \domark).
+ \let\prevsectiondefs=\lastsectiondefs
+ \ifx\temptype\Ynothingkeyword
+ \ifx\sectionlevel\seckeyword
+ \gdef\lastsectiondefs{\gdef\thissectionname{#1}\gdef\thissectionnum{}%
+ \gdef\thissection{\thissectionname}}%
+ \fi
+ \else\ifx\temptype\Yomitfromtockeyword
+ % Don't redefine \thissection.
+ \else\ifx\temptype\Yappendixkeyword
+ \ifx\sectionlevel\seckeyword
+ \toks0={#1}%
+ \xdef\lastsectiondefs{%
+ \gdef\noexpand\thissectionname{\the\toks0}%
+ \gdef\noexpand\thissectionnum{#4}%
+ % \noexpand\putwordSection avoids expanding indigestible
+ % commands in some of the translations.
+ \gdef\noexpand\thissection{\noexpand\putwordSection{}
+ \noexpand\thissectionnum:
+ \noexpand\thissectionname}%
+ }%
+ \fi
+ \else
+ \ifx\sectionlevel\seckeyword
+ \toks0={#1}%
+ \xdef\lastsectiondefs{%
+ \gdef\noexpand\thissectionname{\the\toks0}%
+ \gdef\noexpand\thissectionnum{#4}%
+ % \noexpand\putwordSection avoids expanding indigestible
+ % commands in some of the translations.
+ \gdef\noexpand\thissection{\noexpand\putwordSection{}
+ \noexpand\thissectionnum:
+ \noexpand\thissectionname}%
+ }%
+ \fi
+ \fi\fi\fi
+ %
+ % Go into vertical mode. Usually we'll already be there, but we
+ % don't want the following whatsit to end up in a preceding paragraph
+ % if the document didn't happen to have a blank line.
+ \par
+ %
+ % Output the mark. Pass it through \safewhatsit, to take care of
+ % the preceding space.
+ \safewhatsit\domark
+ %
+ % Insert space above the heading.
+ \csname #2headingbreak\endcsname
+ %
+ % Now the second mark, after the heading break. No break points
+ % between here and the heading.
+ \global\let\prevsectiondefs=\lastsectiondefs
+ \domark
+ %
+ % Only insert the space after the number if we have a section number.
+ \ifx\temptype\Ynothingkeyword
+ \setbox0 = \hbox{}%
+ \def\toctype{unn}%
+ \gdef\lastsection{#1}%
+ \else\ifx\temptype\Yomitfromtockeyword
+ % for @headings -- no section number, don't include in toc,
+ % and don't redefine \lastsection.
+ \setbox0 = \hbox{}%
+ \def\toctype{omit}%
+ \let\sectionlevel=\empty
+ \else\ifx\temptype\Yappendixkeyword
+ \setbox0 = \hbox{#4\enspace}%
+ \def\toctype{app}%
+ \gdef\lastsection{#1}%
+ \else
+ \setbox0 = \hbox{#4\enspace}%
+ \def\toctype{num}%
+ \gdef\lastsection{#1}%
+ \fi\fi\fi
+ %
+ % Write the toc entry (before \donoderef). See comments in \chapmacro.
+ \writetocentry{\toctype\sectionlevel}{#1}{#4}%
+ %
+ % Write the node reference (= pdf destination for pdftex).
+ % Again, see comments in \chapmacro.
+ \donoderef{#3}%
+ %
+ % Interline glue will be inserted when the vbox is completed.
+ % That glue will be a valid breakpoint for the page, since it'll be
+ % preceded by a whatsit (usually from the \donoderef, or from the
+ % \writetocentry if there was no node). We don't want to allow that
+ % break, since then the whatsits could end up on page n while the
+ % section is on page n+1, thus toc/etc. are wrong. Debian bug 276000.
+ \nobreak
+ %
+ % Output the actual section heading.
+ \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \ptexraggedright
+ \hangindent=\wd0 % zero if no section number
+ \unhbox0 #1}%
+ }%
+ % Add extra space after the heading -- half of whatever came above it.
+ % Don't allow stretch, though.
+ \kern .5 \csname #2headingskip\endcsname
+ %
+ % Do not let the kern be a potential breakpoint, as it would be if it
+ % was followed by glue.
+ \nobreak
+ %
+ % We'll almost certainly start a paragraph next, so don't let that
+ % glue accumulate. (Not a breakpoint because it's preceded by a
+ % discardable item.) However, when a paragraph is not started next
+ % (\startdefun, \cartouche, \center, etc.), this needs to be wiped out
+ % or the negative glue will cause weirdly wrong output, typically
+ % obscuring the section heading with something else.
+ \vskip-\parskip
+ %
+ % This is so the last item on the main vertical list is a known
+ % \penalty > 10000, so \startdefun, etc., can recognize the situation
+ % and do the needful.
+ \penalty 10001
+}
+
+
+\message{toc,}
+% Table of contents.
+\newwrite\tocfile
+
+% Write an entry to the toc file, opening it if necessary.
+% Called from @chapter, etc.
+%
+% Example usage: \writetocentry{sec}{Section Name}{\the\chapno.\the\secno}
+% We append the current node name (if any) and page number as additional
+% arguments for the \{chap,sec,...}entry macros which will eventually
+% read this. The node name is used in the pdf outlines as the
+% destination to jump to.
+%
+% We open the .toc file for writing here instead of at @setfilename (or
+% any other fixed time) so that @contents can be anywhere in the document.
+% But if #1 is `omit', then we don't do anything. This is used for the
+% table of contents chapter openings themselves.
+%
+\newif\iftocfileopened
+\def\omitkeyword{omit}%
+%
+\def\writetocentry#1#2#3{%
+ \edef\writetoctype{#1}%
+ \ifx\writetoctype\omitkeyword \else
+ \iftocfileopened\else
+ \immediate\openout\tocfile = \jobname.toc
+ \global\tocfileopenedtrue
+ \fi
+ %
+ \iflinks
+ {\atdummies
+ \edef\temp{%
+ \write\tocfile{@#1entry{#2}{#3}{\lastnode}{\noexpand\folio}}}%
+ \temp
+ }%
+ \fi
+ \fi
+ %
+ % Tell \shipout to create a pdf destination on each page, if we're
+ % writing pdf. These are used in the table of contents. We can't
+ % just write one on every page because the title pages are numbered
+ % 1 and 2 (the page numbers aren't printed), and so are the first
+ % two pages of the document. Thus, we'd have two destinations named
+ % `1', and two named `2'.
+ \ifpdf \global\pdfmakepagedesttrue \fi
+}
+
+
+% These characters do not print properly in the Computer Modern roman
+% fonts, so we must take special care. This is more or less redundant
+% with the Texinfo input format setup at the end of this file.
+%
+\def\activecatcodes{%
+ \catcode`\"=\active
+ \catcode`\$=\active
+ \catcode`\<=\active
+ \catcode`\>=\active
+ \catcode`\\=\active
+ \catcode`\^=\active
+ \catcode`\_=\active
+ \catcode`\|=\active
+ \catcode`\~=\active
+}
+
+
+% Read the toc file, which is essentially Texinfo input.
+\def\readtocfile{%
+ \setupdatafile
+ \activecatcodes
+ \input \tocreadfilename
+}
+
+\newskip\contentsrightmargin \contentsrightmargin=1in
+\newcount\savepageno
+\newcount\lastnegativepageno \lastnegativepageno = -1
+
+% Prepare to read what we've written to \tocfile.
+%
+\def\startcontents#1{%
+ % If @setchapternewpage on, and @headings double, the contents should
+ % start on an odd page, unlike chapters. Thus, we maintain
+ % \contentsalignmacro in parallel with \pagealignmacro.
+ % From: Torbjorn Granlund <tege@matematik.su.se>
+ \contentsalignmacro
+ \immediate\closeout\tocfile
+ %
+ % Don't need to put `Contents' or `Short Contents' in the headline.
+ % It is abundantly clear what they are.
+ \chapmacro{#1}{Yomitfromtoc}{}%
+ %
+ \savepageno = \pageno
+ \begingroup % Set up to handle contents files properly.
+ \raggedbottom % Worry more about breakpoints than the bottom.
+ \advance\hsize by -\contentsrightmargin % Don't use the full line length.
+ %
+ % Roman numerals for page numbers.
+ \ifnum \pageno>0 \global\pageno = \lastnegativepageno \fi
+}
+
+% redefined for the two-volume lispref. We always output on
+% \jobname.toc even if this is redefined.
+%
+\def\tocreadfilename{\jobname.toc}
+
+% Normal (long) toc.
+%
+\def\contents{%
+ \startcontents{\putwordTOC}%
+ \openin 1 \tocreadfilename\space
+ \ifeof 1 \else
+ \readtocfile
+ \fi
+ \vfill \eject
+ \contentsalignmacro % in case @setchapternewpage odd is in effect
+ \ifeof 1 \else
+ \pdfmakeoutlines
+ \fi
+ \closein 1
+ \endgroup
+ \lastnegativepageno = \pageno
+ \global\pageno = \savepageno
+}
+
+% And just the chapters.
+\def\summarycontents{%
+ \startcontents{\putwordShortTOC}%
+ %
+ \let\partentry = \shortpartentry
+ \let\numchapentry = \shortchapentry
+ \let\appentry = \shortchapentry
+ \let\unnchapentry = \shortunnchapentry
+ % We want a true roman here for the page numbers.
+ \secfonts
+ \let\rm=\shortcontrm \let\bf=\shortcontbf
+ \let\sl=\shortcontsl \let\tt=\shortconttt
+ \rm
+ \hyphenpenalty = 10000
+ \advance\baselineskip by 1pt % Open it up a little.
+ \def\numsecentry##1##2##3##4{}
+ \let\appsecentry = \numsecentry
+ \let\unnsecentry = \numsecentry
+ \let\numsubsecentry = \numsecentry
+ \let\appsubsecentry = \numsecentry
+ \let\unnsubsecentry = \numsecentry
+ \let\numsubsubsecentry = \numsecentry
+ \let\appsubsubsecentry = \numsecentry
+ \let\unnsubsubsecentry = \numsecentry
+ \openin 1 \tocreadfilename\space
+ \ifeof 1 \else
+ \readtocfile
+ \fi
+ \closein 1
+ \vfill \eject
+ \contentsalignmacro % in case @setchapternewpage odd is in effect
+ \endgroup
+ \lastnegativepageno = \pageno
+ \global\pageno = \savepageno
+}
+\let\shortcontents = \summarycontents
+
+% Typeset the label for a chapter or appendix for the short contents.
+% The arg is, e.g., `A' for an appendix, or `3' for a chapter.
+%
+\def\shortchaplabel#1{%
+ % This space should be enough, since a single number is .5em, and the
+ % widest letter (M) is 1em, at least in the Computer Modern fonts.
+ % But use \hss just in case.
+ % (This space doesn't include the extra space that gets added after
+ % the label; that gets put in by \shortchapentry above.)
+ %
+ % We'd like to right-justify chapter numbers, but that looks strange
+ % with appendix letters. And right-justifying numbers and
+ % left-justifying letters looks strange when there is less than 10
+ % chapters. Have to read the whole toc once to know how many chapters
+ % there are before deciding ...
+ \hbox to 1em{#1\hss}%
+}
+
+% These macros generate individual entries in the table of contents.
+% The first argument is the chapter or section name.
+% The last argument is the page number.
+% The arguments in between are the chapter number, section number, ...
+
+% Parts, in the main contents. Replace the part number, which doesn't
+% exist, with an empty box. Let's hope all the numbers have the same width.
+% Also ignore the page number, which is conventionally not printed.
+\def\numeralbox{\setbox0=\hbox{8}\hbox to \wd0{\hfil}}
+\def\partentry#1#2#3#4{\dochapentry{\numeralbox\labelspace#1}{}}
+%
+% Parts, in the short toc.
+\def\shortpartentry#1#2#3#4{%
+ \penalty-300
+ \vskip.5\baselineskip plus.15\baselineskip minus.1\baselineskip
+ \shortchapentry{{\bf #1}}{\numeralbox}{}{}%
+}
+
+% Chapters, in the main contents.
+\def\numchapentry#1#2#3#4{\dochapentry{#2\labelspace#1}{#4}}
+%
+% Chapters, in the short toc.
+% See comments in \dochapentry re vbox and related settings.
+\def\shortchapentry#1#2#3#4{%
+ \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno\bgroup#4\egroup}%
+}
+
+% Appendices, in the main contents.
+% Need the word Appendix, and a fixed-size box.
+%
+\def\appendixbox#1{%
+ % We use M since it's probably the widest letter.
+ \setbox0 = \hbox{\putwordAppendix{} M}%
+ \hbox to \wd0{\putwordAppendix{} #1\hss}}
+%
+\def\appentry#1#2#3#4{\dochapentry{\appendixbox{#2}\labelspace#1}{#4}}
+
+% Unnumbered chapters.
+\def\unnchapentry#1#2#3#4{\dochapentry{#1}{#4}}
+\def\shortunnchapentry#1#2#3#4{\tocentry{#1}{\doshortpageno\bgroup#4\egroup}}
+
+% Sections.
+\def\numsecentry#1#2#3#4{\dosecentry{#2\labelspace#1}{#4}}
+\let\appsecentry=\numsecentry
+\def\unnsecentry#1#2#3#4{\dosecentry{#1}{#4}}
+
+% Subsections.
+\def\numsubsecentry#1#2#3#4{\dosubsecentry{#2\labelspace#1}{#4}}
+\let\appsubsecentry=\numsubsecentry
+\def\unnsubsecentry#1#2#3#4{\dosubsecentry{#1}{#4}}
+
+% And subsubsections.
+\def\numsubsubsecentry#1#2#3#4{\dosubsubsecentry{#2\labelspace#1}{#4}}
+\let\appsubsubsecentry=\numsubsubsecentry
+\def\unnsubsubsecentry#1#2#3#4{\dosubsubsecentry{#1}{#4}}
+
+% This parameter controls the indentation of the various levels.
+% Same as \defaultparindent.
+\newdimen\tocindent \tocindent = 15pt
+
+% Now for the actual typesetting. In all these, #1 is the text and #2 is the
+% page number.
+%
+% If the toc has to be broken over pages, we want it to be at chapters
+% if at all possible; hence the \penalty.
+\def\dochapentry#1#2{%
+ \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip
+ \begingroup
+ \chapentryfonts
+ \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+ \endgroup
+ \nobreak\vskip .25\baselineskip plus.1\baselineskip
+}
+
+\def\dosecentry#1#2{\begingroup
+ \secentryfonts \leftskip=\tocindent
+ \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+\endgroup}
+
+\def\dosubsecentry#1#2{\begingroup
+ \subsecentryfonts \leftskip=2\tocindent
+ \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+\endgroup}
+
+\def\dosubsubsecentry#1#2{\begingroup
+ \subsubsecentryfonts \leftskip=3\tocindent
+ \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+\endgroup}
+
+% We use the same \entry macro as for the index entries.
+\let\tocentry = \entry
+
+% Space between chapter (or whatever) number and the title.
+\def\labelspace{\hskip1em \relax}
+
+\def\dopageno#1{{\rm #1}}
+\def\doshortpageno#1{{\rm #1}}
+
+\def\chapentryfonts{\secfonts \rm}
+\def\secentryfonts{\textfonts}
+\def\subsecentryfonts{\textfonts}
+\def\subsubsecentryfonts{\textfonts}
+
+
+\message{environments,}
+% @foo ... @end foo.
+
+% @tex ... @end tex escapes into raw TeX temporarily.
+% One exception: @ is still an escape character, so that @end tex works.
+% But \@ or @@ will get a plain @ character.
+
+\envdef\tex{%
+ \setupmarkupstyle{tex}%
+ \catcode `\\=0 \catcode `\{=1 \catcode `\}=2
+ \catcode `\$=3 \catcode `\&=4 \catcode `\#=6
+ \catcode `\^=7 \catcode `\_=8 \catcode `\~=\active \let~=\tie
+ \catcode `\%=14
+ \catcode `\+=\other
+ \catcode `\"=\other
+ \catcode `\|=\other
+ \catcode `\<=\other
+ \catcode `\>=\other
+ \catcode `\`=\other
+ \catcode `\'=\other
+ \escapechar=`\\
+ %
+ % ' is active in math mode (mathcode"8000). So reset it, and all our
+ % other math active characters (just in case), to plain's definitions.
+ \mathactive
+ %
+ \let\b=\ptexb
+ \let\bullet=\ptexbullet
+ \let\c=\ptexc
+ \let\,=\ptexcomma
+ \let\.=\ptexdot
+ \let\dots=\ptexdots
+ \let\equiv=\ptexequiv
+ \let\!=\ptexexclam
+ \let\i=\ptexi
+ \let\indent=\ptexindent
+ \let\noindent=\ptexnoindent
+ \let\{=\ptexlbrace
+ \let\+=\tabalign
+ \let\}=\ptexrbrace
+ \let\/=\ptexslash
+ \let\*=\ptexstar
+ \let\t=\ptext
+ \expandafter \let\csname top\endcsname=\ptextop % we've made it outer
+ \let\frenchspacing=\plainfrenchspacing
+ %
+ \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}%
+ \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}%
+ \def\@{@}%
+}
+% There is no need to define \Etex.
+
+% Define @lisp ... @end lisp.
+% @lisp environment forms a group so it can rebind things,
+% including the definition of @end lisp (which normally is erroneous).
+
+% Amount to narrow the margins by for @lisp.
+\newskip\lispnarrowing \lispnarrowing=0.4in
+
+% This is the definition that ^^M gets inside @lisp, @example, and other
+% such environments. \null is better than a space, since it doesn't
+% have any width.
+\def\lisppar{\null\endgraf}
+
+% This space is always present above and below environments.
+\newskip\envskipamount \envskipamount = 0pt
+
+% Make spacing and below environment symmetrical. We use \parskip here
+% to help in doing that, since in @example-like environments \parskip
+% is reset to zero; thus the \afterenvbreak inserts no space -- but the
+% start of the next paragraph will insert \parskip.
+%
+\def\aboveenvbreak{{%
+ % =10000 instead of <10000 because of a special case in \itemzzz and
+ % \sectionheading, q.v.
+ \ifnum \lastpenalty=10000 \else
+ \advance\envskipamount by \parskip
+ \endgraf
+ \ifdim\lastskip<\envskipamount
+ \removelastskip
+ % it's not a good place to break if the last penalty was \nobreak
+ % or better ...
+ \ifnum\lastpenalty<10000 \penalty-50 \fi
+ \vskip\envskipamount
+ \fi
+ \fi
+}}
+
+\let\afterenvbreak = \aboveenvbreak
+
+% \nonarrowing is a flag. If "set", @lisp etc don't narrow margins; it will
+% also clear it, so that its embedded environments do the narrowing again.
+\let\nonarrowing=\relax
+
+% @cartouche ... @end cartouche: draw rectangle w/rounded corners around
+% environment contents.
+\font\circle=lcircle10
+\newdimen\circthick
+\newdimen\cartouter\newdimen\cartinner
+\newskip\normbskip\newskip\normpskip\newskip\normlskip
+\circthick=\fontdimen8\circle
+%
+\def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth
+\def\ctr{{\hskip 6pt\circle\char'010}}
+\def\cbl{{\circle\char'012\hskip -6pt}}
+\def\cbr{{\hskip 6pt\circle\char'011}}
+\def\carttop{\hbox to \cartouter{\hskip\lskip
+ \ctl\leaders\hrule height\circthick\hfil\ctr
+ \hskip\rskip}}
+\def\cartbot{\hbox to \cartouter{\hskip\lskip
+ \cbl\leaders\hrule height\circthick\hfil\cbr
+ \hskip\rskip}}
+%
+\newskip\lskip\newskip\rskip
+
+\envdef\cartouche{%
+ \ifhmode\par\fi % can't be in the midst of a paragraph.
+ \startsavinginserts
+ \lskip=\leftskip \rskip=\rightskip
+ \leftskip=0pt\rightskip=0pt % we want these *outside*.
+ \cartinner=\hsize \advance\cartinner by-\lskip
+ \advance\cartinner by-\rskip
+ \cartouter=\hsize
+ \advance\cartouter by 18.4pt % allow for 3pt kerns on either
+ % side, and for 6pt waste from
+ % each corner char, and rule thickness
+ \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip
+ %
+ % If this cartouche directly follows a sectioning command, we need the
+ % \parskip glue (backspaced over by default) or the cartouche can
+ % collide with the section heading.
+ \ifnum\lastpenalty>10000 \vskip\parskip \penalty\lastpenalty \fi
+ %
+ \vbox\bgroup
+ \baselineskip=0pt\parskip=0pt\lineskip=0pt
+ \carttop
+ \hbox\bgroup
+ \hskip\lskip
+ \vrule\kern3pt
+ \vbox\bgroup
+ \kern3pt
+ \hsize=\cartinner
+ \baselineskip=\normbskip
+ \lineskip=\normlskip
+ \parskip=\normpskip
+ \vskip -\parskip
+ \comment % For explanation, see the end of def\group.
+}
+\def\Ecartouche{%
+ \ifhmode\par\fi
+ \kern3pt
+ \egroup
+ \kern3pt\vrule
+ \hskip\rskip
+ \egroup
+ \cartbot
+ \egroup
+ \checkinserts
+}
+
+
+% This macro is called at the beginning of all the @example variants,
+% inside a group.
+\newdimen\nonfillparindent
+\def\nonfillstart{%
+ \aboveenvbreak
+ \ifdim\hfuzz < 12pt \hfuzz = 12pt \fi % Don't be fussy
+ \sepspaces % Make spaces be word-separators rather than space tokens.
+ \let\par = \lisppar % don't ignore blank lines
+ \obeylines % each line of input is a line of output
+ \parskip = 0pt
+ % Turn off paragraph indentation but redefine \indent to emulate
+ % the normal \indent.
+ \nonfillparindent=\parindent
+ \parindent = 0pt
+ \let\indent\nonfillindent
+ %
+ \emergencystretch = 0pt % don't try to avoid overfull boxes
+ \ifx\nonarrowing\relax
+ \advance \leftskip by \lispnarrowing
+ \exdentamount=\lispnarrowing
+ \else
+ \let\nonarrowing = \relax
+ \fi
+ \let\exdent=\nofillexdent
+}
+
+\begingroup
+\obeyspaces
+% We want to swallow spaces (but not other tokens) after the fake
+% @indent in our nonfill-environments, where spaces are normally
+% active and set to @tie, resulting in them not being ignored after
+% @indent.
+\gdef\nonfillindent{\futurelet\temp\nonfillindentcheck}%
+\gdef\nonfillindentcheck{%
+\ifx\temp %
+\expandafter\nonfillindentgobble%
+\else%
+\leavevmode\nonfillindentbox%
+\fi%
+}%
+\endgroup
+\def\nonfillindentgobble#1{\nonfillindent}
+\def\nonfillindentbox{\hbox to \nonfillparindent{\hss}}
+
+% If you want all examples etc. small: @set dispenvsize small.
+% If you want even small examples the full size: @set dispenvsize nosmall.
+% This affects the following displayed environments:
+% @example, @display, @format, @lisp
+%
+\def\smallword{small}
+\def\nosmallword{nosmall}
+\let\SETdispenvsize\relax
+\def\setnormaldispenv{%
+ \ifx\SETdispenvsize\smallword
+ % end paragraph for sake of leading, in case document has no blank
+ % line. This is redundant with what happens in \aboveenvbreak, but
+ % we need to do it before changing the fonts, and it's inconvenient
+ % to change the fonts afterward.
+ \ifnum \lastpenalty=10000 \else \endgraf \fi
+ \smallexamplefonts \rm
+ \fi
+}
+\def\setsmalldispenv{%
+ \ifx\SETdispenvsize\nosmallword
+ \else
+ \ifnum \lastpenalty=10000 \else \endgraf \fi
+ \smallexamplefonts \rm
+ \fi
+}
+
+% We often define two environments, @foo and @smallfoo.
+% Let's do it in one command. #1 is the env name, #2 the definition.
+\def\makedispenvdef#1#2{%
+ \expandafter\envdef\csname#1\endcsname {\setnormaldispenv #2}%
+ \expandafter\envdef\csname small#1\endcsname {\setsmalldispenv #2}%
+ \expandafter\let\csname E#1\endcsname \afterenvbreak
+ \expandafter\let\csname Esmall#1\endcsname \afterenvbreak
+}
+
+% Define two environment synonyms (#1 and #2) for an environment.
+\def\maketwodispenvdef#1#2#3{%
+ \makedispenvdef{#1}{#3}%
+ \makedispenvdef{#2}{#3}%
+}
+%
+% @lisp: indented, narrowed, typewriter font;
+% @example: same as @lisp.
+%
+% @smallexample and @smalllisp: use smaller fonts.
+% Originally contributed by Pavel@xerox.
+%
+\maketwodispenvdef{lisp}{example}{%
+ \nonfillstart
+ \tt\setupmarkupstyle{example}%
+ \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special.
+ \gobble % eat return
+}
+% @display/@smalldisplay: same as @lisp except keep current font.
+%
+\makedispenvdef{display}{%
+ \nonfillstart
+ \gobble
+}
+
+% @format/@smallformat: same as @display except don't narrow margins.
+%
+\makedispenvdef{format}{%
+ \let\nonarrowing = t%
+ \nonfillstart
+ \gobble
+}
+
+% @flushleft: same as @format, but doesn't obey \SETdispenvsize.
+\envdef\flushleft{%
+ \let\nonarrowing = t%
+ \nonfillstart
+ \gobble
+}
+\let\Eflushleft = \afterenvbreak
+
+% @flushright.
+%
+\envdef\flushright{%
+ \let\nonarrowing = t%
+ \nonfillstart
+ \advance\leftskip by 0pt plus 1fill\relax
+ \gobble
+}
+\let\Eflushright = \afterenvbreak
+
+
+% @raggedright does more-or-less normal line breaking but no right
+% justification. From plain.tex. Don't stretch around special
+% characters in urls in this environment, since the stretch at the right
+% should be enough.
+\envdef\raggedright{%
+ \rightskip0pt plus2.4em \spaceskip.3333em \xspaceskip.5em\relax
+ \def\urefprestretchamount{0pt}%
+ \def\urefpoststretchamount{0pt}%
+}
+\let\Eraggedright\par
+
+\envdef\raggedleft{%
+ \parindent=0pt \leftskip0pt plus2em
+ \spaceskip.3333em \xspaceskip.5em \parfillskip=0pt
+ \hbadness=10000 % Last line will usually be underfull, so turn off
+ % badness reporting.
+}
+\let\Eraggedleft\par
+
+\envdef\raggedcenter{%
+ \parindent=0pt \rightskip0pt plus1em \leftskip0pt plus1em
+ \spaceskip.3333em \xspaceskip.5em \parfillskip=0pt
+ \hbadness=10000 % Last line will usually be underfull, so turn off
+ % badness reporting.
+}
+\let\Eraggedcenter\par
+
+
+% @quotation does normal linebreaking (hence we can't use \nonfillstart)
+% and narrows the margins. We keep \parskip nonzero in general, since
+% we're doing normal filling. So, when using \aboveenvbreak and
+% \afterenvbreak, temporarily make \parskip 0.
+%
+\makedispenvdef{quotation}{\quotationstart}
+%
+\def\quotationstart{%
+ \indentedblockstart % same as \indentedblock, but increase right margin too.
+ \ifx\nonarrowing\relax
+ \advance\rightskip by \lispnarrowing
+ \fi
+ \parsearg\quotationlabel
+}
+
+% We have retained a nonzero parskip for the environment, since we're
+% doing normal filling.
+%
+\def\Equotation{%
+ \par
+ \ifx\quotationauthor\thisisundefined\else
+ % indent a bit.
+ \leftline{\kern 2\leftskip \sl ---\quotationauthor}%
+ \fi
+ {\parskip=0pt \afterenvbreak}%
+}
+\def\Esmallquotation{\Equotation}
+
+% If we're given an argument, typeset it in bold with a colon after.
+\def\quotationlabel#1{%
+ \def\temp{#1}%
+ \ifx\temp\empty \else
+ {\bf #1: }%
+ \fi
+}
+
+% @indentedblock is like @quotation, but indents only on the left and
+% has no optional argument.
+%
+\makedispenvdef{indentedblock}{\indentedblockstart}
+%
+\def\indentedblockstart{%
+ {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip
+ \parindent=0pt
+ %
+ % @cartouche defines \nonarrowing to inhibit narrowing at next level down.
+ \ifx\nonarrowing\relax
+ \advance\leftskip by \lispnarrowing
+ \exdentamount = \lispnarrowing
+ \else
+ \let\nonarrowing = \relax
+ \fi
+}
+
+% Keep a nonzero parskip for the environment, since we're doing normal filling.
+%
+\def\Eindentedblock{%
+ \par
+ {\parskip=0pt \afterenvbreak}%
+}
+\def\Esmallindentedblock{\Eindentedblock}
+
+
+% LaTeX-like @verbatim...@end verbatim and @verb{<char>...<char>}
+% If we want to allow any <char> as delimiter,
+% we need the curly braces so that makeinfo sees the @verb command, eg:
+% `@verbx...x' would look like the '@verbx' command. --janneke@gnu.org
+%
+% [Knuth]: Donald Ervin Knuth, 1996. The TeXbook.
+%
+% [Knuth] p.344; only we need to do the other characters Texinfo sets
+% active too. Otherwise, they get lost as the first character on a
+% verbatim line.
+\def\dospecials{%
+ \do\ \do\\\do\{\do\}\do\$\do\&%
+ \do\#\do\^\do\^^K\do\_\do\^^A\do\%\do\~%
+ \do\<\do\>\do\|\do\@\do+\do\"%
+ % Don't do the quotes -- if we do, @set txicodequoteundirected and
+ % @set txicodequotebacktick will not have effect on @verb and
+ % @verbatim, and ?` and !` ligatures won't get disabled.
+ %\do\`\do\'%
+}
+%
+% [Knuth] p. 380
+\def\uncatcodespecials{%
+ \def\do##1{\catcode`##1=\other}\dospecials}
+%
+% Setup for the @verb command.
+%
+% Eight spaces for a tab
+\begingroup
+ \catcode`\^^I=\active
+ \gdef\tabeightspaces{\catcode`\^^I=\active\def^^I{\ \ \ \ \ \ \ \ }}
+\endgroup
+%
+\def\setupverb{%
+ \tt % easiest (and conventionally used) font for verbatim
+ \def\par{\leavevmode\endgraf}%
+ \setupmarkupstyle{verb}%
+ \tabeightspaces
+ % Respect line breaks,
+ % print special symbols as themselves, and
+ % make each space count
+ % must do in this order:
+ \obeylines \uncatcodespecials \sepspaces
+}
+
+% Setup for the @verbatim environment
+%
+% Real tab expansion.
+\newdimen\tabw \setbox0=\hbox{\tt\space} \tabw=8\wd0 % tab amount
+%
+% We typeset each line of the verbatim in an \hbox, so we can handle
+% tabs. The \global is in case the verbatim line starts with an accent,
+% or some other command that starts with a begin-group. Otherwise, the
+% entire \verbbox would disappear at the corresponding end-group, before
+% it is typeset. Meanwhile, we can't have nested verbatim commands
+% (can we?), so the \global won't be overwriting itself.
+\newbox\verbbox
+\def\starttabbox{\global\setbox\verbbox=\hbox\bgroup}
+%
+\begingroup
+ \catcode`\^^I=\active
+ \gdef\tabexpand{%
+ \catcode`\^^I=\active
+ \def^^I{\leavevmode\egroup
+ \dimen\verbbox=\wd\verbbox % the width so far, or since the previous tab
+ \divide\dimen\verbbox by\tabw
+ \multiply\dimen\verbbox by\tabw % compute previous multiple of \tabw
+ \advance\dimen\verbbox by\tabw % advance to next multiple of \tabw
+ \wd\verbbox=\dimen\verbbox \box\verbbox \starttabbox
+ }%
+ }
+\endgroup
+
+% start the verbatim environment.
+\def\setupverbatim{%
+ \let\nonarrowing = t%
+ \nonfillstart
+ \tt % easiest (and conventionally used) font for verbatim
+ % The \leavevmode here is for blank lines. Otherwise, we would
+ % never \starttabox and the \egroup would end verbatim mode.
+ \def\par{\leavevmode\egroup\box\verbbox\endgraf}%
+ \tabexpand
+ \setupmarkupstyle{verbatim}%
+ % Respect line breaks,
+ % print special symbols as themselves, and
+ % make each space count.
+ % Must do in this order:
+ \obeylines \uncatcodespecials \sepspaces
+ \everypar{\starttabbox}%
+}
+
+% Do the @verb magic: verbatim text is quoted by unique
+% delimiter characters. Before first delimiter expect a
+% right brace, after last delimiter expect closing brace:
+%
+% \def\doverb'{'<char>#1<char>'}'{#1}
+%
+% [Knuth] p. 382; only eat outer {}
+\begingroup
+ \catcode`[=1\catcode`]=2\catcode`\{=\other\catcode`\}=\other
+ \gdef\doverb{#1[\def\next##1#1}[##1\endgroup]\next]
+\endgroup
+%
+\def\verb{\begingroup\setupverb\doverb}
+%
+%
+% Do the @verbatim magic: define the macro \doverbatim so that
+% the (first) argument ends when '@end verbatim' is reached, ie:
+%
+% \def\doverbatim#1@end verbatim{#1}
+%
+% For Texinfo it's a lot easier than for LaTeX,
+% because texinfo's \verbatim doesn't stop at '\end{verbatim}':
+% we need not redefine '\', '{' and '}'.
+%
+% Inspired by LaTeX's verbatim command set [latex.ltx]
+%
+\begingroup
+ \catcode`\ =\active
+ \obeylines %
+ % ignore everything up to the first ^^M, that's the newline at the end
+ % of the @verbatim input line itself. Otherwise we get an extra blank
+ % line in the output.
+ \xdef\doverbatim#1^^M#2@end verbatim{#2\noexpand\end\gobble verbatim}%
+ % We really want {...\end verbatim} in the body of the macro, but
+ % without the active space; thus we have to use \xdef and \gobble.
+\endgroup
+%
+\envdef\verbatim{%
+ \setupverbatim\doverbatim
+}
+\let\Everbatim = \afterenvbreak
+
+
+% @verbatiminclude FILE - insert text of file in verbatim environment.
+%
+\def\verbatiminclude{\parseargusing\filenamecatcodes\doverbatiminclude}
+%
+\def\doverbatiminclude#1{%
+ {%
+ \makevalueexpandable
+ \setupverbatim
+ \indexnofonts % Allow `@@' and other weird things in file names.
+ \wlog{texinfo.tex: doing @verbatiminclude of #1^^J}%
+ \input #1
+ \afterenvbreak
+ }%
+}
+
+% @copying ... @end copying.
+% Save the text away for @insertcopying later.
+%
+% We save the uninterpreted tokens, rather than creating a box.
+% Saving the text in a box would be much easier, but then all the
+% typesetting commands (@smallbook, font changes, etc.) have to be done
+% beforehand -- and a) we want @copying to be done first in the source
+% file; b) letting users define the frontmatter in as flexible order as
+% possible is very desirable.
+%
+\def\copying{\checkenv{}\begingroup\scanargctxt\docopying}
+\def\docopying#1@end copying{\endgroup\def\copyingtext{#1}}
+%
+\def\insertcopying{%
+ \begingroup
+ \parindent = 0pt % paragraph indentation looks wrong on title page
+ \scanexp\copyingtext
+ \endgroup
+}
+
+
+\message{defuns,}
+% @defun etc.
+
+\newskip\defbodyindent \defbodyindent=.4in
+\newskip\defargsindent \defargsindent=50pt
+\newskip\deflastargmargin \deflastargmargin=18pt
+\newcount\defunpenalty
+
+% Start the processing of @deffn:
+\def\startdefun{%
+ \ifnum\lastpenalty<10000
+ \medbreak
+ \defunpenalty=10003 % Will keep this @deffn together with the
+ % following @def command, see below.
+ \else
+ % If there are two @def commands in a row, we'll have a \nobreak,
+ % which is there to keep the function description together with its
+ % header. But if there's nothing but headers, we need to allow a
+ % break somewhere. Check specifically for penalty 10002, inserted
+ % by \printdefunline, instead of 10000, since the sectioning
+ % commands also insert a nobreak penalty, and we don't want to allow
+ % a break between a section heading and a defun.
+ %
+ % As a further refinement, we avoid "club" headers by signalling
+ % with penalty of 10003 after the very first @deffn in the
+ % sequence (see above), and penalty of 10002 after any following
+ % @def command.
+ \ifnum\lastpenalty=10002 \penalty2000 \else \defunpenalty=10002 \fi
+ %
+ % Similarly, after a section heading, do not allow a break.
+ % But do insert the glue.
+ \medskip % preceded by discardable penalty, so not a breakpoint
+ \fi
+ %
+ \parindent=0in
+ \advance\leftskip by \defbodyindent
+ \exdentamount=\defbodyindent
+}
+
+\def\dodefunx#1{%
+ % First, check whether we are in the right environment:
+ \checkenv#1%
+ %
+ % As above, allow line break if we have multiple x headers in a row.
+ % It's not a great place, though.
+ \ifnum\lastpenalty=10002 \penalty3000 \else \defunpenalty=10002 \fi
+ %
+ % And now, it's time to reuse the body of the original defun:
+ \expandafter\gobbledefun#1%
+}
+\def\gobbledefun#1\startdefun{}
+
+% \printdefunline \deffnheader{text}
+%
+\def\printdefunline#1#2{%
+ \begingroup
+ % call \deffnheader:
+ #1#2 \endheader
+ % common ending:
+ \interlinepenalty = 10000
+ \advance\rightskip by 0pt plus 1fil\relax
+ \endgraf
+ \nobreak\vskip -\parskip
+ \penalty\defunpenalty % signal to \startdefun and \dodefunx
+ % Some of the @defun-type tags do not enable magic parentheses,
+ % rendering the following check redundant. But we don't optimize.
+ \checkparencounts
+ \endgroup
+}
+
+\def\Edefun{\endgraf\medbreak}
+
+% \makedefun{deffn} creates \deffn, \deffnx and \Edeffn;
+% the only thing remaining is to define \deffnheader.
+%
+\def\makedefun#1{%
+ \expandafter\let\csname E#1\endcsname = \Edefun
+ \edef\temp{\noexpand\domakedefun
+ \makecsname{#1}\makecsname{#1x}\makecsname{#1header}}%
+ \temp
+}
+
+% \domakedefun \deffn \deffnx \deffnheader
+%
+% Define \deffn and \deffnx, without parameters.
+% \deffnheader has to be defined explicitly.
+%
+\def\domakedefun#1#2#3{%
+ \envdef#1{%
+ \startdefun
+ \doingtypefnfalse % distinguish typed functions from all else
+ \parseargusing\activeparens{\printdefunline#3}%
+ }%
+ \def#2{\dodefunx#1}%
+ \def#3%
+}
+
+\newif\ifdoingtypefn % doing typed function?
+\newif\ifrettypeownline % typeset return type on its own line?
+
+% @deftypefnnewline on|off says whether the return type of typed functions
+% are printed on their own line. This affects @deftypefn, @deftypefun,
+% @deftypeop, and @deftypemethod.
+%
+\parseargdef\deftypefnnewline{%
+ \def\temp{#1}%
+ \ifx\temp\onword
+ \expandafter\let\csname SETtxideftypefnnl\endcsname
+ = \empty
+ \else\ifx\temp\offword
+ \expandafter\let\csname SETtxideftypefnnl\endcsname
+ = \relax
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @txideftypefnnl value `\temp',
+ must be on|off}%
+ \fi\fi
+}
+
+% Untyped functions:
+
+% @deffn category name args
+\makedefun{deffn}{\deffngeneral{}}
+
+% @deffn category class name args
+\makedefun{defop}#1 {\defopon{#1\ \putwordon}}
+
+% \defopon {category on}class name args
+\def\defopon#1#2 {\deffngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} }
+
+% \deffngeneral {subind}category name args
+%
+\def\deffngeneral#1#2 #3 #4\endheader{%
+ % Remember that \dosubind{fn}{foo}{} is equivalent to \doind{fn}{foo}.
+ \dosubind{fn}{\code{#3}}{#1}%
+ \defname{#2}{}{#3}\magicamp\defunargs{#4\unskip}%
+}
+
+% Typed functions:
+
+% @deftypefn category type name args
+\makedefun{deftypefn}{\deftypefngeneral{}}
+
+% @deftypeop category class type name args
+\makedefun{deftypeop}#1 {\deftypeopon{#1\ \putwordon}}
+
+% \deftypeopon {category on}class type name args
+\def\deftypeopon#1#2 {\deftypefngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} }
+
+% \deftypefngeneral {subind}category type name args
+%
+\def\deftypefngeneral#1#2 #3 #4 #5\endheader{%
+ \dosubind{fn}{\code{#4}}{#1}%
+ \doingtypefntrue
+ \defname{#2}{#3}{#4}\defunargs{#5\unskip}%
+}
+
+% Typed variables:
+
+% @deftypevr category type var args
+\makedefun{deftypevr}{\deftypecvgeneral{}}
+
+% @deftypecv category class type var args
+\makedefun{deftypecv}#1 {\deftypecvof{#1\ \putwordof}}
+
+% \deftypecvof {category of}class type var args
+\def\deftypecvof#1#2 {\deftypecvgeneral{\putwordof\ \code{#2}}{#1\ \code{#2}} }
+
+% \deftypecvgeneral {subind}category type var args
+%
+\def\deftypecvgeneral#1#2 #3 #4 #5\endheader{%
+ \dosubind{vr}{\code{#4}}{#1}%
+ \defname{#2}{#3}{#4}\defunargs{#5\unskip}%
+}
+
+% Untyped variables:
+
+% @defvr category var args
+\makedefun{defvr}#1 {\deftypevrheader{#1} {} }
+
+% @defcv category class var args
+\makedefun{defcv}#1 {\defcvof{#1\ \putwordof}}
+
+% \defcvof {category of}class var args
+\def\defcvof#1#2 {\deftypecvof{#1}#2 {} }
+
+% Types:
+
+% @deftp category name args
+\makedefun{deftp}#1 #2 #3\endheader{%
+ \doind{tp}{\code{#2}}%
+ \defname{#1}{}{#2}\defunargs{#3\unskip}%
+}
+
+% Remaining @defun-like shortcuts:
+\makedefun{defun}{\deffnheader{\putwordDeffunc} }
+\makedefun{defmac}{\deffnheader{\putwordDefmac} }
+\makedefun{defspec}{\deffnheader{\putwordDefspec} }
+\makedefun{deftypefun}{\deftypefnheader{\putwordDeffunc} }
+\makedefun{defvar}{\defvrheader{\putwordDefvar} }
+\makedefun{defopt}{\defvrheader{\putwordDefopt} }
+\makedefun{deftypevar}{\deftypevrheader{\putwordDefvar} }
+\makedefun{defmethod}{\defopon\putwordMethodon}
+\makedefun{deftypemethod}{\deftypeopon\putwordMethodon}
+\makedefun{defivar}{\defcvof\putwordInstanceVariableof}
+\makedefun{deftypeivar}{\deftypecvof\putwordInstanceVariableof}
+
+% \defname, which formats the name of the @def (not the args).
+% #1 is the category, such as "Function".
+% #2 is the return type, if any.
+% #3 is the function name.
+%
+% We are followed by (but not passed) the arguments, if any.
+%
+\def\defname#1#2#3{%
+ \par
+ % Get the values of \leftskip and \rightskip as they were outside the @def...
+ \advance\leftskip by -\defbodyindent
+ %
+ % Determine if we are typesetting the return type of a typed function
+ % on a line by itself.
+ \rettypeownlinefalse
+ \ifdoingtypefn % doing a typed function specifically?
+ % then check user option for putting return type on its own line:
+ \expandafter\ifx\csname SETtxideftypefnnl\endcsname\relax \else
+ \rettypeownlinetrue
+ \fi
+ \fi
+ %
+ % How we'll format the category name. Putting it in brackets helps
+ % distinguish it from the body text that may end up on the next line
+ % just below it.
+ \def\temp{#1}%
+ \setbox0=\hbox{\kern\deflastargmargin \ifx\temp\empty\else [\rm\temp]\fi}
+ %
+ % Figure out line sizes for the paragraph shape. We'll always have at
+ % least two.
+ \tempnum = 2
+ %
+ % The first line needs space for \box0; but if \rightskip is nonzero,
+ % we need only space for the part of \box0 which exceeds it:
+ \dimen0=\hsize \advance\dimen0 by -\wd0 \advance\dimen0 by \rightskip
+ %
+ % If doing a return type on its own line, we'll have another line.
+ \ifrettypeownline
+ \advance\tempnum by 1
+ \def\maybeshapeline{0in \hsize}%
+ \else
+ \def\maybeshapeline{}%
+ \fi
+ %
+ % The continuations:
+ \dimen2=\hsize \advance\dimen2 by -\defargsindent
+ %
+ % The final paragraph shape:
+ \parshape \tempnum 0in \dimen0 \maybeshapeline \defargsindent \dimen2
+ %
+ % Put the category name at the right margin.
+ \noindent
+ \hbox to 0pt{%
+ \hfil\box0 \kern-\hsize
+ % \hsize has to be shortened this way:
+ \kern\leftskip
+ % Intentionally do not respect \rightskip, since we need the space.
+ }%
+ %
+ % Allow all lines to be underfull without complaint:
+ \tolerance=10000 \hbadness=10000
+ \exdentamount=\defbodyindent
+ {%
+ % defun fonts. We use typewriter by default (used to be bold) because:
+ % . we're printing identifiers, they should be in tt in principle.
+ % . in languages with many accents, such as Czech or French, it's
+ % common to leave accents off identifiers. The result looks ok in
+ % tt, but exceedingly strange in rm.
+ % . we don't want -- and --- to be treated as ligatures.
+ % . this still does not fix the ?` and !` ligatures, but so far no
+ % one has made identifiers using them :).
+ \df \tt
+ \def\temp{#2}% text of the return type
+ \ifx\temp\empty\else
+ \tclose{\temp}% typeset the return type
+ \ifrettypeownline
+ % put return type on its own line; prohibit line break following:
+ \hfil\vadjust{\nobreak}\break
+ \else
+ \space % type on same line, so just followed by a space
+ \fi
+ \fi % no return type
+ #3% output function name
+ }%
+ {\rm\enskip}% hskip 0.5 em of \tenrm
+ %
+ \boldbrax
+ % arguments will be output next, if any.
+}
+
+% Print arguments in slanted roman (not ttsl), inconsistently with using
+% tt for the name. This is because literal text is sometimes needed in
+% the argument list (groff manual), and ttsl and tt are not very
+% distinguishable. Prevent hyphenation at `-' chars.
+%
+\def\defunargs#1{%
+ % use sl by default (not ttsl),
+ % tt for the names.
+ \df \sl \hyphenchar\font=0
+ %
+ % On the other hand, if an argument has two dashes (for instance), we
+ % want a way to get ttsl. We used to recommend @var for that, so
+ % leave the code in, but it's strange for @var to lead to typewriter.
+ % Nowadays we recommend @code, since the difference between a ttsl hyphen
+ % and a tt hyphen is pretty tiny. @code also disables ?` !`.
+ \def\var##1{{\setupmarkupstyle{var}\ttslanted{##1}}}%
+ #1%
+ \sl\hyphenchar\font=45
+}
+
+% We want ()&[] to print specially on the defun line.
+%
+\def\activeparens{%
+ \catcode`\(=\active \catcode`\)=\active
+ \catcode`\[=\active \catcode`\]=\active
+ \catcode`\&=\active
+}
+
+% Make control sequences which act like normal parenthesis chars.
+\let\lparen = ( \let\rparen = )
+
+% Be sure that we always have a definition for `(', etc. For example,
+% if the fn name has parens in it, \boldbrax will not be in effect yet,
+% so TeX would otherwise complain about undefined control sequence.
+{
+ \activeparens
+ \global\let(=\lparen \global\let)=\rparen
+ \global\let[=\lbrack \global\let]=\rbrack
+ \global\let& = \&
+
+ \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb}
+ \gdef\magicamp{\let&=\amprm}
+}
+
+\newcount\parencount
+
+% If we encounter &foo, then turn on ()-hacking afterwards
+\newif\ifampseen
+\def\amprm#1 {\ampseentrue{\bf\&#1 }}
+
+\def\parenfont{%
+ \ifampseen
+ % At the first level, print parens in roman,
+ % otherwise use the default font.
+ \ifnum \parencount=1 \rm \fi
+ \else
+ % The \sf parens (in \boldbrax) actually are a little bolder than
+ % the contained text. This is especially needed for [ and ] .
+ \sf
+ \fi
+}
+\def\infirstlevel#1{%
+ \ifampseen
+ \ifnum\parencount=1
+ #1%
+ \fi
+ \fi
+}
+\def\bfafterword#1 {#1 \bf}
+
+\def\opnr{%
+ \global\advance\parencount by 1
+ {\parenfont(}%
+ \infirstlevel \bfafterword
+}
+\def\clnr{%
+ {\parenfont)}%
+ \infirstlevel \sl
+ \global\advance\parencount by -1
+}
+
+\newcount\brackcount
+\def\lbrb{%
+ \global\advance\brackcount by 1
+ {\bf[}%
+}
+\def\rbrb{%
+ {\bf]}%
+ \global\advance\brackcount by -1
+}
+
+\def\checkparencounts{%
+ \ifnum\parencount=0 \else \badparencount \fi
+ \ifnum\brackcount=0 \else \badbrackcount \fi
+}
+% these should not use \errmessage; the glibc manual, at least, actually
+% has such constructs (when documenting function pointers).
+\def\badparencount{%
+ \message{Warning: unbalanced parentheses in @def...}%
+ \global\parencount=0
+}
+\def\badbrackcount{%
+ \message{Warning: unbalanced square brackets in @def...}%
+ \global\brackcount=0
+}
+
+
+\message{macros,}
+% @macro.
+
+% To do this right we need a feature of e-TeX, \scantokens,
+% which we arrange to emulate with a temporary file in ordinary TeX.
+\ifx\eTeXversion\thisisundefined
+ \newwrite\macscribble
+ \def\scantokens#1{%
+ \toks0={#1}%
+ \immediate\openout\macscribble=\jobname.tmp
+ \immediate\write\macscribble{\the\toks0}%
+ \immediate\closeout\macscribble
+ \input \jobname.tmp
+ }
+\fi
+
+\def\scanmacro#1{\begingroup
+ \newlinechar`\^^M
+ \let\xeatspaces\eatspaces
+ %
+ % Undo catcode changes of \startcontents and \doprintindex
+ % When called from @insertcopying or (short)caption, we need active
+ % backslash to get it printed correctly. Previously, we had
+ % \catcode`\\=\other instead. We'll see whether a problem appears
+ % with macro expansion. --kasal, 19aug04
+ \catcode`\@=0 \catcode`\\=\active \escapechar=`\@
+ %
+ % ... and for \example:
+ \spaceisspace
+ %
+ % The \empty here causes a following catcode 5 newline to be eaten as
+ % part of reading whitespace after a control sequence. It does not
+ % eat a catcode 13 newline. There's no good way to handle the two
+ % cases (untried: maybe e-TeX's \everyeof could help, though plain TeX
+ % would then have different behavior). See the Macro Details node in
+ % the manual for the workaround we recommend for macros and
+ % line-oriented commands.
+ %
+ \scantokens{#1\empty}%
+\endgroup}
+
+\def\scanexp#1{%
+ \edef\temp{\noexpand\scanmacro{#1}}%
+ \temp
+}
+
+\newcount\paramno % Count of parameters
+\newtoks\macname % Macro name
+\newif\ifrecursive % Is it recursive?
+
+% List of all defined macros in the form
+% \definedummyword\macro1\definedummyword\macro2...
+% Currently is also contains all @aliases; the list can be split
+% if there is a need.
+\def\macrolist{}
+
+% Add the macro to \macrolist
+\def\addtomacrolist#1{\expandafter \addtomacrolistxxx \csname#1\endcsname}
+\def\addtomacrolistxxx#1{%
+ \toks0 = \expandafter{\macrolist\definedummyword#1}%
+ \xdef\macrolist{\the\toks0}%
+}
+
+% Utility routines.
+% This does \let #1 = #2, with \csnames; that is,
+% \let \csname#1\endcsname = \csname#2\endcsname
+% (except of course we have to play expansion games).
+%
+\def\cslet#1#2{%
+ \expandafter\let
+ \csname#1\expandafter\endcsname
+ \csname#2\endcsname
+}
+
+% Trim leading and trailing spaces off a string.
+% Concepts from aro-bend problem 15 (see CTAN).
+{\catcode`\@=11
+\gdef\eatspaces #1{\expandafter\trim@\expandafter{#1 }}
+\gdef\trim@ #1{\trim@@ @#1 @ #1 @ @@}
+\gdef\trim@@ #1@ #2@ #3@@{\trim@@@\empty #2 @}
+\def\unbrace#1{#1}
+\unbrace{\gdef\trim@@@ #1 } #2@{#1}
+}
+
+% Trim a single trailing ^^M off a string.
+{\catcode`\^^M=\other \catcode`\Q=3%
+\gdef\eatcr #1{\eatcra #1Q^^MQ}%
+\gdef\eatcra#1^^MQ{\eatcrb#1Q}%
+\gdef\eatcrb#1Q#2Q{#1}%
+}
+
+% Macro bodies are absorbed as an argument in a context where
+% all characters are catcode 10, 11 or 12, except \ which is active
+% (as in normal texinfo). It is necessary to change the definition of \
+% to recognize macro arguments; this is the job of \mbodybackslash.
+%
+% Non-ASCII encodings make 8-bit characters active, so un-activate
+% them to avoid their expansion. Must do this non-globally, to
+% confine the change to the current group.
+%
+% It's necessary to have hard CRs when the macro is executed. This is
+% done by making ^^M (\endlinechar) catcode 12 when reading the macro
+% body, and then making it the \newlinechar in \scanmacro.
+%
+\def\scanctxt{% used as subroutine
+ \catcode`\"=\other
+ \catcode`\+=\other
+ \catcode`\<=\other
+ \catcode`\>=\other
+ \catcode`\@=\other
+ \catcode`\^=\other
+ \catcode`\_=\other
+ \catcode`\|=\other
+ \catcode`\~=\other
+ \ifx\declaredencoding\ascii \else \setnonasciicharscatcodenonglobal\other \fi
+}
+
+\def\scanargctxt{% used for copying and captions, not macros.
+ \scanctxt
+ \catcode`\\=\other
+ \catcode`\^^M=\other
+}
+
+\def\macrobodyctxt{% used for @macro definitions
+ \scanctxt
+ \catcode`\{=\other
+ \catcode`\}=\other
+ \catcode`\^^M=\other
+ \usembodybackslash
+}
+
+\def\macroargctxt{% used when scanning invocations
+ \scanctxt
+ \catcode`\\=0
+}
+% why catcode 0 for \ in the above? To recognize \\ \{ \} as "escapes"
+% for the single characters \ { }. Thus, we end up with the "commands"
+% that would be written @\ @{ @} in a Texinfo document.
+%
+% We already have @{ and @}. For @\, we define it here, and only for
+% this purpose, to produce a typewriter backslash (so, the @\ that we
+% define for @math can't be used with @macro calls):
+%
+\def\\{\normalbackslash}%
+%
+% We would like to do this for \, too, since that is what makeinfo does.
+% But it is not possible, because Texinfo already has a command @, for a
+% cedilla accent. Documents must use @comma{} instead.
+%
+% \anythingelse will almost certainly be an error of some kind.
+
+
+% \mbodybackslash is the definition of \ in @macro bodies.
+% It maps \foo\ => \csname macarg.foo\endcsname => #N
+% where N is the macro parameter number.
+% We define \csname macarg.\endcsname to be \realbackslash, so
+% \\ in macro replacement text gets you a backslash.
+%
+{\catcode`@=0 @catcode`@\=@active
+ @gdef@usembodybackslash{@let\=@mbodybackslash}
+ @gdef@mbodybackslash#1\{@csname macarg.#1@endcsname}
+}
+\expandafter\def\csname macarg.\endcsname{\realbackslash}
+
+\def\margbackslash#1{\char`\#1 }
+
+\def\macro{\recursivefalse\parsearg\macroxxx}
+\def\rmacro{\recursivetrue\parsearg\macroxxx}
+
+\def\macroxxx#1{%
+ \getargs{#1}% now \macname is the macname and \argl the arglist
+ \ifx\argl\empty % no arguments
+ \paramno=0\relax
+ \else
+ \expandafter\parsemargdef \argl;%
+ \if\paramno>256\relax
+ \ifx\eTeXversion\thisisundefined
+ \errhelp = \EMsimple
+ \errmessage{You need eTeX to compile a file with macros with more than 256 arguments}
+ \fi
+ \fi
+ \fi
+ \if1\csname ismacro.\the\macname\endcsname
+ \message{Warning: redefining \the\macname}%
+ \else
+ \expandafter\ifx\csname \the\macname\endcsname \relax
+ \else \errmessage{Macro name \the\macname\space already defined}\fi
+ \global\cslet{macsave.\the\macname}{\the\macname}%
+ \global\expandafter\let\csname ismacro.\the\macname\endcsname=1%
+ \addtomacrolist{\the\macname}%
+ \fi
+ \begingroup \macrobodyctxt
+ \ifrecursive \expandafter\parsermacbody
+ \else \expandafter\parsemacbody
+ \fi}
+
+\parseargdef\unmacro{%
+ \if1\csname ismacro.#1\endcsname
+ \global\cslet{#1}{macsave.#1}%
+ \global\expandafter\let \csname ismacro.#1\endcsname=0%
+ % Remove the macro name from \macrolist:
+ \begingroup
+ \expandafter\let\csname#1\endcsname \relax
+ \let\definedummyword\unmacrodo
+ \xdef\macrolist{\macrolist}%
+ \endgroup
+ \else
+ \errmessage{Macro #1 not defined}%
+ \fi
+}
+
+% Called by \do from \dounmacro on each macro. The idea is to omit any
+% macro definitions that have been changed to \relax.
+%
+\def\unmacrodo#1{%
+ \ifx #1\relax
+ % remove this
+ \else
+ \noexpand\definedummyword \noexpand#1%
+ \fi
+}
+
+% This makes use of the obscure feature that if the last token of a
+% <parameter list> is #, then the preceding argument is delimited by
+% an opening brace, and that opening brace is not consumed.
+\def\getargs#1{\getargsxxx#1{}}
+\def\getargsxxx#1#{\getmacname #1 \relax\getmacargs}
+\def\getmacname#1 #2\relax{\macname={#1}}
+\def\getmacargs#1{\def\argl{#1}}
+
+% For macro processing make @ a letter so that we can make Texinfo private macro names.
+\edef\texiatcatcode{\the\catcode`\@}
+\catcode `@=11\relax
+
+% Parse the optional {params} list. Set up \paramno and \paramlist
+% so \defmacro knows what to do. Define \macarg.BLAH for each BLAH
+% in the params list to some hook where the argument is to be expanded. If
+% there are less than 10 arguments that hook is to be replaced by ##N where N
+% is the position in that list, that is to say the macro arguments are to be
+% defined `a la TeX in the macro body.
+%
+% That gets used by \mbodybackslash (above).
+%
+% We need to get `macro parameter char #' into several definitions.
+% The technique used is stolen from LaTeX: let \hash be something
+% unexpandable, insert that wherever you need a #, and then redefine
+% it to # just before using the token list produced.
+%
+% The same technique is used to protect \eatspaces till just before
+% the macro is used.
+%
+% If there are 10 or more arguments, a different technique is used, where the
+% hook remains in the body, and when macro is to be expanded the body is
+% processed again to replace the arguments.
+%
+% In that case, the hook is \the\toks N-1, and we simply set \toks N-1 to the
+% argument N value and then \edef the body (nothing else will expand because of
+% the catcode regime underwhich the body was input).
+%
+% If you compile with TeX (not eTeX), and you have macros with 10 or more
+% arguments, you need that no macro has more than 256 arguments, otherwise an
+% error is produced.
+\def\parsemargdef#1;{%
+ \paramno=0\def\paramlist{}%
+ \let\hash\relax
+ \let\xeatspaces\relax
+ \parsemargdefxxx#1,;,%
+ % In case that there are 10 or more arguments we parse again the arguments
+ % list to set new definitions for the \macarg.BLAH macros corresponding to
+ % each BLAH argument. It was anyhow needed to parse already once this list
+ % in order to count the arguments, and as macros with at most 9 arguments
+ % are by far more frequent than macro with 10 or more arguments, defining
+ % twice the \macarg.BLAH macros does not cost too much processing power.
+ \ifnum\paramno<10\relax\else
+ \paramno0\relax
+ \parsemmanyargdef@@#1,;,% 10 or more arguments
+ \fi
+}
+\def\parsemargdefxxx#1,{%
+ \if#1;\let\next=\relax
+ \else \let\next=\parsemargdefxxx
+ \advance\paramno by 1
+ \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname
+ {\xeatspaces{\hash\the\paramno}}%
+ \edef\paramlist{\paramlist\hash\the\paramno,}%
+ \fi\next}
+
+\def\parsemmanyargdef@@#1,{%
+ \if#1;\let\next=\relax
+ \else
+ \let\next=\parsemmanyargdef@@
+ \edef\tempb{\eatspaces{#1}}%
+ \expandafter\def\expandafter\tempa
+ \expandafter{\csname macarg.\tempb\endcsname}%
+ % Note that we need some extra \noexpand\noexpand, this is because we
+ % don't want \the to be expanded in the \parsermacbody as it uses an
+ % \xdef .
+ \expandafter\edef\tempa
+ {\noexpand\noexpand\noexpand\the\toks\the\paramno}%
+ \advance\paramno by 1\relax
+ \fi\next}
+
+% These two commands read recursive and nonrecursive macro bodies.
+% (They're different since rec and nonrec macros end differently.)
+%
+
+\catcode `\@\texiatcatcode
+\long\def\parsemacbody#1@end macro%
+{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}%
+\long\def\parsermacbody#1@end rmacro%
+{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}%
+\catcode `\@=11\relax
+
+\let\endargs@\relax
+\let\nil@\relax
+\def\nilm@{\nil@}%
+\long\def\nillm@{\nil@}%
+
+% This macro is expanded during the Texinfo macro expansion, not during its
+% definition. It gets all the arguments values and assigns them to macros
+% macarg.ARGNAME
+%
+% #1 is the macro name
+% #2 is the list of argument names
+% #3 is the list of argument values
+\def\getargvals@#1#2#3{%
+ \def\macargdeflist@{}%
+ \def\saveparamlist@{#2}% Need to keep a copy for parameter expansion.
+ \def\paramlist{#2,\nil@}%
+ \def\macroname{#1}%
+ \begingroup
+ \macroargctxt
+ \def\argvaluelist{#3,\nil@}%
+ \def\@tempa{#3}%
+ \ifx\@tempa\empty
+ \setemptyargvalues@
+ \else
+ \getargvals@@
+ \fi
+}
+
+%
+\def\getargvals@@{%
+ \ifx\paramlist\nilm@
+ % Some sanity check needed here that \argvaluelist is also empty.
+ \ifx\argvaluelist\nillm@
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Too many arguments in macro `\macroname'!}%
+ \fi
+ \let\next\macargexpandinbody@
+ \else
+ \ifx\argvaluelist\nillm@
+ % No more arguments values passed to macro. Set remaining named-arg
+ % macros to empty.
+ \let\next\setemptyargvalues@
+ \else
+ % pop current arg name into \@tempb
+ \def\@tempa##1{\pop@{\@tempb}{\paramlist}##1\endargs@}%
+ \expandafter\@tempa\expandafter{\paramlist}%
+ % pop current argument value into \@tempc
+ \def\@tempa##1{\longpop@{\@tempc}{\argvaluelist}##1\endargs@}%
+ \expandafter\@tempa\expandafter{\argvaluelist}%
+ % Here \@tempb is the current arg name and \@tempc is the current arg value.
+ % First place the new argument macro definition into \@tempd
+ \expandafter\macname\expandafter{\@tempc}%
+ \expandafter\let\csname macarg.\@tempb\endcsname\relax
+ \expandafter\def\expandafter\@tempe\expandafter{%
+ \csname macarg.\@tempb\endcsname}%
+ \edef\@tempd{\long\def\@tempe{\the\macname}}%
+ \push@\@tempd\macargdeflist@
+ \let\next\getargvals@@
+ \fi
+ \fi
+ \next
+}
+
+\def\push@#1#2{%
+ \expandafter\expandafter\expandafter\def
+ \expandafter\expandafter\expandafter#2%
+ \expandafter\expandafter\expandafter{%
+ \expandafter#1#2}%
+}
+
+% Replace arguments by their values in the macro body, and place the result
+% in macro \@tempa
+\def\macvalstoargs@{%
+ % To do this we use the property that token registers that are \the'ed
+ % within an \edef expand only once. So we are going to place all argument
+ % values into respective token registers.
+ %
+ % First we save the token context, and initialize argument numbering.
+ \begingroup
+ \paramno0\relax
+ % Then, for each argument number #N, we place the corresponding argument
+ % value into a new token list register \toks#N
+ \expandafter\putargsintokens@\saveparamlist@,;,%
+ % Then, we expand the body so that argument are replaced by their
+ % values. The trick for values not to be expanded themselves is that they
+ % are within tokens and that tokens expand only once in an \edef .
+ \edef\@tempc{\csname mac.\macroname .body\endcsname}%
+ % Now we restore the token stack pointer to free the token list registers
+ % which we have used, but we make sure that expanded body is saved after
+ % group.
+ \expandafter
+ \endgroup
+ \expandafter\def\expandafter\@tempa\expandafter{\@tempc}%
+ }
+
+\def\macargexpandinbody@{%
+ %% Define the named-macro outside of this group and then close this group.
+ \expandafter
+ \endgroup
+ \macargdeflist@
+ % First the replace in body the macro arguments by their values, the result
+ % is in \@tempa .
+ \macvalstoargs@
+ % Then we point at the \norecurse or \gobble (for recursive) macro value
+ % with \@tempb .
+ \expandafter\let\expandafter\@tempb\csname mac.\macroname .recurse\endcsname
+ % Depending on whether it is recursive or not, we need some tailing
+ % \egroup .
+ \ifx\@tempb\gobble
+ \let\@tempc\relax
+ \else
+ \let\@tempc\egroup
+ \fi
+ % And now we do the real job:
+ \edef\@tempd{\noexpand\@tempb{\macroname}\noexpand\scanmacro{\@tempa}\@tempc}%
+ \@tempd
+}
+
+\def\putargsintokens@#1,{%
+ \if#1;\let\next\relax
+ \else
+ \let\next\putargsintokens@
+ % First we allocate the new token list register, and give it a temporary
+ % alias \@tempb .
+ \toksdef\@tempb\the\paramno
+ % Then we place the argument value into that token list register.
+ \expandafter\let\expandafter\@tempa\csname macarg.#1\endcsname
+ \expandafter\@tempb\expandafter{\@tempa}%
+ \advance\paramno by 1\relax
+ \fi
+ \next
+}
+
+% Save the token stack pointer into macro #1
+\def\texisavetoksstackpoint#1{\edef#1{\the\@cclvi}}
+% Restore the token stack pointer from number in macro #1
+\def\texirestoretoksstackpoint#1{\expandafter\mathchardef\expandafter\@cclvi#1\relax}
+% newtoks that can be used non \outer .
+\def\texinonouternewtoks{\alloc@ 5\toks \toksdef \@cclvi}
+
+% Tailing missing arguments are set to empty
+\def\setemptyargvalues@{%
+ \ifx\paramlist\nilm@
+ \let\next\macargexpandinbody@
+ \else
+ \expandafter\setemptyargvaluesparser@\paramlist\endargs@
+ \let\next\setemptyargvalues@
+ \fi
+ \next
+}
+
+\def\setemptyargvaluesparser@#1,#2\endargs@{%
+ \expandafter\def\expandafter\@tempa\expandafter{%
+ \expandafter\def\csname macarg.#1\endcsname{}}%
+ \push@\@tempa\macargdeflist@
+ \def\paramlist{#2}%
+}
+
+% #1 is the element target macro
+% #2 is the list macro
+% #3,#4\endargs@ is the list value
+\def\pop@#1#2#3,#4\endargs@{%
+ \def#1{#3}%
+ \def#2{#4}%
+}
+\long\def\longpop@#1#2#3,#4\endargs@{%
+ \long\def#1{#3}%
+ \long\def#2{#4}%
+}
+
+% This defines a Texinfo @macro. There are eight cases: recursive and
+% nonrecursive macros of zero, one, up to nine, and many arguments.
+% Much magic with \expandafter here.
+% \xdef is used so that macro definitions will survive the file
+% they're defined in; @include reads the file inside a group.
+%
+\def\defmacro{%
+ \let\hash=##% convert placeholders to macro parameter chars
+ \ifrecursive
+ \ifcase\paramno
+ % 0
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \noexpand\scanmacro{\temp}}%
+ \or % 1
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \bgroup\noexpand\macroargctxt
+ \noexpand\braceorline
+ \expandafter\noexpand\csname\the\macname xxx\endcsname}%
+ \expandafter\xdef\csname\the\macname xxx\endcsname##1{%
+ \egroup\noexpand\scanmacro{\temp}}%
+ \else
+ \ifnum\paramno<10\relax % at most 9
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \bgroup\noexpand\macroargctxt
+ \noexpand\csname\the\macname xx\endcsname}%
+ \expandafter\xdef\csname\the\macname xx\endcsname##1{%
+ \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}%
+ \expandafter\expandafter
+ \expandafter\xdef
+ \expandafter\expandafter
+ \csname\the\macname xxx\endcsname
+ \paramlist{\egroup\noexpand\scanmacro{\temp}}%
+ \else % 10 or more
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \noexpand\getargvals@{\the\macname}{\argl}%
+ }%
+ \global\expandafter\let\csname mac.\the\macname .body\endcsname\temp
+ \global\expandafter\let\csname mac.\the\macname .recurse\endcsname\gobble
+ \fi
+ \fi
+ \else
+ \ifcase\paramno
+ % 0
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \noexpand\norecurse{\the\macname}%
+ \noexpand\scanmacro{\temp}\egroup}%
+ \or % 1
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \bgroup\noexpand\macroargctxt
+ \noexpand\braceorline
+ \expandafter\noexpand\csname\the\macname xxx\endcsname}%
+ \expandafter\xdef\csname\the\macname xxx\endcsname##1{%
+ \egroup
+ \noexpand\norecurse{\the\macname}%
+ \noexpand\scanmacro{\temp}\egroup}%
+ \else % at most 9
+ \ifnum\paramno<10\relax
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \bgroup\noexpand\macroargctxt
+ \expandafter\noexpand\csname\the\macname xx\endcsname}%
+ \expandafter\xdef\csname\the\macname xx\endcsname##1{%
+ \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}%
+ \expandafter\expandafter
+ \expandafter\xdef
+ \expandafter\expandafter
+ \csname\the\macname xxx\endcsname
+ \paramlist{%
+ \egroup
+ \noexpand\norecurse{\the\macname}%
+ \noexpand\scanmacro{\temp}\egroup}%
+ \else % 10 or more:
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \noexpand\getargvals@{\the\macname}{\argl}%
+ }%
+ \global\expandafter\let\csname mac.\the\macname .body\endcsname\temp
+ \global\expandafter\let\csname mac.\the\macname .recurse\endcsname\norecurse
+ \fi
+ \fi
+ \fi}
+
+\catcode `\@\texiatcatcode\relax
+
+\def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}}
+
+% \braceorline decides whether the next nonwhitespace character is a
+% {. If so it reads up to the closing }, if not, it reads the whole
+% line. Whatever was read is then fed to the next control sequence
+% as an argument (by \parsebrace or \parsearg).
+%
+\def\braceorline#1{\let\macnamexxx=#1\futurelet\nchar\braceorlinexxx}
+\def\braceorlinexxx{%
+ \ifx\nchar\bgroup\else
+ \expandafter\parsearg
+ \fi \macnamexxx}
+
+
+% @alias.
+% We need some trickery to remove the optional spaces around the equal
+% sign. Make them active and then expand them all to nothing.
+%
+\def\alias{\parseargusing\obeyspaces\aliasxxx}
+\def\aliasxxx #1{\aliasyyy#1\relax}
+\def\aliasyyy #1=#2\relax{%
+ {%
+ \expandafter\let\obeyedspace=\empty
+ \addtomacrolist{#1}%
+ \xdef\next{\global\let\makecsname{#1}=\makecsname{#2}}%
+ }%
+ \next
+}
+
+
+\message{cross references,}
+
+\newwrite\auxfile
+\newif\ifhavexrefs % True if xref values are known.
+\newif\ifwarnedxrefs % True if we warned once that they aren't known.
+
+% @inforef is relatively simple.
+\def\inforef #1{\inforefzzz #1,,,,**}
+\def\inforefzzz #1,#2,#3,#4**{%
+ \putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}},
+ node \samp{\ignorespaces#1{}}}
+
+% @node's only job in TeX is to define \lastnode, which is used in
+% cross-references. The @node line might or might not have commas, and
+% might or might not have spaces before the first comma, like:
+% @node foo , bar , ...
+% We don't want such trailing spaces in the node name.
+%
+\parseargdef\node{\checkenv{}\donode #1 ,\finishnodeparse}
+%
+% also remove a trailing comma, in case of something like this:
+% @node Help-Cross, , , Cross-refs
+\def\donode#1 ,#2\finishnodeparse{\dodonode #1,\finishnodeparse}
+\def\dodonode#1,#2\finishnodeparse{\gdef\lastnode{#1}}
+
+\let\nwnode=\node
+\let\lastnode=\empty
+
+% Write a cross-reference definition for the current node. #1 is the
+% type (Ynumbered, Yappendix, Ynothing).
+%
+\def\donoderef#1{%
+ \ifx\lastnode\empty\else
+ \setref{\lastnode}{#1}%
+ \global\let\lastnode=\empty
+ \fi
+}
+
+% @anchor{NAME} -- define xref target at arbitrary point.
+%
+\newcount\savesfregister
+%
+\def\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi}
+\def\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi}
+\def\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces}
+
+% \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an
+% anchor), which consists of three parts:
+% 1) NAME-title - the current sectioning name taken from \lastsection,
+% or the anchor name.
+% 2) NAME-snt - section number and type, passed as the SNT arg, or
+% empty for anchors.
+% 3) NAME-pg - the page number.
+%
+% This is called from \donoderef, \anchor, and \dofloat. In the case of
+% floats, there is an additional part, which is not written here:
+% 4) NAME-lof - the text as it should appear in a @listoffloats.
+%
+\def\setref#1#2{%
+ \pdfmkdest{#1}%
+ \iflinks
+ {%
+ \atdummies % preserve commands, but don't expand them
+ \edef\writexrdef##1##2{%
+ \write\auxfile{@xrdef{#1-% #1 of \setref, expanded by the \edef
+ ##1}{##2}}% these are parameters of \writexrdef
+ }%
+ \toks0 = \expandafter{\lastsection}%
+ \immediate \writexrdef{title}{\the\toks0 }%
+ \immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc.
+ \safewhatsit{\writexrdef{pg}{\folio}}% will be written later, at \shipout
+ }%
+ \fi
+}
+
+% @xrefautosectiontitle on|off says whether @section(ing) names are used
+% automatically in xrefs, if the third arg is not explicitly specified.
+% This was provided as a "secret" @set xref-automatic-section-title
+% variable, now it's official.
+%
+\parseargdef\xrefautomaticsectiontitle{%
+ \def\temp{#1}%
+ \ifx\temp\onword
+ \expandafter\let\csname SETxref-automatic-section-title\endcsname
+ = \empty
+ \else\ifx\temp\offword
+ \expandafter\let\csname SETxref-automatic-section-title\endcsname
+ = \relax
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @xrefautomaticsectiontitle value `\temp',
+ must be on|off}%
+ \fi\fi
+}
+
+%
+% @xref, @pxref, and @ref generate cross-references. For \xrefX, #1 is
+% the node name, #2 the name of the Info cross-reference, #3 the printed
+% node name, #4 the name of the Info file, #5 the name of the printed
+% manual. All but the node name can be omitted.
+%
+\def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]}
+\def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]}
+\def\ref#1{\xrefX[#1,,,,,,,]}
+%
+\newbox\toprefbox
+\newbox\printedrefnamebox
+\newbox\infofilenamebox
+\newbox\printedmanualbox
+%
+\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup
+ \unsepspaces
+ %
+ % Get args without leading/trailing spaces.
+ \def\printedrefname{\ignorespaces #3}%
+ \setbox\printedrefnamebox = \hbox{\printedrefname\unskip}%
+ %
+ \def\infofilename{\ignorespaces #4}%
+ \setbox\infofilenamebox = \hbox{\infofilename\unskip}%
+ %
+ \def\printedmanual{\ignorespaces #5}%
+ \setbox\printedmanualbox = \hbox{\printedmanual\unskip}%
+ %
+ % If the printed reference name (arg #3) was not explicitly given in
+ % the @xref, figure out what we want to use.
+ \ifdim \wd\printedrefnamebox = 0pt
+ % No printed node name was explicitly given.
+ \expandafter\ifx\csname SETxref-automatic-section-title\endcsname \relax
+ % Not auto section-title: use node name inside the square brackets.
+ \def\printedrefname{\ignorespaces #1}%
+ \else
+ % Auto section-title: use chapter/section title inside
+ % the square brackets if we have it.
+ \ifdim \wd\printedmanualbox > 0pt
+ % It is in another manual, so we don't have it; use node name.
+ \def\printedrefname{\ignorespaces #1}%
+ \else
+ \ifhavexrefs
+ % We (should) know the real title if we have the xref values.
+ \def\printedrefname{\refx{#1-title}{}}%
+ \else
+ % Otherwise just copy the Info node name.
+ \def\printedrefname{\ignorespaces #1}%
+ \fi%
+ \fi
+ \fi
+ \fi
+ %
+ % Make link in pdf output.
+ \ifpdf
+ {\indexnofonts
+ \turnoffactive
+ \makevalueexpandable
+ % This expands tokens, so do it after making catcode changes, so _
+ % etc. don't get their TeX definitions. This ignores all spaces in
+ % #4, including (wrongly) those in the middle of the filename.
+ \getfilename{#4}%
+ %
+ % This (wrongly) does not take account of leading or trailing
+ % spaces in #1, which should be ignored.
+ \edef\pdfxrefdest{#1}%
+ \ifx\pdfxrefdest\empty
+ \def\pdfxrefdest{Top}% no empty targets
+ \else
+ \txiescapepdf\pdfxrefdest % escape PDF special chars
+ \fi
+ %
+ \leavevmode
+ \startlink attr{/Border [0 0 0]}%
+ \ifnum\filenamelength>0
+ goto file{\the\filename.pdf} name{\pdfxrefdest}%
+ \else
+ goto name{\pdfmkpgn{\pdfxrefdest}}%
+ \fi
+ }%
+ \setcolor{\linkcolor}%
+ \fi
+ %
+ % Float references are printed completely differently: "Figure 1.2"
+ % instead of "[somenode], p.3". We distinguish them by the
+ % LABEL-title being set to a magic string.
+ {%
+ % Have to otherify everything special to allow the \csname to
+ % include an _ in the xref name, etc.
+ \indexnofonts
+ \turnoffactive
+ \expandafter\global\expandafter\let\expandafter\Xthisreftitle
+ \csname XR#1-title\endcsname
+ }%
+ \iffloat\Xthisreftitle
+ % If the user specified the print name (third arg) to the ref,
+ % print it instead of our usual "Figure 1.2".
+ \ifdim\wd\printedrefnamebox = 0pt
+ \refx{#1-snt}{}%
+ \else
+ \printedrefname
+ \fi
+ %
+ % If the user also gave the printed manual name (fifth arg), append
+ % "in MANUALNAME".
+ \ifdim \wd\printedmanualbox > 0pt
+ \space \putwordin{} \cite{\printedmanual}%
+ \fi
+ \else
+ % node/anchor (non-float) references.
+ %
+ % If we use \unhbox to print the node names, TeX does not insert
+ % empty discretionaries after hyphens, which means that it will not
+ % find a line break at a hyphen in a node names. Since some manuals
+ % are best written with fairly long node names, containing hyphens,
+ % this is a loss. Therefore, we give the text of the node name
+ % again, so it is as if TeX is seeing it for the first time.
+ %
+ \ifdim \wd\printedmanualbox > 0pt
+ % Cross-manual reference with a printed manual name.
+ %
+ \crossmanualxref{\cite{\printedmanual\unskip}}%
+ %
+ \else\ifdim \wd\infofilenamebox > 0pt
+ % Cross-manual reference with only an info filename (arg 4), no
+ % printed manual name (arg 5). This is essentially the same as
+ % the case above; we output the filename, since we have nothing else.
+ %
+ \crossmanualxref{\code{\infofilename\unskip}}%
+ %
+ \else
+ % Reference within this manual.
+ %
+ % _ (for example) has to be the character _ for the purposes of the
+ % control sequence corresponding to the node, but it has to expand
+ % into the usual \leavevmode...\vrule stuff for purposes of
+ % printing. So we \turnoffactive for the \refx-snt, back on for the
+ % printing, back off for the \refx-pg.
+ {\turnoffactive
+ % Only output a following space if the -snt ref is nonempty; for
+ % @unnumbered and @anchor, it won't be.
+ \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}%
+ \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi
+ }%
+ % output the `[mynode]' via the macro below so it can be overridden.
+ \xrefprintnodename\printedrefname
+ %
+ % But we always want a comma and a space:
+ ,\space
+ %
+ % output the `page 3'.
+ \turnoffactive \putwordpage\tie\refx{#1-pg}{}%
+ \fi\fi
+ \fi
+ \endlink
+\endgroup}
+
+% Output a cross-manual xref to #1. Used just above (twice).
+%
+% Only include the text "Section ``foo'' in" if the foo is neither
+% missing or Top. Thus, @xref{,,,foo,The Foo Manual} outputs simply
+% "see The Foo Manual", the idea being to refer to the whole manual.
+%
+% But, this being TeX, we can't easily compare our node name against the
+% string "Top" while ignoring the possible spaces before and after in
+% the input. By adding the arbitrary 7sp below, we make it much less
+% likely that a real node name would have the same width as "Top" (e.g.,
+% in a monospaced font). Hopefully it will never happen in practice.
+%
+% For the same basic reason, we retypeset the "Top" at every
+% reference, since the current font is indeterminate.
+%
+\def\crossmanualxref#1{%
+ \setbox\toprefbox = \hbox{Top\kern7sp}%
+ \setbox2 = \hbox{\ignorespaces \printedrefname \unskip \kern7sp}%
+ \ifdim \wd2 > 7sp % nonempty?
+ \ifdim \wd2 = \wd\toprefbox \else % same as Top?
+ \putwordSection{} ``\printedrefname'' \putwordin{}\space
+ \fi
+ \fi
+ #1%
+}
+
+% This macro is called from \xrefX for the `[nodename]' part of xref
+% output. It's a separate macro only so it can be changed more easily,
+% since square brackets don't work well in some documents. Particularly
+% one that Bob is working on :).
+%
+\def\xrefprintnodename#1{[#1]}
+
+% Things referred to by \setref.
+%
+\def\Ynothing{}
+\def\Yomitfromtoc{}
+\def\Ynumbered{%
+ \ifnum\secno=0
+ \putwordChapter@tie \the\chapno
+ \else \ifnum\subsecno=0
+ \putwordSection@tie \the\chapno.\the\secno
+ \else \ifnum\subsubsecno=0
+ \putwordSection@tie \the\chapno.\the\secno.\the\subsecno
+ \else
+ \putwordSection@tie \the\chapno.\the\secno.\the\subsecno.\the\subsubsecno
+ \fi\fi\fi
+}
+\def\Yappendix{%
+ \ifnum\secno=0
+ \putwordAppendix@tie @char\the\appendixno{}%
+ \else \ifnum\subsecno=0
+ \putwordSection@tie @char\the\appendixno.\the\secno
+ \else \ifnum\subsubsecno=0
+ \putwordSection@tie @char\the\appendixno.\the\secno.\the\subsecno
+ \else
+ \putwordSection@tie
+ @char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno
+ \fi\fi\fi
+}
+
+% Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME.
+% If its value is nonempty, SUFFIX is output afterward.
+%
+\def\refx#1#2{%
+ {%
+ \indexnofonts
+ \otherbackslash
+ \expandafter\global\expandafter\let\expandafter\thisrefX
+ \csname XR#1\endcsname
+ }%
+ \ifx\thisrefX\relax
+ % If not defined, say something at least.
+ \angleleft un\-de\-fined\angleright
+ \iflinks
+ \ifhavexrefs
+ {\toks0 = {#1}% avoid expansion of possibly-complex value
+ \message{\linenumber Undefined cross reference `\the\toks0'.}}%
+ \else
+ \ifwarnedxrefs\else
+ \global\warnedxrefstrue
+ \message{Cross reference values unknown; you must run TeX again.}%
+ \fi
+ \fi
+ \fi
+ \else
+ % It's defined, so just use it.
+ \thisrefX
+ \fi
+ #2% Output the suffix in any case.
+}
+
+% This is the macro invoked by entries in the aux file. Usually it's
+% just a \def (we prepend XR to the control sequence name to avoid
+% collisions). But if this is a float type, we have more work to do.
+%
+\def\xrdef#1#2{%
+ {% The node name might contain 8-bit characters, which in our current
+ % implementation are changed to commands like @'e. Don't let these
+ % mess up the control sequence name.
+ \indexnofonts
+ \turnoffactive
+ \xdef\safexrefname{#1}%
+ }%
+ %
+ \expandafter\gdef\csname XR\safexrefname\endcsname{#2}% remember this xref
+ %
+ % Was that xref control sequence that we just defined for a float?
+ \expandafter\iffloat\csname XR\safexrefname\endcsname
+ % it was a float, and we have the (safe) float type in \iffloattype.
+ \expandafter\let\expandafter\floatlist
+ \csname floatlist\iffloattype\endcsname
+ %
+ % Is this the first time we've seen this float type?
+ \expandafter\ifx\floatlist\relax
+ \toks0 = {\do}% yes, so just \do
+ \else
+ % had it before, so preserve previous elements in list.
+ \toks0 = \expandafter{\floatlist\do}%
+ \fi
+ %
+ % Remember this xref in the control sequence \floatlistFLOATTYPE,
+ % for later use in \listoffloats.
+ \expandafter\xdef\csname floatlist\iffloattype\endcsname{\the\toks0
+ {\safexrefname}}%
+ \fi
+}
+
+% Read the last existing aux file, if any. No error if none exists.
+%
+\def\tryauxfile{%
+ \openin 1 \jobname.aux
+ \ifeof 1 \else
+ \readdatafile{aux}%
+ \global\havexrefstrue
+ \fi
+ \closein 1
+}
+
+\def\setupdatafile{%
+ \catcode`\^^@=\other
+ \catcode`\^^A=\other
+ \catcode`\^^B=\other
+ \catcode`\^^C=\other
+ \catcode`\^^D=\other
+ \catcode`\^^E=\other
+ \catcode`\^^F=\other
+ \catcode`\^^G=\other
+ \catcode`\^^H=\other
+ \catcode`\^^K=\other
+ \catcode`\^^L=\other
+ \catcode`\^^N=\other
+ \catcode`\^^P=\other
+ \catcode`\^^Q=\other
+ \catcode`\^^R=\other
+ \catcode`\^^S=\other
+ \catcode`\^^T=\other
+ \catcode`\^^U=\other
+ \catcode`\^^V=\other
+ \catcode`\^^W=\other
+ \catcode`\^^X=\other
+ \catcode`\^^Z=\other
+ \catcode`\^^[=\other
+ \catcode`\^^\=\other
+ \catcode`\^^]=\other
+ \catcode`\^^^=\other
+ \catcode`\^^_=\other
+ % It was suggested to set the catcode of ^ to 7, which would allow ^^e4 etc.
+ % in xref tags, i.e., node names. But since ^^e4 notation isn't
+ % supported in the main text, it doesn't seem desirable. Furthermore,
+ % that is not enough: for node names that actually contain a ^
+ % character, we would end up writing a line like this: 'xrdef {'hat
+ % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first
+ % argument, and \hat is not an expandable control sequence. It could
+ % all be worked out, but why? Either we support ^^ or we don't.
+ %
+ % The other change necessary for this was to define \auxhat:
+ % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter
+ % and then to call \auxhat in \setq.
+ %
+ \catcode`\^=\other
+ %
+ % Special characters. Should be turned off anyway, but...
+ \catcode`\~=\other
+ \catcode`\[=\other
+ \catcode`\]=\other
+ \catcode`\"=\other
+ \catcode`\_=\other
+ \catcode`\|=\other
+ \catcode`\<=\other
+ \catcode`\>=\other
+ \catcode`\$=\other
+ \catcode`\#=\other
+ \catcode`\&=\other
+ \catcode`\%=\other
+ \catcode`+=\other % avoid \+ for paranoia even though we've turned it off
+ %
+ % This is to support \ in node names and titles, since the \
+ % characters end up in a \csname. It's easier than
+ % leaving it active and making its active definition an actual \
+ % character. What I don't understand is why it works in the *value*
+ % of the xrdef. Seems like it should be a catcode12 \, and that
+ % should not typeset properly. But it works, so I'm moving on for
+ % now. --karl, 15jan04.
+ \catcode`\\=\other
+ %
+ % Make the characters 128-255 be printing characters.
+ {%
+ \count1=128
+ \def\loop{%
+ \catcode\count1=\other
+ \advance\count1 by 1
+ \ifnum \count1<256 \loop \fi
+ }%
+ }%
+ %
+ % @ is our escape character in .aux files, and we need braces.
+ \catcode`\{=1
+ \catcode`\}=2
+ \catcode`\@=0
+}
+
+\def\readdatafile#1{%
+\begingroup
+ \setupdatafile
+ \input\jobname.#1
+\endgroup}
+
+
+\message{insertions,}
+% including footnotes.
+
+\newcount \footnoteno
+
+% The trailing space in the following definition for supereject is
+% vital for proper filling; pages come out unaligned when you do a
+% pagealignmacro call if that space before the closing brace is
+% removed. (Generally, numeric constants should always be followed by a
+% space to prevent strange expansion errors.)
+\def\supereject{\par\penalty -20000\footnoteno =0 }
+
+% @footnotestyle is meaningful for Info output only.
+\let\footnotestyle=\comment
+
+{\catcode `\@=11
+%
+% Auto-number footnotes. Otherwise like plain.
+\gdef\footnote{%
+ \let\indent=\ptexindent
+ \let\noindent=\ptexnoindent
+ %
+ \global\advance\footnoteno by \@ne
+ \edef\thisfootno{$^{\the\footnoteno}$}%
+ %
+ % In case the footnote comes at the end of a sentence, preserve the
+ % extra spacing after we do the footnote number.
+ \let\@sf\empty
+ \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\ptexslash\fi
+ %
+ % Remove inadvertent blank space before typesetting the footnote number.
+ \unskip
+ \thisfootno\@sf
+ \dofootnote
+}%
+
+% Don't bother with the trickery in plain.tex to not require the
+% footnote text as a parameter. Our footnotes don't need to be so general.
+%
+% Oh yes, they do; otherwise, @ifset (and anything else that uses
+% \parseargline) fails inside footnotes because the tokens are fixed when
+% the footnote is read. --karl, 16nov96.
+%
+\gdef\dofootnote{%
+ \insert\footins\bgroup
+ %
+ % Nested footnotes are not supported in TeX, that would take a lot
+ % more work. (\startsavinginserts does not suffice.)
+ \let\footnote=\errfootnote
+ %
+ % We want to typeset this text as a normal paragraph, even if the
+ % footnote reference occurs in (for example) a display environment.
+ % So reset some parameters.
+ \hsize=\pagewidth
+ \interlinepenalty\interfootnotelinepenalty
+ \splittopskip\ht\strutbox % top baseline for broken footnotes
+ \splitmaxdepth\dp\strutbox
+ \floatingpenalty\@MM
+ \leftskip\z@skip
+ \rightskip\z@skip
+ \spaceskip\z@skip
+ \xspaceskip\z@skip
+ \parindent\defaultparindent
+ %
+ \smallfonts \rm
+ %
+ % Because we use hanging indentation in footnotes, a @noindent appears
+ % to exdent this text, so make it be a no-op. makeinfo does not use
+ % hanging indentation so @noindent can still be needed within footnote
+ % text after an @example or the like (not that this is good style).
+ \let\noindent = \relax
+ %
+ % Hang the footnote text off the number. Use \everypar in case the
+ % footnote extends for more than one paragraph.
+ \everypar = {\hang}%
+ \textindent{\thisfootno}%
+ %
+ % Don't crash into the line above the footnote text. Since this
+ % expands into a box, it must come within the paragraph, lest it
+ % provide a place where TeX can split the footnote.
+ \footstrut
+ %
+ % Invoke rest of plain TeX footnote routine.
+ \futurelet\next\fo@t
+}
+}%end \catcode `\@=11
+
+\def\errfootnote{%
+ \errhelp=\EMsimple
+ \errmessage{Nested footnotes not supported in texinfo.tex,
+ even though they work in makeinfo; sorry}
+}
+
+% In case a @footnote appears in a vbox, save the footnote text and create
+% the real \insert just after the vbox finished. Otherwise, the insertion
+% would be lost.
+% Similarly, if a @footnote appears inside an alignment, save the footnote
+% text to a box and make the \insert when a row of the table is finished.
+% And the same can be done for other insert classes. --kasal, 16nov03.
+%
+% Replace the \insert primitive by a cheating macro.
+% Deeper inside, just make sure that the saved insertions are not spilled
+% out prematurely.
+%
+\def\startsavinginserts{%
+ \ifx \insert\ptexinsert
+ \let\insert\saveinsert
+ \else
+ \let\checkinserts\relax
+ \fi
+}
+
+% This \insert replacement works for both \insert\footins{foo} and
+% \insert\footins\bgroup foo\egroup, but it doesn't work for \insert27{foo}.
+%
+\def\saveinsert#1{%
+ \edef\next{\noexpand\savetobox \makeSAVEname#1}%
+ \afterassignment\next
+ % swallow the left brace
+ \let\temp =
+}
+\def\makeSAVEname#1{\makecsname{SAVE\expandafter\gobble\string#1}}
+\def\savetobox#1{\global\setbox#1 = \vbox\bgroup \unvbox#1}
+
+\def\checksaveins#1{\ifvoid#1\else \placesaveins#1\fi}
+
+\def\placesaveins#1{%
+ \ptexinsert \csname\expandafter\gobblesave\string#1\endcsname
+ {\box#1}%
+}
+
+% eat @SAVE -- beware, all of them have catcode \other:
+{
+ \def\dospecials{\do S\do A\do V\do E} \uncatcodespecials % ;-)
+ \gdef\gobblesave @SAVE{}
+}
+
+% initialization:
+\def\newsaveins #1{%
+ \edef\next{\noexpand\newsaveinsX \makeSAVEname#1}%
+ \next
+}
+\def\newsaveinsX #1{%
+ \csname newbox\endcsname #1%
+ \expandafter\def\expandafter\checkinserts\expandafter{\checkinserts
+ \checksaveins #1}%
+}
+
+% initialize:
+\let\checkinserts\empty
+\newsaveins\footins
+\newsaveins\margin
+
+
+% @image. We use the macros from epsf.tex to support this.
+% If epsf.tex is not installed and @image is used, we complain.
+%
+% Check for and read epsf.tex up front. If we read it only at @image
+% time, we might be inside a group, and then its definitions would get
+% undone and the next image would fail.
+\openin 1 = epsf.tex
+\ifeof 1 \else
+ % Do not bother showing banner with epsf.tex v2.7k (available in
+ % doc/epsf.tex and on ctan).
+ \def\epsfannounce{\toks0 = }%
+ \input epsf.tex
+\fi
+\closein 1
+%
+% We will only complain once about lack of epsf.tex.
+\newif\ifwarnednoepsf
+\newhelp\noepsfhelp{epsf.tex must be installed for images to
+ work. It is also included in the Texinfo distribution, or you can get
+ it from ftp://tug.org/tex/epsf.tex.}
+%
+\def\image#1{%
+ \ifx\epsfbox\thisisundefined
+ \ifwarnednoepsf \else
+ \errhelp = \noepsfhelp
+ \errmessage{epsf.tex not found, images will be ignored}%
+ \global\warnednoepsftrue
+ \fi
+ \else
+ \imagexxx #1,,,,,\finish
+ \fi
+}
+%
+% Arguments to @image:
+% #1 is (mandatory) image filename; we tack on .eps extension.
+% #2 is (optional) width, #3 is (optional) height.
+% #4 is (ignored optional) html alt text.
+% #5 is (ignored optional) extension.
+% #6 is just the usual extra ignored arg for parsing stuff.
+\newif\ifimagevmode
+\def\imagexxx#1,#2,#3,#4,#5,#6\finish{\begingroup
+ \catcode`\^^M = 5 % in case we're inside an example
+ \normalturnoffactive % allow _ et al. in names
+ % If the image is by itself, center it.
+ \ifvmode
+ \imagevmodetrue
+ \else \ifx\centersub\centerV
+ % for @center @image, we need a vbox so we can have our vertical space
+ \imagevmodetrue
+ \vbox\bgroup % vbox has better behavior than vtop herev
+ \fi\fi
+ %
+ \ifimagevmode
+ \nobreak\medskip
+ % Usually we'll have text after the image which will insert
+ % \parskip glue, so insert it here too to equalize the space
+ % above and below.
+ \nobreak\vskip\parskip
+ \nobreak
+ \fi
+ %
+ % Leave vertical mode so that indentation from an enclosing
+ % environment such as @quotation is respected.
+ % However, if we're at the top level, we don't want the
+ % normal paragraph indentation.
+ % On the other hand, if we are in the case of @center @image, we don't
+ % want to start a paragraph, which will create a hsize-width box and
+ % eradicate the centering.
+ \ifx\centersub\centerV\else \noindent \fi
+ %
+ % Output the image.
+ \ifpdf
+ \dopdfimage{#1}{#2}{#3}%
+ \else
+ % \epsfbox itself resets \epsf?size at each figure.
+ \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi
+ \setbox0 = \hbox{\ignorespaces #3}\ifdim\wd0 > 0pt \epsfysize=#3\relax \fi
+ \epsfbox{#1.eps}%
+ \fi
+ %
+ \ifimagevmode
+ \medskip % space after a standalone image
+ \fi
+ \ifx\centersub\centerV \egroup \fi
+\endgroup}
+
+
+% @float FLOATTYPE,LABEL,LOC ... @end float for displayed figures, tables,
+% etc. We don't actually implement floating yet, we always include the
+% float "here". But it seemed the best name for the future.
+%
+\envparseargdef\float{\eatcommaspace\eatcommaspace\dofloat#1, , ,\finish}
+
+% There may be a space before second and/or third parameter; delete it.
+\def\eatcommaspace#1, {#1,}
+
+% #1 is the optional FLOATTYPE, the text label for this float, typically
+% "Figure", "Table", "Example", etc. Can't contain commas. If omitted,
+% this float will not be numbered and cannot be referred to.
+%
+% #2 is the optional xref label. Also must be present for the float to
+% be referable.
+%
+% #3 is the optional positioning argument; for now, it is ignored. It
+% will somehow specify the positions allowed to float to (here, top, bottom).
+%
+% We keep a separate counter for each FLOATTYPE, which we reset at each
+% chapter-level command.
+\let\resetallfloatnos=\empty
+%
+\def\dofloat#1,#2,#3,#4\finish{%
+ \let\thiscaption=\empty
+ \let\thisshortcaption=\empty
+ %
+ % don't lose footnotes inside @float.
+ %
+ % BEWARE: when the floats start float, we have to issue warning whenever an
+ % insert appears inside a float which could possibly float. --kasal, 26may04
+ %
+ \startsavinginserts
+ %
+ % We can't be used inside a paragraph.
+ \par
+ %
+ \vtop\bgroup
+ \def\floattype{#1}%
+ \def\floatlabel{#2}%
+ \def\floatloc{#3}% we do nothing with this yet.
+ %
+ \ifx\floattype\empty
+ \let\safefloattype=\empty
+ \else
+ {%
+ % the floattype might have accents or other special characters,
+ % but we need to use it in a control sequence name.
+ \indexnofonts
+ \turnoffactive
+ \xdef\safefloattype{\floattype}%
+ }%
+ \fi
+ %
+ % If label is given but no type, we handle that as the empty type.
+ \ifx\floatlabel\empty \else
+ % We want each FLOATTYPE to be numbered separately (Figure 1,
+ % Table 1, Figure 2, ...). (And if no label, no number.)
+ %
+ \expandafter\getfloatno\csname\safefloattype floatno\endcsname
+ \global\advance\floatno by 1
+ %
+ {%
+ % This magic value for \lastsection is output by \setref as the
+ % XREFLABEL-title value. \xrefX uses it to distinguish float
+ % labels (which have a completely different output format) from
+ % node and anchor labels. And \xrdef uses it to construct the
+ % lists of floats.
+ %
+ \edef\lastsection{\floatmagic=\safefloattype}%
+ \setref{\floatlabel}{Yfloat}%
+ }%
+ \fi
+ %
+ % start with \parskip glue, I guess.
+ \vskip\parskip
+ %
+ % Don't suppress indentation if a float happens to start a section.
+ \restorefirstparagraphindent
+}
+
+% we have these possibilities:
+% @float Foo,lbl & @caption{Cap}: Foo 1.1: Cap
+% @float Foo,lbl & no caption: Foo 1.1
+% @float Foo & @caption{Cap}: Foo: Cap
+% @float Foo & no caption: Foo
+% @float ,lbl & Caption{Cap}: 1.1: Cap
+% @float ,lbl & no caption: 1.1
+% @float & @caption{Cap}: Cap
+% @float & no caption:
+%
+\def\Efloat{%
+ \let\floatident = \empty
+ %
+ % In all cases, if we have a float type, it comes first.
+ \ifx\floattype\empty \else \def\floatident{\floattype}\fi
+ %
+ % If we have an xref label, the number comes next.
+ \ifx\floatlabel\empty \else
+ \ifx\floattype\empty \else % if also had float type, need tie first.
+ \appendtomacro\floatident{\tie}%
+ \fi
+ % the number.
+ \appendtomacro\floatident{\chaplevelprefix\the\floatno}%
+ \fi
+ %
+ % Start the printed caption with what we've constructed in
+ % \floatident, but keep it separate; we need \floatident again.
+ \let\captionline = \floatident
+ %
+ \ifx\thiscaption\empty \else
+ \ifx\floatident\empty \else
+ \appendtomacro\captionline{: }% had ident, so need a colon between
+ \fi
+ %
+ % caption text.
+ \appendtomacro\captionline{\scanexp\thiscaption}%
+ \fi
+ %
+ % If we have anything to print, print it, with space before.
+ % Eventually this needs to become an \insert.
+ \ifx\captionline\empty \else
+ \vskip.5\parskip
+ \captionline
+ %
+ % Space below caption.
+ \vskip\parskip
+ \fi
+ %
+ % If have an xref label, write the list of floats info. Do this
+ % after the caption, to avoid chance of it being a breakpoint.
+ \ifx\floatlabel\empty \else
+ % Write the text that goes in the lof to the aux file as
+ % \floatlabel-lof. Besides \floatident, we include the short
+ % caption if specified, else the full caption if specified, else nothing.
+ {%
+ \atdummies
+ %
+ % since we read the caption text in the macro world, where ^^M
+ % is turned into a normal character, we have to scan it back, so
+ % we don't write the literal three characters "^^M" into the aux file.
+ \scanexp{%
+ \xdef\noexpand\gtemp{%
+ \ifx\thisshortcaption\empty
+ \thiscaption
+ \else
+ \thisshortcaption
+ \fi
+ }%
+ }%
+ \immediate\write\auxfile{@xrdef{\floatlabel-lof}{\floatident
+ \ifx\gtemp\empty \else : \gtemp \fi}}%
+ }%
+ \fi
+ \egroup % end of \vtop
+ %
+ % place the captured inserts
+ %
+ % BEWARE: when the floats start floating, we have to issue warning
+ % whenever an insert appears inside a float which could possibly
+ % float. --kasal, 26may04
+ %
+ \checkinserts
+}
+
+% Append the tokens #2 to the definition of macro #1, not expanding either.
+%
+\def\appendtomacro#1#2{%
+ \expandafter\def\expandafter#1\expandafter{#1#2}%
+}
+
+% @caption, @shortcaption
+%
+\def\caption{\docaption\thiscaption}
+\def\shortcaption{\docaption\thisshortcaption}
+\def\docaption{\checkenv\float \bgroup\scanargctxt\defcaption}
+\def\defcaption#1#2{\egroup \def#1{#2}}
+
+% The parameter is the control sequence identifying the counter we are
+% going to use. Create it if it doesn't exist and assign it to \floatno.
+\def\getfloatno#1{%
+ \ifx#1\relax
+ % Haven't seen this figure type before.
+ \csname newcount\endcsname #1%
+ %
+ % Remember to reset this floatno at the next chap.
+ \expandafter\gdef\expandafter\resetallfloatnos
+ \expandafter{\resetallfloatnos #1=0 }%
+ \fi
+ \let\floatno#1%
+}
+
+% \setref calls this to get the XREFLABEL-snt value. We want an @xref
+% to the FLOATLABEL to expand to "Figure 3.1". We call \setref when we
+% first read the @float command.
+%
+\def\Yfloat{\floattype@tie \chaplevelprefix\the\floatno}%
+
+% Magic string used for the XREFLABEL-title value, so \xrefX can
+% distinguish floats from other xref types.
+\def\floatmagic{!!float!!}
+
+% #1 is the control sequence we are passed; we expand into a conditional
+% which is true if #1 represents a float ref. That is, the magic
+% \lastsection value which we \setref above.
+%
+\def\iffloat#1{\expandafter\doiffloat#1==\finish}
+%
+% #1 is (maybe) the \floatmagic string. If so, #2 will be the
+% (safe) float type for this float. We set \iffloattype to #2.
+%
+\def\doiffloat#1=#2=#3\finish{%
+ \def\temp{#1}%
+ \def\iffloattype{#2}%
+ \ifx\temp\floatmagic
+}
+
+% @listoffloats FLOATTYPE - print a list of floats like a table of contents.
+%
+\parseargdef\listoffloats{%
+ \def\floattype{#1}% floattype
+ {%
+ % the floattype might have accents or other special characters,
+ % but we need to use it in a control sequence name.
+ \indexnofonts
+ \turnoffactive
+ \xdef\safefloattype{\floattype}%
+ }%
+ %
+ % \xrdef saves the floats as a \do-list in \floatlistSAFEFLOATTYPE.
+ \expandafter\ifx\csname floatlist\safefloattype\endcsname \relax
+ \ifhavexrefs
+ % if the user said @listoffloats foo but never @float foo.
+ \message{\linenumber No `\safefloattype' floats to list.}%
+ \fi
+ \else
+ \begingroup
+ \leftskip=\tocindent % indent these entries like a toc
+ \let\do=\listoffloatsdo
+ \csname floatlist\safefloattype\endcsname
+ \endgroup
+ \fi
+}
+
+% This is called on each entry in a list of floats. We're passed the
+% xref label, in the form LABEL-title, which is how we save it in the
+% aux file. We strip off the -title and look up \XRLABEL-lof, which
+% has the text we're supposed to typeset here.
+%
+% Figures without xref labels will not be included in the list (since
+% they won't appear in the aux file).
+%
+\def\listoffloatsdo#1{\listoffloatsdoentry#1\finish}
+\def\listoffloatsdoentry#1-title\finish{{%
+ % Can't fully expand XR#1-lof because it can contain anything. Just
+ % pass the control sequence. On the other hand, XR#1-pg is just the
+ % page number, and we want to fully expand that so we can get a link
+ % in pdf output.
+ \toksA = \expandafter{\csname XR#1-lof\endcsname}%
+ %
+ % use the same \entry macro we use to generate the TOC and index.
+ \edef\writeentry{\noexpand\entry{\the\toksA}{\csname XR#1-pg\endcsname}}%
+ \writeentry
+}}
+
+
+\message{localization,}
+
+% For single-language documents, @documentlanguage is usually given very
+% early, just after @documentencoding. Single argument is the language
+% (de) or locale (de_DE) abbreviation.
+%
+{
+ \catcode`\_ = \active
+ \globaldefs=1
+\parseargdef\documentlanguage{\begingroup
+ \let_=\normalunderscore % normal _ character for filenames
+ \tex % read txi-??.tex file in plain TeX.
+ % Read the file by the name they passed if it exists.
+ \openin 1 txi-#1.tex
+ \ifeof 1
+ \documentlanguagetrywithoutunderscore{#1_\finish}%
+ \else
+ \globaldefs = 1 % everything in the txi-LL files needs to persist
+ \input txi-#1.tex
+ \fi
+ \closein 1
+ \endgroup % end raw TeX
+\endgroup}
+%
+% If they passed de_DE, and txi-de_DE.tex doesn't exist,
+% try txi-de.tex.
+%
+\gdef\documentlanguagetrywithoutunderscore#1_#2\finish{%
+ \openin 1 txi-#1.tex
+ \ifeof 1
+ \errhelp = \nolanghelp
+ \errmessage{Cannot read language file txi-#1.tex}%
+ \else
+ \globaldefs = 1 % everything in the txi-LL files needs to persist
+ \input txi-#1.tex
+ \fi
+ \closein 1
+}
+}% end of special _ catcode
+%
+\newhelp\nolanghelp{The given language definition file cannot be found or
+is empty. Maybe you need to install it? Putting it in the current
+directory should work if nowhere else does.}
+
+% This macro is called from txi-??.tex files; the first argument is the
+% \language name to set (without the "\lang@" prefix), the second and
+% third args are \{left,right}hyphenmin.
+%
+% The language names to pass are determined when the format is built.
+% See the etex.log file created at that time, e.g.,
+% /usr/local/texlive/2008/texmf-var/web2c/pdftex/etex.log.
+%
+% With TeX Live 2008, etex now includes hyphenation patterns for all
+% available languages. This means we can support hyphenation in
+% Texinfo, at least to some extent. (This still doesn't solve the
+% accented characters problem.)
+%
+\catcode`@=11
+\def\txisetlanguage#1#2#3{%
+ % do not set the language if the name is undefined in the current TeX.
+ \expandafter\ifx\csname lang@#1\endcsname \relax
+ \message{no patterns for #1}%
+ \else
+ \global\language = \csname lang@#1\endcsname
+ \fi
+ % but there is no harm in adjusting the hyphenmin values regardless.
+ \global\lefthyphenmin = #2\relax
+ \global\righthyphenmin = #3\relax
+}
+
+% Helpers for encodings.
+% Set the catcode of characters 128 through 255 to the specified number.
+%
+\def\setnonasciicharscatcode#1{%
+ \count255=128
+ \loop\ifnum\count255<256
+ \global\catcode\count255=#1\relax
+ \advance\count255 by 1
+ \repeat
+}
+
+\def\setnonasciicharscatcodenonglobal#1{%
+ \count255=128
+ \loop\ifnum\count255<256
+ \catcode\count255=#1\relax
+ \advance\count255 by 1
+ \repeat
+}
+
+% @documentencoding sets the definition of non-ASCII characters
+% according to the specified encoding.
+%
+\parseargdef\documentencoding{%
+ % Encoding being declared for the document.
+ \def\declaredencoding{\csname #1.enc\endcsname}%
+ %
+ % Supported encodings: names converted to tokens in order to be able
+ % to compare them with \ifx.
+ \def\ascii{\csname US-ASCII.enc\endcsname}%
+ \def\latnine{\csname ISO-8859-15.enc\endcsname}%
+ \def\latone{\csname ISO-8859-1.enc\endcsname}%
+ \def\lattwo{\csname ISO-8859-2.enc\endcsname}%
+ \def\utfeight{\csname UTF-8.enc\endcsname}%
+ %
+ \ifx \declaredencoding \ascii
+ \asciichardefs
+ %
+ \else \ifx \declaredencoding \lattwo
+ \setnonasciicharscatcode\active
+ \lattwochardefs
+ %
+ \else \ifx \declaredencoding \latone
+ \setnonasciicharscatcode\active
+ \latonechardefs
+ %
+ \else \ifx \declaredencoding \latnine
+ \setnonasciicharscatcode\active
+ \latninechardefs
+ %
+ \else \ifx \declaredencoding \utfeight
+ \setnonasciicharscatcode\active
+ \utfeightchardefs
+ %
+ \else
+ \message{Unknown document encoding #1, ignoring.}%
+ %
+ \fi % utfeight
+ \fi % latnine
+ \fi % latone
+ \fi % lattwo
+ \fi % ascii
+}
+
+% A message to be logged when using a character that isn't available
+% the default font encoding (OT1).
+%
+\def\missingcharmsg#1{\message{Character missing in OT1 encoding: #1.}}
+
+% Take account of \c (plain) vs. \, (Texinfo) difference.
+\def\cedilla#1{\ifx\c\ptexc\c{#1}\else\,{#1}\fi}
+
+% First, make active non-ASCII characters in order for them to be
+% correctly categorized when TeX reads the replacement text of
+% macros containing the character definitions.
+\setnonasciicharscatcode\active
+%
+% Latin1 (ISO-8859-1) character definitions.
+\def\latonechardefs{%
+ \gdef^^a0{\tie}
+ \gdef^^a1{\exclamdown}
+ \gdef^^a2{\missingcharmsg{CENT SIGN}}
+ \gdef^^a3{{\pounds}}
+ \gdef^^a4{\missingcharmsg{CURRENCY SIGN}}
+ \gdef^^a5{\missingcharmsg{YEN SIGN}}
+ \gdef^^a6{\missingcharmsg{BROKEN BAR}}
+ \gdef^^a7{\S}
+ \gdef^^a8{\"{}}
+ \gdef^^a9{\copyright}
+ \gdef^^aa{\ordf}
+ \gdef^^ab{\guillemetleft}
+ \gdef^^ac{$\lnot$}
+ \gdef^^ad{\-}
+ \gdef^^ae{\registeredsymbol}
+ \gdef^^af{\={}}
+ %
+ \gdef^^b0{\textdegree}
+ \gdef^^b1{$\pm$}
+ \gdef^^b2{$^2$}
+ \gdef^^b3{$^3$}
+ \gdef^^b4{\'{}}
+ \gdef^^b5{$\mu$}
+ \gdef^^b6{\P}
+ %
+ \gdef^^b7{$^.$}
+ \gdef^^b8{\cedilla\ }
+ \gdef^^b9{$^1$}
+ \gdef^^ba{\ordm}
+ %
+ \gdef^^bb{\guillemetright}
+ \gdef^^bc{$1\over4$}
+ \gdef^^bd{$1\over2$}
+ \gdef^^be{$3\over4$}
+ \gdef^^bf{\questiondown}
+ %
+ \gdef^^c0{\`A}
+ \gdef^^c1{\'A}
+ \gdef^^c2{\^A}
+ \gdef^^c3{\~A}
+ \gdef^^c4{\"A}
+ \gdef^^c5{\ringaccent A}
+ \gdef^^c6{\AE}
+ \gdef^^c7{\cedilla C}
+ \gdef^^c8{\`E}
+ \gdef^^c9{\'E}
+ \gdef^^ca{\^E}
+ \gdef^^cb{\"E}
+ \gdef^^cc{\`I}
+ \gdef^^cd{\'I}
+ \gdef^^ce{\^I}
+ \gdef^^cf{\"I}
+ %
+ \gdef^^d0{\DH}
+ \gdef^^d1{\~N}
+ \gdef^^d2{\`O}
+ \gdef^^d3{\'O}
+ \gdef^^d4{\^O}
+ \gdef^^d5{\~O}
+ \gdef^^d6{\"O}
+ \gdef^^d7{$\times$}
+ \gdef^^d8{\O}
+ \gdef^^d9{\`U}
+ \gdef^^da{\'U}
+ \gdef^^db{\^U}
+ \gdef^^dc{\"U}
+ \gdef^^dd{\'Y}
+ \gdef^^de{\TH}
+ \gdef^^df{\ss}
+ %
+ \gdef^^e0{\`a}
+ \gdef^^e1{\'a}
+ \gdef^^e2{\^a}
+ \gdef^^e3{\~a}
+ \gdef^^e4{\"a}
+ \gdef^^e5{\ringaccent a}
+ \gdef^^e6{\ae}
+ \gdef^^e7{\cedilla c}
+ \gdef^^e8{\`e}
+ \gdef^^e9{\'e}
+ \gdef^^ea{\^e}
+ \gdef^^eb{\"e}
+ \gdef^^ec{\`{\dotless i}}
+ \gdef^^ed{\'{\dotless i}}
+ \gdef^^ee{\^{\dotless i}}
+ \gdef^^ef{\"{\dotless i}}
+ %
+ \gdef^^f0{\dh}
+ \gdef^^f1{\~n}
+ \gdef^^f2{\`o}
+ \gdef^^f3{\'o}
+ \gdef^^f4{\^o}
+ \gdef^^f5{\~o}
+ \gdef^^f6{\"o}
+ \gdef^^f7{$\div$}
+ \gdef^^f8{\o}
+ \gdef^^f9{\`u}
+ \gdef^^fa{\'u}
+ \gdef^^fb{\^u}
+ \gdef^^fc{\"u}
+ \gdef^^fd{\'y}
+ \gdef^^fe{\th}
+ \gdef^^ff{\"y}
+}
+
+% Latin9 (ISO-8859-15) encoding character definitions.
+\def\latninechardefs{%
+ % Encoding is almost identical to Latin1.
+ \latonechardefs
+ %
+ \gdef^^a4{\euro}
+ \gdef^^a6{\v S}
+ \gdef^^a8{\v s}
+ \gdef^^b4{\v Z}
+ \gdef^^b8{\v z}
+ \gdef^^bc{\OE}
+ \gdef^^bd{\oe}
+ \gdef^^be{\"Y}
+}
+
+% Latin2 (ISO-8859-2) character definitions.
+\def\lattwochardefs{%
+ \gdef^^a0{\tie}
+ \gdef^^a1{\ogonek{A}}
+ \gdef^^a2{\u{}}
+ \gdef^^a3{\L}
+ \gdef^^a4{\missingcharmsg{CURRENCY SIGN}}
+ \gdef^^a5{\v L}
+ \gdef^^a6{\'S}
+ \gdef^^a7{\S}
+ \gdef^^a8{\"{}}
+ \gdef^^a9{\v S}
+ \gdef^^aa{\cedilla S}
+ \gdef^^ab{\v T}
+ \gdef^^ac{\'Z}
+ \gdef^^ad{\-}
+ \gdef^^ae{\v Z}
+ \gdef^^af{\dotaccent Z}
+ %
+ \gdef^^b0{\textdegree}
+ \gdef^^b1{\ogonek{a}}
+ \gdef^^b2{\ogonek{ }}
+ \gdef^^b3{\l}
+ \gdef^^b4{\'{}}
+ \gdef^^b5{\v l}
+ \gdef^^b6{\'s}
+ \gdef^^b7{\v{}}
+ \gdef^^b8{\cedilla\ }
+ \gdef^^b9{\v s}
+ \gdef^^ba{\cedilla s}
+ \gdef^^bb{\v t}
+ \gdef^^bc{\'z}
+ \gdef^^bd{\H{}}
+ \gdef^^be{\v z}
+ \gdef^^bf{\dotaccent z}
+ %
+ \gdef^^c0{\'R}
+ \gdef^^c1{\'A}
+ \gdef^^c2{\^A}
+ \gdef^^c3{\u A}
+ \gdef^^c4{\"A}
+ \gdef^^c5{\'L}
+ \gdef^^c6{\'C}
+ \gdef^^c7{\cedilla C}
+ \gdef^^c8{\v C}
+ \gdef^^c9{\'E}
+ \gdef^^ca{\ogonek{E}}
+ \gdef^^cb{\"E}
+ \gdef^^cc{\v E}
+ \gdef^^cd{\'I}
+ \gdef^^ce{\^I}
+ \gdef^^cf{\v D}
+ %
+ \gdef^^d0{\DH}
+ \gdef^^d1{\'N}
+ \gdef^^d2{\v N}
+ \gdef^^d3{\'O}
+ \gdef^^d4{\^O}
+ \gdef^^d5{\H O}
+ \gdef^^d6{\"O}
+ \gdef^^d7{$\times$}
+ \gdef^^d8{\v R}
+ \gdef^^d9{\ringaccent U}
+ \gdef^^da{\'U}
+ \gdef^^db{\H U}
+ \gdef^^dc{\"U}
+ \gdef^^dd{\'Y}
+ \gdef^^de{\cedilla T}
+ \gdef^^df{\ss}
+ %
+ \gdef^^e0{\'r}
+ \gdef^^e1{\'a}
+ \gdef^^e2{\^a}
+ \gdef^^e3{\u a}
+ \gdef^^e4{\"a}
+ \gdef^^e5{\'l}
+ \gdef^^e6{\'c}
+ \gdef^^e7{\cedilla c}
+ \gdef^^e8{\v c}
+ \gdef^^e9{\'e}
+ \gdef^^ea{\ogonek{e}}
+ \gdef^^eb{\"e}
+ \gdef^^ec{\v e}
+ \gdef^^ed{\'{\dotless{i}}}
+ \gdef^^ee{\^{\dotless{i}}}
+ \gdef^^ef{\v d}
+ %
+ \gdef^^f0{\dh}
+ \gdef^^f1{\'n}
+ \gdef^^f2{\v n}
+ \gdef^^f3{\'o}
+ \gdef^^f4{\^o}
+ \gdef^^f5{\H o}
+ \gdef^^f6{\"o}
+ \gdef^^f7{$\div$}
+ \gdef^^f8{\v r}
+ \gdef^^f9{\ringaccent u}
+ \gdef^^fa{\'u}
+ \gdef^^fb{\H u}
+ \gdef^^fc{\"u}
+ \gdef^^fd{\'y}
+ \gdef^^fe{\cedilla t}
+ \gdef^^ff{\dotaccent{}}
+}
+
+% UTF-8 character definitions.
+%
+% This code to support UTF-8 is based on LaTeX's utf8.def, with some
+% changes for Texinfo conventions. It is included here under the GPL by
+% permission from Frank Mittelbach and the LaTeX team.
+%
+\newcount\countUTFx
+\newcount\countUTFy
+\newcount\countUTFz
+
+\gdef\UTFviiiTwoOctets#1#2{\expandafter
+ \UTFviiiDefined\csname u8:#1\string #2\endcsname}
+%
+\gdef\UTFviiiThreeOctets#1#2#3{\expandafter
+ \UTFviiiDefined\csname u8:#1\string #2\string #3\endcsname}
+%
+\gdef\UTFviiiFourOctets#1#2#3#4{\expandafter
+ \UTFviiiDefined\csname u8:#1\string #2\string #3\string #4\endcsname}
+
+\gdef\UTFviiiDefined#1{%
+ \ifx #1\relax
+ \message{\linenumber Unicode char \string #1 not defined for Texinfo}%
+ \else
+ \expandafter #1%
+ \fi
+}
+
+\begingroup
+ \catcode`\~13
+ \catcode`\"12
+
+ \def\UTFviiiLoop{%
+ \global\catcode\countUTFx\active
+ \uccode`\~\countUTFx
+ \uppercase\expandafter{\UTFviiiTmp}%
+ \advance\countUTFx by 1
+ \ifnum\countUTFx < \countUTFy
+ \expandafter\UTFviiiLoop
+ \fi}
+
+ \countUTFx = "C2
+ \countUTFy = "E0
+ \def\UTFviiiTmp{%
+ \xdef~{\noexpand\UTFviiiTwoOctets\string~}}
+ \UTFviiiLoop
+
+ \countUTFx = "E0
+ \countUTFy = "F0
+ \def\UTFviiiTmp{%
+ \xdef~{\noexpand\UTFviiiThreeOctets\string~}}
+ \UTFviiiLoop
+
+ \countUTFx = "F0
+ \countUTFy = "F4
+ \def\UTFviiiTmp{%
+ \xdef~{\noexpand\UTFviiiFourOctets\string~}}
+ \UTFviiiLoop
+\endgroup
+
+\begingroup
+ \catcode`\"=12
+ \catcode`\<=12
+ \catcode`\.=12
+ \catcode`\,=12
+ \catcode`\;=12
+ \catcode`\!=12
+ \catcode`\~=13
+
+ \gdef\DeclareUnicodeCharacter#1#2{%
+ \countUTFz = "#1\relax
+ %\wlog{\space\space defining Unicode char U+#1 (decimal \the\countUTFz)}%
+ \begingroup
+ \parseXMLCharref
+ \def\UTFviiiTwoOctets##1##2{%
+ \csname u8:##1\string ##2\endcsname}%
+ \def\UTFviiiThreeOctets##1##2##3{%
+ \csname u8:##1\string ##2\string ##3\endcsname}%
+ \def\UTFviiiFourOctets##1##2##3##4{%
+ \csname u8:##1\string ##2\string ##3\string ##4\endcsname}%
+ \expandafter\expandafter\expandafter\expandafter
+ \expandafter\expandafter\expandafter
+ \gdef\UTFviiiTmp{#2}%
+ \endgroup}
+
+ \gdef\parseXMLCharref{%
+ \ifnum\countUTFz < "A0\relax
+ \errhelp = \EMsimple
+ \errmessage{Cannot define Unicode char value < 00A0}%
+ \else\ifnum\countUTFz < "800\relax
+ \parseUTFviiiA,%
+ \parseUTFviiiB C\UTFviiiTwoOctets.,%
+ \else\ifnum\countUTFz < "10000\relax
+ \parseUTFviiiA;%
+ \parseUTFviiiA,%
+ \parseUTFviiiB E\UTFviiiThreeOctets.{,;}%
+ \else
+ \parseUTFviiiA;%
+ \parseUTFviiiA,%
+ \parseUTFviiiA!%
+ \parseUTFviiiB F\UTFviiiFourOctets.{!,;}%
+ \fi\fi\fi
+ }
+
+ \gdef\parseUTFviiiA#1{%
+ \countUTFx = \countUTFz
+ \divide\countUTFz by 64
+ \countUTFy = \countUTFz
+ \multiply\countUTFz by 64
+ \advance\countUTFx by -\countUTFz
+ \advance\countUTFx by 128
+ \uccode `#1\countUTFx
+ \countUTFz = \countUTFy}
+
+ \gdef\parseUTFviiiB#1#2#3#4{%
+ \advance\countUTFz by "#10\relax
+ \uccode `#3\countUTFz
+ \uppercase{\gdef\UTFviiiTmp{#2#3#4}}}
+\endgroup
+
+\def\utfeightchardefs{%
+ \DeclareUnicodeCharacter{00A0}{\tie}
+ \DeclareUnicodeCharacter{00A1}{\exclamdown}
+ \DeclareUnicodeCharacter{00A3}{\pounds}
+ \DeclareUnicodeCharacter{00A8}{\"{ }}
+ \DeclareUnicodeCharacter{00A9}{\copyright}
+ \DeclareUnicodeCharacter{00AA}{\ordf}
+ \DeclareUnicodeCharacter{00AB}{\guillemetleft}
+ \DeclareUnicodeCharacter{00AD}{\-}
+ \DeclareUnicodeCharacter{00AE}{\registeredsymbol}
+ \DeclareUnicodeCharacter{00AF}{\={ }}
+
+ \DeclareUnicodeCharacter{00B0}{\ringaccent{ }}
+ \DeclareUnicodeCharacter{00B4}{\'{ }}
+ \DeclareUnicodeCharacter{00B8}{\cedilla{ }}
+ \DeclareUnicodeCharacter{00BA}{\ordm}
+ \DeclareUnicodeCharacter{00BB}{\guillemetright}
+ \DeclareUnicodeCharacter{00BF}{\questiondown}
+
+ \DeclareUnicodeCharacter{00C0}{\`A}
+ \DeclareUnicodeCharacter{00C1}{\'A}
+ \DeclareUnicodeCharacter{00C2}{\^A}
+ \DeclareUnicodeCharacter{00C3}{\~A}
+ \DeclareUnicodeCharacter{00C4}{\"A}
+ \DeclareUnicodeCharacter{00C5}{\AA}
+ \DeclareUnicodeCharacter{00C6}{\AE}
+ \DeclareUnicodeCharacter{00C7}{\cedilla{C}}
+ \DeclareUnicodeCharacter{00C8}{\`E}
+ \DeclareUnicodeCharacter{00C9}{\'E}
+ \DeclareUnicodeCharacter{00CA}{\^E}
+ \DeclareUnicodeCharacter{00CB}{\"E}
+ \DeclareUnicodeCharacter{00CC}{\`I}
+ \DeclareUnicodeCharacter{00CD}{\'I}
+ \DeclareUnicodeCharacter{00CE}{\^I}
+ \DeclareUnicodeCharacter{00CF}{\"I}
+
+ \DeclareUnicodeCharacter{00D0}{\DH}
+ \DeclareUnicodeCharacter{00D1}{\~N}
+ \DeclareUnicodeCharacter{00D2}{\`O}
+ \DeclareUnicodeCharacter{00D3}{\'O}
+ \DeclareUnicodeCharacter{00D4}{\^O}
+ \DeclareUnicodeCharacter{00D5}{\~O}
+ \DeclareUnicodeCharacter{00D6}{\"O}
+ \DeclareUnicodeCharacter{00D8}{\O}
+ \DeclareUnicodeCharacter{00D9}{\`U}
+ \DeclareUnicodeCharacter{00DA}{\'U}
+ \DeclareUnicodeCharacter{00DB}{\^U}
+ \DeclareUnicodeCharacter{00DC}{\"U}
+ \DeclareUnicodeCharacter{00DD}{\'Y}
+ \DeclareUnicodeCharacter{00DE}{\TH}
+ \DeclareUnicodeCharacter{00DF}{\ss}
+
+ \DeclareUnicodeCharacter{00E0}{\`a}
+ \DeclareUnicodeCharacter{00E1}{\'a}
+ \DeclareUnicodeCharacter{00E2}{\^a}
+ \DeclareUnicodeCharacter{00E3}{\~a}
+ \DeclareUnicodeCharacter{00E4}{\"a}
+ \DeclareUnicodeCharacter{00E5}{\aa}
+ \DeclareUnicodeCharacter{00E6}{\ae}
+ \DeclareUnicodeCharacter{00E7}{\cedilla{c}}
+ \DeclareUnicodeCharacter{00E8}{\`e}
+ \DeclareUnicodeCharacter{00E9}{\'e}
+ \DeclareUnicodeCharacter{00EA}{\^e}
+ \DeclareUnicodeCharacter{00EB}{\"e}
+ \DeclareUnicodeCharacter{00EC}{\`{\dotless{i}}}
+ \DeclareUnicodeCharacter{00ED}{\'{\dotless{i}}}
+ \DeclareUnicodeCharacter{00EE}{\^{\dotless{i}}}
+ \DeclareUnicodeCharacter{00EF}{\"{\dotless{i}}}
+
+ \DeclareUnicodeCharacter{00F0}{\dh}
+ \DeclareUnicodeCharacter{00F1}{\~n}
+ \DeclareUnicodeCharacter{00F2}{\`o}
+ \DeclareUnicodeCharacter{00F3}{\'o}
+ \DeclareUnicodeCharacter{00F4}{\^o}
+ \DeclareUnicodeCharacter{00F5}{\~o}
+ \DeclareUnicodeCharacter{00F6}{\"o}
+ \DeclareUnicodeCharacter{00F8}{\o}
+ \DeclareUnicodeCharacter{00F9}{\`u}
+ \DeclareUnicodeCharacter{00FA}{\'u}
+ \DeclareUnicodeCharacter{00FB}{\^u}
+ \DeclareUnicodeCharacter{00FC}{\"u}
+ \DeclareUnicodeCharacter{00FD}{\'y}
+ \DeclareUnicodeCharacter{00FE}{\th}
+ \DeclareUnicodeCharacter{00FF}{\"y}
+
+ \DeclareUnicodeCharacter{0100}{\=A}
+ \DeclareUnicodeCharacter{0101}{\=a}
+ \DeclareUnicodeCharacter{0102}{\u{A}}
+ \DeclareUnicodeCharacter{0103}{\u{a}}
+ \DeclareUnicodeCharacter{0104}{\ogonek{A}}
+ \DeclareUnicodeCharacter{0105}{\ogonek{a}}
+ \DeclareUnicodeCharacter{0106}{\'C}
+ \DeclareUnicodeCharacter{0107}{\'c}
+ \DeclareUnicodeCharacter{0108}{\^C}
+ \DeclareUnicodeCharacter{0109}{\^c}
+ \DeclareUnicodeCharacter{0118}{\ogonek{E}}
+ \DeclareUnicodeCharacter{0119}{\ogonek{e}}
+ \DeclareUnicodeCharacter{010A}{\dotaccent{C}}
+ \DeclareUnicodeCharacter{010B}{\dotaccent{c}}
+ \DeclareUnicodeCharacter{010C}{\v{C}}
+ \DeclareUnicodeCharacter{010D}{\v{c}}
+ \DeclareUnicodeCharacter{010E}{\v{D}}
+
+ \DeclareUnicodeCharacter{0112}{\=E}
+ \DeclareUnicodeCharacter{0113}{\=e}
+ \DeclareUnicodeCharacter{0114}{\u{E}}
+ \DeclareUnicodeCharacter{0115}{\u{e}}
+ \DeclareUnicodeCharacter{0116}{\dotaccent{E}}
+ \DeclareUnicodeCharacter{0117}{\dotaccent{e}}
+ \DeclareUnicodeCharacter{011A}{\v{E}}
+ \DeclareUnicodeCharacter{011B}{\v{e}}
+ \DeclareUnicodeCharacter{011C}{\^G}
+ \DeclareUnicodeCharacter{011D}{\^g}
+ \DeclareUnicodeCharacter{011E}{\u{G}}
+ \DeclareUnicodeCharacter{011F}{\u{g}}
+
+ \DeclareUnicodeCharacter{0120}{\dotaccent{G}}
+ \DeclareUnicodeCharacter{0121}{\dotaccent{g}}
+ \DeclareUnicodeCharacter{0124}{\^H}
+ \DeclareUnicodeCharacter{0125}{\^h}
+ \DeclareUnicodeCharacter{0128}{\~I}
+ \DeclareUnicodeCharacter{0129}{\~{\dotless{i}}}
+ \DeclareUnicodeCharacter{012A}{\=I}
+ \DeclareUnicodeCharacter{012B}{\={\dotless{i}}}
+ \DeclareUnicodeCharacter{012C}{\u{I}}
+ \DeclareUnicodeCharacter{012D}{\u{\dotless{i}}}
+
+ \DeclareUnicodeCharacter{0130}{\dotaccent{I}}
+ \DeclareUnicodeCharacter{0131}{\dotless{i}}
+ \DeclareUnicodeCharacter{0132}{IJ}
+ \DeclareUnicodeCharacter{0133}{ij}
+ \DeclareUnicodeCharacter{0134}{\^J}
+ \DeclareUnicodeCharacter{0135}{\^{\dotless{j}}}
+ \DeclareUnicodeCharacter{0139}{\'L}
+ \DeclareUnicodeCharacter{013A}{\'l}
+
+ \DeclareUnicodeCharacter{0141}{\L}
+ \DeclareUnicodeCharacter{0142}{\l}
+ \DeclareUnicodeCharacter{0143}{\'N}
+ \DeclareUnicodeCharacter{0144}{\'n}
+ \DeclareUnicodeCharacter{0147}{\v{N}}
+ \DeclareUnicodeCharacter{0148}{\v{n}}
+ \DeclareUnicodeCharacter{014C}{\=O}
+ \DeclareUnicodeCharacter{014D}{\=o}
+ \DeclareUnicodeCharacter{014E}{\u{O}}
+ \DeclareUnicodeCharacter{014F}{\u{o}}
+
+ \DeclareUnicodeCharacter{0150}{\H{O}}
+ \DeclareUnicodeCharacter{0151}{\H{o}}
+ \DeclareUnicodeCharacter{0152}{\OE}
+ \DeclareUnicodeCharacter{0153}{\oe}
+ \DeclareUnicodeCharacter{0154}{\'R}
+ \DeclareUnicodeCharacter{0155}{\'r}
+ \DeclareUnicodeCharacter{0158}{\v{R}}
+ \DeclareUnicodeCharacter{0159}{\v{r}}
+ \DeclareUnicodeCharacter{015A}{\'S}
+ \DeclareUnicodeCharacter{015B}{\'s}
+ \DeclareUnicodeCharacter{015C}{\^S}
+ \DeclareUnicodeCharacter{015D}{\^s}
+ \DeclareUnicodeCharacter{015E}{\cedilla{S}}
+ \DeclareUnicodeCharacter{015F}{\cedilla{s}}
+
+ \DeclareUnicodeCharacter{0160}{\v{S}}
+ \DeclareUnicodeCharacter{0161}{\v{s}}
+ \DeclareUnicodeCharacter{0162}{\cedilla{t}}
+ \DeclareUnicodeCharacter{0163}{\cedilla{T}}
+ \DeclareUnicodeCharacter{0164}{\v{T}}
+
+ \DeclareUnicodeCharacter{0168}{\~U}
+ \DeclareUnicodeCharacter{0169}{\~u}
+ \DeclareUnicodeCharacter{016A}{\=U}
+ \DeclareUnicodeCharacter{016B}{\=u}
+ \DeclareUnicodeCharacter{016C}{\u{U}}
+ \DeclareUnicodeCharacter{016D}{\u{u}}
+ \DeclareUnicodeCharacter{016E}{\ringaccent{U}}
+ \DeclareUnicodeCharacter{016F}{\ringaccent{u}}
+
+ \DeclareUnicodeCharacter{0170}{\H{U}}
+ \DeclareUnicodeCharacter{0171}{\H{u}}
+ \DeclareUnicodeCharacter{0174}{\^W}
+ \DeclareUnicodeCharacter{0175}{\^w}
+ \DeclareUnicodeCharacter{0176}{\^Y}
+ \DeclareUnicodeCharacter{0177}{\^y}
+ \DeclareUnicodeCharacter{0178}{\"Y}
+ \DeclareUnicodeCharacter{0179}{\'Z}
+ \DeclareUnicodeCharacter{017A}{\'z}
+ \DeclareUnicodeCharacter{017B}{\dotaccent{Z}}
+ \DeclareUnicodeCharacter{017C}{\dotaccent{z}}
+ \DeclareUnicodeCharacter{017D}{\v{Z}}
+ \DeclareUnicodeCharacter{017E}{\v{z}}
+
+ \DeclareUnicodeCharacter{01C4}{D\v{Z}}
+ \DeclareUnicodeCharacter{01C5}{D\v{z}}
+ \DeclareUnicodeCharacter{01C6}{d\v{z}}
+ \DeclareUnicodeCharacter{01C7}{LJ}
+ \DeclareUnicodeCharacter{01C8}{Lj}
+ \DeclareUnicodeCharacter{01C9}{lj}
+ \DeclareUnicodeCharacter{01CA}{NJ}
+ \DeclareUnicodeCharacter{01CB}{Nj}
+ \DeclareUnicodeCharacter{01CC}{nj}
+ \DeclareUnicodeCharacter{01CD}{\v{A}}
+ \DeclareUnicodeCharacter{01CE}{\v{a}}
+ \DeclareUnicodeCharacter{01CF}{\v{I}}
+
+ \DeclareUnicodeCharacter{01D0}{\v{\dotless{i}}}
+ \DeclareUnicodeCharacter{01D1}{\v{O}}
+ \DeclareUnicodeCharacter{01D2}{\v{o}}
+ \DeclareUnicodeCharacter{01D3}{\v{U}}
+ \DeclareUnicodeCharacter{01D4}{\v{u}}
+
+ \DeclareUnicodeCharacter{01E2}{\={\AE}}
+ \DeclareUnicodeCharacter{01E3}{\={\ae}}
+ \DeclareUnicodeCharacter{01E6}{\v{G}}
+ \DeclareUnicodeCharacter{01E7}{\v{g}}
+ \DeclareUnicodeCharacter{01E8}{\v{K}}
+ \DeclareUnicodeCharacter{01E9}{\v{k}}
+
+ \DeclareUnicodeCharacter{01F0}{\v{\dotless{j}}}
+ \DeclareUnicodeCharacter{01F1}{DZ}
+ \DeclareUnicodeCharacter{01F2}{Dz}
+ \DeclareUnicodeCharacter{01F3}{dz}
+ \DeclareUnicodeCharacter{01F4}{\'G}
+ \DeclareUnicodeCharacter{01F5}{\'g}
+ \DeclareUnicodeCharacter{01F8}{\`N}
+ \DeclareUnicodeCharacter{01F9}{\`n}
+ \DeclareUnicodeCharacter{01FC}{\'{\AE}}
+ \DeclareUnicodeCharacter{01FD}{\'{\ae}}
+ \DeclareUnicodeCharacter{01FE}{\'{\O}}
+ \DeclareUnicodeCharacter{01FF}{\'{\o}}
+
+ \DeclareUnicodeCharacter{021E}{\v{H}}
+ \DeclareUnicodeCharacter{021F}{\v{h}}
+
+ \DeclareUnicodeCharacter{0226}{\dotaccent{A}}
+ \DeclareUnicodeCharacter{0227}{\dotaccent{a}}
+ \DeclareUnicodeCharacter{0228}{\cedilla{E}}
+ \DeclareUnicodeCharacter{0229}{\cedilla{e}}
+ \DeclareUnicodeCharacter{022E}{\dotaccent{O}}
+ \DeclareUnicodeCharacter{022F}{\dotaccent{o}}
+
+ \DeclareUnicodeCharacter{0232}{\=Y}
+ \DeclareUnicodeCharacter{0233}{\=y}
+ \DeclareUnicodeCharacter{0237}{\dotless{j}}
+
+ \DeclareUnicodeCharacter{02DB}{\ogonek{ }}
+
+ \DeclareUnicodeCharacter{1E02}{\dotaccent{B}}
+ \DeclareUnicodeCharacter{1E03}{\dotaccent{b}}
+ \DeclareUnicodeCharacter{1E04}{\udotaccent{B}}
+ \DeclareUnicodeCharacter{1E05}{\udotaccent{b}}
+ \DeclareUnicodeCharacter{1E06}{\ubaraccent{B}}
+ \DeclareUnicodeCharacter{1E07}{\ubaraccent{b}}
+ \DeclareUnicodeCharacter{1E0A}{\dotaccent{D}}
+ \DeclareUnicodeCharacter{1E0B}{\dotaccent{d}}
+ \DeclareUnicodeCharacter{1E0C}{\udotaccent{D}}
+ \DeclareUnicodeCharacter{1E0D}{\udotaccent{d}}
+ \DeclareUnicodeCharacter{1E0E}{\ubaraccent{D}}
+ \DeclareUnicodeCharacter{1E0F}{\ubaraccent{d}}
+
+ \DeclareUnicodeCharacter{1E1E}{\dotaccent{F}}
+ \DeclareUnicodeCharacter{1E1F}{\dotaccent{f}}
+
+ \DeclareUnicodeCharacter{1E20}{\=G}
+ \DeclareUnicodeCharacter{1E21}{\=g}
+ \DeclareUnicodeCharacter{1E22}{\dotaccent{H}}
+ \DeclareUnicodeCharacter{1E23}{\dotaccent{h}}
+ \DeclareUnicodeCharacter{1E24}{\udotaccent{H}}
+ \DeclareUnicodeCharacter{1E25}{\udotaccent{h}}
+ \DeclareUnicodeCharacter{1E26}{\"H}
+ \DeclareUnicodeCharacter{1E27}{\"h}
+
+ \DeclareUnicodeCharacter{1E30}{\'K}
+ \DeclareUnicodeCharacter{1E31}{\'k}
+ \DeclareUnicodeCharacter{1E32}{\udotaccent{K}}
+ \DeclareUnicodeCharacter{1E33}{\udotaccent{k}}
+ \DeclareUnicodeCharacter{1E34}{\ubaraccent{K}}
+ \DeclareUnicodeCharacter{1E35}{\ubaraccent{k}}
+ \DeclareUnicodeCharacter{1E36}{\udotaccent{L}}
+ \DeclareUnicodeCharacter{1E37}{\udotaccent{l}}
+ \DeclareUnicodeCharacter{1E3A}{\ubaraccent{L}}
+ \DeclareUnicodeCharacter{1E3B}{\ubaraccent{l}}
+ \DeclareUnicodeCharacter{1E3E}{\'M}
+ \DeclareUnicodeCharacter{1E3F}{\'m}
+
+ \DeclareUnicodeCharacter{1E40}{\dotaccent{M}}
+ \DeclareUnicodeCharacter{1E41}{\dotaccent{m}}
+ \DeclareUnicodeCharacter{1E42}{\udotaccent{M}}
+ \DeclareUnicodeCharacter{1E43}{\udotaccent{m}}
+ \DeclareUnicodeCharacter{1E44}{\dotaccent{N}}
+ \DeclareUnicodeCharacter{1E45}{\dotaccent{n}}
+ \DeclareUnicodeCharacter{1E46}{\udotaccent{N}}
+ \DeclareUnicodeCharacter{1E47}{\udotaccent{n}}
+ \DeclareUnicodeCharacter{1E48}{\ubaraccent{N}}
+ \DeclareUnicodeCharacter{1E49}{\ubaraccent{n}}
+
+ \DeclareUnicodeCharacter{1E54}{\'P}
+ \DeclareUnicodeCharacter{1E55}{\'p}
+ \DeclareUnicodeCharacter{1E56}{\dotaccent{P}}
+ \DeclareUnicodeCharacter{1E57}{\dotaccent{p}}
+ \DeclareUnicodeCharacter{1E58}{\dotaccent{R}}
+ \DeclareUnicodeCharacter{1E59}{\dotaccent{r}}
+ \DeclareUnicodeCharacter{1E5A}{\udotaccent{R}}
+ \DeclareUnicodeCharacter{1E5B}{\udotaccent{r}}
+ \DeclareUnicodeCharacter{1E5E}{\ubaraccent{R}}
+ \DeclareUnicodeCharacter{1E5F}{\ubaraccent{r}}
+
+ \DeclareUnicodeCharacter{1E60}{\dotaccent{S}}
+ \DeclareUnicodeCharacter{1E61}{\dotaccent{s}}
+ \DeclareUnicodeCharacter{1E62}{\udotaccent{S}}
+ \DeclareUnicodeCharacter{1E63}{\udotaccent{s}}
+ \DeclareUnicodeCharacter{1E6A}{\dotaccent{T}}
+ \DeclareUnicodeCharacter{1E6B}{\dotaccent{t}}
+ \DeclareUnicodeCharacter{1E6C}{\udotaccent{T}}
+ \DeclareUnicodeCharacter{1E6D}{\udotaccent{t}}
+ \DeclareUnicodeCharacter{1E6E}{\ubaraccent{T}}
+ \DeclareUnicodeCharacter{1E6F}{\ubaraccent{t}}
+
+ \DeclareUnicodeCharacter{1E7C}{\~V}
+ \DeclareUnicodeCharacter{1E7D}{\~v}
+ \DeclareUnicodeCharacter{1E7E}{\udotaccent{V}}
+ \DeclareUnicodeCharacter{1E7F}{\udotaccent{v}}
+
+ \DeclareUnicodeCharacter{1E80}{\`W}
+ \DeclareUnicodeCharacter{1E81}{\`w}
+ \DeclareUnicodeCharacter{1E82}{\'W}
+ \DeclareUnicodeCharacter{1E83}{\'w}
+ \DeclareUnicodeCharacter{1E84}{\"W}
+ \DeclareUnicodeCharacter{1E85}{\"w}
+ \DeclareUnicodeCharacter{1E86}{\dotaccent{W}}
+ \DeclareUnicodeCharacter{1E87}{\dotaccent{w}}
+ \DeclareUnicodeCharacter{1E88}{\udotaccent{W}}
+ \DeclareUnicodeCharacter{1E89}{\udotaccent{w}}
+ \DeclareUnicodeCharacter{1E8A}{\dotaccent{X}}
+ \DeclareUnicodeCharacter{1E8B}{\dotaccent{x}}
+ \DeclareUnicodeCharacter{1E8C}{\"X}
+ \DeclareUnicodeCharacter{1E8D}{\"x}
+ \DeclareUnicodeCharacter{1E8E}{\dotaccent{Y}}
+ \DeclareUnicodeCharacter{1E8F}{\dotaccent{y}}
+
+ \DeclareUnicodeCharacter{1E90}{\^Z}
+ \DeclareUnicodeCharacter{1E91}{\^z}
+ \DeclareUnicodeCharacter{1E92}{\udotaccent{Z}}
+ \DeclareUnicodeCharacter{1E93}{\udotaccent{z}}
+ \DeclareUnicodeCharacter{1E94}{\ubaraccent{Z}}
+ \DeclareUnicodeCharacter{1E95}{\ubaraccent{z}}
+ \DeclareUnicodeCharacter{1E96}{\ubaraccent{h}}
+ \DeclareUnicodeCharacter{1E97}{\"t}
+ \DeclareUnicodeCharacter{1E98}{\ringaccent{w}}
+ \DeclareUnicodeCharacter{1E99}{\ringaccent{y}}
+
+ \DeclareUnicodeCharacter{1EA0}{\udotaccent{A}}
+ \DeclareUnicodeCharacter{1EA1}{\udotaccent{a}}
+
+ \DeclareUnicodeCharacter{1EB8}{\udotaccent{E}}
+ \DeclareUnicodeCharacter{1EB9}{\udotaccent{e}}
+ \DeclareUnicodeCharacter{1EBC}{\~E}
+ \DeclareUnicodeCharacter{1EBD}{\~e}
+
+ \DeclareUnicodeCharacter{1ECA}{\udotaccent{I}}
+ \DeclareUnicodeCharacter{1ECB}{\udotaccent{i}}
+ \DeclareUnicodeCharacter{1ECC}{\udotaccent{O}}
+ \DeclareUnicodeCharacter{1ECD}{\udotaccent{o}}
+
+ \DeclareUnicodeCharacter{1EE4}{\udotaccent{U}}
+ \DeclareUnicodeCharacter{1EE5}{\udotaccent{u}}
+
+ \DeclareUnicodeCharacter{1EF2}{\`Y}
+ \DeclareUnicodeCharacter{1EF3}{\`y}
+ \DeclareUnicodeCharacter{1EF4}{\udotaccent{Y}}
+
+ \DeclareUnicodeCharacter{1EF8}{\~Y}
+ \DeclareUnicodeCharacter{1EF9}{\~y}
+
+ \DeclareUnicodeCharacter{2013}{--}
+ \DeclareUnicodeCharacter{2014}{---}
+ \DeclareUnicodeCharacter{2018}{\quoteleft}
+ \DeclareUnicodeCharacter{2019}{\quoteright}
+ \DeclareUnicodeCharacter{201A}{\quotesinglbase}
+ \DeclareUnicodeCharacter{201C}{\quotedblleft}
+ \DeclareUnicodeCharacter{201D}{\quotedblright}
+ \DeclareUnicodeCharacter{201E}{\quotedblbase}
+ \DeclareUnicodeCharacter{2022}{\bullet}
+ \DeclareUnicodeCharacter{2026}{\dots}
+ \DeclareUnicodeCharacter{2039}{\guilsinglleft}
+ \DeclareUnicodeCharacter{203A}{\guilsinglright}
+ \DeclareUnicodeCharacter{20AC}{\euro}
+
+ \DeclareUnicodeCharacter{2192}{\expansion}
+ \DeclareUnicodeCharacter{21D2}{\result}
+
+ \DeclareUnicodeCharacter{2212}{\minus}
+ \DeclareUnicodeCharacter{2217}{\point}
+ \DeclareUnicodeCharacter{2261}{\equiv}
+}% end of \utfeightchardefs
+
+
+% US-ASCII character definitions.
+\def\asciichardefs{% nothing need be done
+ \relax
+}
+
+% Make non-ASCII characters printable again for compatibility with
+% existing Texinfo documents that may use them, even without declaring a
+% document encoding.
+%
+\setnonasciicharscatcode \other
+
+
+\message{formatting,}
+
+\newdimen\defaultparindent \defaultparindent = 15pt
+
+\chapheadingskip = 15pt plus 4pt minus 2pt
+\secheadingskip = 12pt plus 3pt minus 2pt
+\subsecheadingskip = 9pt plus 2pt minus 2pt
+
+% Prevent underfull vbox error messages.
+\vbadness = 10000
+
+% Don't be very finicky about underfull hboxes, either.
+\hbadness = 6666
+
+% Following George Bush, get rid of widows and orphans.
+\widowpenalty=10000
+\clubpenalty=10000
+
+% Use TeX 3.0's \emergencystretch to help line breaking, but if we're
+% using an old version of TeX, don't do anything. We want the amount of
+% stretch added to depend on the line length, hence the dependence on
+% \hsize. We call this whenever the paper size is set.
+%
+\def\setemergencystretch{%
+ \ifx\emergencystretch\thisisundefined
+ % Allow us to assign to \emergencystretch anyway.
+ \def\emergencystretch{\dimen0}%
+ \else
+ \emergencystretch = .15\hsize
+ \fi
+}
+
+% Parameters in order: 1) textheight; 2) textwidth;
+% 3) voffset; 4) hoffset; 5) binding offset; 6) topskip;
+% 7) physical page height; 8) physical page width.
+%
+% We also call \setleading{\textleading}, so the caller should define
+% \textleading. The caller should also set \parskip.
+%
+\def\internalpagesizes#1#2#3#4#5#6#7#8{%
+ \voffset = #3\relax
+ \topskip = #6\relax
+ \splittopskip = \topskip
+ %
+ \vsize = #1\relax
+ \advance\vsize by \topskip
+ \outervsize = \vsize
+ \advance\outervsize by 2\topandbottommargin
+ \pageheight = \vsize
+ %
+ \hsize = #2\relax
+ \outerhsize = \hsize
+ \advance\outerhsize by 0.5in
+ \pagewidth = \hsize
+ %
+ \normaloffset = #4\relax
+ \bindingoffset = #5\relax
+ %
+ \ifpdf
+ \pdfpageheight #7\relax
+ \pdfpagewidth #8\relax
+ % if we don't reset these, they will remain at "1 true in" of
+ % whatever layout pdftex was dumped with.
+ \pdfhorigin = 1 true in
+ \pdfvorigin = 1 true in
+ \fi
+ %
+ \setleading{\textleading}
+ %
+ \parindent = \defaultparindent
+ \setemergencystretch
+}
+
+% @letterpaper (the default).
+\def\letterpaper{{\globaldefs = 1
+ \parskip = 3pt plus 2pt minus 1pt
+ \textleading = 13.2pt
+ %
+ % If page is nothing but text, make it come out even.
+ \internalpagesizes{607.2pt}{6in}% that's 46 lines
+ {\voffset}{.25in}%
+ {\bindingoffset}{36pt}%
+ {11in}{8.5in}%
+}}
+
+% Use @smallbook to reset parameters for 7x9.25 trim size.
+\def\smallbook{{\globaldefs = 1
+ \parskip = 2pt plus 1pt
+ \textleading = 12pt
+ %
+ \internalpagesizes{7.5in}{5in}%
+ {-.2in}{0in}%
+ {\bindingoffset}{16pt}%
+ {9.25in}{7in}%
+ %
+ \lispnarrowing = 0.3in
+ \tolerance = 700
+ \hfuzz = 1pt
+ \contentsrightmargin = 0pt
+ \defbodyindent = .5cm
+}}
+
+% Use @smallerbook to reset parameters for 6x9 trim size.
+% (Just testing, parameters still in flux.)
+\def\smallerbook{{\globaldefs = 1
+ \parskip = 1.5pt plus 1pt
+ \textleading = 12pt
+ %
+ \internalpagesizes{7.4in}{4.8in}%
+ {-.2in}{-.4in}%
+ {0pt}{14pt}%
+ {9in}{6in}%
+ %
+ \lispnarrowing = 0.25in
+ \tolerance = 700
+ \hfuzz = 1pt
+ \contentsrightmargin = 0pt
+ \defbodyindent = .4cm
+}}
+
+% Use @afourpaper to print on European A4 paper.
+\def\afourpaper{{\globaldefs = 1
+ \parskip = 3pt plus 2pt minus 1pt
+ \textleading = 13.2pt
+ %
+ % Double-side printing via postscript on Laserjet 4050
+ % prints double-sided nicely when \bindingoffset=10mm and \hoffset=-6mm.
+ % To change the settings for a different printer or situation, adjust
+ % \normaloffset until the front-side and back-side texts align. Then
+ % do the same for \bindingoffset. You can set these for testing in
+ % your texinfo source file like this:
+ % @tex
+ % \global\normaloffset = -6mm
+ % \global\bindingoffset = 10mm
+ % @end tex
+ \internalpagesizes{673.2pt}{160mm}% that's 51 lines
+ {\voffset}{\hoffset}%
+ {\bindingoffset}{44pt}%
+ {297mm}{210mm}%
+ %
+ \tolerance = 700
+ \hfuzz = 1pt
+ \contentsrightmargin = 0pt
+ \defbodyindent = 5mm
+}}
+
+% Use @afivepaper to print on European A5 paper.
+% From romildo@urano.iceb.ufop.br, 2 July 2000.
+% He also recommends making @example and @lisp be small.
+\def\afivepaper{{\globaldefs = 1
+ \parskip = 2pt plus 1pt minus 0.1pt
+ \textleading = 12.5pt
+ %
+ \internalpagesizes{160mm}{120mm}%
+ {\voffset}{\hoffset}%
+ {\bindingoffset}{8pt}%
+ {210mm}{148mm}%
+ %
+ \lispnarrowing = 0.2in
+ \tolerance = 800
+ \hfuzz = 1.2pt
+ \contentsrightmargin = 0pt
+ \defbodyindent = 2mm
+ \tableindent = 12mm
+}}
+
+% A specific text layout, 24x15cm overall, intended for A4 paper.
+\def\afourlatex{{\globaldefs = 1
+ \afourpaper
+ \internalpagesizes{237mm}{150mm}%
+ {\voffset}{4.6mm}%
+ {\bindingoffset}{7mm}%
+ {297mm}{210mm}%
+ %
+ % Must explicitly reset to 0 because we call \afourpaper.
+ \globaldefs = 0
+}}
+
+% Use @afourwide to print on A4 paper in landscape format.
+\def\afourwide{{\globaldefs = 1
+ \afourpaper
+ \internalpagesizes{241mm}{165mm}%
+ {\voffset}{-2.95mm}%
+ {\bindingoffset}{7mm}%
+ {297mm}{210mm}%
+ \globaldefs = 0
+}}
+
+% @pagesizes TEXTHEIGHT[,TEXTWIDTH]
+% Perhaps we should allow setting the margins, \topskip, \parskip,
+% and/or leading, also. Or perhaps we should compute them somehow.
+%
+\parseargdef\pagesizes{\pagesizesyyy #1,,\finish}
+\def\pagesizesyyy#1,#2,#3\finish{{%
+ \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \hsize=#2\relax \fi
+ \globaldefs = 1
+ %
+ \parskip = 3pt plus 2pt minus 1pt
+ \setleading{\textleading}%
+ %
+ \dimen0 = #1\relax
+ \advance\dimen0 by \voffset
+ %
+ \dimen2 = \hsize
+ \advance\dimen2 by \normaloffset
+ %
+ \internalpagesizes{#1}{\hsize}%
+ {\voffset}{\normaloffset}%
+ {\bindingoffset}{44pt}%
+ {\dimen0}{\dimen2}%
+}}
+
+% Set default to letter.
+%
+\letterpaper
+
+
+\message{and turning on texinfo input format.}
+
+\def^^L{\par} % remove \outer, so ^L can appear in an @comment
+
+% DEL is a comment character, in case @c does not suffice.
+\catcode`\^^? = 14
+
+% Define macros to output various characters with catcode for normal text.
+\catcode`\"=\other \def\normaldoublequote{"}
+\catcode`\$=\other \def\normaldollar{$}%$ font-lock fix
+\catcode`\+=\other \def\normalplus{+}
+\catcode`\<=\other \def\normalless{<}
+\catcode`\>=\other \def\normalgreater{>}
+\catcode`\^=\other \def\normalcaret{^}
+\catcode`\_=\other \def\normalunderscore{_}
+\catcode`\|=\other \def\normalverticalbar{|}
+\catcode`\~=\other \def\normaltilde{~}
+
+% This macro is used to make a character print one way in \tt
+% (where it can probably be output as-is), and another way in other fonts,
+% where something hairier probably needs to be done.
+%
+% #1 is what to print if we are indeed using \tt; #2 is what to print
+% otherwise. Since all the Computer Modern typewriter fonts have zero
+% interword stretch (and shrink), and it is reasonable to expect all
+% typewriter fonts to have this, we can check that font parameter.
+%
+\def\ifusingtt#1#2{\ifdim \fontdimen3\font=0pt #1\else #2\fi}
+
+% Same as above, but check for italic font. Actually this also catches
+% non-italic slanted fonts since it is impossible to distinguish them from
+% italic fonts. But since this is only used by $ and it uses \sl anyway
+% this is not a problem.
+\def\ifusingit#1#2{\ifdim \fontdimen1\font>0pt #1\else #2\fi}
+
+% Turn off all special characters except @
+% (and those which the user can use as if they were ordinary).
+% Most of these we simply print from the \tt font, but for some, we can
+% use math or other variants that look better in normal text.
+
+\catcode`\"=\active
+\def\activedoublequote{{\tt\char34}}
+\let"=\activedoublequote
+\catcode`\~=\active \def\activetilde{{\tt\char126}} \let~ = \activetilde
+\chardef\hat=`\^
+\catcode`\^=\active \def\activehat{{\tt \hat}} \let^ = \activehat
+
+\catcode`\_=\active
+\def_{\ifusingtt\normalunderscore\_}
+\let\realunder=_
+% Subroutine for the previous macro.
+\def\_{\leavevmode \kern.07em \vbox{\hrule width.3em height.1ex}\kern .07em }
+
+\catcode`\|=\active
+\def|{{\tt\char124}}
+
+\chardef \less=`\<
+\catcode`\<=\active \def\activeless{{\tt \less}}\let< = \activeless
+\chardef \gtr=`\>
+\catcode`\>=\active \def\activegtr{{\tt \gtr}}\let> = \activegtr
+\catcode`\+=\active \def+{{\tt \char 43}}
+\catcode`\$=\active \def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix
+
+% used for headline/footline in the output routine, in case the page
+% breaks in the middle of an @tex block.
+\def\texinfochars{%
+ \let< = \activeless
+ \let> = \activegtr
+ \let~ = \activetilde
+ \let^ = \activehat
+ \markupsetuplqdefault \markupsetuprqdefault
+ \let\b = \strong
+ \let\i = \smartitalic
+ % in principle, all other definitions in \tex have to be undone too.
+}
+
+% If a .fmt file is being used, characters that might appear in a file
+% name cannot be active until we have parsed the command line.
+% So turn them off again, and have \everyjob (or @setfilename) turn them on.
+% \otherifyactive is called near the end of this file.
+\def\otherifyactive{\catcode`+=\other \catcode`\_=\other}
+
+% Used sometimes to turn off (effectively) the active characters even after
+% parsing them.
+\def\turnoffactive{%
+ \normalturnoffactive
+ \otherbackslash
+}
+
+\catcode`\@=0
+
+% \backslashcurfont outputs one backslash character in current font,
+% as in \char`\\.
+\global\chardef\backslashcurfont=`\\
+\global\let\rawbackslashxx=\backslashcurfont % let existing .??s files work
+
+% \realbackslash is an actual character `\' with catcode other, and
+% \doublebackslash is two of them (for the pdf outlines).
+{\catcode`\\=\other @gdef@realbackslash{\} @gdef@doublebackslash{\\}}
+
+% In texinfo, backslash is an active character; it prints the backslash
+% in fixed width font.
+\catcode`\\=\active % @ for escape char from now on.
+
+% The story here is that in math mode, the \char of \backslashcurfont
+% ends up printing the roman \ from the math symbol font (because \char
+% in math mode uses the \mathcode, and plain.tex sets
+% \mathcode`\\="026E). It seems better for @backslashchar{} to always
+% print a typewriter backslash, hence we use an explicit \mathchar,
+% which is the decimal equivalent of "715c (class 7, e.g., use \fam;
+% ignored family value; char position "5C). We can't use " for the
+% usual hex value because it has already been made active.
+@def@normalbackslash{{@tt @ifmmode @mathchar29020 @else @backslashcurfont @fi}}
+@let@backslashchar = @normalbackslash % @backslashchar{} is for user documents.
+
+% On startup, @fixbackslash assigns:
+% @let \ = @normalbackslash
+% \rawbackslash defines an active \ to do \backslashcurfont.
+% \otherbackslash defines an active \ to be a literal `\' character with
+% catcode other. We switch back and forth between these.
+@gdef@rawbackslash{@let\=@backslashcurfont}
+@gdef@otherbackslash{@let\=@realbackslash}
+
+% Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of
+% the literal character `\'. Also revert - to its normal character, in
+% case the active - from code has slipped in.
+%
+{@catcode`- = @active
+ @gdef@normalturnoffactive{%
+ @let-=@normaldash
+ @let"=@normaldoublequote
+ @let$=@normaldollar %$ font-lock fix
+ @let+=@normalplus
+ @let<=@normalless
+ @let>=@normalgreater
+ @let\=@normalbackslash
+ @let^=@normalcaret
+ @let_=@normalunderscore
+ @let|=@normalverticalbar
+ @let~=@normaltilde
+ @markupsetuplqdefault
+ @markupsetuprqdefault
+ @unsepspaces
+ }
+}
+
+% Make _ and + \other characters, temporarily.
+% This is canceled by @fixbackslash.
+@otherifyactive
+
+% If a .fmt file is being used, we don't want the `\input texinfo' to show up.
+% That is what \eatinput is for; after that, the `\' should revert to printing
+% a backslash.
+%
+@gdef@eatinput input texinfo{@fixbackslash}
+@global@let\ = @eatinput
+
+% On the other hand, perhaps the file did not have a `\input texinfo'. Then
+% the first `\' in the file would cause an error. This macro tries to fix
+% that, assuming it is called before the first `\' could plausibly occur.
+% Also turn back on active characters that might appear in the input
+% file name, in case not using a pre-dumped format.
+%
+@gdef@fixbackslash{%
+ @ifx\@eatinput @let\ = @normalbackslash @fi
+ @catcode`+=@active
+ @catcode`@_=@active
+}
+
+% Say @foo, not \foo, in error messages.
+@escapechar = `@@
+
+% These (along with & and #) are made active for url-breaking, so need
+% active definitions as the normal characters.
+@def@normaldot{.}
+@def@normalquest{?}
+@def@normalslash{/}
+
+% These look ok in all fonts, so just make them not special.
+% @hashchar{} gets its own user-level command, because of #line.
+@catcode`@& = @other @def@normalamp{&}
+@catcode`@# = @other @def@normalhash{#}
+@catcode`@% = @other @def@normalpercent{%}
+
+@let @hashchar = @normalhash
+
+@c Finally, make ` and ' active, so that txicodequoteundirected and
+@c txicodequotebacktick work right in, e.g., @w{@code{`foo'}}. If we
+@c don't make ` and ' active, @code will not get them as active chars.
+@c Do this last of all since we use ` in the previous @catcode assignments.
+@catcode`@'=@active
+@catcode`@`=@active
+@markupsetuplqdefault
+@markupsetuprqdefault
+
+@c Local variables:
+@c eval: (add-hook 'write-file-hooks 'time-stamp)
+@c page-delimiter: "^\\\\message"
+@c time-stamp-start: "def\\\\texinfoversion{"
+@c time-stamp-format: "%:y-%02m-%02d.%02H"
+@c time-stamp-end: "}"
+@c End:
+
+@c vim:sw=2:
+
+@ignore
+ arch-tag: e1b36e32-c96e-4135-a41a-0b2efa2ea115
+@end ignore
diff --git a/doc/version.texi b/doc/version.texi
new file mode 100644
index 0000000..5d0c32b
--- /dev/null
+++ b/doc/version.texi
@@ -0,0 +1,4 @@
+@set UPDATED 28 December 2015
+@set UPDATED-MONTH December 2015
+@set EDITION 4.6.0
+@set VERSION 4.6.0
diff --git a/doc/versionmaint.texi b/doc/versionmaint.texi
new file mode 100644
index 0000000..5d0c32b
--- /dev/null
+++ b/doc/versionmaint.texi
@@ -0,0 +1,4 @@
+@set UPDATED 28 December 2015
+@set UPDATED-MONTH December 2015
+@set EDITION 4.6.0
+@set VERSION 4.6.0