summaryrefslogtreecommitdiff
path: root/Build/source/utils/texinfo/util
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2006-01-17 21:16:42 +0000
committerKarl Berry <karl@freefriends.org>2006-01-17 21:16:42 +0000
commita3d3111bfe26b8e5f5bc6049dfb2a4ca2edc7881 (patch)
treef4a8a34f904c1bb86adcc3ae0e14434badc6dbe4 /Build/source/utils/texinfo/util
parent6c0eafbb1395d426a72a74538e0b2a95e8344ca6 (diff)
utils 1
git-svn-id: svn://tug.org/texlive/trunk@1484 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/utils/texinfo/util')
-rw-r--r--Build/source/utils/texinfo/util/Makefile.am45
-rw-r--r--Build/source/utils/texinfo/util/Makefile.in579
-rw-r--r--Build/source/utils/texinfo/util/README14
-rw-r--r--Build/source/utils/texinfo/util/depend.mak17
-rw-r--r--Build/source/utils/texinfo/util/deref.c209
-rw-r--r--Build/source/utils/texinfo/util/dir-example482
-rwxr-xr-xBuild/source/utils/texinfo/util/fix-info-dir317
-rwxr-xr-xBuild/source/utils/texinfo/util/fixfonts84
-rw-r--r--Build/source/utils/texinfo/util/fixref.gawk145
-rw-r--r--Build/source/utils/texinfo/util/gdoc914
-rwxr-xr-xBuild/source/utils/texinfo/util/gen-dir-node212
-rwxr-xr-xBuild/source/utils/texinfo/util/gendocs.sh285
-rwxr-xr-xBuild/source/utils/texinfo/util/gendocs_template100
-rwxr-xr-xBuild/source/utils/texinfo/util/infosrch104
-rw-r--r--Build/source/utils/texinfo/util/install-info-html157
-rw-r--r--Build/source/utils/texinfo/util/install-info.c1590
-rw-r--r--Build/source/utils/texinfo/util/outline.gawk145
-rw-r--r--Build/source/utils/texinfo/util/prepinfo.awk356
-rwxr-xr-xBuild/source/utils/texinfo/util/tex3patch70
-rw-r--r--Build/source/utils/texinfo/util/texi-docstring-magic.el347
-rwxr-xr-xBuild/source/utils/texinfo/util/texi2dvi836
-rwxr-xr-xBuild/source/utils/texinfo/util/texi2pdf19
-rw-r--r--Build/source/utils/texinfo/util/texindex.c1628
-rw-r--r--Build/source/utils/texinfo/util/texindex.rc36
-rw-r--r--Build/source/utils/texinfo/util/texinfo-cat.in3
-rw-r--r--Build/source/utils/texinfo/util/texinfo.dtd484
-rw-r--r--Build/source/utils/texinfo/util/texinfo.xsl242
-rwxr-xr-xBuild/source/utils/texinfo/util/txitextest77
-rw-r--r--Build/source/utils/texinfo/util/win32.mak60
29 files changed, 9557 insertions, 0 deletions
diff --git a/Build/source/utils/texinfo/util/Makefile.am b/Build/source/utils/texinfo/util/Makefile.am
new file mode 100644
index 00000000000..6451fa9b653
--- /dev/null
+++ b/Build/source/utils/texinfo/util/Makefile.am
@@ -0,0 +1,45 @@
+# $Id: Makefile.am,v 1.14 2004/08/26 11:43:18 karl Exp $
+# Makefile.am for texinfo/util.
+# Run automake in .. to produce Makefile.in from this.
+#
+# This file is free software; as a special exception the author 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.
+
+bin_PROGRAMS = ginstall-info texindex
+bin_SCRIPTS = texi2dvi texi2pdf
+
+# Use `ginstall-info' in the definition of PROGRAMS and in dependencies
+# because automake generates an install-info target in every Makefile (a
+# bug, IMHO, but this is easier than patching Automake.)
+ginstall_info_SOURCES = install-info.c
+
+# Transform `ginstall-info' to `install-info' before applying any
+# user-specified name transformations.
+transform = s/ginstall-info/install-info/; $(program_transform_name)
+
+localedir = $(datadir)/locale
+INCLUDES = -I$(top_srcdir)/lib -I../intl -DLOCALEDIR=\"$(localedir)\"
+LDADD = ../lib/libtxi.a $(LIBINTL)
+
+dist_pkgdata_DATA = texinfo.dtd texinfo.xsl
+pkgdata_DATA = texinfo.cat
+
+# we don't actually use version.texi in the rule, but it's one way of
+# noticing when the version changes.
+texinfo.cat: texinfo-cat.in $(top_srcdir)/doc/version.texi
+ sed 's/__VERSION__/@VERSION@/g' $(srcdir)/texinfo-cat.in >$@
+
+# Most of these are for fun. The only official/installed ones are the
+# texi2* scripts.
+#
+EXTRA_DIST = README deref.c dir-example fix-info-dir fixfonts \
+ fixref.gawk gdoc gen-dir-node gendocs.sh gendocs_template infosrch \
+ install-info-html outline.gawk \
+ prepinfo.awk tex3patch texi-docstring-magic.el texi2dvi texi2pdf txitextest \
+ $(dist_pkgdata_DATA) texinfo-cat.in
+CLEANFILES = $(pkgdata_DATA)
diff --git a/Build/source/utils/texinfo/util/Makefile.in b/Build/source/utils/texinfo/util/Makefile.in
new file mode 100644
index 00000000000..ca2ff2b942f
--- /dev/null
+++ b/Build/source/utils/texinfo/util/Makefile.in
@@ -0,0 +1,579 @@
+# Makefile.in generated by automake 1.9.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004 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@
+
+# $Id: Makefile.am,v 1.14 2004/08/26 11:43:18 karl Exp $
+# Makefile.am for texinfo/util.
+# Run automake in .. to produce Makefile.in from this.
+#
+# This file is free software; as a special exception the author 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.
+
+
+
+SOURCES = $(ginstall_info_SOURCES) texindex.c
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+bin_PROGRAMS = ginstall-info$(EXEEXT) texindex$(EXEEXT)
+subdir = util
+DIST_COMMON = README $(dist_pkgdata_DATA) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/codeset.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/glibc21.m4 \
+ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intdiv0.m4 \
+ $(top_srcdir)/m4/intmax.m4 $(top_srcdir)/m4/inttypes-pri.m4 \
+ $(top_srcdir)/m4/inttypes.m4 $(top_srcdir)/m4/inttypes_h.m4 \
+ $(top_srcdir)/m4/lcmessage.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/longdouble.m4 $(top_srcdir)/m4/longlong.m4 \
+ $(top_srcdir)/m4/mkstemp.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/onceonly_2_57.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/printf-posix.m4 $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/signed.m4 $(top_srcdir)/m4/size_max.m4 \
+ $(top_srcdir)/m4/stdint_h.m4 $(top_srcdir)/m4/strcase.m4 \
+ $(top_srcdir)/m4/uintmax_t.m4 $(top_srcdir)/m4/ulonglong.m4 \
+ $(top_srcdir)/m4/wchar_t.m4 $(top_srcdir)/m4/wint_t.m4 \
+ $(top_srcdir)/m4/xsize.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)" \
+ "$(DESTDIR)$(pkgdatadir)" "$(DESTDIR)$(pkgdatadir)"
+binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(bin_PROGRAMS)
+am_ginstall_info_OBJECTS = install-info.$(OBJEXT)
+ginstall_info_OBJECTS = $(am_ginstall_info_OBJECTS)
+ginstall_info_LDADD = $(LDADD)
+am__DEPENDENCIES_1 =
+ginstall_info_DEPENDENCIES = ../lib/libtxi.a $(am__DEPENDENCIES_1)
+texindex_SOURCES = texindex.c
+texindex_OBJECTS = texindex.$(OBJEXT)
+texindex_LDADD = $(LDADD)
+texindex_DEPENDENCIES = ../lib/libtxi.a $(am__DEPENDENCIES_1)
+binSCRIPT_INSTALL = $(INSTALL_SCRIPT)
+SCRIPTS = $(bin_SCRIPTS)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(ginstall_info_SOURCES) texindex.c
+DIST_SOURCES = $(ginstall_info_SOURCES) texindex.c
+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 = `echo $$p | sed -e 's|^.*/||'`;
+dist_pkgdataDATA_INSTALL = $(INSTALL_DATA)
+pkgdataDATA_INSTALL = $(INSTALL_DATA)
+DATA = $(dist_pkgdata_DATA) $(pkgdata_DATA)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+# Transform `ginstall-info' to `install-info' before applying any
+# user-specified name transformations.
+transform = s/ginstall-info/install-info/; $(program_transform_name)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GENCAT = @GENCAT@
+GLIBC21 = @GLIBC21@
+GMSGFMT = @GMSGFMT@
+HAVE_ASPRINTF = @HAVE_ASPRINTF@
+HAVE_POSIX_PRINTF = @HAVE_POSIX_PRINTF@
+HAVE_SNPRINTF = @HAVE_SNPRINTF@
+HAVE_WPRINTF = @HAVE_WPRINTF@
+HELP2MAN = @HELP2MAN@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTALL_WARNINGS_FALSE = @INSTALL_WARNINGS_FALSE@
+INSTALL_WARNINGS_TRUE = @INSTALL_WARNINGS_TRUE@
+INSTOBJEXT = @INSTOBJEXT@
+INTLBISON = @INTLBISON@
+INTLLIBS = @INTLLIBS@
+INTLOBJS = @INTLOBJS@
+INTL_LIBTOOL_SUFFIX_PREFIX = @INTL_LIBTOOL_SUFFIX_PREFIX@
+LDFLAGS = @LDFLAGS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
+MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
+MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGMERGE = @MSGMERGE@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+TERMLIBS = @TERMLIBS@
+TOOLS_ONLY_FALSE = @TOOLS_ONLY_FALSE@
+TOOLS_ONLY_TRUE = @TOOLS_ONLY_TRUE@
+USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+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@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+native_tools = @native_tools@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+bin_SCRIPTS = texi2dvi texi2pdf
+
+# Use `ginstall-info' in the definition of PROGRAMS and in dependencies
+# because automake generates an install-info target in every Makefile (a
+# bug, IMHO, but this is easier than patching Automake.)
+ginstall_info_SOURCES = install-info.c
+localedir = $(datadir)/locale
+INCLUDES = -I$(top_srcdir)/lib -I../intl -DLOCALEDIR=\"$(localedir)\"
+LDADD = ../lib/libtxi.a $(LIBINTL)
+dist_pkgdata_DATA = texinfo.dtd texinfo.xsl
+pkgdata_DATA = texinfo.cat
+
+# Most of these are for fun. The only official/installed ones are the
+# texi2* scripts.
+#
+EXTRA_DIST = README deref.c dir-example fix-info-dir fixfonts \
+ fixref.gawk gdoc gen-dir-node gendocs.sh gendocs_template infosrch \
+ install-info-html outline.gawk \
+ prepinfo.awk tex3patch texi-docstring-magic.el texi2dvi texi2pdf txitextest \
+ $(dist_pkgdata_DATA) texinfo-cat.in
+
+CLEANFILES = $(pkgdata_DATA)
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu util/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu util/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: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)"
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ if test -f $$p \
+ ; then \
+ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
+ $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
+ rm -f "$(DESTDIR)$(bindir)/$$f"; \
+ done
+
+clean-binPROGRAMS:
+ -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+ginstall-info$(EXEEXT): $(ginstall_info_OBJECTS) $(ginstall_info_DEPENDENCIES)
+ @rm -f ginstall-info$(EXEEXT)
+ $(LINK) $(ginstall_info_LDFLAGS) $(ginstall_info_OBJECTS) $(ginstall_info_LDADD) $(LIBS)
+texindex$(EXEEXT): $(texindex_OBJECTS) $(texindex_DEPENDENCIES)
+ @rm -f texindex$(EXEEXT)
+ $(LINK) $(texindex_LDFLAGS) $(texindex_OBJECTS) $(texindex_LDADD) $(LIBS)
+install-binSCRIPTS: $(bin_SCRIPTS)
+ @$(NORMAL_INSTALL)
+ test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)"
+ @list='$(bin_SCRIPTS)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ if test -f $$d$$p; then \
+ f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
+ echo " $(binSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(bindir)/$$f'"; \
+ $(binSCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(bindir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-binSCRIPTS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_SCRIPTS)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
+ echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
+ rm -f "$(DESTDIR)$(bindir)/$$f"; \
+ done
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/install-info.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/texindex.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+uninstall-info-am:
+install-dist_pkgdataDATA: $(dist_pkgdata_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(pkgdatadir)" || $(mkdir_p) "$(DESTDIR)$(pkgdatadir)"
+ @list='$(dist_pkgdata_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(dist_pkgdataDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(pkgdatadir)/$$f'"; \
+ $(dist_pkgdataDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(pkgdatadir)/$$f"; \
+ done
+
+uninstall-dist_pkgdataDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(dist_pkgdata_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(pkgdatadir)/$$f'"; \
+ rm -f "$(DESTDIR)$(pkgdatadir)/$$f"; \
+ done
+install-pkgdataDATA: $(pkgdata_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(pkgdatadir)" || $(mkdir_p) "$(DESTDIR)$(pkgdatadir)"
+ @list='$(pkgdata_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(pkgdataDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(pkgdatadir)/$$f'"; \
+ $(pkgdataDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(pkgdatadir)/$$f"; \
+ done
+
+uninstall-pkgdataDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkgdata_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(pkgdatadir)/$$f'"; \
+ rm -f "$(DESTDIR)$(pkgdatadir)/$$f"; \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS) $(SCRIPTS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgdatadir)" "$(DESTDIR)$(pkgdatadir)"; do \
+ test -z "$$dir" || $(mkdir_p) "$$dir"; \
+ done
+install: 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:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-generic mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-dist_pkgdataDATA install-pkgdataDATA
+
+install-exec-am: install-binPROGRAMS install-binSCRIPTS
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \
+ uninstall-dist_pkgdataDATA uninstall-info-am \
+ uninstall-pkgdataDATA
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
+ clean-generic ctags distclean distclean-compile \
+ distclean-generic distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-binPROGRAMS \
+ install-binSCRIPTS install-data install-data-am \
+ install-dist_pkgdataDATA install-exec install-exec-am \
+ install-info install-info-am install-man install-pkgdataDATA \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-binPROGRAMS \
+ uninstall-binSCRIPTS uninstall-dist_pkgdataDATA \
+ uninstall-info-am uninstall-pkgdataDATA
+
+
+# we don't actually use version.texi in the rule, but it's one way of
+# noticing when the version changes.
+texinfo.cat: texinfo-cat.in $(top_srcdir)/doc/version.texi
+ sed 's/__VERSION__/@VERSION@/g' $(srcdir)/texinfo-cat.in >$@
+# 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/Build/source/utils/texinfo/util/README b/Build/source/utils/texinfo/util/README
new file mode 100644
index 00000000000..5354c3520b2
--- /dev/null
+++ b/Build/source/utils/texinfo/util/README
@@ -0,0 +1,14 @@
+$Id: README,v 1.5 2004/04/11 17:56:47 karl Exp $
+texinfo/util/README
+
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved.
+
+Assorted Texinfo-related programs and scripts.
+
+texindex, texi2dvi, and install-info get installed.
+The other items here are for your amusement and/or hacking pleasure.
+
diff --git a/Build/source/utils/texinfo/util/depend.mak b/Build/source/utils/texinfo/util/depend.mak
new file mode 100644
index 00000000000..6168ecd62e4
--- /dev/null
+++ b/Build/source/utils/texinfo/util/depend.mak
@@ -0,0 +1,17 @@
+$(objdir)/deref.obj: \
+
+
+$(objdir)/texindex.obj: \
+ ../lib/system.h \
+ ../config.h \
+ $(gnuw32dir)/win32lib.h \
+ ../lib/gettext.h \
+ $(kpathseadir)/getopt.h
+
+$(objdir)/install-info.obj: \
+ ../lib/system.h \
+ ../config.h \
+ $(gnuw32dir)/win32lib.h \
+ ../lib/gettext.h \
+ $(kpathseadir)/getopt.h
+
diff --git a/Build/source/utils/texinfo/util/deref.c b/Build/source/utils/texinfo/util/deref.c
new file mode 100644
index 00000000000..e08be48105f
--- /dev/null
+++ b/Build/source/utils/texinfo/util/deref.c
@@ -0,0 +1,209 @@
+/*
+ * deref.c
+ *
+ * Make all texinfo references into the one argument form.
+ *
+ * Arnold Robbins
+ * arnold@gnu.org
+ * Written: December, 1991
+ * Released: November, 1998
+ *
+ * Copyright, 1991, 1998 Arnold David Robbins
+ *
+ * DEREF 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * DEREF 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+/*
+ * LIMITATIONS:
+ * One texinfo cross reference per line.
+ * Cross references may not cross newlines.
+ * Use of fgets for input (to be fixed).
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <errno.h>
+
+/* for gcc on the 3B1, delete if this gives you grief */
+extern int fclose(FILE *fp);
+extern int fprintf(FILE *fp, const char *str, ...);
+/* extern int sprintf(char *str, const char *fmt, ...); */
+extern int fputs(char *buf, FILE *fp);
+
+extern char *strerror(int errno);
+extern char *strchr(char *cp, int ch);
+extern int strncmp(const char *s1, const char *s2, int count);
+
+extern int errno;
+
+void process(FILE *fp);
+void repair(char *line, char *ref, int toffset);
+
+int Errs = 0;
+char *Name = "stdin";
+int Line = 0;
+char *Me;
+
+/* main --- handle arguments, global vars for errors */
+
+int
+main(int argc, char **argv)
+{
+ FILE *fp;
+
+ Me = argv[0];
+
+ if (argc == 1)
+ process(stdin);
+ else
+ for (argc--, argv++; *argv != NULL; argc--, argv++) {
+ if (argv[0][0] == '-' && argv[0][1] == '\0') {
+ Name = "stdin";
+ Line = 0;
+ process(stdin);
+ } else if ((fp = fopen(*argv, "r")) != NULL) {
+ Name = *argv;
+ Line = 0;
+ process(fp);
+ fclose(fp);
+ } else {
+ fprintf(stderr, "%s: can not open: %s\n",
+ *argv, strerror(errno));
+ Errs++;
+ }
+ }
+ return Errs != 0;
+}
+
+/* isref --- decide if we've seen a texinfo cross reference */
+
+int
+isref(char *cp)
+{
+ if (strncmp(cp, "@ref{", 5) == 0)
+ return 5;
+ if (strncmp(cp, "@xref{", 6) == 0)
+ return 6;
+ if (strncmp(cp, "@pxref{", 7) == 0)
+ return 7;
+ return 0;
+}
+
+/* process --- read files, look for references, fix them up */
+
+void
+process(FILE *fp)
+{
+ char buf[BUFSIZ];
+ char *cp;
+ int count;
+
+ while (fgets(buf, sizeof buf, fp) != NULL) {
+ Line++;
+ cp = strchr(buf, '@');
+ if (cp == NULL) {
+ fputs(buf, stdout);
+ continue;
+ }
+ do {
+ count = isref(cp);
+ if (count == 0) {
+ cp++;
+ cp = strchr(cp, '@');
+ if (cp == NULL) {
+ fputs(buf, stdout);
+ goto next;
+ }
+ continue;
+ }
+ /* got one */
+ repair(buf, cp, count);
+ break;
+ } while (cp != NULL);
+ next: ;
+ }
+}
+
+/* repair --- turn all texinfo cross references into the one argument form */
+
+void
+repair(char *line, char *ref, int toffset)
+{
+ int braces = 1; /* have seen first left brace */
+ char *cp;
+
+ ref += toffset;
+
+ /* output line up to and including left brace in reference */
+ for (cp = line; cp <= ref; cp++)
+ putchar(*cp);
+
+ /* output node name */
+ for (; *cp && *cp != '}' && *cp != ',' && *cp != '\n'; cp++)
+ putchar(*cp);
+
+ if (*cp != '}') { /* could have been one arg xref */
+ /* skip to matching right brace */
+ for (; braces > 0; cp++) {
+ switch (*cp) {
+ case '@':
+ cp++; /* blindly skip next character */
+ break;
+ case '{':
+ braces++;
+ break;
+ case '}':
+ braces--;
+ break;
+ case '\n':
+ case '\0':
+ Errs++;
+ fprintf(stderr,
+ "%s: %s: %d: mismatched braces\n",
+ Me, Name, Line);
+ goto out;
+ default:
+ break;
+ }
+ }
+ out:
+ ;
+ }
+
+ putchar('}');
+ if (*cp == '}')
+ cp++;
+
+ /* now the rest of the line */
+ for (; *cp; cp++)
+ putchar(*cp);
+ return;
+}
+
+/* strerror --- return error string, delete if in your library */
+
+char *
+strerror(int errno)
+{
+ static char buf[100];
+ extern int sys_nerr;
+ extern char *sys_errlist[];
+
+ if (errno < sys_nerr && errno >= 0)
+ return sys_errlist[errno];
+
+ sprintf(buf, "unknown error %d", errno);
+ return buf;
+}
diff --git a/Build/source/utils/texinfo/util/dir-example b/Build/source/utils/texinfo/util/dir-example
new file mode 100644
index 00000000000..2b88f5f9217
--- /dev/null
+++ b/Build/source/utils/texinfo/util/dir-example
@@ -0,0 +1,482 @@
+This is the directory file `dir' a.k.a. `DIR', which contains the
+ topmost node of the Info hierarchy.
+This particular dir file is merely made available for your hacking
+ pleasure, not official or standard in any way. If it doesn't make sense
+ to you, or you don't like it, ignore it.
+rms suggested that we follow the categories of the Free Software
+ Directory (http://www.gnu.org/directory/) where possible. Since
+ capitalization in the directory is random, I've chosen to use
+ `minimum' capitals, just the first word and proper nouns.
+If you have dir entries for Texinfo manuals you'd like to be added here,
+ please send them to karl@gnu.org.
+
+$Id: dir-example,v 1.51 2004/12/18 02:11:43 karl Exp $
+
+File: dir, Node: Top, This is the top of the INFO tree.
+
+This is the Info main menu (aka directory node).
+A few useful Info commands:
+
+ `q' quits;
+ `?' lists all Info commands;
+ `h' starts the Info tutorial;
+ `mTexinfo RET' visits the Texinfo manual, etc.
+
+Not all of the topics shown below may be available on this system.
+
+* Menu:
+
+Basics
+* Bash: (bash). The GNU Bourne-Again SHell.
+* BC: (bc). Arbitrary precision calculator language.
+* Common options: (coreutils)Common options. Common options.
+* Coreutils: (coreutils). Core GNU (file, text, shell) utilities.
+* DC: (dc). Postfix desk calculator.
+* Date input formats: (coreutils)Date input formats.
+* File permissions: (coreutils)File permissions. Access modes.
+* Finding files: (find). Operating on files matching certain criteria.
+* Gcal: (gcal). GNU calendar program.
+* Time: (time). Measuring program resource usage.
+
+Text creation and manipulation
+* Diffutils: (diff). Comparing and merging files.
+* Ed: (ed). Line editor.
+* Gawk: (gawk). A text scanning and processing language.
+* grep: (grep). Print lines matching a pattern.
+* m4: (m4). General-purpose text macro processor.
+* sed: (sed). Stream EDitor.
+* Wdiff: (wdiff). Word difference finder and related tools.
+
+Texinfo documentation system
+* Info: (info). Documentation browsing system.
+* Texi2HTML: (texi2html). Texinfo to HTML Converter.
+* Texinfo: (texinfo). The GNU documentation format.
+* info standalone: (info-stnd). Standalone Info reader.
+* infokey: (info-stnd)Invoking infokey. Compile Info customizations.
+* install-info: (texinfo)Invoking install-info. Updating info/dir entries.
+* makeinfo: (texinfo)Creating an Info File. Translate Texinfo source.
+* texi2dvi: (texinfo)Format with texi2dvi. Printing Texinfo documentation.
+* texindex: (texinfo)Format with tex/texindex. Sorting Texinfo index files.
+
+Archiving
+* Cpio: (cpio). Copy-in-copy-out archiver to tape or disk.
+* Shar utilities: (sharutils). Shell archiver, uuencode/uudecode.
+* Tar: (tar). Making tape (or disk) archives.
+
+Compression
+* bzip2: (bzip2). General (de)compression of files (blocksort).
+* Gzip: (gzip). General (de)compression of files (lzw).
+
+Email
+* Anubis: (anubis). The GNU outgoing mail processor.
+* Mailutils: (mailutils). Utilities & library for mailboxes, protocols.
+
+Network applications
+* Gawkinet: (gawkinet). TCP/IP Internetworking With `gawk'.
+* Wget: (wget). Non-interactive network downloader.
+
+Printing Tools
+* a2ps: (a2ps). PostScript Generating Utility
+* PreScript: (a2ps) PreScript. Input language for a2ps
+* card: (a2ps) card. Print Reference Cards
+* fixps: (a2ps) fixps. Fixing Some Ill Designed PostScript Files
+* fixnt: (a2ps) fixnt. Fixing Microsoft NT PostScript Files
+* pdiff: (a2ps) pdiff. Produce Pretty Comparison of Files
+* psmandup: (a2ps) psmandup. Printing Duplex on Simplex Printers
+* psset: (a2ps) psset. Inserting calls to setpagedevice
+
+Software development
+* As: (as). Assembler.
+* Autoconf: (autoconf). Create source code configuration scripts.
+* Binutils: (binutils). ar/copy/objdump/nm/size/strip/ranlib.
+* automake: (automake). Making Makefile.in's.
+* bison: (bison). GNU parser generator (Yacc replacement).
+* Cpp: (cpp). The GNU C preprocessor.
+* Cpplib: (cppinternals). Cpplib internals.
+* CVS: (cvs). Concurrent versions system for source control.
+* DejaGnu: (dejagnu). Testing framework.
+* Gdb: (gdb). The GNU debugger.
+* egcs: (egcs). Experimental GNU C compiler.
+* Flex: (flex). A fast scanner generator.
+* g77: (g77). GNU Fortran 77 compiler.
+* Gasp: (gasp). GNU Assembler preprocessor.
+* gcc: (gcc). The GNU Compiler Collection.
+* gccinstall: (gccinstall). Installing the GNU Compiler Collection.
+* gccint: (gccint). Internals of the GNU Compiler Collection.
+* Gnats: (gnats). Cygnus bug tracking system.
+* Gnulib: (gnulib). Source files to share among distributions.
+* Gperf: (gperf). Perfect hash function generator.
+* Gprof: (gprof). Profiler.
+* Guile Reference: (guile). The Guile reference manual.
+* Guile Tutorial: (guile-tut). The Guile Tutorial.
+* Identifier DB: (id-utils). Identifier database utilities.
+* Indent: (indent). Prettyprinter for programs.
+* Ld: (ld). Linker.
+* Libtool: (libtool). Generic library support script.
+* Make: (make). Remake files automatically.
+* Remsync: (remsync). Remote synchronization of directory trees.
+* Send PR: (send-pr). Cygnus bug reporting for Gnats.
+* Source config: (cfg-paper). Some theory on configuring source packages.
+* help2man: (help2man). Automatic manual page generation from -help.
+
+Emacs
+* Ada mode: (ada-mode). The GNU Emacs mode for editing Ada.
+* Autotype: (autotype). Convenient features for text that you enter frequently
+ in Emacs.
+* CC Mode: (ccmode). Emacs mode for editing C, C++, Objective-C,
+ Java, Pike, and IDL code.
+* CL: (cl). Partial Common Lisp support for Emacs Lisp.
+* Dired-X: (dired-x). Dired Extra Features.
+* EUDC: (eudc). A client for directory servers (LDAP, PH)
+* Ebrowse: (ebrowse). A C++ class browser for Emacs.
+* Ediff: (ediff). A visual interface for comparing and merging programs.
+* Emacs: (emacs). The extensible self-documenting text editor.
+* Elisp: (elisp). GNU Emacs Lisp reference manual.
+* Emacs FAQ: (efaq). Frequently Asked Questions about Emacs.
+* Emacs MIME: (emacs-mime). The MIME de/composition library.
+* Eshell: (eshell). A command shell implemented in Emacs Lisp.
+* Forms: (forms). Emacs package for editing data bases
+ by filling in forms.
+* Gnus: (gnus). The newsreader Gnus.
+* IDLWAVE: (idlwave). Major mode and shell for IDL and WAVE/CL files.
+* Intro Elisp: (emacs-lisp-intro). Introduction to Elisp programming.
+
+* AUC TeX: (auctex). Editing (La)TeX files.
+* MH-E: (mh-e). Emacs interface to the MH mail system.
+* Message: (message). Mail and news composition mode that goes with Gnus.
+* PCL-CVS: (pcl-cvs). Emacs front-end to CVS.
+* RefTeX: (reftex). Emacs support for LaTeX cross-references and citations.
+* SC: (sc). Supercite lets you cite parts of messages you're
+ replying to, in flexible ways.
+* Speedbar: (speedbar). File/Tag summarizing utility.
+* TRAMP: (tramp). Transparent Remote Access, Multiple Protocol
+ Emacs remote file access via rsh and rcp.
+* VIP: (vip). An older VI-emulation for Emacs.
+* VIPER: (viper). The newest Emacs VI-emulation mode.
+ (also, A VI Plan for Emacs Rescue or the VI PERil.)
+* VM: (vm). View Mail for Emacs.
+* Widget: (widget). Documenting the "widget" package used by the
+ Emacs Custom facility.
+* WoMan: (woman). Browse UN*X Manual Pages `Wo (without) Man'.
+
+Typesetting
+* Font utilities: (fontu). Programs for font manipulation.
+* Groff: (groff). The GNU troff document formatting system.
+* GV: (gv). The GNU PostScript and PDF viewer.
+
+GNU Gettext Utilities
+* ISO3166: (gettext)Country Codes. ISO 3166 country codes.
+* ISO639: (gettext)Language Codes. ISO 639 language codes.
+* xgettext: (gettext)xgettext Invocation. Extract strings into a PO file.
+* autopoint: (gettext)autopoint Invocation. Copy gettext infrastructure.
+* envsubst: (gettext)envsubst Invocation. Expand environment variables.
+* gettext: (gettext). GNU gettext utilities.
+* gettextize: (gettext)gettextize Invocation. Prepare a package for gettext.
+* msgattrib: (gettext)msgattrib Invocation. Select part of a PO file.
+* msgcat: (gettext)msgcat Invocation. Combine several PO files.
+* msgcmp: (gettext)msgcmp Invocation. Compare a PO file and template.
+* msgcomm: (gettext)msgcomm Invocation. Match two PO files.
+* msgconv: (gettext)msgconv Invocation. Convert PO file to encoding.
+* msgen: (gettext)msgen Invocation. Create an English PO file.
+* msgexec: (gettext)msgexec Invocation. Process a PO file.
+* msgfilter: (gettext)msgfilter Invocation. Pipe a PO file through a filter.
+* msgfmt: (gettext)msgfmt Invocation. Make MO files out of PO files.
+* msggrep: (gettext)msggrep Invocation. Select part of a PO file.
+* msginit: (gettext)msginit Invocation. Create a fresh PO file.
+* msgmerge: (gettext)msgmerge Invocation. Update a PO file from template.
+* msgunfmt: (gettext)msgunfmt Invocation. Uncompile MO file into PO file.
+* msguniq: (gettext)msguniq Invocation. Unify duplicates for PO file.
+* ngettext: (gettext)ngettext Invocation. Translate a message with plural.
+
+Software libraries
+* Annotate: (annotate). High-level GDB to GUI's.
+* Bfd: (bfd). The Binary File Descriptor library.
+* CVS protocol: (cvsclient). CVS client/server protocol specification.
+* Gdb-Internals: (gdbint). The GNU debugger's internals.
+* GDB library: (libgdb). Application programming interface to GDB.
+* GDBM: (gdbm). Hashed databases.
+* GDK: (gdk). General drawing kit.
+* GTK: (gtk). GIMP toolkit.
+* History: (history). Recall previous lines of input.
+* Ld internals: (ldint). GNU linker internals.
+* Libc: (libc). C library.
+* Mmalloc: (mmalloc). The GNU mapped-malloc package.
+* Stabs: (stabs). The "stabs" debugging information format.
+* Readline: (readline). General command-line interface.
+* Regex: (regex). Regular expressions.
+* Termcap: (termcap). All about /etc/termcap.
+
+C++ libraries
+* Iostream: (iostream). C++ input/output.
+* Libg++: (libg++). C++ classes.
+* autosprintf: (autosprintf). Support for printf format strings in C++.
+
+GNU organization
+* Maintain: (maintain). GNU maintainer guidelines.
+* Standards: (standards). GNU coding standards.
+* Tasks: (tasks). GNU task list.
+
+GNU music project
+* LilyPond: (lilypond). The GNU music typesetter.
+* LilyPond internals: (lilypond-internals). LilyPond internals.
+* ly2dvi: (lilypond)Invoking ly2dvi:: Titling LilyPond scores.
+* convert-ly: (lilypond)Invoking convert-ly:: Older LilyPond versions.
+* midi2ly: (lilypond)Invoking midi2ly:: Importing MIDI.
+* etf2ly: (lilypond)Invoking etf2ly:: Importing Finale.
+* abc2ly: (lilypond)Invoking abc2ly:: Importing ABC.
+* pmx2ly: (lilypond)Invoking pmx2ly:: Importing PMX.
+* musedata2ly: (lilypond)Invoking musedata2ly::Importing Musedata.
+* mup2ly: (lilypond)Invoking mup2ly:: Importing MUP.
+
+TeX
+* Afm2tfm: (dvips)Invoking afm2tfm. Making Type 1 fonts available to TeX.
+* Dvips: (dvips). DVI-to-PostScript translator.
+* DVI-to-PNG: (dvipng). DVI to Portable Network Graphics (PNG).
+* Eplain: (eplain). Expanding on plain TeX.
+* Kpathsearch: (kpathsea). File lookup along search paths.
+* LaTeX: (latex). LaTeX.
+* MakeIndex: (makeindex). Index creation for TeX.
+* Naming TeX fonts: (fontname). Filenames for TeX fonts.
+* TDS: (tds). Standard TeX directory structure.
+* TeXDraw: (texdraw). Drawing PostScript diagrams within TeX.
+* Web2c: (web2c). TeX, Metafont, and their companion programs.
+
+DOS
+* GNUish: (gnuish). GNU utilities for DOS.
+* Mtools: (mtools). Access DOS disks from Unix.
+
+Science
+* R FAQ: (R-FAQ). The R statistical language FAQ.
+
+Other things
+* Amd: (am-utils). Filesystem automounter.
+* CMUCL: (cmu-user). CMU Common Lisp.
+* File headers: (filehdr). Bibliographic information for computer files.
+* GCP: (gcp). Game club protocol.
+* GIMP: (pdb). The GIMP procedural database.
+* HTML: (snafu). Hypertext Markup Language 2.0 specification.
+* Jargon: (jargon). The jargon file.
+* Netpbm: (netpbm). Images/graphics manipulation programs.
+* JED: (jed). JED editor documentation.
+* octave: (octave). Octave - A language for numerical computation.
+* Perl: (perl). Practical extraction and report language.
+* PRCS: (prcs). Project revision control system.
+* Screen: (screen). Terminal multiplexer.
+
+Individual utilities
+* aclocal: (automake)Invoking aclocal. Generating aclocal.m4.
+* aid: (id-utils)aid invocation. Matching strings.
+* ar: (binutils)ar. Create/modify/extract archives.
+* at-pr: (gnats)at-pr. Bug report timely reminders.
+* autoconf: (autoconf)autoconf Invocation.
+ How to create configuration scripts
+* autoheader: (autoconf)autoheader Invocation.
+ How to create configuration templates
+* autom4te: (autoconf)autom4te Invocation.
+ The Autoconf executables backbone
+* autoreconf: (autoconf)autoreconf Invocation.
+ Remaking multiple `configure' scripts
+* autoscan: (autoconf)autoscan Invocation.
+ Semi-automatic `configure.ac' writing
+* autoupdate: (autoconf)autoupdate Invocation.
+ Automatic update of `configure.ac'
+* awk: (gawk)Invoking gawk. Text scanning and processing.
+* basename: (coreutils)basename invocation. Strip directory and suffix.
+* bibtex: (web2c)BibTeX invocation. Maintaining bibliographies.
+* c++filt: (binutils)c++filt. Demangle C++ symbols.
+* cat: (coreutils)cat invocation. Concatenate and write files.
+* chgrp: (coreutils)chgrp invocation. Change file groups.
+* chmod: (coreutils)chmod invocation. Change file permissions.
+* chown: (coreutils)chown invocation. Change file owners/groups.
+* chroot: (coreutils)chroot invocation. Specify the root directory.
+* cksum: (coreutils)cksum invocation. Print POSIX CRC checksum.
+* cmp: (diff)Invoking cmp. Compare 2 files byte by byte.
+* comm: (coreutils)comm invocation. Compare sorted files by line.
+* comsatd: (mailutils)comsatd. Comsat daemon.
+* config.status: (autoconf)config.status Invocation. Recreating configurations.
+* configure: (autoconf)configure Invocation. Configuring a package.
+* cp: (coreutils)cp invocation. Copy files.
+* csplit: (coreutils)csplit invocation. Split by context.
+* cut: (coreutils)cut invocation. Print selected parts of lines.
+* date: (coreutils)date invocation. Print/set system date and time.
+* dd: (coreutils)dd invocation. Copy and convert a file.
+* df: (coreutils)df invocation. Report filesystem disk usage.
+* diff: (diff)Invoking diff. Compare 2 files line by line.
+* diff3: (diff)Invoking diff3. Compare 3 files line by line.
+* dir: (coreutils)dir invocation. List directories briefly.
+* dircolors: (coreutils)dircolors invocation. Color setup for ls.
+* dirname: (coreutils)dirname invocation. Strip non-directory suffix.
+* dmp: (web2c)Dmp invocation. Troff->MPX (MetaPost pictures).
+* du: (coreutils)du invocation. Report on disk usage.
+* dvicopy: (web2c)DVIcopy invocation. Virtual font expansion
+* dvipng: (dvipng)Invoking dvipng. A DVI-to-PNG translator.
+* dvitomp: (web2c)DVItoMP invocation. DVI to MPX (MetaPost pictures).
+* dvitype: (web2c)DVItype invocation. DVI to human-readable text.
+* echo: (coreutils)echo invocation. Print a line of text.
+* edit-pr: (gnats)Invoking edit-pr. Changing bugs.
+* egrep: (grep)Invoking. grep -E.
+* eid: (id-utils)eid invocation. Invoking an editor on matches.
+* env: (coreutils)env invocation. Modify the environment.
+* expand: (coreutils)expand invocation. Convert tabs to spaces.
+* expr: (coreutils)expr invocation. Evaluate expressions.
+* factor: (coreutils)factor invocation. Print prime factors
+* false: (coreutils)false invocation. Do nothing, unsuccessfully.
+* fgrep: (fgrep)Invoking. grep -F.
+* fid: (id-utils)fid invocation. Listing a file's identifiers.
+* file-pr: (gnats)file-pr. Processing incoming traffic.
+* find: (find)Invoking find. Finding and acting on files.
+* fmt: (coreutils)fmt invocation. Reformat paragraph text.
+* fold: (coreutils)fold invocation. Wrap long input lines.
+* frm: (mailutils)frm. List headers from a mailbox.
+* gcal2txt: (gcal)Invoking gcal2txt. Calendar resource to text file.
+* gftodvi: (web2c)GFtoDVI invocation. Generic font proofsheets.
+* gftopk: (web2c)GFtoPK invocation. Generic to packed fonts.
+* gftype: (web2c)GFtype invocation. GF to human-readable text.
+* gid: (id-utils)gid invocation. Listing all matching lines.
+* git: (git). GNU interactive tools.
+* groups: (coreutils)groups invocation. Print group names a user is in.
+* guimb: (mailutils)guimb. Mailbox processing language.
+* gunzip: (gzip)Overview. Decompression.
+* gzexe: (gzip)Overview. Compress executables.
+* head: (coreutils)head invocation. Output the first part of files.
+* hostid: (coreutils)hostid invocation. Print numeric host identifier.
+* hostname: (coreutils)hostname invocation. Print or set system name.
+* id: (coreutils)id invocation. Print real/effective uid/gid.
+* idx: (id-utils)idx invocation. Testing mkid scanners.
+* ifnames: (autoconf)ifnames Invocation. Listing conditionals in source.
+* iid: (id-utils)iid invocation. Interactive complex queries.
+* imap4d: (mailutils)imap4d. IMAP4 daemon.
+* inimf: (web2c)inimf invocation. Initial Metafont.
+* inimp: (web2c)inimp invocation. Initial MetaPost.
+* initex: (web2c)initex invocation. Initial TeX.
+* install: (coreutils)install invocation. Copy and change attributes.
+* join: (coreutils)join invocation. Join lines on a common field.
+* kill: (coreutils)kill invocation. Send a signal to processes.
+* kpsewhich: (kpathsea)Invoking kpsewhich. TeX file searching.
+* libtoolize: (libtool)Invoking libtoolize. Adding libtool support.
+* lid: (id-utils)lid invocation. Matching identifier patterns.
+* link: (coreutils)link invocation. Make hard links between files.
+* ln: (coreutils)ln invocation. Make links between files.
+* locate: (find)Invoking locate. Finding files in a database.
+* logname: (coreutils)logname invocation. Print current login name.
+* ls: (coreutils)ls invocation. List directory contents.
+* mail-files: (sharutils)mail-files invocation. Send files to remote site.
+* mail.local: (mailutils)mail.local. Deliver mail to local mailbox.
+* mail: (mailutils)mail. Send and receive mail.
+* mailshar: (sharutils)mailshar invocation. Make and send a shell archive.
+* makempx: (web2c)MakeMPX invocation. MetaPost label typesetting.
+* maketexmf: (kpathsea)MakeTeX scripts. MF source generation.
+* maketexpk: (kpathsea)MakeTeX scripts. PK bitmap generation.
+* maketextex: (kpathsea)MakeTeX scripts. TeX source generation.
+* maketextfm: (kpathsea)MakeTeX scripts. TeX font metric generation.
+* md5sum: (coreutils)md5sum invocation. Print or check message-digests.
+* mdiff: (wdiff)mdiff invocation. Line cluster finder.
+* messages: (mailutils)messages. Count messages in mailbox.
+* mf: (web2c)mf invocation. Creating typeface families.
+* mft: (web2c)MFT invocation. Prettyprinting Metafont source.
+* mgetty: (mgetty). Faxes, voicemail and more.
+* mkdir: (coreutils)mkdir invocation. Create directories.
+* mkfifo: (coreutils)mkfifo invocation. Create FIFOs (named pipes).
+* mkid: (id-utils)mkid invocation. Creating an ID database.
+* mknod: (coreutils)mknod invocation. Create special files.
+* mp: (web2c)mp invocation. Creating technical diagrams.
+* mpto: (web2c)MPto invocation. MetaPost label extraction.
+* mv: (coreutils)mv invocation. Rename files.
+* newer: (web2c)Newer invocation. Compare modification times.
+* nice: (coreutils)nice invocation. Modify scheduling priority.
+* nl: (coreutils)nl invocation. Number lines and write files.
+* nlmconv: (binutils)nlmconv. Convert object to NetWare LM.
+* nm: (binutils)nm. List symbols in object files.
+* nohup: (coreutils)nohup invocation. Immunize to hangups.
+* objcopy: (binutils)objcopy. Copy/translate object files.
+* objdump: (binutils)objdump. Display info from object files.
+* od: (coreutils)od invocation. Dump files in octal, etc.
+* paste: (coreutils)paste invocation. Merge lines of files.
+* patch: (diff)Invoking patch. Apply a patch to a file.
+* patgen: (web2c)Patgen invocation. Creating hyphenation patterns.
+* pathchk: (coreutils)pathchk invocation. Check file name portability.
+* pid: (id-utils)pid invocation. Looking up filenames.
+* pktogf: (web2c)PKtoGF invocation. Packed to generic fonts.
+* pktype: (web2c)PKtype invocation. PK to human-readable text.
+* pltotf: (web2c)PLtoTF invocation. Property list to TFM.
+* pooltype: (web2c)Pooltype invocation. Display WEB pool files.
+* pop3d: (mailutils)pop3d. POP3 daemon.
+* pr: (coreutils)pr invocation. Paginate or columnate files.
+* pr-addr: (gnats)pr-addr. Bug report address retrieval.
+* pr-edit: (gnats)pr-edit. The edit-pr driver.
+* printenv: (coreutils)printenv invocation. Print environment variables.
+* printf: (coreutils)printf invocation. Format and print data.
+* protoize: (gcc)Running Protoize. Add prototypes to sources.
+* ptx: (coreutils)ptx invocation. Produce permuted indexes.
+* pwd: (coreutils)pwd invocation. Print working directory.
+* query-pr: (gnats)Invoking query-pr. Bug searching/reporting.
+* queue-pr: (gnats)queue-pr. Handling incoming traffic.
+* ranlib: (binutils)ranlib. Index archive file contents.
+* readlink: (coreutils)readlink invocation. Print referent of a symlink.
+* readmsg: (mailutils)readmsg. Extract messages from a folder.
+* rm: (coreutils)rm invocation. Remove files.
+* rmdir: (coreutils)rmdir invocation. Remove empty directories.
+* sdiff: (diff)Invoking sdiff. Merge 2 files side-by-side.
+* send-pr: (gnats)Invoking send-pr. Submitting bugs.
+* seq: (coreutils)seq invocation. Print numeric sequences
+* shar: (sharutils)shar invocation. Create shell archive.
+* shred: (coreutils)shred invocation. Remove files more securely.
+* sieve: (mailutils)sieve. Mail filtering utility.
+* size: (binutils)size. List object file section sizes.
+* sleep: (coreutils)sleep invocation. Delay for a specified time.
+* sort: (coreutils)sort invocation. Sort text files.
+* split: (coreutils)split invocation. Split into fixed-size pieces.
+* stat: (coreutils)stat invocation. Report file(system) status.
+* strings: (binutils)strings. List printable strings.
+* strip: (binutils)strip. Discard symbols.
+* stty: (coreutils)stty invocation. Print/change terminal settings.
+* su: (coreutils)su invocation. Modify user and group id.
+* sum: (coreutils)sum invocation. Print traditional checksum.
+* sync: (coreutils)sync invocation. Synchronize memory and disk.
+* tabs: (tput)Invoking tabs. Tab settings.
+* tac: (coreutils)tac invocation. Reverse files.
+* tail: (coreutils)tail invocation. Output the last part of files.
+* tangle: (web2c)Tangle invocation. WEB to Pascal.
+* tar: (tar)tar invocation. Invoking GNU `tar'.
+* tcal: (gcal)Invoking tcal. Run Gcal with tomorrow's date.
+* tee: (coreutils)tee invocation. Redirect to multiple files.
+* test: (coreutils)test invocation. File/string tests.
+* testsuite: (autoconf)testsuite Invocation. Running an Autotest test suite.
+* tex: (web2c)tex invocation. Typesetting.
+* tftopl: (web2c)TFtoPL invocation. TFM -> property list.
+* touch: (coreutils)touch invocation. Change file timestamps.
+* tput: (tput)Invoking tput. Termcap in shell scripts.
+* tr: (coreutils)tr invocation. Translate characters.
+* true: (coreutils)true invocation. Do nothing, successfully.
+* tsort: (coreutils)tsort invocation. Topological sort.
+* tty: (coreutils)tty invocation. Print terminal name.
+* txt2gcal: (gcal)Invoking txt2gcal. Calendar text to resource file.
+* umb-scheme: (umb-scheme). UMB Scheme Interpreter.
+* uname: (coreutils)uname invocation. Print system information.
+* unexpand: (coreutils)unexpand invocation. Convert spaces to tabs.
+* unify: (wdiff)unify invocation. Diff format converter.
+* uniq: (coreutils)uniq invocation. Uniquify files.
+* unlink: (coreutils)unlink invocation. Removal via unlink(2).
+* unprotoize: (gcc)Running Protoize. Remove prototypes from sources.
+* unshar: (sharutils)unshar invocation. Extract from shell archive.
+* updatedb: (find)Invoking updatedb. Building the locate database.
+* users: (coreutils)users invocation. Print current user names.
+* vdir: (coreutils)vdir invocation. List directories verbosely.
+* vftovp: (web2c)VFtoVP invocation. Virtual font -> virtual pl.
+* view-pr: (gnats)Invoking view-pr. Showing bug reports.
+* virmf: (web2c)virmf invocation. Virgin Metafont.
+* virmp: (web2c)virmp invocation. Virgin MetaPost.
+* virtex: (web2c)virtex invocation. Virgin TeX.
+* vptovf: (web2c)VPtoVF invocation. Virtual pl -> virtual font.
+* wc: (coreutils)wc invocation. Line, word, and byte counts.
+* weave: (web2c)Weave invocation. WEB to TeX.
+* who: (coreutils)who invocation. Print who is logged in.
+* whoami: (coreutils)whoami invocation. Print effective user id.
+* xargs: (find)Invoking xargs. Operating on many files.
+* yes: (coreutils)yes invocation. Print a string indefinitely.
+* zcat: (gzip)Overview. Decompression to stdout.
+* zdiff: (gzip)Overview. Compare compressed files.
+* zforce: (gzip)Overview. Force .gz extension on files.
+* zgrep: (gzip)Overview. Search compressed files.
+* zmore: (gzip)Overview. Decompression output by pages.
+* zsh: (zsh). An enhanced Bourne shell.
diff --git a/Build/source/utils/texinfo/util/fix-info-dir b/Build/source/utils/texinfo/util/fix-info-dir
new file mode 100755
index 00000000000..b1144ed6a4e
--- /dev/null
+++ b/Build/source/utils/texinfo/util/fix-info-dir
@@ -0,0 +1,317 @@
+#!/bin/sh
+#fix-info-dir (GNU texinfo)
+VERSION=1.1
+#Copyright (C) 1998, 2003 Free Software Foundation, Inc.
+#fix-info-dir comes with NO WARRANTY, to the extent permitted by law.
+#You may redistribute copies of fix-info-dir
+#under the terms of the GNU General Public License.
+#For more information about these matters, see the files named COPYING."
+#fix-info-dir was derived from update-info and gen-dir-node
+# The skeleton file contains info topic names in the
+# order they should appear in the output. There are three special
+# lines that alter the behavior: a line consisting of just "--" causes
+# the next line to be echoed verbatim to the output. A line
+# containing just "%%" causes all the remaining filenames (wildcards
+# allowed) in the rest of the file to be ignored. A line containing
+# just "!!" exits the script when reached (unless preceded by a line
+# containing just "--").
+#Author: Richard L. Hawes, rhawes@dmapub.dma.org.
+
+# ###SECTION 1### Constants
+set -h 2>/dev/null
+# ENVIRONMENT
+if test -z "$TMPDIR"; then
+ TMPDIR="/usr/tmp"
+fi
+if test -z "$LINENO"; then
+ LINENO="0"
+fi
+
+MENU_BEGIN='^\*\([ ]\)\{1,\}Menu:'
+MENU_ITEM='^\* ([^ ]).*:([ ])+\('
+MENU_FILTER1='s/^\*\([ ]\)\{1,\}/* /'
+MENU_FILTER2='s/\([ ]\)\{1,\}$//g'
+
+TMP_FILE1="${TMPDIR}/fx${$}.info"
+TMP_FILE2="${TMPDIR}/fy${$}.info"
+TMP_FILE_LIST="$TMP_FILE1 $TMP_FILE2"
+
+TRY_HELP_MSG="Try --help for more information"
+
+# ###SECTION 100### main program
+#variables set by options
+CREATE_NODE=""
+DEBUG=":"
+MODE=""
+#
+Total="0"
+Changed=""
+
+while test "$*"; do
+ case "$1" in
+ -c|--create) CREATE_NODE="y";;
+ --debug) set -eux; DEBUG="set>&2";;
+ -d|--delete) MODE="Detect_Invalid";;
+ +d);;
+ --version)
+cat<<VersionEOF
+fix-info-dir (GNU Texinfo) $VERSION
+Copyright (C) 1998 Free Software Foundation, Inc.
+fix-info-dir comes with NO WARRANTY, to the extent permitted by law.
+You may redistribute copies of fix-info-dir
+under the terms of the GNU General Public License.
+For more information about these matters, see the files named COPYING.
+Author: Richard L. Hawes
+VersionEOF
+ exit;;
+
+ --help)
+cat<<HelpEndOfFile
+Usage: fix-info-dir [OPTION]... [INFO_DIR/[DIR_FILE]] [SKELETON]
+
+It detects and inserts missing menu items into the info dir file.
+The info dir must be the current directory.
+
+Options:
+-c, --create create a new info node
+-d, --delete delete invalid menu items (ignore missing menu items)
+ --debug print debug information to standard error path
+ --help print this help message and exit
+ --version print current version and exit
+Backup of the info node has a '.old' suffix added. This is a shell script.
+Environment Variables: TMPDIR
+Email bug reports to bug-texinfo@gnu.org.
+HelpEndOfFile
+ exit;;
+
+ [-+]*) echo "$0:$LINENO: \"$1\" is not a valid option">&2
+ echo "$TRY_HELP_MSG">&2
+ exit 2;;
+ *) break;;
+ esac
+ shift
+done
+
+ORIGINAL_DIR=`pwd`
+
+if test "$#" -gt "0"; then
+ INFO_DIR="$1"
+ shift
+else
+ INFO_DIR=$DEFAULT_INFO_DIR
+fi
+
+if test ! -d "${INFO_DIR}"; then
+ DIR_FILE=`basename ${INFO_DIR}`;
+ INFO_DIR=`dirname ${INFO_DIR}`;
+else
+ DIR_FILE="dir"
+fi
+
+cd "$INFO_DIR"||exit
+
+
+if test "$CREATE_NODE"; then
+ if test "$#" -gt "0"; then
+ if test `expr $1 : /` = '1'; then
+ SKELETON="$1"
+ else
+ SKELETON="$ORIGINAL_DIR/$1"
+ fi
+ if test ! -r "$SKELETON" && test -f "$SKELETON"; then
+ echo "$0:$LINENO: $SKELETON is not readable">&2
+ exit 2
+ fi
+ shift
+ else
+ SKELETON=/dev/null
+
+ fi
+else
+ if test ! -f "$DIR_FILE"; then
+ echo "$0:$LINENO: $DIR_FILE is irregular or nonexistant">&2
+ exit 2
+ elif test ! -r "$DIR_FILE"; then
+ echo "$0:$LINENO: $DIR_FILE is not readable">&2
+ exit 2
+ elif test ! -w "$DIR_FILE"; then
+ echo "$0:$LINENO: $DIR_FILE is not writeable">&2
+ exit 2
+ fi
+fi
+
+if test "$#" -gt "0"; then
+ echo "$0:$LINENO: Too many parameters">&2
+ echo "$TRY_HELP_MSG">&2
+ exit 2
+fi
+
+if test -f "$DIR_FILE"; then
+ cp "$DIR_FILE" "$DIR_FILE.old"
+ echo "Backed up $DIR_FILE to $DIR_FILE.old."
+fi
+
+if test "$CREATE_NODE"; then
+ if test "$MODE"; then
+ echo "$0:$LINENO: ERROR: Illogical option combination: -d -c">&2
+ echo "$TRY_HELP_MSG">&2
+ exit 2
+ fi
+ echo "Creating new Info Node: `pwd`/$DIR_FILE"
+ Changed="y"
+
+{
+
+ ### output the dir header
+ echo "-*- Text -*-"
+ echo "This file was generated automatically by $0."
+ echo "This version was generated on `date`"
+ echo "by `whoami`@`hostname` for `pwd`"
+
+ cat<<DIR_FILE_END_OF_FILE
+This is the file .../info/$DIR_FILE, which contains the topmost node of the
+Info hierarchy. The first time you invoke Info you start off
+looking at that node, which is ($DIR_FILE)Top.
+
+
+File: $DIR_FILE Node: Top This is the top of the INFO tree
+
+ This (the Directory node) gives a menu of major topics.
+ Typing "q" exits, "?" lists all Info commands, "d" returns here,
+ "h" gives a primer for first-timers,
+ "mEmacs<Return>" visits the Emacs topic, etc.
+
+ In Emacs, you can click mouse button 2 on a menu item or cross reference
+ to select it.
+
+* Menu: The list of major topics begins on the next line.
+
+DIR_FILE_END_OF_FILE
+
+### go through the list of files in the skeleton. If an info file
+### exists, grab the ENTRY information from it. If an entry exists
+### use it, otherwise create a minimal $DIR_FILE entry.
+
+ # Read one line from the file. This is so that we can echo lines with
+ # whitespace and quoted characters in them.
+ while read fileline; do
+ # flag fancy features
+ if test ! -z "$echoline"; then # echo line
+ echo "$fileline"
+ echoline=""
+ continue
+ elif test "${fileline}" = "--"; then
+ # echo the next line
+ echoline="1"
+ continue
+ elif test "${fileline}" = "%%"; then
+ # skip remaining files listed in skeleton file
+ skip="1"
+ continue
+ elif test "${fileline}" = "!!"; then
+ # quit now
+ break
+ fi
+
+ # handle files if they exist
+ for file in $fileline""; do
+ fname=
+ if test -z "$file"; then
+ break
+ fi
+ # Find the file to operate upon.
+ if test -r "$file"; then
+ fname="$file"
+ elif test -r "${file}.info"; then
+ fname="${file}.info"
+ elif test -r "${file}.gz"; then
+ fname="${file}.gz"
+ elif test -r "${file}.info.gz"; then
+ fname="${file}.info.gz"
+ else
+ echo "$0:$LINENO: can't find info file for ${file}?">&2
+ continue
+ fi
+
+ # if we found something and aren't skipping, do the entry
+ if test "$skip"; then
+ continue
+ fi
+
+ infoname=`echo $file|sed -e 's/.info$//'`
+ entry=`zcat -f $fname|\
+ sed -e '1,/START-INFO-DIR-ENTRY/d'\
+ -e '/END-INFO-DIR-ENTRY/,$d'`
+ if [ ! -z "${entry}" ]; then
+ echo "${entry}"
+ else
+ echo "* ${infoname}: (${infoname})."
+ fi
+ Total=`expr "$Total" + "1"`
+ done
+ done
+}>$DIR_FILE<$SKELETON
+fi
+
+trap ' eval "$DEBUG"; rm -f $TMP_FILE_LIST; exit ' 0
+trap ' rm -f $TMP_FILE_LIST
+ exit ' 1
+trap ' rm -f $TMP_FILE_LIST
+ echo "$0:$LINENO: received INT signal.">&2
+ exit ' 2
+trap ' rm -f $TMP_FILE_LIST
+ echo "$0:$LINENO: received QUIT signal.">&2
+ exit ' 3
+
+sed -e "1,/$MENU_BEGIN/d" -e "$MENU_FILTER1" -e "$MENU_FILTER2"<$DIR_FILE\
+|sed -n -e '/\* /{
+s/).*$//g
+s/\.gz$//
+s/\.info$//
+s/^.*(//p
+}'|sort -u>$TMP_FILE1
+ls -F|sed -e '/\/$/d' -e '/[-.][0-9]/d'\
+ -e "/^$DIR_FILE\$/d" -e "/^$DIR_FILE.old\$/d"\
+ -e 's/[*@]$//' -e 's/\.gz$//' -e 's/\.info$//'|sort>$TMP_FILE2
+
+if test -z "$MODE"; then
+ #Detect Missing
+ DONE_MSG="total menu item(s) were inserted into `pwd`/$DIR_FILE"
+ for Info_Name in `comm -13 $TMP_FILE1 $TMP_FILE2`; do
+ if test -r "$Info_Name"; then
+ Info_File="$Info_Name"
+ elif test -r "${Info_Name}.info"; then
+ Info_File="${Info_Name}.info"
+ elif test -r "${Info_Name}.gz"; then
+ Info_File="${Info_Name}.gz"
+ elif test -r "${Info_Name}.info.gz"; then
+ Info_File="${Info_Name}.info.gz"
+ else
+ echo "$0:$LINENO: can't find info file for ${Info_Name}?">&2
+ continue
+ fi
+ Changed="y"
+ if install-info $Info_File $DIR_FILE; then
+ Total=`expr "$Total" + "1"`
+ fi
+ done
+else
+ # Detect Invalid
+ DONE_MSG="total invalid menu item(s) were removed from `pwd`/$DIR_FILE"
+ for Info_Name in `comm -23 $TMP_FILE1 $TMP_FILE2`; do
+ Changed="y"
+ if install-info --remove $Info_Name $DIR_FILE; then
+ Total=`expr "$Total" + "1"`
+ fi
+ done
+fi
+
+# print summary
+if test "$Changed"; then
+ echo "$Total $DONE_MSG"
+else
+ echo "Nothing to do"
+fi
+rm -f $TMP_FILE_LIST
+eval "$DEBUG"
+exit 0
diff --git a/Build/source/utils/texinfo/util/fixfonts b/Build/source/utils/texinfo/util/fixfonts
new file mode 100755
index 00000000000..ee2ea719219
--- /dev/null
+++ b/Build/source/utils/texinfo/util/fixfonts
@@ -0,0 +1,84 @@
+#!/bin/sh
+# Make links named `lcircle10' for all TFM and GF/PK files, if no
+# lcircle10 files already exist.
+
+# Don't override definition of prefix and/or libdir if they are
+# already defined in the environment.
+if test "z${prefix}" = "z" ; then
+ prefix=/usr/local
+else
+ # prefix may contain references to other variables, thanks to make.
+ eval prefix=\""${prefix}"\"
+fi
+
+if test "z${libdir}" = "z" ; then
+ libdir="${prefix}/lib/tex"
+else
+ # libdir may contain references to other variables, thanks to make.
+ eval libdir=\""${libdir}"\"
+fi
+
+texlibdir="${libdir}"
+texfontdir="${texlibdir}/fonts"
+
+# Directories for the different font formats, in case they're not all
+# stored in one place.
+textfmdir="${textfmdir-${texfontdir}}"
+texpkdir="${texpkdir-${texfontdir}}"
+texgfdir="${texgfdir-${texfontdir}}"
+
+test "z${TMPDIR}" = "z" && TMPDIR="/tmp"
+
+tempfile="${TMPDIR}/circ$$"
+tempfile2="${TMPDIR}/circ2$$"
+
+# EXIT SIGHUP SIGINT SIGQUIT SIGTERM
+#trap 'rm -f "${tempfile}" "${tempfile2}"' 0 1 2 3 15
+
+# Find all the fonts with names that include `circle'.
+(cd "${texfontdir}"; find . -name '*circle*' -print > "${tempfile}")
+
+# If they have lcircle10.tfm, assume everything is there, and quit.
+if grep 'lcircle10\.tfm' "${tempfile}" > /dev/null 2>&1 ; then
+ echo "Found lcircle10.tfm."
+ exit 0
+fi
+
+# No TFM file for lcircle. Make a link to circle10.tfm if it exists,
+# and then make a link to the bitmap files.
+grep 'circle10\.tfm' "${tempfile}" > "${tempfile2}" \
+ || {
+ echo "I can't find any circle fonts in ${texfontdir}.
+If it isn't installed somewhere else, you need to get the Metafont sources
+from somewhere, e.g., labrea.stanford.edu:pub/tex/latex/circle10.mf, and
+run Metafont on them."
+ exit 1
+ }
+
+# We have circle10.tfm. (If we have it more than once, take the first
+# one.) Make the link.
+tempfile2_line1="`sed -ne '1p;q' \"${tempfile2}\"`"
+ln "${tempfile2_line1}" "${textfmdir}/lcircle10.tfm"
+echo "Linked to ${tempfile2_line1}."
+
+# Now make a link for the PK files, if any.
+(cd "${texpkdir}"
+ for f in `grep 'circle10.*pk' "${tempfile}"` ; do
+ set - `echo "$f" \
+ | sed -ne '/\//!s/^/.\//;s/\(.*\)\/\([^\/][^\/]*\)$/\1 \2/;p'`
+ ln "$f" "${1}/l${2}"
+ echo "Linked to $f."
+ done
+)
+
+# And finally for the GF files.
+(cd "${texgfdir}"
+ for f in `grep 'circle10.*gf' "${tempfile}"` ; do
+ set - `echo "$f" \
+ | sed -ne '/\//!s/^/.\//;s/\(.*\)\/\([^\/][^\/]*\)$/\1 \2/;p'`
+ ln "$f" "${1}/l${2}"
+ echo "Linked to $f."
+ done
+)
+
+# eof
diff --git a/Build/source/utils/texinfo/util/fixref.gawk b/Build/source/utils/texinfo/util/fixref.gawk
new file mode 100644
index 00000000000..f0e3cf6d606
--- /dev/null
+++ b/Build/source/utils/texinfo/util/fixref.gawk
@@ -0,0 +1,145 @@
+#! /usr/local/bin/gawk -f
+
+# fixref.awk --- fix xrefs in texinfo documents
+# Copyright, 1991, Arnold David Robbins, arnold@skeeve.atl.ga.us
+# Copyright, 1998, Arnold David Robbins, arnold@gnu.org
+
+# FIXREF 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 2 of the License, or
+# (at your option) any later version.
+#
+# FIXREF 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+# Updated: Jul 21 1992 --- change unknown
+# Updated: Jul 18 1997 --- bug fix
+
+# usage: gawk -f fixref.awk input-file > output-file
+# or if you have #!: fixref.awk input-file > output-file
+
+# Limitations:
+# 1. no more than one cross reference on a line
+# 2. cross references may not cross a newline
+
+BEGIN \
+{
+ # we make two passes over the file. To do that we artificially
+ # tweak the argument vector to do a variable assignment
+
+ if (ARGC != 2) {
+ printf("usage: %s texinfo-file\n", ARGV[0]) > "/dev/stderr"
+ exit 1
+ }
+ ARGV[2] = "pass=2"
+ ARGV[3] = ARGV[1]
+ ARGC = 4
+
+ # examine paragraphs
+ RS = ""
+
+ heading = "@(chapter|appendix|unnumbered|(appendix(sec|subsec|subsubsec))|section|subsection|subsubsection|unnumberedsec|heading|top)"
+
+ pass = 1
+
+ # put space between paragraphs on output
+ ORS = "\n\n"
+}
+
+pass == 1 && NF == 0 { next }
+
+# pass == 1 && /@node/ \
+# bug fix 7/18/96
+pass == 1 && /^@node/ \
+{
+ lname = name = ""
+ n = split($0, lines, "\n")
+ for (i = 1; i <= n; i++) {
+ if (lines[i] ~ ("^" heading)) {
+ sub(heading, "", lines[i])
+ sub(/^[ \t]*/, "", lines[i])
+ lname = lines[i]
+# printf "long name is '%s'\n", lines[i]
+ } else if (lines[i] ~ /@node/) {
+ sub(/@node[ \t]*/, "", lines[i])
+ sub(/[ \t]*,.*$/, "", lines[i])
+ name = lines[i]
+# printf "node name is '%s'\n", lines[i]
+ }
+ }
+ if (name && lname)
+ names[name] = lname
+ else if (lname)
+ printf("node name for %s missing!\n", lname) > "/dev/stderr"
+ else
+ printf("long name for %s missing!\n", name) > "/dev/stderr"
+
+ if (name ~ /:/)
+ printf("node `%s' contains a `:'\n", name) > "/dev/stderr"
+
+ if (lname) {
+ if (lname ~ /:/)
+ printf("name `%s' contains a `:'\n", lname) > "/dev/stderr"
+ else if (lname ~ /,/) {
+ printf("name `%s' contains a `,'\n", lname) > "/dev/stderr"
+ gsub(/,/, " ", lname)
+ names[name] = lname # added 7/18/97
+ }
+ }
+}
+
+pass == 2 && /@(x|px)?ref{/ \
+{
+ # split the paragraph into lines
+ # write them out one by one after fixing them
+ n = split($0, lines, "\n")
+ for (i = 1; i <= n; i++)
+ if (lines[i] ~ /@(x|px)?ref{/) {
+ res = updateref(lines[i])
+ printf "%s\n", res
+ } else
+ printf "%s\n", lines[i]
+
+ printf "\n" # avoid ORS
+ next
+}
+
+function updateref(orig, refkind, line)
+{
+ line = orig # work on a copy
+
+ # find the beginning of the reference
+ match(line, "@(x|px)?ref{")
+ refkind = substr(line, RSTART, RLENGTH)
+
+ # pull out just the node name
+ sub(/.*ref{/, "", line)
+ sub(/}.*$/, "", line)
+ sub(/,.*/, "", line)
+
+# debugging
+# printf("found ref to node '%s'\n", line) > "/dev/stderr"
+
+ # If the node name and the section name are the same
+ # we don't want to bother doing this.
+
+ if (! (line in names)) # sanity checking
+ printf("no long name for %s\n", line) > "/dev/stderr"
+ else if (names[line] != line && names[line] !~ /[:,]/) {
+ # build up new ref
+ newref = refkind line ", ," names[line] "}"
+ pat = refkind line "[^}]*}"
+
+ sub(pat, newref, orig)
+ }
+
+ return orig
+}
+
+pass == 2 { print }
diff --git a/Build/source/utils/texinfo/util/gdoc b/Build/source/utils/texinfo/util/gdoc
new file mode 100644
index 00000000000..3c52fb04593
--- /dev/null
+++ b/Build/source/utils/texinfo/util/gdoc
@@ -0,0 +1,914 @@
+#!/usr/bin/perl
+
+## Copyright (c) 2002, 2003 Simon Josefsson ##
+## added -texinfo, -listfunc ##
+## man page revamp ##
+## various improvements ##
+## Copyright (c) 1998 Michael Zucchi, All Rights Reserved ##
+## hacked to allow -tex option --nmav ##
+## ##
+## This software falls under the GNU Public License. Please read ##
+## the COPYING file for more information ##
+
+#
+# This will read a 'c' file and scan for embedded comments in the
+# style of gnome comments (+minor extensions - see below).
+#
+# This program is modified by Nikos Mavroyanopoulos, for the gnutls
+# project.
+
+# Note: This only supports 'c'.
+
+# usage:
+# gdoc [ -docbook | -html | -text | -man | -tex | -texinfo | -listfunc ]
+# [ -sourceversion verno ] [ -includefuncprefix ] [ -bugsto address ]
+# [ -seeinfo infonode ] [ -copyright notice ] [ -verbatimcopying ]
+# [ -function funcname [ -function funcname ...] ] c file(s)s > outputfil
+e
+#
+# Set output format using one of -docbook, -html, -text, -man, -tex,
+# -texinfo, or -listfunc. Default is man.
+#
+# -sourceversion
+# Version number for source code, e.g. '1.0.4'. Used in 'man' headers.
+# Defaults to using current date.
+#
+# -includefuncprefix
+# For man pages, generate a #include <FILE.h> based on the function
+# prefix. For example, a function gss_init_sec_context will generate
+# an include statement of #include <gss.h>.
+#
+# -bugsto address
+# For man pages, include a section about reporting bugs and mention
+# the given e-mail address, e.g 'bug-libidn@gnu.org'.
+#
+# -seeinfo infonode
+# For man pages, include a section that point to an info manual
+# for more information.
+#
+# -copyright notice
+# For man pages, include a copyright section with the given
+# notice after a preamble. Use, e.g., '2002, 2003 Simon Josefsson'.
+#
+# -verbatimcopying
+# For man pages, and when the -copyright parameter is used,
+# add a licensing statement that say verbatim copying is permitted.
+#
+# -function funcname
+# If set, then only generate documentation for the given function(s). A
+ll
+# other functions are ignored.
+#
+# c files - list of 'c' files to process
+#
+# All output goes to stdout, with errors to stderr.
+
+#
+# format of comments.
+# In the following table, (...)? signifies optional structure.
+# (...)* signifies 0 or more structure elements
+# /**
+# * function_name(:)? (- short description)?
+# (* @parameterx: (description of parameter x)?)*
+# (* a blank line)?
+# * (Description:)? (Description of function)?
+# * (Section header: (section description)? )*
+# (*)?*/
+#
+# So .. the trivial example would be:
+#
+# /**
+# * my_function
+# **/
+#
+# If the Description: header tag is ommitted, then there must be a blank line
+# after the last parameter specification.
+# e.g.
+# /**
+# * my_function - does my stuff
+# * @my_arg: its mine damnit
+# *
+# * Does my stuff explained.
+# */
+#
+# or, could also use:
+# /**
+# * my_function - does my stuff
+# * @my_arg: its mine damnit
+# * Description: Does my stuff explained.
+# */
+# etc.
+#
+# All descriptions can be multiline, apart from the short function description
+.
+#
+# All descriptive text is further processed, scanning for the following specia
+l
+# patterns, which are highlighted appropriately.
+#
+# 'funcname()' - function
+# '$ENVVAR' - environmental variable
+# '&struct_name' - name of a structure
+# '@parameter' - name of a parameter
+# '%CONST' - name of a constant.
+
+#
+# Extensions for LaTeX:
+#
+# 1. the symbol '->' will be replaced with a rightarrow
+# 2. x^y with ${x}^{y}$.
+# 3. xxx\: with xxx:
+
+use POSIX qw(strftime);
+
+# match expressions used to find embedded type information
+$type_constant = "\\\%(\\w+)";
+$type_func = "(\\w+\\(\\))";
+$type_param = "\\\@(\\w+)";
+$type_struct = "\\\&(\\w+)";
+$type_env = "(\\\$\\w+)";
+
+
+# Output conversion substitutions.
+# One for each output format
+
+# these work fairly well
+%highlights_html = ( $type_constant, "<i>\$1</i>",
+ $type_func, "<b>\$1</b>",
+ $type_struct, "<i>\$1</i>",
+ $type_param, "<tt><b>\$1</b></tt>" );
+$blankline_html = "<p>";
+
+%highlights_texinfo = ( $type_constant, "\\\@var{\$1}",
+ $type_func, "\\\@code{\$1}",
+ $type_struct, "\\\@code{\$1}",
+ $type_param, "\\\@code{\$1}" );
+$blankline_texinfo = "";
+
+%highlights_tex = ( $type_constant, "{\\\\it \$1}",
+ $type_func, "{\\\\bf \$1}",
+ $type_struct, "{\\\\it \$1}",
+ $type_param, "{\\\\bf \$1}" );
+$blankline_tex = "\\\\";
+
+# sgml, docbook format
+%highlights_sgml = ( $type_constant, "<replaceable class=\"option\">\$1</repla
+ceable>",
+ $type_func, "<function>\$1</function>",
+ $type_struct, "<structname>\$1</structname>",
+ $type_env, "<envar>\$1</envar>",
+ $type_param, "<parameter>\$1</parameter>" );
+$blankline_sgml = "</para><para>\n";
+
+# these are pretty rough
+%highlights_man = ( $type_constant, "\\n.I \\\"\$1\\\"\\n",
+ $type_func, "\\n.B \\\"\$1\\\"\\n",
+ $type_struct, "\\n.I \\\"\$1\\\"\\n",
+ $type_param."([\.\, ]*)\n?", "\\n.I \\\"\$1\$2\\\"\\n" );
+$blankline_man = "";
+
+# text-mode
+%highlights_text = ( $type_constant, "\$1",
+ $type_func, "\$1",
+ $type_struct, "\$1",
+ $type_param, "\$1" );
+$blankline_text = "";
+
+
+sub usage {
+ print "Usage: $0 [ -v ] [ -docbook | -html | -text | -man | -tex | -texinf
+o -listfunc ]\n";
+ print " [ -sourceversion verno ] [ -includefuncprefix ]\n";
+ print " [ -bugsto address ] [ -seeinfo infonode ] [ -copyright not
+ice]\n";
+ print " [ -verbatimcopying ]\n";
+ print " [ -function funcname [ -function funcname ...] ]\n";
+ print " c source file(s) > outputfile\n";
+ exit 1;
+}
+
+# read arguments
+if ($#ARGV==-1) {
+ usage();
+}
+
+$verbose = 0;
+$output_mode = "man";
+%highlights = %highlights_man;
+$blankline = $blankline_man;
+$modulename = "API Documentation";
+$sourceversion = strftime "%Y-%m-%d", localtime;
+$function_only = 0;
+while ($ARGV[0] =~ m/^-(.*)/) {
+ $cmd = shift @ARGV;
+ if ($cmd eq "-html") {
+ $output_mode = "html";
+ %highlights = %highlights_html;
+ $blankline = $blankline_html;
+ } elsif ($cmd eq "-man") {
+ $output_mode = "man";
+ %highlights = %highlights_man;
+ $blankline = $blankline_man;
+ } elsif ($cmd eq "-tex") {
+ $output_mode = "tex";
+ %highlights = %highlights_tex;
+ $blankline = $blankline_tex;
+ } elsif ($cmd eq "-texinfo") {
+ $output_mode = "texinfo";
+ %highlights = %highlights_texinfo;
+ $blankline = $blankline_texinfo;
+ } elsif ($cmd eq "-text") {
+ $output_mode = "text";
+ %highlights = %highlights_text;
+ $blankline = $blankline_text;
+ } elsif ($cmd eq "-docbook") {
+ $output_mode = "sgml";
+ %highlights = %highlights_sgml;
+ $blankline = $blankline_sgml;
+ } elsif ($cmd eq "-listfunc") {
+ $output_mode = "listfunc";
+ } elsif ($cmd eq "-module") { # not needed for sgml, inherits from calling
+ document
+ $modulename = shift @ARGV;
+ } elsif ($cmd eq "-sourceversion") {
+ $sourceversion = shift @ARGV;
+ } elsif ($cmd eq "-includefuncprefix") {
+ $includefuncprefix = 1;
+ } elsif ($cmd eq "-bugsto") {
+ $bugsto = shift @ARGV;
+ } elsif ($cmd eq "-copyright") {
+ $copyright = shift @ARGV;
+ } elsif ($cmd eq "-verbatimcopying") {
+ $verbatimcopying = 1;
+ } elsif ($cmd eq "-seeinfo") {
+ $seeinfo = shift @ARGV;
+ } elsif ($cmd eq "-function") { # to only output specific functions
+ $function_only = 1;
+ $function = shift @ARGV;
+ $function_table{$function} = 1;
+ } elsif ($cmd eq "-v") {
+ $verbose = 1;
+ } elsif (($cmd eq "-h") || ($cmd eq "--help")) {
+ usage();
+ }
+}
+
+##
+# dumps section contents to arrays/hashes intended for that purpose.
+#
+sub dump_section {
+ my $name = shift @_;
+ my $contents = join "\n", @_;
+
+ if ($name =~ m/$type_constant/) {
+ $name = $1;
+# print STDERR "constant section '$1' = '$contents'\n";
+ $constants{$name} = $contents;
+ } elsif ($name =~ m/$type_param/) {
+# print STDERR "parameter def '$1' = '$contents'\n";
+ $name = $1;
+ $parameters{$name} = $contents;
+ } else {
+# print STDERR "other section '$name' = '$contents'\n";
+ $sections{$name} = $contents;
+ push @sectionlist, $name;
+ }
+}
+
+##
+# output function
+#
+# parameters, a hash.
+# function => "function name"
+# parameterlist => @list of parameters
+# parameters => %parameter descriptions
+# sectionlist => @list of sections
+# sections => %descriont descriptions
+#
+
+sub repstr {
+ $pattern = shift;
+ $repl = shift;
+ $match1 = shift;
+ $match2 = shift;
+ $match3 = shift;
+ $match4 = shift;
+
+ $output = $repl;
+ $output =~ s,\$1,$match1,g;
+ $output =~ s,\$2,$match2,g;
+ $output =~ s,\$3,$match3,g;
+ $output =~ s,\$4,$match4,g;
+
+ eval "\$return = qq/$output/";
+
+# print "pattern $pattern matched 1=$match1 2=$match2 3=$match3 4=$match4 r
+eplace $repl yielded $output interpolated $return\n";
+
+ $return;
+}
+
+sub output_highlight {
+ my $contents = join "\n", @_;
+ my $line;
+
+ foreach $pattern (keys %highlights) {
+# print "scanning pattern $pattern ($highlights{$pattern})\n";
+ $contents =~ s:$pattern:repstr($pattern, $highlights{$pattern}, $1, $2
+, $3, $4):gse;
+ }
+ foreach $line (split "\n", $contents) {
+ if ($line eq ""){
+ print $lineprefix, $blankline;
+ } else {
+ print $lineprefix, $line;
+ }
+ print "\n";
+ }
+}
+
+sub just_highlight {
+ my $contents = join "\n", @_;
+ my $line;
+ my $ret = "";
+
+ foreach $pattern (keys %highlights) {
+# print "scanning pattern $pattern ($highlights{$pattern})\n";
+ $contents =~ s:$pattern:repstr($pattern, $highlights{$pattern}, $1, $2
+, $3, $4):gse;
+ }
+ foreach $line (split "\n", $contents) {
+ if ($line eq ""){
+ $ret = $ret . $lineprefix . $blankline;
+ } else {
+ $ret = $ret . $lineprefix . $line;
+ }
+ $ret = $ret . "\n";
+ }
+
+ return $ret;
+}
+
+# output in texinfo
+sub output_texinfo {
+ my %args = %{$_[0]};
+ my ($parameter, $section);
+ my $count;
+
+ print "\@deftypefun {" . $args{'functiontype'} . "} ";
+ print "{".$args{'function'}."} ";
+ print "(";
+ $count = 0;
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ print $args{'parametertypes'}{$parameter}." \@var{".$parameter."}";
+ if ($count != $#{$args{'parameterlist'}}) {
+ $count++;
+ print ", ";
+ }
+ }
+ print ")\n";
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ if ($args{'parameters'}{$parameter}) {
+ print "\@var{".$parameter."}: ";
+ output_highlight($args{'parameters'}{$parameter});
+ print "\n";
+ }
+ }
+ foreach $section (@{$args{'sectionlist'}}) {
+ print "\n\@strong{$section:} " if $section ne $section_default;
+ $args{'sections'}{$section} =~ s:([{}]):\@\1:gs;
+ output_highlight($args{'sections'}{$section});
+ }
+ print "\@end deftypefun\n\n";
+}
+
+# output in html
+sub output_html {
+ my %args = %{$_[0]};
+ my ($parameter, $section);
+ my $count;
+ print "\n\n<a name=\"". $args{'function'} . "\">&nbsp</a><h2>Function</h2>
+\n";
+
+ print "<i>".$args{'functiontype'}."</i>\n";
+ print "<b>".$args{'function'}."</b>\n";
+ print "(";
+ $count = 0;
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ print "<i>".$args{'parametertypes'}{$parameter}."</i> <b>".$parameter.
+"</b>\n";
+ if ($count != $#{$args{'parameterlist'}}) {
+ $count++;
+ print ", ";
+ }
+ }
+ print ")\n";
+
+ print "<h3>Arguments</h3>\n";
+ print "<dl>\n";
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ print "<dt><i>".$args{'parametertypes'}{$parameter}."</i> <b>".$parame
+ter."</b>\n";
+ print "<dd>";
+ output_highlight($args{'parameters'}{$parameter});
+ }
+ print "</dl>\n";
+ foreach $section (@{$args{'sectionlist'}}) {
+ print "<h3>$section</h3>\n";
+ print "<ul>\n";
+ output_highlight($args{'sections'}{$section});
+ print "</ul>\n";
+ }
+ print "<hr>\n";
+}
+
+# output in tex
+sub output_tex {
+ my %args = %{$_[0]};
+ my ($parameter, $section);
+ my $count;
+ my $func = $args{'function'};
+ my $param;
+ my $param2;
+ my $sec;
+ my $check;
+ my $type;
+
+ $func =~ s/_/\\_/g;
+
+ print "\n\n\\subsection{". $func . "}\n\\label{" . $args{'function'} . "}\
+n";
+
+ $type = $args{'functiontype'};
+ $type =~ s/_/\\_/g;
+
+ print "{\\it ".$type."}\n";
+ print "{\\bf ".$func."}\n";
+ print "(";
+ $count = 0;
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ $param = $args{'parametertypes'}{$parameter};
+ $param2 = $parameter;
+ $param =~ s/_/\\_/g;
+ $param2 =~ s/_/\\_/g;
+
+ print "{\\it ".$param."} {\\bf ".$param2."}";
+ if ($count != $#{$args{'parameterlist'}}) {
+ $count++;
+ print ", ";
+ }
+ }
+ print ")\n";
+
+ print "\n{\\large{Arguments}}\n";
+
+ print "\\begin{itemize}\n";
+ $check=0;
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ $param1 = $args{'parametertypes'}{$parameter};
+ $param1 =~ s/_/\\_/g;
+ $param2 = $parameter;
+ $param2 =~ s/_/\\_/g;
+
+ $check = 1;
+ print "\\item {\\it ".$param1."} {\\bf ".$param2."}: \n";
+# print "\n";
+
+ $param3 = $args{'parameters'}{$parameter};
+ $param3 =~ s/&([a-zA-Z\_]+)/{\\it \1}/g;
+
+ $out = just_highlight($param3);
+ $out =~ s/_/\\_/g;
+ print $out;
+ }
+ if ($check==0) {
+ print "\\item void\n";
+ }
+ print "\\end{itemize}\n";
+
+ foreach $section (@{$args{'sectionlist'}}) {
+ $sec = $section;
+ $sec =~ s/_/\\_/g;
+ $sec =~ s/&([a-zA-Z\_]+)/{\\it \1}/g;
+
+ print "\n{\\large{$sec}}\\\\\n";
+ print "\\begin{rmfamily}\n";
+
+ $sec = $args{'sections'}{$section};
+ $sec =~ s/\\:/:/g;
+ $sec =~ s/&([a-zA-Z\_]+)/{\\it \1}/g;
+ $sec =~ s/->/\$\\rightarrow\$/g;
+ $sec =~ s/([0-9]+)\^([0-9]+)/\$\{\1\}\^\{\2\}\$/g;
+
+ $out = just_highlight($sec);
+ $out =~ s/_/\\_/g;
+
+ print $out;
+ print "\\end{rmfamily}\n";
+ }
+ print "\n";
+}
+
+
+# output in sgml DocBook
+sub output_sgml {
+ my %args = %{$_[0]};
+ my ($parameter, $section);
+ my $count;
+ my $id;
+
+ $id = $args{'module'}."-".$args{'function'};
+ $id =~ s/[^A-Za-z0-9]/-/g;
+
+ print "<refentry>\n";
+ print "<refmeta>\n";
+ print "<refentrytitle><phrase id=\"$id\">".$args{'function'}."</phrase></r
+efentrytitle>\n";
+ print "</refmeta>\n";
+ print "<refnamediv>\n";
+ print " <refname>".$args{'function'}."</refname>\n";
+ print " <refpurpose>\n";
+ print " ".$args{'purpose'}."\n";
+ print " </refpurpose>\n";
+ print "</refnamediv>\n";
+
+ print "<refsynopsisdiv>\n";
+ print " <title>Synopsis</title>\n";
+ print " <funcsynopsis>\n";
+ print " <funcdef>".$args{'functiontype'}." ";
+ print "<function>".$args{'function'}." ";
+ print "</function></funcdef>\n";
+
+# print "<refsect1>\n";
+# print " <title>Synopsis</title>\n";
+# print " <funcsynopsis>\n";
+# print " <funcdef>".$args{'functiontype'}." ";
+# print "<function>".$args{'function'}." ";
+# print "</function></funcdef>\n";
+
+ $count = 0;
+ if ($#{$args{'parameterlist'}} >= 0) {
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ print " <paramdef>".$args{'parametertypes'}{$parameter};
+ print " <parameter>$parameter</parameter></paramdef>\n";
+ }
+ } else {
+ print " <void>\n";
+ }
+ print " </funcsynopsis>\n";
+ print "</refsynopsisdiv>\n";
+# print "</refsect1>\n";
+
+ # print parameters
+ print "<refsect1>\n <title>Arguments</title>\n";
+# print "<para>\nArguments\n";
+ if ($#{$args{'parameterlist'}} >= 0) {
+ print " <variablelist>\n";
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ print " <varlistentry>\n <term><parameter>$parameter</parameter
+></term>\n";
+ print " <listitem>\n <para>\n";
+ $lineprefix=" ";
+ output_highlight($args{'parameters'}{$parameter});
+ print " </para>\n </listitem>\n </varlistentry>\n";
+ }
+ print " </variablelist>\n";
+ } else {
+ print " <para>\n None\n </para>\n";
+ }
+ print "</refsect1>\n";
+
+ # print out each section
+ $lineprefix=" ";
+ foreach $section (@{$args{'sectionlist'}}) {
+ print "<refsect1>\n <title>$section</title>\n <para>\n";
+# print "<para>\n$section\n";
+ if ($section =~ m/EXAMPLE/i) {
+ print "<example><para>\n";
+ }
+ output_highlight($args{'sections'}{$section});
+# print "</para>";
+ if ($section =~ m/EXAMPLE/i) {
+ print "</para></example>\n";
+ }
+ print " </para>\n</refsect1>\n";
+ }
+
+ print "\n\n";
+}
+
+##
+# output in man
+sub output_man {
+ my %args = %{$_[0]};
+ my ($parameter, $section);
+ my $count;
+
+ print ".TH \"$args{'function'}\" 3 \"$args{'sourceversion'}\" \"". $args{'
+module'} . "\" \"". $args{'module'} . "\"\n";
+
+ print ".SH NAME\n";
+
+ print $args{'function'}."\n";
+
+ print ".SH SYNOPSIS\n";
+ print ".B #include <". lc((split /_/, $args{'function'})[0]) . ".h>\n"
+ if $args{'includefuncprefix'};
+ print ".sp\n";
+ print ".BI \"".$args{'functiontype'}." ".$args{'function'}."(";
+ $count = 0;
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ print $args{'parametertypes'}{$parameter}." \" ".$parameter." \"";
+ if ($count != $#{$args{'parameterlist'}}) {
+ $count++;
+ print ", ";
+ }
+ }
+ print ");\"\n";
+
+ print ".SH ARGUMENTS\n";
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ print ".IP \"".$args{'parametertypes'}{$parameter}." ".$parameter."\"
+12\n";
+ output_highlight($args{'parameters'}{$parameter});
+ }
+ foreach $section (@{$args{'sectionlist'}}) {
+ print ".SH \"" . uc($section) . "\"\n";
+ output_highlight($args{'sections'}{$section});
+ }
+
+ if ($args{'bugsto'}) {
+ print ".SH \"REPORTING BUGS\"\n";
+ print "Report bugs to <". $args{'bugsto'} . ">.\n";
+ }
+
+ if ($args{'copyright'}) {
+ print ".SH COPYRIGHT\n";
+ print "Copyright \\(co ". $args{'copyright'} . ".\n";
+ if ($args{'verbatimcopying'}) {
+ print ".br\n";
+ print "Permission is granted to make and distribute verbatim copie
+s of this\n";
+ print "manual provided the copyright notice and this permission no
+tice are\n";
+ print "preserved on all copies.\n";
+ }
+ }
+
+ if ($args{'seeinfo'}) {
+ print ".SH \"SEE ALSO\"\n";
+ print "The full documentation for\n";
+ print ".B " . $args{'module'} . "\n";
+ print "is maintained as a Texinfo manual. If the\n";
+ print ".B info\n";
+ print "and\n";
+ print ".B " . $args{'module'} . "\n";
+ print "programs are properly installed at your site, the command\n";
+ print ".IP\n";
+ print ".B info " . $args{'seeinfo'} . "\n";
+ print ".PP\n";
+ print "should give you access to the complete manual.\n";
+ }
+}
+
+sub output_listfunc {
+ my %args = %{$_[0]};
+ print $args{'function'} . "\n";
+}
+
+##
+# output in text
+sub output_text {
+ my %args = %{$_[0]};
+ my ($parameter, $section);
+
+ print "Function = ".$args{'function'}."\n";
+ print " return type: ".$args{'functiontype'}."\n\n";
+ foreach $parameter (@{$args{'parameterlist'}}) {
+ print " ".$args{'parametertypes'}{$parameter}." ".$parameter."\n";
+ print " -> ".$args{'parameters'}{$parameter}."\n";
+ }
+ foreach $section (@{$args{'sectionlist'}}) {
+ print " $section:\n";
+ print " -> ";
+ output_highlight($args{'sections'}{$section});
+ }
+}
+
+##
+# generic output function - calls the right one based
+# on current output mode.
+sub output_function {
+# output_html(@_);
+ eval "output_".$output_mode."(\@_);";
+}
+
+
+##
+# takes a function prototype and spits out all the details
+# stored in the global arrays/hsahes.
+sub dump_function {
+ my $prototype = shift @_;
+
+ if ($prototype =~ m/^()([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/ ||
+ $prototype =~ m/^(\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/ ||
+ $prototype =~ m/^(\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/ ||
+ $prototype =~ m/^(\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/ ||
+ $prototype =~ m/^(\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/)
+ {
+ $return_type = $1;
+ $function_name = $2;
+ $args = $3;
+
+# print STDERR "ARGS = '$args'\n";
+
+ foreach $arg (split ',', $args) {
+ # strip leading/trailing spaces
+ $arg =~ s/^\s*//;
+ $arg =~ s/\s*$//;
+# print STDERR "SCAN ARG: '$arg'\n";
+ @args = split('\s', $arg);
+
+# print STDERR " -> @args\n";
+ $param = pop @args;
+# print STDERR " -> @args\n";
+ if ($param =~ m/^(\*+)(.*)/) {
+ $param = $2;
+ push @args, $1;
+ }
+ if ($param =~ m/^(.*)(\[\])$/) {
+ $param = $1;
+ push @args, $2;
+ }
+# print STDERR " :> @args\n";
+ $type = join " ", @args;
+
+ if ($parameters{$param} eq "" && $param != "void") {
+ $parameters{$param} = "-- undescribed --";
+ print STDERR "Warning($lineno): Function parameter '$param' no
+t described in '$function_name'\n";
+ }
+
+ push @parameterlist, $param;
+ $parametertypes{$param} = $type;
+
+# print STDERR "param = '$param', type = '$type'\n";
+ }
+ } else {
+ print STDERR "Error($lineno): cannot understand prototype: '$prototype
+'\n";
+ return;
+ }
+
+ if ($function_only==0 || defined($function_table{$function_name})) {
+ output_function({'function' => $function_name,
+ 'module' => $modulename,
+ 'sourceversion' => $sourceversion,
+ 'includefuncprefix' => $includefuncprefix,
+ 'bugsto' => $bugsto,
+ 'copyright' => $copyright,
+ 'verbatimcopying' => $verbatimcopying,
+ 'seeinfo' => $seeinfo,
+ 'functiontype' => $return_type,
+ 'parameterlist' => \@parameterlist,
+ 'parameters' => \%parameters,
+ 'parametertypes' => \%parametertypes,
+ 'sectionlist' => \@sectionlist,
+ 'sections' => \%sections,
+ 'purpose' => $function_purpose
+ });
+ }
+}
+
+######################################################################
+# main
+# states
+# 0 - normal code
+# 1 - looking for function name
+# 2 - scanning field start.
+# 3 - scanning prototype.
+$state = 0;
+$section = "";
+
+$doc_special = "\@\%\$\&";
+
+$doc_start = "^/\\*\\*\$";
+$doc_end = "\\*/";
+$doc_com = "\\s*\\*\\s*";
+$doc_func = $doc_com."(\\w+):?";
+$doc_sect = $doc_com."([".$doc_special."[:upper:]][\\w ]+):(.*)";
+$doc_content = $doc_com."(.*)";
+
+%constants = ();
+%parameters = ();
+@parameterlist = ();
+%sections = ();
+@sectionlist = ();
+
+$contents = "";
+$section_default = "Description"; # default section
+$section = $section_default;
+
+$lineno = 0;
+foreach $file (@ARGV) {
+ if (!open(IN,"<$file")) {
+ print STDERR "Error: Cannot open file $file\n";
+ next;
+ }
+ while (<IN>) {
+ $lineno++;
+
+ if ($state == 0) {
+ if (/$doc_start/o) {
+ $state = 1; # next line is always the function nam
+e
+ }
+ } elsif ($state == 1) { # this line is the function name (always)
+ if (/$doc_func/o) {
+ $function = $1;
+ $state = 2;
+ if (/-(.*)/) {
+ $function_purpose = $1;
+ } else {
+ $function_purpose = "";
+ }
+ if ($verbose) {
+ print STDERR "Info($lineno): Scanning doc for $function\n"
+;
+ }
+ } else {
+ print STDERR "WARN($lineno): Cannot understand $_ on line $lin
+eno",
+ " - I thought it was a doc line\n";
+ $state = 0;
+ }
+ } elsif ($state == 2) { # look for head: lines, and include content
+ if (/$doc_sect/o) {
+ $newsection = $1;
+ $newcontents = $2;
+
+ if ($contents ne "") {
+ dump_section($section, $contents);
+ $section = $section_default;
+ }
+
+ $contents = $newcontents;
+ if ($contents ne "") {
+ $contents .= "\n";
+ }
+ $section = $newsection;
+ } elsif (/$doc_end/) {
+
+ if ($contents ne "") {
+ dump_section($section, $contents);
+ $section = $section_default;
+ $contents = "";
+ }
+
+# print STDERR "end of doc comment, looking for prototype\n";
+ $prototype = "";
+ $state = 3;
+ } elsif (/$doc_content/) {
+ # miguel-style comment kludge, look for blank lines after
+ # @parameter line to signify start of description
+ if ($1 eq "" && $section =~ m/^@/) {
+ dump_section($section, $contents);
+ $section = $section_default;
+ $contents = "";
+ } else {
+ $contents .= $1."\n";
+ }
+ } else {
+ # i dont know - bad line? ignore.
+ print STDERR "WARNING($lineno): bad line: $_";
+ }
+ } elsif ($state == 3) { # scanning for function { (end of prototype)
+ if (m#\s*/\*\s+MACDOC\s*#io) {
+ # do nothing
+ }
+ elsif (/([^\{]*)/) {
+ $prototype .= $1;
+ }
+ if (/\{/) {
+ $prototype =~ s@/\*.*?\*/@@gos; # strip comments.
+ $prototype =~ s@[\r\n]+@ @gos; # strip newlines/cr's.
+ $prototype =~ s@^ +@@gos; # strip leading spaces
+ dump_function($prototype);
+
+ $function = "";
+ %constants = ();
+ %parameters = ();
+ %parametertypes = ();
+ @parameterlist = ();
+ %sections = ();
+ @sectionlist = ();
+ $prototype = "";
+
+ $state = 0;
+ }
+ }
+ }
+}
+
+
+
diff --git a/Build/source/utils/texinfo/util/gen-dir-node b/Build/source/utils/texinfo/util/gen-dir-node
new file mode 100755
index 00000000000..262bdd77a9b
--- /dev/null
+++ b/Build/source/utils/texinfo/util/gen-dir-node
@@ -0,0 +1,212 @@
+#!/bin/sh
+# $Id: gen-dir-node,v 1.3 2004/04/11 17:56:47 karl Exp $
+# Generate the top-level Info node, given a directory of Info files
+# and (optionally) a skeleton file. The output will be suitable for a
+# top-level dir file. The skeleton file contains info topic names in the
+# order they should appear in the output. There are three special
+# lines that alter the behavior: a line consisting of just "--" causes
+# the next line to be echoed verbatim to the output. A line
+# containing just "%%" causes all the remaining filenames (wildcards
+# allowed) in the rest of the file to be ignored. A line containing
+# just "!!" exits the script when reached (unless preceded by a line
+# containing just "--"). Once the script reaches the end of the
+# skeleton file, it goes through the remaining files in the directory
+# in order, putting their entries at the end. The script will use the
+# ENTRY information in each info file if it exists. Otherwise it will
+# make a minimal entry.
+
+# sent by Jeffrey Osier <jeffrey@cygnus.com>, who thinks it came from
+# zoo@winternet.com (david d `zoo' zuhn)
+
+# modified 7 April 1995 by Joe Harrington <jh@tecate.gsfc.nasa.gov> to
+# take special flags
+
+INFODIR=$1
+if [ $# = 2 ] ; then
+ SKELETON=$2
+else
+ SKELETON=/dev/null
+fi
+
+skip=
+
+if [ $# -gt 2 ] ; then
+ echo usage: $0 info-directory [ skeleton-file ] 1>&2
+ exit 1
+elif [ -z "${INFODIR}" ] ; then
+ INFODIR="%%DEFAULT_INFO_DIR%%"
+else
+ true
+fi
+
+if [ ! -d ${INFODIR} ] ; then
+ echo "$0: first argument must specify a directory"
+ exit 1
+fi
+
+### output the dir header
+echo "-*- Text -*-"
+echo "This file was generated automatically by $0."
+echo "This version was generated on `date`"
+echo "by `whoami`@`hostname` for `(cd ${INFODIR}; pwd)`"
+
+cat << moobler
+\$Id: gen-dir-node,v 1.3 2004/04/11 17:56:47 karl Exp $
+This is the file .../info/dir, which contains the topmost node of the
+Info hierarchy. The first time you invoke Info you start off
+looking at that node, which is (dir)Top.
+
+File: dir Node: Top This is the top of the INFO tree
+
+ This (the Directory node) gives a menu of major topics.
+ Typing "q" exits, "?" lists all Info commands, "d" returns here,
+ "h" gives a primer for first-timers,
+ "mEmacs<Return>" visits the Emacs topic, etc.
+
+ In Emacs, you can click mouse button 2 on a menu item or cross reference
+ to select it.
+
+* Menu: The list of major topics begins on the next line.
+
+moobler
+
+### go through the list of files in the skeleton. If an info file
+### exists, grab the ENTRY information from it. If an entry exists
+### use it, otherwise create a minimal dir entry.
+###
+### Then remove that file from the list of existing files. If any
+### additional files remain (ones that don't have a skeleton entry),
+### then generate entries for those in the same way, putting the info for
+### those at the end....
+
+infofiles=`(cd ${INFODIR}; /bin/ls | grep -v '\-[0-9]*$' | egrep -v '^dir$|^dir\.info$|^dir\.orig$')`
+
+# echoing gets clobbered by backquotes; we do it the hard way...
+lines=`wc $SKELETON | awk '{print $1}'`
+line=1
+while [ $lines -ge $line ] ; do
+ # Read one line from the file. This is so that we can echo lines with
+ # whitespace and quoted characters in them.
+ fileline=`awk NR==$line $SKELETON`
+
+ # flag fancy features
+ if [ ! -z "$echoline" ] ; then # echo line
+ echo "$fileline"
+ fileline=
+ echoline=
+ elif [ "${fileline}" = "--" ] ; then # should we echo the next line?
+ echoline=1
+ elif [ "${fileline}" = "%%" ] ; then # eliminate remaining files from dir?
+ skip=1
+ elif [ "${fileline}" = "!!" ] ; then # quit now
+ exit 0
+ fi
+
+ # handle files if they exist
+ for file in $fileline"" ; do # expand wildcards ("" handles blank lines)
+
+ fname=
+
+ if [ -z "$echoline" ] && [ ! -z "$file" ] ; then
+ # Find the file to operate upon. Check both possible names.
+ infoname=`echo $file | sed 's/\.info$//'`
+ noext=
+ ext=
+ if [ -f ${INFODIR}/$infoname ] ; then
+ noext=$infoname
+ fi
+ if [ -f ${INFODIR}/${infoname}.info ] ; then
+ ext=${infoname}.info
+ fi
+
+ # If it exists with both names take what was said in the file.
+ if [ ! -z "$ext" ] && [ ! -z "$noext" ]; then
+ fname=$file
+ warn="### Warning: $ext and $noext both exist! Using ${file}. ###"
+ elif [ ! -z "${noext}${ext}" ]; then
+ # just take the name if it exists only once
+ fname=${noext}${ext}
+ fi
+
+ # if we found something and aren't skipping, do the entry
+ if [ ! -z "$fname" ] ; then
+ if [ -z "$skip" ] ; then
+
+ if [ ! -z "$warn" ] ; then # issue any warning
+ echo $warn
+ warn=
+ fi
+
+ entry=`sed -e '1,/START-INFO-DIR-ENTRY/d' \
+ -e '/END-INFO-DIR-ENTRY/,$d' ${INFODIR}/$fname`
+ if [ ! -z "${entry}" ] ; then
+ echo "${entry}"
+ else
+ echo "* ${infoname}: (${infoname})."
+ fi
+ fi
+
+ # remove the name from the directory listing
+ infofiles=`echo "" ${infofiles} "" | sed -e "s/ ${fname} / /" -e "s/ / /g"`
+
+ fi
+
+ fi
+
+ done
+
+ line=`expr $line + 1`
+done
+
+if [ -z "${infofiles}" ] ; then
+ exit 0
+elif [ $lines -gt 0 ]; then
+ echo
+fi
+
+# Sort remaining files by INFO-DIR-SECTION.
+prevsect=
+filesectdata=`(cd ${INFODIR}; fgrep INFO-DIR-SECTION /dev/null ${infofiles} | \
+ fgrep -v 'INFO-DIR-SECTION Miscellaneous' | \
+ sort -t: -k2 -k1 | tr ' ' '_')`
+for sectdata in ${filesectdata}; do
+ file=`echo ${sectdata} | cut -d: -f1`
+ section=`sed -n -e 's/^INFO-DIR-SECTION //p' ${INFODIR}/${file}`
+ infofiles=`echo "" ${infofiles} "" | sed -e "s/ ${file} / /" -e "s/ / /g"`
+
+ if [ "${prevsect}" != "${section}" ] ; then
+ if [ ! -z "${prevsect}" ] ; then
+ echo ""
+ fi
+ echo "${section}"
+ prevsect="${section}"
+ fi
+
+ infoname=`echo $file | sed 's/\.info$//'`
+ entry=`sed -e '1,/START-INFO-DIR-ENTRY/d' \
+ -e '/END-INFO-DIR-ENTRY/,$d' ${INFODIR}/${file}`
+ if [ ! -z "${entry}" ] ; then
+ echo "${entry}"
+ elif [ ! -d "${INFODIR}/${file}" ] ; then
+ echo "* ${infoname}: (${infoname})."
+ fi
+done
+
+# Process miscellaneous files.
+for file in ${infofiles}; do
+ if [ ! -z "${prevsect}" ] ; then
+ echo ""
+ echo "Miscellaneous"
+ prevsect=""
+ fi
+
+ infoname=`echo $file | sed 's/\.info$//'`
+ entry=`sed -e '1,/START-INFO-DIR-ENTRY/d' \
+ -e '/END-INFO-DIR-ENTRY/,$d' ${INFODIR}/${file}`
+
+ if [ ! -z "${entry}" ] ; then
+ echo "${entry}"
+ elif [ ! -d "${INFODIR}/${file}" ] ; then
+ echo "* ${infoname}: (${infoname})."
+ fi
+done
diff --git a/Build/source/utils/texinfo/util/gendocs.sh b/Build/source/utils/texinfo/util/gendocs.sh
new file mode 100755
index 00000000000..27d4f52d653
--- /dev/null
+++ b/Build/source/utils/texinfo/util/gendocs.sh
@@ -0,0 +1,285 @@
+#!/bin/sh
+# gendocs.sh -- generate a GNU manual in many formats. This script is
+# mentioned in maintain.texi. See the help message below for usage details.
+# $Id: gendocs.sh,v 1.13 2004/09/01 11:40:20 karl Exp $
+#
+# Copyright (C) 2003, 2004 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 2, 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, you can either send email to this
+# program's maintainer or write to: The Free Software Foundation,
+# Inc.; 59 Temple Place, Suite 330; Boston, MA 02111-1307, USA.
+#
+# Original author: Mohit Agarwal.
+# Send bug reports and any other correspondence to bug-texinfo@gnu.org.
+
+prog="`basename \"$0\"`"
+srcdir=`pwd`
+
+scripturl="http://savannah.gnu.org/cgi-bin/viewcvs/texinfo/texinfo/util/gendocs.sh"
+templateurl="http://savannah.gnu.org/cgi-bin/viewcvs/texinfo/texinfo/util/gendocs_template"
+
+: ${MAKEINFO="makeinfo"}
+: ${TEXI2DVI="texi2dvi -t @finalout"}
+: ${DVIPS="dvips"}
+: ${DOCBOOK2TXT="docbook2txt"}
+: ${DOCBOOK2HTML="docbook2html"}
+: ${DOCBOOK2PDF="docbook2pdf"}
+: ${DOCBOOK2PS="docbook2ps"}
+: ${GENDOCS_TEMPLATE_DIR="."}
+unset CDPATH
+
+rcs_revision='$Revision: 1.13 $'
+rcs_version=`set - $rcs_revision; echo $2`
+program=`echo $0 | sed -e 's!.*/!!'`
+version="gendocs.sh $rcs_version
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+There is NO warranty. You may redistribute this software
+under the terms of the GNU General Public License.
+For more information about these matters, see the files named COPYING."
+
+usage="Usage: $prog [OPTION]... PACKAGE MANUAL-TITLE
+
+Generate various output formats from PACKAGE.texinfo (or .texi or .txi) source.
+See the GNU Maintainers document for a more extensive discussion:
+ http://www.gnu.org/prep/maintain_toc.html
+
+Options:
+ -o OUTDIR write files into OUTDIR, instead of manual/.
+ --docbook convert to DocBook too (xml, txt, html, pdf and ps).
+ --html ARG pass indicated ARG to makeinfo for HTML targets.
+ --help display this help and exit successfully.
+ --version display version information and exit successfully.
+
+Simple example: $prog emacs \"GNU Emacs Manual\"
+
+Typical sequence:
+ cd YOURPACKAGESOURCE/doc
+ wget \"$scripturl\"
+ wget \"$templateurl\"
+ $prog YOURMANUAL \"GNU YOURMANUAL - One-line description\"
+
+Output will be in a new subdirectory \"manual\" (by default, use -o OUTDIR
+to override). Move all the new files into your web CVS tree, as
+explained in the Web Pages node of maintain.texi.
+
+MANUAL-TITLE is included as part of the HTML <title> of the overall
+manual/index.html file. It should include the name of the package being
+documented. manual/index.html is created by substitution from the file
+$GENDOCS_TEMPLATE_DIR/gendocs_template. (Feel free to modify the
+generic template for your own purposes.)
+
+If you have several manuals, you'll need to run this script several
+times with different YOURMANUAL values, specifying a different output
+directory with -o each time. Then write (by hand) an overall index.html
+with links to them all.
+
+You can set the environment variables MAKEINFO, TEXI2DVI, and DVIPS to
+control the programs that get executed, and GENDOCS_TEMPLATE_DIR to
+control where the gendocs_template file is looked for.
+
+Email bug reports or enhancement requests to bug-texinfo@gnu.org.
+"
+
+calcsize()
+{
+ size="`ls -ksl $1 | awk '{print $1}'`"
+ echo $size
+}
+
+outdir=manual
+html=
+PACKAGE=
+MANUAL_TITLE=
+
+while test $# -gt 0; do
+ case $1 in
+ --help) echo "$usage"; exit 0;;
+ --version) echo "$version"; exit 0;;
+ -o) shift; outdir=$1;;
+ --docbook) docbook=yes;;
+ --html) shift; html=$1;;
+ -*)
+ echo "$0: Unknown or ambiguous option \`$1'." >&2
+ echo "$0: Try \`--help' for more information." >&2
+ exit 1;;
+ *)
+ if test -z "$PACKAGE"; then
+ PACKAGE=$1
+ elif test -z "$MANUAL_TITLE"; then
+ MANUAL_TITLE=$1
+ else
+ echo "$0: extra non-option argument \`$1'." >&2
+ exit 1
+ fi;;
+ esac
+ shift
+done
+
+if test -s $srcdir/$PACKAGE.texinfo; then
+ srcfile=$srcdir/$PACKAGE.texinfo
+elif test -s $srcdir/$PACKAGE.texi; then
+ srcfile=$srcdir/$PACKAGE.texi
+elif test -s $srcdir/$PACKAGE.txi; then
+ srcfile=$srcdir/$PACKAGE.txi
+else
+ echo "$0: cannot find .texinfo or .texi or .txi for $PACKAGE in $srcdir." >&2
+ exit 1
+fi
+
+if test ! -r $GENDOCS_TEMPLATE_DIR/gendocs_template; then
+ echo "$0: cannot read $GENDOCS_TEMPLATE_DIR/gendocs_template." >&2
+ echo "$0: it is available from $templateurl." >&2
+ exit 1
+fi
+
+echo Generating output formats for $srcfile
+
+cmd="${MAKEINFO} -o $PACKAGE.info $srcfile"
+echo "Generating info files... ($cmd)"
+$cmd
+mkdir -p $outdir/
+tar czf $outdir/$PACKAGE.info.tar.gz $PACKAGE.info*
+info_tgz_size="`calcsize $outdir/$PACKAGE.info.tar.gz`"
+# do not mv the info files, there's no point in having them available
+# separately on the web.
+
+cmd="${TEXI2DVI} $srcfile"
+echo "Generating dvi ... ($cmd)"
+$cmd
+
+# now, before we compress dvi:
+echo Generating postscript...
+${DVIPS} $PACKAGE -o
+gzip -f -9 $PACKAGE.ps
+ps_gz_size="`calcsize $PACKAGE.ps.gz`"
+mv $PACKAGE.ps.gz $outdir/
+
+# compress/finish dvi:
+gzip -f -9 $PACKAGE.dvi
+dvi_gz_size="`calcsize $PACKAGE.dvi.gz`"
+mv $PACKAGE.dvi.gz $outdir/
+
+cmd="${TEXI2DVI} --pdf $srcfile"
+echo "Generating pdf ... ($cmd)"
+$cmd
+pdf_size="`calcsize $PACKAGE.pdf`"
+mv $PACKAGE.pdf $outdir/
+
+cmd="${MAKEINFO} -o $PACKAGE.txt --no-split --no-headers $srcfile"
+echo "Generating ASCII... ($cmd)"
+$cmd
+ascii_size="`calcsize $PACKAGE.txt`"
+gzip -f -9 -c $PACKAGE.txt >$outdir/$PACKAGE.txt.gz
+ascii_gz_size="`calcsize $outdir/$PACKAGE.txt.gz`"
+mv $PACKAGE.txt $outdir/
+
+cmd="${MAKEINFO} --no-split --html -o $PACKAGE.html $html $srcfile"
+echo "Generating monolithic html... ($cmd)"
+rm -rf $PACKAGE.html # in case a directory is left over
+$cmd
+html_mono_size="`calcsize $PACKAGE.html`"
+gzip -f -9 -c $PACKAGE.html >$outdir/$PACKAGE.html.gz
+html_mono_gz_size="`calcsize $outdir/$PACKAGE.html.gz`"
+mv $PACKAGE.html $outdir/
+
+cmd="${MAKEINFO} --html -o $PACKAGE.html $html $srcfile"
+echo "Generating html by node... ($cmd)"
+$cmd
+split_html_dir=$PACKAGE.html
+(
+ cd ${split_html_dir} || exit 1
+ tar -czf ../$outdir/${PACKAGE}.html_node.tar.gz -- *.html
+)
+html_node_tgz_size="`calcsize $outdir/${PACKAGE}.html_node.tar.gz`"
+rm -f $outdir/html_node/*.html
+mkdir -p $outdir/html_node/
+mv ${split_html_dir}/*.html $outdir/html_node/
+rmdir ${split_html_dir}
+
+echo Making .tar.gz for sources...
+srcfiles=`ls *.texinfo *.texi *.txi *.eps 2>/dev/null`
+tar cvzfh $outdir/$PACKAGE.texi.tar.gz $srcfiles
+texi_tgz_size="`calcsize $outdir/$PACKAGE.texi.tar.gz`"
+
+if test -n "$docbook"; then
+ cmd="${MAKEINFO} -o - --docbook $srcfile > ${srcdir}/$PACKAGE-db.xml"
+ echo "Generating docbook XML... $(cmd)"
+ eval $cmd
+ docbook_xml_size="`calcsize $PACKAGE-db.xml`"
+ gzip -f -9 -c $PACKAGE-db.xml >$outdir/$PACKAGE-db.xml.gz
+ docbook_xml_gz_size="`calcsize $outdir/$PACKAGE-db.xml.gz`"
+ mv $PACKAGE-db.xml $outdir/
+
+ cmd="${DOCBOOK2HTML} -o $split_html_db_dir ${outdir}/$PACKAGE-db.xml"
+ echo "Generating docbook HTML... ($cmd)"
+ $cmd
+ split_html_db_dir=html_node_db
+ (
+ cd ${split_html_db_dir} || exit 1
+ tar -czf ../$outdir/${PACKAGE}.html_node_db.tar.gz -- *.html
+ )
+ html_node_db_tgz_size="`calcsize $outdir/${PACKAGE}.html_node_db.tar.gz`"
+ rm -f $outdir/html_node_db/*.html
+ mkdir -p $outdir/html_node_db
+ mv ${split_html_db_dir}/*.html $outdir/html_node_db/
+ rmdir ${split_html_db_dir}
+
+ cmd="${DOCBOOK2TXT} ${outdir}/$PACKAGE-db.xml"
+ echo "Generating docbook ASCII... ($cmd)"
+ $cmd
+ docbook_ascii_size="`calcsize $PACKAGE-db.txt`"
+ mv $PACKAGE-db.txt $outdir/
+
+ cmd="${DOCBOOK2PS} ${outdir}/$PACKAGE-db.xml"
+ echo "Generating docbook PS... $(cmd)"
+ $cmd
+ gzip -f -9 -c $PACKAGE-db.ps >$outdir/$PACKAGE-db.ps.gz
+ docbook_ps_gz_size="`calcsize $outdir/$PACKAGE-db.ps.gz`"
+ mv $PACKAGE-db.ps $outdir/
+
+ cmd="${DOCBOOK2PDF} ${outdir}/$PACKAGE-db.xml"
+ echo "Generating docbook PDF... ($cmd)"
+ $cmd
+ docbook_pdf_size="`calcsize $PACKAGE-db.pdf`"
+ mv $PACKAGE-db.pdf $outdir/
+fi
+
+echo Writing index file...
+curdate="`date '+%B %d, %Y'`"
+sed \
+ -e "s!%%TITLE%%!$MANUAL_TITLE!g" \
+ -e "s!%%DATE%%!$curdate!g" \
+ -e "s!%%PACKAGE%%!$PACKAGE!g" \
+ -e "s!%%HTML_MONO_SIZE%%!$html_mono_size!g" \
+ -e "s!%%HTML_MONO_GZ_SIZE%%!$html_mono_gz_size!g" \
+ -e "s!%%HTML_NODE_TGZ_SIZE%%!$html_node_tgz_size!g" \
+ -e "s!%%INFO_TGZ_SIZE%%!$info_tgz_size!g" \
+ -e "s!%%DVI_GZ_SIZE%%!$dvi_gz_size!g" \
+ -e "s!%%PDF_SIZE%%!$pdf_size!g" \
+ -e "s!%%PS_GZ_SIZE%%!$ps_gz_size!g" \
+ -e "s!%%ASCII_SIZE%%!$ascii_size!g" \
+ -e "s!%%ASCII_GZ_SIZE%%!$ascii_gz_size!g" \
+ -e "s!%%TEXI_TGZ_SIZE%%!$texi_tgz_size!g" \
+ -e "s!%%DOCBOOK_HTML_NODE_TGZ_SIZE%%!$html_node_db_tgz_size!g" \
+ -e "s!%%DOCBOOK_ASCII_SIZE%%!$docbook_ascii_size!g" \
+ -e "s!%%DOCBOOK_PS_GZ_SIZE%%!$docbook_ps_gz_size!g" \
+ -e "s!%%DOCBOOK_PDF_SIZE%%!$docbook_pdf_size!g" \
+ -e "s!%%DOCBOOK_XML_SIZE%%!$docbook_xml_size!g" \
+ -e "s!%%DOCBOOK_XML_GZ_SIZE%%!$docbook_xml_gz_size!g" \
+ -e "s,%%SCRIPTURL%%,$scripturl,g" \
+ -e "s!%%SCRIPTNAME%%!$prog!g" \
+$GENDOCS_TEMPLATE_DIR/gendocs_template >$outdir/index.html
+
+echo "Done! See $outdir/ subdirectory for new files."
diff --git a/Build/source/utils/texinfo/util/gendocs_template b/Build/source/utils/texinfo/util/gendocs_template
new file mode 100755
index 00000000000..6fb2cf950ba
--- /dev/null
+++ b/Build/source/utils/texinfo/util/gendocs_template
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<!-- $Id: gendocs_template,v 1.6 2004/09/23 13:16:19 karl Exp $ -->
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+
+<head>
+<title>%%TITLE%% - GNU Project - Free Software Foundation (FSF)</title>
+<meta http-equiv="content-type" content='text/html; charset=utf-8' />
+<link rel="stylesheet" type="text/css" href="/gnu.css" />
+<link rev="made" href="webmasters@gnu.org" />
+</head>
+
+<!-- This document is in XML, and xhtml 1.0 -->
+<!-- Please make sure to properly nest your tags -->
+<!-- and ensure that your final document validates -->
+<!-- consistent with W3C xhtml 1.0 and CSS standards -->
+<!-- See validator.w3.org -->
+
+<body>
+
+<h3>%%TITLE%%</h3>
+
+<address>Free Software Foundation</address>
+<address>last updated %%DATE%%</address>
+<p>
+<a href="/graphics/gnu-head.jpg">
+ <img src="/graphics/gnu-head-sm.jpg"
+ alt=" [image of the head of a GNU] "
+ width="129" height="122" />
+</a>
+<a href="/philosophy/gif.html">(no gifs due to patent problems)</a>
+</p>
+<hr />
+
+<p>This manual (%%PACKAGE%%) is available in the following formats:</p>
+
+<ul>
+ <li><a href="%%PACKAGE%%.html">HTML
+ (%%HTML_MONO_SIZE%%K characters)</a> - entirely on one web page.</li>
+ <li><a href="html_node/index.html">HTML</a> - with one web page per
+ node.</li>
+ <li><a href="%%PACKAGE%%.html.gz">HTML compressed
+ (%%HTML_MONO_GZ_SIZE%%K gzipped characters)</a> - entirely on
+ one web page.</li>
+ <li><a href="%%PACKAGE%%.html_node.tar.gz">HTML compressed
+ (%%HTML_NODE_TGZ_SIZE%%K gzipped tar file)</a> -
+ with one web page per node.</li>
+ <li><a href="%%PACKAGE%%.info.tar.gz">Info document
+ (%%INFO_TGZ_SIZE%%K characters gzipped tar file)</a>.</li>
+ <li><a href="%%PACKAGE%%.txt">ASCII text
+ (%%ASCII_SIZE%%K characters)</a>.</li>
+ <li><a href="%%PACKAGE%%.txt.gz">ASCII text compressed
+ (%%ASCII_GZ_SIZE%%K gzipped characters)</a>.</li>
+ <li><a href="%%PACKAGE%%.dvi.gz">TeX dvi file
+ (%%DVI_GZ_SIZE%%K characters gzipped)</a>.</li>
+ <li><a href="%%PACKAGE%%.ps.gz">PostScript file
+ (%%PS_GZ_SIZE%%K characters gzipped)</a>.</li>
+ <li><a href="%%PACKAGE%%.pdf">PDF file
+ (%%PDF_SIZE%%K characters)</a>.</li>
+ <li><a href="%%PACKAGE%%.texi.tar.gz">Texinfo source
+ (%%TEXI_TGZ_SIZE%%K characters gzipped tar file)</a></li>
+</ul>
+
+<p>(This page generated by the <a href="%%SCRIPTURL%%">%%SCRIPTNAME%%
+script</a>.)</p>
+
+<div class="copyright">
+<p>
+Return to the <a href="/home.html">GNU Project home page</a>.
+</p>
+
+<p>
+Please send FSF &amp; GNU inquiries to
+<a href="mailto:gnu@gnu.org"><em>gnu@gnu.org</em></a>.
+There are also <a href="/home.html#ContactInfo">other ways to contact</a>
+the FSF.
+<br />
+Please send broken links and other corrections (or suggestions) to
+<a href="mailto:webmasters@gnu.org"><em>webmasters@gnu.org</em></a>.
+</p>
+
+<p>
+Copyright (C) 2004 Free Software Foundation, Inc.,
+59 Temple Place - Suite 330, Boston, MA 02111, USA
+<br />
+Verbatim copying and distribution of this entire article is
+permitted in any medium, provided this notice is preserved.
+</p>
+
+<p>
+Updated:
+<!-- timestamp start -->
+$Date: 2004/09/23 13:16:19 $ $Author: karl $
+<!-- timestamp end -->
+</p>
+</div>
+
+</body>
+</html>
diff --git a/Build/source/utils/texinfo/util/infosrch b/Build/source/utils/texinfo/util/infosrch
new file mode 100755
index 00000000000..af4a9a6290d
--- /dev/null
+++ b/Build/source/utils/texinfo/util/infosrch
@@ -0,0 +1,104 @@
+#!/usr/local/bin/perl -w
+# $Id: infosrch,v 1.2 2004/04/11 17:56:47 karl Exp $
+# infosrch does a regex search on an info manual.
+# By Harry Putnam <reader@newsguy.com>.
+
+($myscript = $0) =~ s:^.*/::;
+$six = '';
+
+if($ARGV[0] eq "help"){
+ &usage;
+ exit;
+}
+if($ARGV[0] eq "-e"){
+ shift;
+ $six = "true";
+}
+if(!$ARGV[1]){
+ &usage;
+ exit;
+}
+
+$target = shift;
+$regex = shift;
+
+$shell_proc = "info --output - --subnodes 2>/dev/null $target";
+
+open(SHELL_PROC," $shell_proc|");
+while(<SHELL_PROC>){
+ chomp;
+ push @lines,$_;
+}
+close(SHELL_PROC);
+$cnt = 0;
+for(@lines){
+ if(/$regex/ && !$six){
+ print "$target\n $lines[($cnt-1)]\n<$cnt> $lines[$cnt]\n $lines[($cnt+1)]\n";
+ print "-- \n";
+ }elsif(/$regex/ && $six){
+ print "$target\n";
+ if($lines[($cnt-6)]){
+ print " $lines[($cnt-6)]\n";
+ }
+ if($lines[($cnt-5)]){
+ print " $lines[($cnt-5)]\n";
+ }
+ if($lines[($cnt-4)]){
+ print " $lines[($cnt-4)]\n";
+ }
+ if($lines[($cnt-3)]){
+ print " $lines[($cnt-3)]\n";
+ }
+ if($lines[($cnt-2)]){
+ print " $lines[($cnt-2)]\n";
+ }
+ if($lines[($cnt-1)]){
+ print " $lines[($cnt-1)]\n";
+ }
+ if($lines[$cnt]){
+ print "$cnt $lines[$cnt]\n";
+ }
+ if($lines[($cnt+1)]){
+ print " $lines[($cnt+1)]\n";
+ }
+ if($lines[($cnt+2)]){
+ print " $lines[($cnt+2)]\n";
+ }
+ if($lines[($cnt+3)]){
+ print " $lines[($cnt+3)]\n";
+ }
+ if($lines[($cnt+4)]){
+ print " $lines[($cnt+4)]\n";
+ }
+ if($lines[($cnt+5)]){
+ print " $lines[($cnt+5)]\n";
+ }
+ if($lines[($cnt+6)]){
+ print " $lines[($cnt+6)]\n";
+ }
+ print "-- \n";
+ }
+ $cnt++;
+}
+
+sub usage {
+ print <<EOM;
+
+Purpose: Extract full text from info node and search it by regex
+Usage: $myscript [-e] TARGET REGEX
+
+Where TARGET is an info node such as `emacs', `bash' etc, and
+REGEX is what you want to find in it.
+
+The -e flag is not required but if used then 6 lines preceding and six
+lines following any hits will be printed. The default (with no -e flag)
+is to print one line before and after.
+
+The output has the line number prepended to the line containing the
+actual regex.
+
+Info command used:
+ info --output - --subnodes 2>/dev/null TARGET
+
+EOM
+}
diff --git a/Build/source/utils/texinfo/util/install-info-html b/Build/source/utils/texinfo/util/install-info-html
new file mode 100644
index 00000000000..4d102959d4c
--- /dev/null
+++ b/Build/source/utils/texinfo/util/install-info-html
@@ -0,0 +1,157 @@
+#!@BASH@
+# $Id: install-info-html,v 1.3 2004/04/11 17:56:47 karl Exp $
+
+name=install-info-html
+version=1.0
+
+all=
+index_dir=.
+
+#
+# debugging
+#
+debug_echo=:
+
+
+#
+# print usage
+#
+function help ()
+{
+ cat << EOF
+$name $version
+Install HTML info document.
+
+Usage: $name [OPTION]... [DOCUMENT-DIR]...
+
+Options:
+ -a,--all assume all subdirectories of index to be DOCUMENT-DIRs
+ -d,--dir=DIR set index directory to DIR (default=.)
+ -D,--debug print debugging info
+ -h,--help this help text
+ -v,--version show version
+EOF
+}
+
+
+function cleanup ()
+{
+ $debug_echo "cleaning ($?)..."
+}
+
+trap cleanup 0 9 15
+
+#
+# Find command line options and switches
+#
+
+# "x:" x takes argument
+#
+options="adhvW:"
+#
+# ugh, "\-" is a hack to support long options
+# must be in double quotes for bash-2.0
+
+while getopts "\-:$options" O
+do
+ $debug_echo "O: \`$O'"
+ $debug_echo "arg: \`$OPTARG'"
+ case $O in
+ a)
+ all=yes
+ ;;
+ D)
+ [ "$debug_echo" = "echo" ] && set -x
+ debug_echo=echo
+ ;;
+ h)
+ help;
+ exit 0
+ ;;
+ v)
+ echo $name $version
+ exit 0
+ ;;
+ d)
+ index_dir=$OPTARG
+ ;;
+ # a long option!
+ -)
+ case "$OPTARG" in
+ a*|-a*)
+ all=yes
+ ;;
+ de*|-de*)
+ [ "$debug_echo" = "echo" ] && set -x
+ debug_echo=echo
+ ;;
+ h*|-h*)
+ help;
+ exit 0
+ ;;
+ di*|-di*)
+ index_dir="`expr \"$OPTARG\" ':' '[^=]*=\(.*\)'`"
+ ;;
+ version|-version)
+ echo $name $version
+ exit 0
+ ;;
+ *|-*)
+ echo "$0: invalid option -- \"$OPTARG\""
+ help;
+ exit -1
+ ;;
+ esac
+ esac
+done
+shift `expr $OPTIND - 1`
+
+#
+# Input file name
+#
+if [ -z "$all" ] && [ -z "$1" ]; then
+ help
+ echo "$name: No HTML documents given"
+ exit 2
+fi
+
+if [ -n "$all" ] && [ -n "$1" ]; then
+ echo "$name: --all specified, ignoring DIRECTORY-DIRs"
+fi
+
+if [ -n "$all" ]; then
+ document_dirs=`/bin/ls -d1 $index_dir`
+else
+ document_dirs=$*
+fi
+
+index_file=$index_dir/index.html
+rm -f $index_file
+echo -n "$name: Writing index: $index_file..."
+
+# head
+cat >> $index_file <<EOF
+<html>
+<head><title>Info documentation index</title></head>
+<body>
+<h1>Info documentation index</h1>
+This is the directory file \`index.html' a.k.a. \`DIR', which contains the
+topmost node of the HTML Info hierarchy.
+<p>
+This is all very much Work in Progress (WiP).
+<p>
+<ul>
+EOF
+
+#list
+for i in $document_dirs; do
+ echo "<li> <a href=\"$i/$i.html\">$i</a></li>"
+done >> $index_file
+
+# foot
+cat >> $index_file <<EOF
+</ul>
+</body>
+</html>
+EOF
+echo
diff --git a/Build/source/utils/texinfo/util/install-info.c b/Build/source/utils/texinfo/util/install-info.c
new file mode 100644
index 00000000000..bbc7a8c25a5
--- /dev/null
+++ b/Build/source/utils/texinfo/util/install-info.c
@@ -0,0 +1,1590 @@
+/* install-info -- create Info directory entry(ies) for an Info file.
+ $Id: install-info.c,v 1.12 2004/04/11 17:56:47 karl Exp $
+
+ Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 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 2 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.*/
+
+#include "system.h"
+#include <getopt.h>
+
+static char *progname = "install-info";
+
+struct spec_entry;
+struct spec_section;
+
+struct line_data *findlines (char *data, int size, int *nlinesp);
+void insert_entry_here (struct spec_entry *entry, int line_number,
+ struct line_data *dir_lines, int n_entries);
+int compare_section_names (const void *s1, const void *s2);
+int compare_entries_text (const void *e1, const void *e2);
+
+/* Data structures. */
+
+
+/* Record info about a single line from a file as read into core. */
+struct line_data
+{
+ /* The start of the line. */
+ char *start;
+ /* The number of characters in the line,
+ excluding the terminating newline. */
+ int size;
+ /* Vector containing pointers to the entries to add before this line.
+ The vector is null-terminated. */
+ struct spec_entry **add_entries_before;
+ /* 1 means output any needed new sections before this line. */
+ int add_sections_before;
+ /* 1 means don't output this line. */
+ int delete;
+};
+
+
+/* This is used for a list of the specified menu section names
+ in which entries should be added. */
+struct spec_section
+{
+ struct spec_section *next;
+ char *name;
+ /* 1 means we have not yet found an existing section with this name
+ in the dir file--so we will need to add a new section. */
+ int missing;
+};
+
+
+/* This is used for a list of the entries specified to be added. */
+struct spec_entry
+{
+ struct spec_entry *next;
+ char *text;
+ int text_len;
+ /* A pointer to the list of sections to which this entry should be
+ added. */
+ struct spec_section *entry_sections;
+ /* A pointer to a section that is beyond the end of the chain whose
+ head is pointed to by entry_sections. */
+ struct spec_section *entry_sections_tail;
+};
+
+
+/* This is used for a list of nodes found by parsing the dir file. */
+struct node
+{
+ struct node *next;
+ /* The node name. */
+ char *name;
+ /* The line number of the line where the node starts.
+ This is the line that contains control-underscore. */
+ int start_line;
+ /* The line number of the line where the node ends,
+ which is the end of the file or where the next line starts. */
+ int end_line;
+ /* Start of first line in this node's menu
+ (the line after the * Menu: line). */
+ char *menu_start;
+ /* The start of the chain of sections in this node's menu. */
+ struct menu_section *sections;
+ /* The last menu section in the chain. */
+ struct menu_section *last_section;
+};
+
+
+/* This is used for a list of sections found in a node's menu.
+ Each struct node has such a list in the sections field. */
+struct menu_section
+{
+ struct menu_section *next;
+ char *name;
+ /* Line number of start of section. */
+ int start_line;
+ /* Line number of end of section. */
+ int end_line;
+};
+
+/* This table defines all the long-named options, says whether they
+ use an argument, and maps them into equivalent single-letter options. */
+
+struct option longopts[] =
+{
+ { "delete", no_argument, NULL, 'r' },
+ { "dir-file", required_argument, NULL, 'd' },
+ { "entry", required_argument, NULL, 'e' },
+ { "help", no_argument, NULL, 'h' },
+ { "infodir", required_argument, NULL, 'D' },
+ { "info-dir", required_argument, NULL, 'D' },
+ { "info-file", required_argument, NULL, 'i' },
+ { "item", required_argument, NULL, 'e' },
+ { "quiet", no_argument, NULL, 'q' },
+ { "remove", no_argument, NULL, 'r' },
+ { "section", required_argument, NULL, 's' },
+ { "version", no_argument, NULL, 'V' },
+ { 0 }
+};
+
+/* Error message functions. */
+
+/* Print error message. S1 is printf control string, S2 and S3 args for it. */
+
+/* VARARGS1 */
+void
+error (const char *s1, const char *s2, const char *s3)
+{
+ fprintf (stderr, "%s: ", progname);
+ fprintf (stderr, s1, s2, s3);
+ putc ('\n', stderr);
+}
+
+/* VARARGS1 */
+void
+warning (const char *s1, const char *s2, const char *s3)
+{
+ fprintf (stderr, _("%s: warning: "), progname);
+ fprintf (stderr, s1, s2, s3);
+ putc ('\n', stderr);
+}
+
+/* Print error message and exit. */
+
+void
+fatal (const char *s1, const char *s2, const char *s3)
+{
+ error (s1, s2, s3);
+ xexit (1);
+}
+
+/* Return a newly-allocated string
+ whose contents concatenate those of S1, S2, S3. */
+char *
+concat (const char *s1, const char *s2, const char *s3)
+{
+ int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3);
+ char *result = (char *) xmalloc (len1 + len2 + len3 + 1);
+
+ strcpy (result, s1);
+ strcpy (result + len1, s2);
+ strcpy (result + len1 + len2, s3);
+ *(result + len1 + len2 + len3) = 0;
+
+ return result;
+}
+
+/* Return a string containing SIZE characters
+ copied from starting at STRING. */
+
+char *
+copy_string (const char *string, int size)
+{
+ int i;
+ char *copy = (char *) xmalloc (size + 1);
+ for (i = 0; i < size; i++)
+ copy[i] = string[i];
+ copy[size] = 0;
+ return copy;
+}
+
+/* Print fatal error message based on errno, with file name NAME. */
+
+void
+pfatal_with_name (const char *name)
+{
+ char *s = concat ("", strerror (errno), _(" for %s"));
+ fatal (s, name, 0);
+}
+
+/* Compare the menu item names in LINE1 (line length LEN1)
+ and LINE2 (line length LEN2). Return 1 if the item name
+ in LINE1 is less, 0 otherwise. */
+
+static int
+menu_line_lessp (char *line1, int len1, char *line2, int len2)
+{
+ int minlen = (len1 < len2 ? len1 : len2);
+ int i;
+
+ for (i = 0; i < minlen; i++)
+ {
+ /* If one item name is a prefix of the other,
+ the former one is less. */
+ if (line1[i] == ':' && line2[i] != ':')
+ return 1;
+ if (line2[i] == ':' && line1[i] != ':')
+ return 0;
+ /* If they both continue and differ, one is less. */
+ if (line1[i] < line2[i])
+ return 1;
+ if (line1[i] > line2[i])
+ return 0;
+ }
+ /* With a properly formatted dir file,
+ we can only get here if the item names are equal. */
+ return 0;
+}
+
+/* Compare the menu item names in LINE1 (line length LEN1)
+ and LINE2 (line length LEN2). Return 1 if the item names are equal,
+ 0 otherwise. */
+
+static int
+menu_line_equal (char *line1, int len1, char *line2, int len2)
+{
+ int minlen = (len1 < len2 ? len1 : len2);
+ int i;
+
+ for (i = 0; i < minlen; i++)
+ {
+ /* If both item names end here, they are equal. */
+ if (line1[i] == ':' && line2[i] == ':')
+ return 1;
+ /* If they both continue and differ, one is less. */
+ if (line1[i] != line2[i])
+ return 0;
+ }
+ /* With a properly formatted dir file,
+ we can only get here if the item names are equal. */
+ return 1;
+}
+
+
+/* Given the full text of a menu entry, null terminated,
+ return just the menu item name (copied). */
+
+char *
+extract_menu_item_name (char *item_text)
+{
+ char *p;
+
+ if (*item_text == '*')
+ item_text++;
+ while (*item_text == ' ')
+ item_text++;
+
+ p = item_text;
+ while (*p && *p != ':') p++;
+ return copy_string (item_text, p - item_text);
+}
+
+/* Given the full text of a menu entry, terminated by null or newline,
+ return just the menu item file (copied). */
+
+char *
+extract_menu_file_name (char *item_text)
+{
+ char *p = item_text;
+
+ /* If we have text that looks like * ITEM: (FILE)NODE...,
+ extract just FILE. Otherwise return "(none)". */
+
+ if (*p == '*')
+ p++;
+ while (*p == ' ')
+ p++;
+
+ /* Skip to and past the colon. */
+ while (*p && *p != '\n' && *p != ':') p++;
+ if (*p == ':') p++;
+
+ /* Skip past the open-paren. */
+ while (1)
+ {
+ if (*p == '(')
+ break;
+ else if (*p == ' ' || *p == '\t')
+ p++;
+ else
+ return "(none)";
+ }
+ p++;
+
+ item_text = p;
+
+ /* File name ends just before the close-paren. */
+ while (*p && *p != '\n' && *p != ')') p++;
+ if (*p != ')')
+ return "(none)";
+
+ return copy_string (item_text, p - item_text);
+}
+
+
+
+/* Return FNAME with any [.info][.gz] suffix removed. */
+
+static char *
+strip_info_suffix (char *fname)
+{
+ char *ret = xstrdup (fname);
+ unsigned len = strlen (ret);
+
+ if (len > 3 && FILENAME_CMP (ret + len - 3, ".gz") == 0)
+ {
+ len -= 3;
+ ret[len] = 0;
+ }
+ else if (len > 4 && FILENAME_CMP (ret + len - 4, ".bz2") == 0)
+ {
+ len -= 4;
+ ret[len] = 0;
+ }
+
+ if (len > 5 && FILENAME_CMP (ret + len - 5, ".info") == 0)
+ {
+ len -= 5;
+ ret[len] = 0;
+ }
+ else if (len > 4 && FILENAME_CMP (ret + len - 4, ".inf") == 0)
+ {
+ len -= 4;
+ ret[len] = 0;
+ }
+#ifdef __MSDOS__
+ else if (len > 4 && (FILENAME_CMP (ret + len - 4, ".inz") == 0
+ || FILENAME_CMP (ret + len - 4, ".igz") == 0))
+ {
+ len -= 4;
+ ret[len] = 0;
+ }
+#endif /* __MSDOS__ */
+
+ return ret;
+}
+
+
+/* Return true if ITEM matches NAME and is followed by TERM_CHAR. ITEM
+ can also be followed by `.gz', `.info.gz', or `.info' (and then
+ TERM_CHAR) and still match. */
+
+static int
+menu_item_equal (const char *item, char term_char, const char *name)
+{
+ int ret;
+ const char *item_basename = item;
+ unsigned name_len = strlen (name);
+
+ /* We must compare the basename in ITEM, since we are passed the
+ basename of the original info file. Otherwise, a new entry like
+ "lilypond/lilypond" won't match "lilypond".
+
+ Actually, it seems to me that we should really compare the whole
+ name, and not just the basename. Couldn't there be dir1/foo.info
+ and dir2/foo.info? Also, it seems like we should be using the
+ filename from the new dir entries, not the filename on the command
+ line. Not worrying about those things right now, though. --karl,
+ 26mar04. */
+ while (*item_basename && !IS_SLASH (*item_basename)
+ && *item_basename != term_char)
+ item_basename++;
+ if (! *item_basename || *item_basename == term_char)
+ item_basename = item; /* no /, use original */
+ else
+ item_basename++; /* have /, move past it */
+
+ /* First, ITEM must actually match NAME (usually it won't). */
+ ret = strncasecmp (item_basename, name, name_len) == 0;
+ if (ret)
+ {
+ /* Then, `foobar' doesn't match `foo', so be sure we've got all of
+ ITEM. The various suffixes should never actually appear in the
+ dir file, but sometimes people put them in. */
+ static char *suffixes[]
+ = { "", ".info.gz", ".info", ".inf", ".gz",
+#ifdef __MSDOS__
+ ".inz", ".igz",
+#endif
+ NULL };
+ unsigned i;
+ ret = 0;
+ for (i = 0; !ret && suffixes[i]; i++)
+ {
+ char *suffix = suffixes[i];
+ unsigned suffix_len = strlen (suffix);
+ ret = strncasecmp (item_basename + name_len, suffix, suffix_len) == 0
+ && item_basename[name_len + suffix_len] == term_char;
+ }
+ }
+
+ return ret;
+}
+
+
+
+void
+suggest_asking_for_help (void)
+{
+ fprintf (stderr, _("\tTry `%s --help' for a complete list of options.\n"),
+ progname);
+ xexit (1);
+}
+
+void
+print_help (void)
+{
+ printf (_("Usage: %s [OPTION]... [INFO-FILE [DIR-FILE]]\n\
+\n\
+Install or delete dir entries from INFO-FILE in the Info directory file\n\
+DIR-FILE.\n\
+\n\
+Options:\n\
+ --delete delete existing entries for INFO-FILE from DIR-FILE;\n\
+ don't insert any new entries.\n\
+ --dir-file=NAME specify file name of Info directory file.\n\
+ This is equivalent to using the DIR-FILE argument.\n\
+ --entry=TEXT insert TEXT as an Info directory entry.\n\
+ TEXT should have the form of an Info menu item line\n\
+ plus zero or more extra lines starting with whitespace.\n\
+ If you specify more than one entry, they are all added.\n\
+ If you don't specify any entries, they are determined\n\
+ from information in the Info file itself.\n\
+ --help display this help and exit.\n\
+ --info-file=FILE specify Info file to install in the directory.\n\
+ This is equivalent to using the INFO-FILE argument.\n\
+ --info-dir=DIR same as --dir-file=DIR/dir.\n\
+ --item=TEXT same as --entry TEXT.\n\
+ An Info directory entry is actually a menu item.\n\
+ --quiet suppress warnings.\n\
+ --remove same as --delete.\n\
+ --section=SEC put this file's entries in section SEC of the directory.\n\
+ If you specify more than one section, all the entries\n\
+ are added in each of the sections.\n\
+ If you don't specify any sections, they are determined\n\
+ from information in the Info file itself.\n\
+ --version display version information and exit.\n\
+"), progname);
+
+ puts (_("\n\
+Email bug reports to bug-texinfo@gnu.org,\n\
+general questions and discussion to help-texinfo@gnu.org.\n\
+Texinfo home page: http://www.gnu.org/software/texinfo/"));
+}
+
+
+/* If DIRFILE does not exist, create a minimal one (or abort). If it
+ already exists, do nothing. */
+
+void
+ensure_dirfile_exists (char *dirfile)
+{
+ int desc = open (dirfile, O_RDONLY);
+ if (desc < 0 && errno == ENOENT)
+ {
+ FILE *f;
+ char *readerr = strerror (errno);
+ close (desc);
+ f = fopen (dirfile, "w");
+ if (f)
+ {
+ fprintf (f, _("This is the file .../info/dir, which contains the\n\
+topmost node of the Info hierarchy, called (dir)Top.\n\
+The first time you invoke Info you start off looking at this node.\n\
+\x1f\n\
+%s\tThis is the top of the INFO tree\n\
+\n\
+ This (the Directory node) gives a menu of major topics.\n\
+ Typing \"q\" exits, \"?\" lists all Info commands, \"d\" returns here,\n\
+ \"h\" gives a primer for first-timers,\n\
+ \"mEmacs<Return>\" visits the Emacs manual, etc.\n\
+\n\
+ In Emacs, you can click mouse button 2 on a menu item or cross reference\n\
+ to select it.\n\
+\n\
+%s\n\
+"), "File: dir,\tNode: Top", /* These keywords must not be translated. */
+ "* Menu:"
+);
+ if (fclose (f) < 0)
+ pfatal_with_name (dirfile);
+ }
+ else
+ {
+ /* Didn't exist, but couldn't open for writing. */
+ fprintf (stderr,
+ _("%s: could not read (%s) and could not create (%s)\n"),
+ dirfile, readerr, strerror (errno));
+ xexit (1);
+ }
+ }
+ else
+ close (desc); /* It already existed, so fine. */
+}
+
+/* Open FILENAME and return the resulting stream pointer. If it doesn't
+ exist, try FILENAME.gz. If that doesn't exist either, call
+ CREATE_CALLBACK (with FILENAME as arg) to create it, if that is
+ non-NULL. If still no luck, fatal error.
+
+ If we do open it, return the actual name of the file opened in
+ OPENED_FILENAME and the compress program to use to (de)compress it in
+ COMPRESSION_PROGRAM. The compression program is determined by the
+ magic number, not the filename. */
+
+FILE *
+open_possibly_compressed_file (char *filename,
+ void (*create_callback) (char *),
+ char **opened_filename, char **compression_program, int *is_pipe)
+{
+ char *local_opened_filename, *local_compression_program;
+ int nread;
+ char data[4];
+ FILE *f;
+
+ /* We let them pass NULL if they don't want this info, but it's easier
+ to always determine it. */
+ if (!opened_filename)
+ opened_filename = &local_opened_filename;
+
+ *opened_filename = filename;
+ f = fopen (*opened_filename, FOPEN_RBIN);
+ if (!f)
+ {
+ *opened_filename = concat (filename, ".gz", "");
+ f = fopen (*opened_filename, FOPEN_RBIN);
+ if (!f)
+ {
+ free (*opened_filename);
+ *opened_filename = concat (filename, ".bz2", "");
+ f = fopen (*opened_filename, FOPEN_RBIN);
+ }
+
+#ifdef __MSDOS__
+ if (!f)
+ {
+ free (*opened_filename);
+ *opened_filename = concat (filename, ".igz", "");
+ f = fopen (*opened_filename, FOPEN_RBIN);
+ }
+ if (!f)
+ {
+ free (*opened_filename);
+ *opened_filename = concat (filename, ".inz", "");
+ f = fopen (*opened_filename, FOPEN_RBIN);
+ }
+#endif
+ if (!f)
+ {
+ if (create_callback)
+ { /* That didn't work either. Create the file if we can. */
+ (*create_callback) (filename);
+
+ /* And try opening it again. */
+ free (*opened_filename);
+ *opened_filename = filename;
+ f = fopen (*opened_filename, FOPEN_RBIN);
+ if (!f)
+ pfatal_with_name (filename);
+ }
+ else
+ pfatal_with_name (filename);
+ }
+ }
+
+ /* Read first few bytes of file rather than relying on the filename.
+ If the file is shorter than this it can't be usable anyway. */
+ nread = fread (data, sizeof (data), 1, f);
+ if (nread != 1)
+ {
+ /* Empty files don't set errno, so we get something like
+ "install-info: No error for foo", which is confusing. */
+ if (nread == 0)
+ fatal (_("%s: empty file"), *opened_filename, 0);
+ pfatal_with_name (*opened_filename);
+ }
+
+ if (!compression_program)
+ compression_program = &local_compression_program;
+
+ if (data[0] == '\x1f' && data[1] == '\x8b')
+#if STRIP_DOT_EXE
+ /* An explicit .exe yields a better diagnostics from popen below
+ if they don't have gzip installed. */
+ *compression_program = "gzip.exe";
+#else
+ *compression_program = "gzip";
+#endif
+ else if(data[0] == 'B' && data[1] == 'Z' && data[2] == 'h')
+#ifndef STRIP_DOT_EXE
+ *compression_program = "bzip2.exe";
+#else
+ *compression_program = "bzip2";
+#endif
+ else if(data[0] == 'B' && data[1] == 'Z' && data[2] == '0')
+#ifndef STRIP_DOT_EXE
+ *compression_program = "bzip.exe";
+#else
+ *compression_program = "bzip";
+#endif
+ else
+ *compression_program = NULL;
+
+ if (*compression_program)
+ { /* It's compressed, so fclose the file and then open a pipe. */
+ char *command = concat (*compression_program," -cd <", *opened_filename);
+ if (fclose (f) < 0)
+ pfatal_with_name (*opened_filename);
+ f = popen (command, "r");
+ if (f)
+ *is_pipe = 1;
+ else
+ pfatal_with_name (command);
+ }
+ else
+ { /* It's a plain file, seek back over the magic bytes. */
+ if (fseek (f, 0, 0) < 0)
+ pfatal_with_name (*opened_filename);
+#if O_BINARY
+ /* Since this is a text file, and we opened it in binary mode,
+ switch back to text mode. */
+ f = freopen (*opened_filename, "r", f);
+#endif
+ *is_pipe = 0;
+ }
+
+ return f;
+}
+
+/* Read all of file FILENAME into memory and return the address of the
+ data. Store the size of the data into SIZEP. If need be, uncompress
+ (i.e., try FILENAME.gz et al. if FILENAME does not exist) and store
+ the actual file name that was opened into OPENED_FILENAME (if it is
+ non-NULL), and the companion compression program (if any, else NULL)
+ into COMPRESSION_PROGRAM (if that is non-NULL). If trouble, do
+ a fatal error. */
+
+char *
+readfile (char *filename, int *sizep,
+ void (*create_callback) (char *), char **opened_filename,
+ char **compression_program)
+{
+ char *real_name;
+ FILE *f;
+ int pipe_p;
+ int filled = 0;
+ int data_size = 8192;
+ char *data = xmalloc (data_size);
+
+ /* If they passed the space for the file name to return, use it. */
+ f = open_possibly_compressed_file (filename, create_callback,
+ opened_filename ? opened_filename
+ : &real_name,
+ compression_program, &pipe_p);
+
+ for (;;)
+ {
+ int nread = fread (data + filled, 1, data_size - filled, f);
+ if (nread < 0)
+ pfatal_with_name (real_name);
+ if (nread == 0)
+ break;
+
+ filled += nread;
+ if (filled == data_size)
+ {
+ data_size += 65536;
+ data = xrealloc (data, data_size);
+ }
+ }
+
+ /* We'll end up wasting space if we're not passing the filename back
+ and it is not just FILENAME, but so what. */
+ /* We need to close the stream, since on some systems the pipe created
+ by popen is simulated by a temporary file which only gets removed
+ inside pclose. */
+ if (pipe_p)
+ pclose (f);
+ else
+ fclose (f);
+
+ *sizep = filled;
+ return data;
+}
+
+/* Output the old dir file, interpolating the new sections
+ and/or new entries where appropriate. If COMPRESSION_PROGRAM is not
+ null, pipe to it to create DIRFILE. Thus if we read dir.gz on input,
+ we'll write dir.gz on output. */
+
+static void
+output_dirfile (char *dirfile, int dir_nlines, struct line_data *dir_lines,
+ int n_entries_to_add, struct spec_entry *entries_to_add,
+ struct spec_section *input_sections, char *compression_program)
+{
+ int i;
+ FILE *output;
+
+ if (compression_program)
+ {
+ char *command = concat (compression_program, ">", dirfile);
+ output = popen (command, "w");
+ }
+ else
+ output = fopen (dirfile, "w");
+
+ if (!output)
+ {
+ perror (dirfile);
+ xexit (1);
+ }
+
+ for (i = 0; i <= dir_nlines; i++)
+ {
+ int j;
+
+ /* If we decided to output some new entries before this line,
+ output them now. */
+ if (dir_lines[i].add_entries_before)
+ for (j = 0; j < n_entries_to_add; j++)
+ {
+ struct spec_entry *this = dir_lines[i].add_entries_before[j];
+ if (this == 0)
+ break;
+ fputs (this->text, output);
+ }
+ /* If we decided to add some sections here
+ because there are no such sections in the file,
+ output them now. */
+ if (dir_lines[i].add_sections_before)
+ {
+ struct spec_section *spec;
+ struct spec_section **sections;
+ int n_sections = 0;
+ struct spec_entry *entry;
+ struct spec_entry **entries;
+ int n_entries = 0;
+
+ /* Count the sections and allocate a vector for all of them. */
+ for (spec = input_sections; spec; spec = spec->next)
+ n_sections++;
+ sections = ((struct spec_section **)
+ xmalloc (n_sections * sizeof (struct spec_section *)));
+
+ /* Fill the vector SECTIONS with pointers to all the sections,
+ and sort them. */
+ j = 0;
+ for (spec = input_sections; spec; spec = spec->next)
+ sections[j++] = spec;
+ qsort (sections, n_sections, sizeof (struct spec_section *),
+ compare_section_names);
+
+ /* Count the entries and allocate a vector for all of them. */
+ for (entry = entries_to_add; entry; entry = entry->next)
+ n_entries++;
+ entries = ((struct spec_entry **)
+ xmalloc (n_entries * sizeof (struct spec_entry *)));
+
+ /* Fill the vector ENTRIES with pointers to all the sections,
+ and sort them. */
+ j = 0;
+ for (entry = entries_to_add; entry; entry = entry->next)
+ entries[j++] = entry;
+ qsort (entries, n_entries, sizeof (struct spec_entry *),
+ compare_entries_text);
+
+ /* Generate the new sections in alphabetical order. In each
+ new section, output all of the entries that belong to that
+ section, in alphabetical order. */
+ for (j = 0; j < n_sections; j++)
+ {
+ spec = sections[j];
+ if (spec->missing)
+ {
+ int k;
+
+ putc ('\n', output);
+ fputs (spec->name, output);
+ putc ('\n', output);
+ for (k = 0; k < n_entries; k++)
+ {
+ struct spec_section *spec1;
+ /* Did they at all want this entry to be put into
+ this section? */
+ entry = entries[k];
+ for (spec1 = entry->entry_sections;
+ spec1 && spec1 != entry->entry_sections_tail;
+ spec1 = spec1->next)
+ {
+ if (!strcmp (spec1->name, spec->name))
+ break;
+ }
+ if (spec1 && spec1 != entry->entry_sections_tail)
+ fputs (entry->text, output);
+ }
+ }
+ }
+
+ free (entries);
+ free (sections);
+ }
+
+ /* Output the original dir lines unless marked for deletion. */
+ if (i < dir_nlines && !dir_lines[i].delete)
+ {
+ fwrite (dir_lines[i].start, 1, dir_lines[i].size, output);
+ putc ('\n', output);
+ }
+ }
+
+ /* Some systems, such as MS-DOS, simulate pipes with temporary files.
+ On those systems, the compressor actually gets run inside pclose,
+ so we must call pclose. */
+ if (compression_program)
+ pclose (output);
+ else
+ fclose (output);
+}
+
+/* Parse the input to find the section names and the entry names it
+ specifies. Return the number of entries to add from this file. */
+int
+parse_input (const struct line_data *lines, int nlines,
+ struct spec_section **sections, struct spec_entry **entries)
+{
+ int n_entries = 0;
+ int prefix_length = strlen ("INFO-DIR-SECTION ");
+ struct spec_section *head = *sections, *tail = NULL;
+ int reset_tail = 0;
+ char *start_of_this_entry = 0;
+ int ignore_sections = *sections != 0;
+ int ignore_entries = *entries != 0;
+
+ int i;
+
+ if (ignore_sections && ignore_entries)
+ return 0;
+
+ /* Loop here processing lines from the input file. Each
+ INFO-DIR-SECTION entry is added to the SECTIONS linked list.
+ Each START-INFO-DIR-ENTRY block is added to the ENTRIES linked
+ list, and all its entries inherit the chain of SECTION entries
+ defined by the last group of INFO-DIR-SECTION entries we have
+ seen until that point. */
+ for (i = 0; i < nlines; i++)
+ {
+ if (!ignore_sections
+ && !strncmp ("INFO-DIR-SECTION ", lines[i].start, prefix_length))
+ {
+ struct spec_section *next
+ = (struct spec_section *) xmalloc (sizeof (struct spec_section));
+ next->name = copy_string (lines[i].start + prefix_length,
+ lines[i].size - prefix_length);
+ next->next = *sections;
+ next->missing = 1;
+ if (reset_tail)
+ {
+ tail = *sections;
+ reset_tail = 0;
+ }
+ *sections = next;
+ head = *sections;
+ }
+ /* If entries were specified explicitly with command options,
+ ignore the entries in the input file. */
+ else if (!ignore_entries)
+ {
+ if (!strncmp ("START-INFO-DIR-ENTRY", lines[i].start, lines[i].size)
+ && sizeof ("START-INFO-DIR-ENTRY") - 1 == lines[i].size)
+ {
+ if (!*sections)
+ {
+ /* We found an entry, but didn't yet see any sections
+ specified. Default to section "Miscellaneous". */
+ *sections = (struct spec_section *)
+ xmalloc (sizeof (struct spec_section));
+ (*sections)->name = "Miscellaneous";
+ (*sections)->next = 0;
+ (*sections)->missing = 1;
+ head = *sections;
+ }
+ /* Next time we see INFO-DIR-SECTION, we will reset the
+ tail pointer. */
+ reset_tail = 1;
+
+ if (start_of_this_entry != 0)
+ fatal (_("START-INFO-DIR-ENTRY without matching END-INFO-DIR-ENTRY"), 0, 0);
+ start_of_this_entry = lines[i + 1].start;
+ }
+ else if (start_of_this_entry)
+ {
+ if ((!strncmp ("* ", lines[i].start, 2)
+ && lines[i].start > start_of_this_entry)
+ || (!strncmp ("END-INFO-DIR-ENTRY",
+ lines[i].start, lines[i].size)
+ && sizeof ("END-INFO-DIR-ENTRY") - 1 == lines[i].size))
+ {
+ /* We found an end of this entry. Allocate another
+ entry, fill its data, and add it to the linked
+ list. */
+ struct spec_entry *next
+ = (struct spec_entry *) xmalloc (sizeof (struct spec_entry));
+ next->text
+ = copy_string (start_of_this_entry,
+ lines[i].start - start_of_this_entry);
+ next->text_len = lines[i].start - start_of_this_entry;
+ next->entry_sections = head;
+ next->entry_sections_tail = tail;
+ next->next = *entries;
+ *entries = next;
+ n_entries++;
+ if (!strncmp ("END-INFO-DIR-ENTRY",
+ lines[i].start, lines[i].size)
+ && sizeof ("END-INFO-DIR-ENTRY") - 1 == lines[i].size)
+ start_of_this_entry = 0;
+ else
+ start_of_this_entry = lines[i].start;
+ }
+ else if (!strncmp ("END-INFO-DIR-ENTRY",
+ lines[i].start, lines[i].size)
+ && sizeof ("END-INFO-DIR-ENTRY") - 1 == lines[i].size)
+ fatal (_("END-INFO-DIR-ENTRY without matching START-INFO-DIR-ENTRY"), 0, 0);
+ }
+ }
+ }
+ if (start_of_this_entry != 0)
+ fatal (_("START-INFO-DIR-ENTRY without matching END-INFO-DIR-ENTRY"),
+ 0, 0);
+
+ /* If we ignored the INFO-DIR-ENTRY directives, we need now go back
+ and plug the names of all the sections we found into every
+ element of the ENTRIES list. */
+ if (ignore_entries && *entries)
+ {
+ struct spec_entry *entry;
+
+ for (entry = *entries; entry; entry = entry->next)
+ {
+ entry->entry_sections = head;
+ entry->entry_sections_tail = tail;
+ }
+ }
+
+ return n_entries;
+}
+
+/* Parse the dir file whose basename is BASE_NAME. Find all the
+ nodes, and their menus, and the sections of their menus. */
+int
+parse_dir_file (struct line_data *lines, int nlines, struct node **nodes,
+ const char *base_name)
+{
+ int node_header_flag = 0;
+ int something_deleted = 0;
+ int i;
+
+ *nodes = 0;
+ for (i = 0; i < nlines; i++)
+ {
+ /* Parse node header lines. */
+ if (node_header_flag)
+ {
+ int j, end;
+ for (j = 0; j < lines[i].size; j++)
+ /* Find the node name and store it in the `struct node'. */
+ if (!strncmp ("Node:", lines[i].start + j, 5))
+ {
+ char *line = lines[i].start;
+ /* Find the start of the node name. */
+ j += 5;
+ while (line[j] == ' ' || line[j] == '\t')
+ j++;
+ /* Find the end of the node name. */
+ end = j;
+ while (line[end] != 0 && line[end] != ',' && line[end] != '\n'
+ && line[end] != '\t')
+ end++;
+ (*nodes)->name = copy_string (line + j, end - j);
+ }
+ node_header_flag = 0;
+ }
+
+ /* Notice the start of a node. */
+ if (*lines[i].start == 037)
+ {
+ struct node *next = (struct node *) xmalloc (sizeof (struct node));
+
+ next->next = *nodes;
+ next->name = NULL;
+ next->start_line = i;
+ next->end_line = 0;
+ next->menu_start = NULL;
+ next->sections = NULL;
+ next->last_section = NULL;
+
+ if (*nodes != 0)
+ (*nodes)->end_line = i;
+ /* Fill in the end of the last menu section
+ of the previous node. */
+ if (*nodes != 0 && (*nodes)->last_section != 0)
+ (*nodes)->last_section->end_line = i;
+
+ *nodes = next;
+
+ /* The following line is the header of this node;
+ parse it. */
+ node_header_flag = 1;
+ }
+
+ /* Notice the lines that start menus. */
+ if (*nodes != 0 && !strncmp ("* Menu:", lines[i].start, 7))
+ (*nodes)->menu_start = lines[i + 1].start;
+
+ /* Notice sections in menus. */
+ if (*nodes != 0
+ && (*nodes)->menu_start != 0
+ && *lines[i].start != '\n'
+ && *lines[i].start != '*'
+ && *lines[i].start != ' '
+ && *lines[i].start != '\t')
+ {
+ /* Add this menu section to the node's list.
+ This list grows in forward order. */
+ struct menu_section *next
+ = (struct menu_section *) xmalloc (sizeof (struct menu_section));
+
+ next->start_line = i + 1;
+ next->next = 0;
+ next->end_line = 0;
+ next->name = copy_string (lines[i].start, lines[i].size);
+ if ((*nodes)->sections)
+ {
+ (*nodes)->last_section->next = next;
+ (*nodes)->last_section->end_line = i;
+ }
+ else
+ (*nodes)->sections = next;
+ (*nodes)->last_section = next;
+ }
+
+ /* Check for an existing entry that should be deleted.
+ Delete all entries which specify this file name. */
+ if (*lines[i].start == '*')
+ {
+ char *q;
+ char *p = lines[i].start;
+
+ p++; /* skip * */
+ while (*p == ' ') p++; /* ignore following spaces */
+ q = p; /* remember this, it's the beginning of the menu item. */
+
+ /* Read menu item. */
+ while (*p != 0 && *p != ':')
+ p++;
+ p++; /* skip : */
+
+ if (*p == ':')
+ { /* XEmacs-style entry, as in * Mew::Messaging. */
+ if (menu_item_equal (q, ':', base_name))
+ {
+ lines[i].delete = 1;
+ something_deleted = 1;
+ }
+ }
+ else
+ { /* Emacs-style entry, as in * Emacs: (emacs). */
+ while (*p == ' ') p++; /* skip spaces after : */
+ if (*p == '(') /* if at parenthesized (FILENAME) */
+ {
+ p++;
+ if (menu_item_equal (p, ')', base_name))
+ {
+ lines[i].delete = 1;
+ something_deleted = 1;
+ }
+ }
+ }
+ }
+
+ /* Treat lines that start with whitespace
+ as continuations; if we are deleting an entry,
+ delete all its continuations as well. */
+ else if (i > 0 && (*lines[i].start == ' ' || *lines[i].start == '\t'))
+ {
+ lines[i].delete = lines[i - 1].delete;
+ }
+ }
+
+ /* Finish the info about the end of the last node. */
+ if (*nodes != 0)
+ {
+ (*nodes)->end_line = nlines;
+ if ((*nodes)->last_section != 0)
+ (*nodes)->last_section->end_line = nlines;
+ }
+
+ return something_deleted;
+}
+
+int
+main (int argc, char **argv)
+{
+ char *opened_dirfilename;
+ char *compression_program;
+ char *infile_sans_info;
+ char *infile = 0, *dirfile = 0;
+
+ /* Record the text of the Info file, as a sequence of characters
+ and as a sequence of lines. */
+ char *input_data = NULL;
+ int input_size = 0;
+ struct line_data *input_lines = NULL;
+ int input_nlines = 0;
+
+ /* Record here the specified section names and directory entries. */
+ struct spec_section *input_sections = NULL;
+ struct spec_entry *entries_to_add = NULL;
+ int n_entries_to_add = 0;
+
+ /* Record the old text of the dir file, as plain characters,
+ as lines, and as nodes. */
+ char *dir_data;
+ int dir_size;
+ int dir_nlines;
+ struct line_data *dir_lines;
+ struct node *dir_nodes;
+
+ /* Nonzero means --delete was specified (just delete existing entries). */
+ int delete_flag = 0;
+ int something_deleted = 0;
+ /* Nonzero means -q was specified. */
+ int quiet_flag = 0;
+
+ int i;
+
+#ifdef HAVE_SETLOCALE
+ /* Set locale via LC_ALL. */
+ setlocale (LC_ALL, "");
+#endif
+
+ /* Set the text message domain. */
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+
+ while (1)
+ {
+ int opt = getopt_long (argc, argv, "i:d:e:s:hHr", longopts, 0);
+
+ if (opt == EOF)
+ break;
+
+ switch (opt)
+ {
+ case 0:
+ /* If getopt returns 0, then it has already processed a
+ long-named option. We should do nothing. */
+ break;
+
+ case 1:
+ abort ();
+
+ case 'd':
+ if (dirfile)
+ {
+ fprintf (stderr, _("%s: already have dir file: %s\n"),
+ progname, dirfile);
+ suggest_asking_for_help ();
+ }
+ dirfile = optarg;
+ break;
+
+ case 'D':
+ if (dirfile)
+ {
+ fprintf (stderr, _("%s: already have dir file: %s\n"),
+ progname, dirfile);
+ suggest_asking_for_help ();
+ }
+ dirfile = concat (optarg, "", "/dir");
+ break;
+
+ case 'e':
+ {
+ struct spec_entry *next
+ = (struct spec_entry *) xmalloc (sizeof (struct spec_entry));
+ int olen = strlen (optarg);
+ if (! (*optarg != 0 && optarg[olen - 1] == '\n'))
+ {
+ optarg = concat (optarg, "\n", "");
+ olen++;
+ }
+ next->text = optarg;
+ next->text_len = olen;
+ next->entry_sections = NULL;
+ next->entry_sections_tail = NULL;
+ next->next = entries_to_add;
+ entries_to_add = next;
+ n_entries_to_add++;
+ }
+ break;
+
+ case 'h':
+ case 'H':
+ print_help ();
+ xexit (0);
+
+ case 'i':
+ if (infile)
+ {
+ fprintf (stderr, _("%s: Specify the Info file only once.\n"),
+ progname);
+ suggest_asking_for_help ();
+ }
+ infile = optarg;
+ break;
+
+ case 'q':
+ quiet_flag = 1;
+ break;
+
+ case 'r':
+ delete_flag = 1;
+ break;
+
+ case 's':
+ {
+ struct spec_section *next
+ = (struct spec_section *) xmalloc (sizeof (struct spec_section));
+ next->name = optarg;
+ next->next = input_sections;
+ next->missing = 1;
+ input_sections = next;
+ }
+ break;
+
+ case 'V':
+ printf ("install-info (GNU %s) %s\n", PACKAGE, VERSION);
+ puts ("");
+ puts ("Copyright (C) 2004 Free Software Foundation, Inc.");
+ printf (_("There is NO warranty. You may redistribute this software\n\
+under the terms of the GNU General Public License.\n\
+For more information about these matters, see the files named COPYING.\n"));
+ xexit (0);
+
+ default:
+ suggest_asking_for_help ();
+ }
+ }
+
+ /* Interpret the non-option arguments as file names. */
+ for (; optind < argc; ++optind)
+ {
+ if (infile == 0)
+ infile = argv[optind];
+ else if (dirfile == 0)
+ dirfile = argv[optind];
+ else
+ error (_("excess command line argument `%s'"), argv[optind], 0);
+ }
+
+ if (!infile)
+ fatal (_("No input file specified; try --help for more information."),
+ 0, 0);
+ if (!dirfile)
+ fatal (_("No dir file specified; try --help for more information."), 0, 0);
+
+ /* Read the Info file and parse it into lines, unless we're deleting. */
+ if (!delete_flag)
+ {
+ input_data = readfile (infile, &input_size, NULL, NULL, NULL);
+ input_lines = findlines (input_data, input_size, &input_nlines);
+ }
+
+ i = parse_input (input_lines, input_nlines,
+ &input_sections, &entries_to_add);
+ if (i > n_entries_to_add)
+ n_entries_to_add = i;
+
+ if (!delete_flag)
+ {
+ if (entries_to_add == 0)
+ { /* No need to abort here, the original info file may not
+ have the requisite Texinfo commands. This is not
+ something an installer should have to correct (it's a
+ problem for the maintainer), and there's no need to cause
+ subsequent parts of `make install' to fail. */
+ warning (_("no info dir entry in `%s'"), infile, 0);
+ xexit (0);
+ }
+
+ /* If the entries came from the command-line arguments, their
+ entry_sections pointers are not yet set. Walk the chain of
+ the entries and for each entry update entry_sections to point
+ to the head of the list of sections where this entry should
+ be put. Note that all the entries specified on the command
+ line get put into ALL the sections we've got, either from the
+ Info file, or (under --section) from the command line,
+ because in the loop below every entry inherits the entire
+ chain of sections. */
+ if (n_entries_to_add > 0 && entries_to_add->entry_sections == NULL)
+ {
+ struct spec_entry *ep;
+
+ /* If we got no sections, default to "Miscellaneous". */
+ if (input_sections == NULL)
+ {
+ input_sections = (struct spec_section *)
+ xmalloc (sizeof (struct spec_section));
+ input_sections->name = "Miscellaneous";
+ input_sections->next = NULL;
+ input_sections->missing = 1;
+ }
+ for (ep = entries_to_add; ep; ep = ep->next)
+ ep->entry_sections = input_sections;
+ }
+ }
+
+ /* Now read in the Info dir file. */
+ dir_data = readfile (dirfile, &dir_size, ensure_dirfile_exists,
+ &opened_dirfilename, &compression_program);
+ dir_lines = findlines (dir_data, dir_size, &dir_nlines);
+
+ /* We will be comparing the entries in the dir file against the
+ current filename, so need to strip off any directory prefix and/or
+ [.info][.gz] suffix. */
+ {
+ char *infile_basename = infile + strlen (infile);
+
+ if (HAVE_DRIVE (infile))
+ infile += 2; /* get past the drive spec X: */
+
+ while (infile_basename > infile && !IS_SLASH (infile_basename[-1]))
+ infile_basename--;
+
+ infile_sans_info = strip_info_suffix (infile_basename);
+ }
+
+ something_deleted
+ = parse_dir_file (dir_lines, dir_nlines, &dir_nodes, infile_sans_info);
+
+ /* Decide where to add the new entries (unless --delete was used).
+ Find the menu sections to add them in.
+ In each section, find the proper alphabetical place to add
+ each of the entries. */
+ if (!delete_flag)
+ {
+ struct node *node;
+ struct menu_section *section;
+ struct spec_section *spec;
+
+ for (node = dir_nodes; node; node = node->next)
+ for (section = node->sections; section; section = section->next)
+ {
+ for (i = section->end_line; i > section->start_line; i--)
+ if (dir_lines[i - 1].size != 0)
+ break;
+ section->end_line = i;
+
+ for (spec = input_sections; spec; spec = spec->next)
+ if (!strcmp (spec->name, section->name))
+ break;
+ if (spec)
+ {
+ int add_at_line = section->end_line;
+ struct spec_entry *entry;
+ /* Say we have found at least one section with this name,
+ so we need not add such a section. */
+ spec->missing = 0;
+ /* For each entry, find the right place in this section
+ to add it. */
+ for (entry = entries_to_add; entry; entry = entry->next)
+ {
+ /* Did they at all want this entry to be put into
+ this section? */
+ for (spec = entry->entry_sections;
+ spec && spec != entry->entry_sections_tail;
+ spec = spec->next)
+ {
+ if (!strcmp (spec->name, section->name))
+ break;
+ }
+ if (!spec || spec == entry->entry_sections_tail)
+ continue;
+
+ /* Subtract one because dir_lines is zero-based,
+ but the `end_line' and `start_line' members are
+ one-based. */
+ for (i = section->end_line - 1;
+ i >= section->start_line - 1; i--)
+ {
+ /* If an entry exists with the same name,
+ and was not marked for deletion
+ (which means it is for some other file),
+ we are in trouble. */
+ if (dir_lines[i].start[0] == '*'
+ && menu_line_equal (entry->text, entry->text_len,
+ dir_lines[i].start,
+ dir_lines[i].size)
+ && !dir_lines[i].delete)
+ fatal (_("menu item `%s' already exists, for file `%s'"),
+ extract_menu_item_name (entry->text),
+ extract_menu_file_name (dir_lines[i].start));
+ if (dir_lines[i].start[0] == '*'
+ && menu_line_lessp (entry->text, entry->text_len,
+ dir_lines[i].start,
+ dir_lines[i].size))
+ add_at_line = i;
+ }
+ insert_entry_here (entry, add_at_line,
+ dir_lines, n_entries_to_add);
+ }
+ }
+ }
+
+ /* Mark the end of the Top node as the place to add any
+ new sections that are needed. */
+ for (node = dir_nodes; node; node = node->next)
+ if (node->name && strcmp (node->name, "Top") == 0)
+ dir_lines[node->end_line].add_sections_before = 1;
+ }
+
+ if (delete_flag && !something_deleted && !quiet_flag)
+ warning (_("no entries found for `%s'; nothing deleted"), infile, 0);
+
+ output_dirfile (opened_dirfilename, dir_nlines, dir_lines, n_entries_to_add,
+ entries_to_add, input_sections, compression_program);
+
+ xexit (0);
+ return 0; /* Avoid bogus warnings. */
+}
+
+/* Divide the text at DATA (of SIZE bytes) into lines.
+ Return a vector of struct line_data describing the lines.
+ Store the length of that vector into *NLINESP. */
+
+struct line_data *
+findlines (char *data, int size, int *nlinesp)
+{
+ int i;
+ int lineflag = 1;
+ int lines_allocated = 511;
+ int filled = 0;
+ struct line_data *lines
+ = xmalloc ((lines_allocated + 1) * sizeof (struct line_data));
+
+ for (i = 0; i < size; i++)
+ {
+ if (lineflag)
+ {
+ if (filled == lines_allocated)
+ {
+ /* try to keep things somewhat page-aligned */
+ lines_allocated = ((lines_allocated + 1) * 2) - 1;
+ lines = xrealloc (lines, (lines_allocated + 1)
+ * sizeof (struct line_data));
+ }
+ lines[filled].start = &data[i];
+ lines[filled].add_entries_before = 0;
+ lines[filled].add_sections_before = 0;
+ lines[filled].delete = 0;
+ if (filled > 0)
+ lines[filled - 1].size
+ = lines[filled].start - lines[filled - 1].start - 1;
+ filled++;
+ }
+ lineflag = (data[i] == '\n');
+ }
+ if (filled > 0)
+ lines[filled - 1].size = &data[i] - lines[filled - 1].start - lineflag;
+
+ /* Do not leave garbage in the last element. */
+ lines[filled].start = NULL;
+ lines[filled].add_entries_before = NULL;
+ lines[filled].add_sections_before = 0;
+ lines[filled].delete = 0;
+ lines[filled].size = 0;
+
+ *nlinesp = filled;
+ return lines;
+}
+
+/* This is the comparison function for qsort for a vector of pointers to
+ struct spec_section. (Have to use const void * as the parameter type
+ to avoid incompatible-with-qsort warnings.)
+ Compare the section names. */
+
+int
+compare_section_names (const void *p1, const void *p2)
+{
+ struct spec_section **sec1 = (struct spec_section **) p1;
+ struct spec_section **sec2 = (struct spec_section **) p2;
+ char *name1 = (*sec1)->name;
+ char *name2 = (*sec2)->name;
+ return strcmp (name1, name2);
+}
+
+/* This is the comparison function for qsort
+ for a vector of pointers to struct spec_entry.
+ Compare the entries' text. */
+
+int
+compare_entries_text (const void *p1, const void *p2)
+{
+ struct spec_entry **entry1 = (struct spec_entry **) p1;
+ struct spec_entry **entry2 = (struct spec_entry **) p2;
+ char *text1 = (*entry1)->text;
+ char *text2 = (*entry2)->text;
+ char *colon1 = strchr (text1, ':');
+ char *colon2 = strchr (text2, ':');
+ int len1, len2;
+
+ if (!colon1)
+ len1 = strlen (text1);
+ else
+ len1 = colon1 - text1;
+ if (!colon2)
+ len2 = strlen (text2);
+ else
+ len2 = colon2 - text2;
+ return strncmp (text1, text2, len1 <= len2 ? len1 : len2);
+}
+
+/* Insert ENTRY into the add_entries_before vector
+ for line number LINE_NUMBER of the dir file.
+ DIR_LINES and N_ENTRIES carry information from like-named variables
+ in main. */
+
+void
+insert_entry_here (struct spec_entry *entry, int line_number,
+ struct line_data *dir_lines, int n_entries)
+{
+ int i, j;
+
+ if (dir_lines[line_number].add_entries_before == 0)
+ {
+ dir_lines[line_number].add_entries_before
+ = (struct spec_entry **) xmalloc (n_entries * sizeof (struct spec_entry *));
+ for (i = 0; i < n_entries; i++)
+ dir_lines[line_number].add_entries_before[i] = 0;
+ }
+
+ /* Find the place where this entry belongs. If there are already
+ several entries to add before LINE_NUMBER, make sure they are in
+ alphabetical order. */
+ for (i = 0; i < n_entries; i++)
+ if (dir_lines[line_number].add_entries_before[i] == 0
+ || menu_line_lessp (entry->text, strlen (entry->text),
+ dir_lines[line_number].add_entries_before[i]->text,
+ strlen (dir_lines[line_number].add_entries_before[i]->text)))
+ break;
+
+ if (i == n_entries)
+ abort ();
+
+ /* If we need to plug ENTRY into the middle of the
+ ADD_ENTRIES_BEFORE array, move the entries which should be output
+ after this one down one notch, before adding a new one. */
+ if (dir_lines[line_number].add_entries_before[i] != 0)
+ for (j = n_entries - 1; j > i; j--)
+ dir_lines[line_number].add_entries_before[j]
+ = dir_lines[line_number].add_entries_before[j - 1];
+
+ dir_lines[line_number].add_entries_before[i] = entry;
+}
diff --git a/Build/source/utils/texinfo/util/outline.gawk b/Build/source/utils/texinfo/util/outline.gawk
new file mode 100644
index 00000000000..329bb17529a
--- /dev/null
+++ b/Build/source/utils/texinfo/util/outline.gawk
@@ -0,0 +1,145 @@
+#! /usr/local/bin/gawk -f
+
+# texi.outline --- produce an outline from a texinfo source file
+#
+# Copyright (C) 1998 Arnold David Robbins (arnold@gnu.org)
+#
+# TEXI.OUTLINE 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 2 of the License, or
+# (at your option) any later version.
+#
+# TEXI.OUTLINE 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+# NOTE:
+# This program uses gensub(), which is specific to gawk.
+# With some work (split, substr, etc), it could be made to work
+# on other awks, but it's not worth the trouble for me.
+
+BEGIN \
+{
+ # Levels at which different nodes can be
+ Level["@top"] = 0
+ Level["@appendix"] = 1
+ Level["@chapter"] = 1
+ Level["@majorheading"] = 1
+ Level["@unnumbered"] = 1
+ Level["@appendixsec"] = 2
+ Level["@heading"] = 2
+ Level["@section"] = 2
+ Level["@unnumberedsec"] = 2
+ Level["@unnumberedsubsec"] = 3
+ Level["@appendixsubsec"] = 3
+ Level["@subheading"] = 3
+ Level["@subsection"] = 3
+ Level["@appendixsubsubsec"] = 4
+ Level["@subsubheading"] = 4
+ Level["@subsubsection"] = 4
+ Level["@unnumberedsubsubsec"] = 4
+
+ # insure that we were called correctly
+ if (ARGC != 2) {
+ printf("usage: %s texinfo-file\n", ARGV[0]) > "/dev/stderr"
+ exit 1
+ }
+
+ # init header counters
+ app_letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ app_h = 0
+ l1_h = l2_h = l3_h = l4_h = 0
+}
+
+# skip lines we're not interested in
+/^[^@]/ || ! ($1 in Level) { next }
+
+Level[$1] == 1 {
+ if ($1 !~ /^@unnumbered/ || $1 !~ /heading/)
+ l1_h++
+ l2_h = l3_h = l4_h = 0
+ Ntabs = 0
+ Number = makenumber($1)
+ Title = maketitle($0)
+ print_title()
+}
+
+Level[$1] == 2 {
+ l2_h++
+ l3_h = l4_h = 0
+ Ntabs = 1
+ Number = makenumber($1)
+ Title = maketitle($0)
+ print_title()
+}
+
+Level[$1] == 3 {
+ l3_h++
+ l4_h = 0
+ Ntabs = 2
+ Number = makenumber($1)
+ Title = maketitle($0)
+ print_title()
+}
+
+Level[$1] == 4 {
+ l4_h++
+ Ntabs = 3
+ Number = makenumber($1)
+ Title = maketitle($0)
+ print_title()
+}
+
+# maketitle --- extract title
+
+function maketitle(str, text)
+{
+ $1 = "" # clobber section keyword
+ text = $0
+ gsub(/^[ \t]*/, "", text)
+ text = gensub(/@[a-z]+{/, "", "g", text)
+ text = gensub(/([^@])}/, "\\1", "g", text)
+ return text
+}
+
+# print_title --- print the title
+
+function print_title( i)
+{
+ for (i = 1; i <= Ntabs; i++)
+ printf "\t"
+ printf("%s %s\n", Number, Title)
+}
+
+# makenumber --- construct a heading number from levels and section command
+
+function makenumber(command, result, lev1)
+{
+ result = ""
+ if (command ~ /^@appendix/) {
+ if (Level[command] == 1)
+ app_h++
+
+ lev1 = substr(app_letters, app_h, 1)
+ } else if (command ~ /^@unnumbered/ || command ~ /heading/) {
+ lev1 = "(unnumbered)"
+ } else
+ lev1 = l1_h ""
+
+ result = lev1 "."
+ if (l2_h > 0) {
+ result = result l2_h "."
+ if (l3_h > 0) {
+ result = result l3_h "."
+ if (l4_h > 0) {
+ result = result l4_h "."
+ }
+ }
+ }
+ return result
+}
diff --git a/Build/source/utils/texinfo/util/prepinfo.awk b/Build/source/utils/texinfo/util/prepinfo.awk
new file mode 100644
index 00000000000..273c97f8460
--- /dev/null
+++ b/Build/source/utils/texinfo/util/prepinfo.awk
@@ -0,0 +1,356 @@
+#! /usr/local/bin/gawk -f
+
+# prepinfo.awk --- fix node lines and menus
+#
+# Copyright, 1998, Arnold Robbins, arnold@gnu.org
+#
+# PREPINFO 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 2 of the License, or
+# (at your option) any later version.
+#
+# PREPINFO 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+BEGIN \
+{
+ # manifest constants
+ TRUE = 1
+ FALSE = 0
+
+ # Levels at which different nodes can be
+ Level["@top"] = 0
+ Level["@appendix"] = 1
+ Level["@chapter"] = 1
+ Level["@majorheading"] = 1
+ Level["@unnumbered"] = 1
+ Level["@appendixsec"] = 2
+ Level["@heading"] = 2
+ Level["@section"] = 2
+ Level["@unnumberedsec"] = 2
+ Level["@unnumberedsubsec"] = 3
+ Level["@appendixsubsec"] = 3
+ Level["@subheading"] = 3
+ Level["@subsection"] = 3
+ Level["@appendixsubsubsec"] = 4
+ Level["@subsubheading"] = 4
+ Level["@subsubsection"] = 4
+ Level["@unnumberedsubsubsec"] = 4
+
+ # Length of menus
+ Menumargin = 78
+
+ # Length of menu item
+ Min_menitem_length = 29
+
+ # insure that we were called correctly
+ if (ARGC != 2) {
+ printf("usage: %s texinfo-file\n", ARGV[0]) > "/dev/stderr"
+ exit 1
+ }
+
+ # Arrange for two passes over input file
+ Pass = 1
+ ARGV[2] = "Pass=2"
+ ARGV[3] = ARGV[1]
+ ARGC = 4
+ Lastlevel = -1
+
+ # Initialize stacks
+ Up[-1] = "(dir)"
+ Prev[0] = "(dir)"
+
+ if (Debug == "args") {
+ for (i = 0; i < ARGC; i++)
+ printf("ARGV[%d] = %s\n", i, ARGV[i]) > "/dev/stderr"
+ }
+}
+
+$1 == "@node" \
+{
+ Name = getnodename($0)
+ Nodeseen = TRUE
+
+ if ((l = length(Name)) > Maxlen)
+ Maxlen = l
+
+ if (Debug == "nodenames")
+ printf("Name = %s\n", Name) > "/dev/stderr"
+
+ if (Pass == 1)
+ next
+}
+
+Pass == 1 && /^@c(omment)?[ \t]+fakenode/ \
+{
+ if (Debug == "fakenodes")
+ printf("fakenode at %d\n", FNR) > "/dev/stderr"
+ Fakenode = TRUE
+ next
+}
+
+Pass == 1 && ($1 in Level) \
+{
+ # skip fake nodes --- titles without associated @node lines
+ if (Fakenode) {
+ if (Debug == "fakenodes")
+ printf("%s at %d is a fakenode\n", $1, FNR) > "/dev/stderr"
+ Fakenode = FALSE
+ next
+ }
+
+ if (Debug == "titles")
+ printf("Processing %s: Name = %s\n", $1, Name) > "/dev/stderr"
+
+ # save type
+ type = $1
+
+ if (! Nodeseen) {
+ err_prefix()
+ printf("%s line with no @node or fakenode line\n",
+ type) > "/dev/stderr"
+ Badheading[FNR] = 1
+ # ??? used ???
+ next
+ } else
+ Nodeseen = FALSE # reset it
+
+ # Squirrel away the info
+ levelnum = Level[type]
+ Node[Name ".level"] = levelnum
+ Node[Name ".name"] = Name
+ if (Debug == "titles") {
+ printf("Node[%s\".level\"] = %s\n", Name, Node[Name ".level"]) > "/dev/stderr"
+ printf("Node[%s\".name\"] = %s\n", Name, Node[Name ".name"]) > "/dev/stderr"
+ }
+
+ if (levelnum == Lastlevel) { # e.g., two sections in a row
+ Node[Name ".up"] = Up[levelnum - 1]
+ if (levelnum in Prev) {
+ Node[Prev[levelnum] ".next"] = Name
+ Node[Name ".prev"] = Prev[levelnum]
+ }
+ Prev[levelnum] = Name
+ Up[levelnum] = Name # ???
+ } else if (levelnum < Lastlevel) { # section, now chapter
+ Lastlevel = levelnum
+ Node[Name ".up"] = Up[levelnum - 1]
+ if (levelnum in Prev) {
+ Node[Name ".prev"] = Prev[levelnum]
+ Node[Prev[levelnum] ".next"] = Name
+ }
+ Prev[levelnum] = Name
+ Up[levelnum] = Name
+ } else { # chapter, now section, levelnum > Lastlevel
+ Node[Name ".up"] = Up[levelnum - 1]
+ Node[Up[Lastlevel] ".child"] = Name
+ Up[levelnum] = Name
+ Prev[levelnum] = Name
+ Lastlevel = levelnum
+ }
+
+ # For master menu
+ if (Level[$1] >= 2)
+ List[++Sequence] = Name
+
+ if (Debug == "titles") {
+ printf("Node[%s\".prev\"] = %s\n", Name, Node[Name ".prev"]) > "/dev/stderr"
+ printf("Node[%s\".up\"] = %s\n", Name, Node[Name ".up"]) > "/dev/stderr"
+ printf("Node[%s\".child\"] = %s\n", Name, Node[Name ".child"]) > "/dev/stderr"
+ }
+}
+
+Pass == 2 && Debug == "dumptitles" && FNR <= 1 \
+{
+ for (i in Node)
+ printf("Node[%s] = %s\n", i, Node[i]) | "sort 1>&2"
+ close("sort 1>&2")
+}
+
+/^@menu/ && Pass == 1, /^@end[ \t]+menu/ && Pass == 1 \
+{
+ if (/^@menu/ || /^@end[ \t]+menu/)
+ next
+
+# if (Debug == "menu")
+# printf("processing: %s\n", $0) > "/dev/stderr"
+
+ if (/^\*/) {
+ if (In_menitem) { # file away info from previousline
+ Node[node ".mendesc"] = desc
+ Node[node ".longdesc"] = longdesc
+ if (Debug == "mendesc") {
+ printf("Node[%s.mendesc] = %s\n",
+ node, Node[node ".mendesc"]) > "/dev/stderr"
+ printf("Node[%s.longdesc] = %s\n",
+ node, Node[node ".longdesc"]) > "/dev/stderr"
+ }
+ }
+ In_menitem = TRUE
+
+ # pull apart menu item
+ $1 = "" # nuke ``*''
+ $0 = $0 # reparse line
+ i1 = index($0, ":")
+ if (i1 <= 0) {
+ err_prefix()
+ printf("badly formed menu item") > "/dev/stderr"
+ next
+ }
+ if (substr($0, i1+1, 1) != ":") { # desc: node. long desc
+ i2 = index($0, ".")
+ if (i2 <= 0) {
+ err_prefix()
+ printf("badly formed menu item") > "/dev/stderr"
+ next
+ }
+ desc = substr($0, 1, i1 - 1)
+ sub(/^[ \t]+/, "", node)
+ sub(/[ \t]+$/, "", node)
+ longdesc = substr($0, i2 + 1)
+ } else { # nodname:: long desc
+ desc = ""
+ node = substr($0, 1, i1 - 1)
+ sub(/^[ \t]+/, "", node)
+ sub(/[ \t]+$/, "", node)
+ longdesc = substr($0, i1 + 2)
+ }
+ } else if (In_menitem) { # continuation line
+ longdesc = longdesc " " $0
+ } else
+ In_menitem = FALSE
+
+ Node[node ".mendesc"] = desc
+ Node[node ".longdesc"] = longdesc
+ if (Debug == "mendesc") {
+ printf("Node[%s.mendesc] = %s\n",
+ node, Node[node ".mendesc"]) > "/dev/stderr"
+ printf("Node[%s.longdesc] = %s\n",
+ node, Node[node ".longdesc"]) > "/dev/stderr"
+ }
+
+ if (Debug == "menu")
+ printf("Menu:: Name %s: desc %s: longdesc %s\n",
+ node, desc, longdesc) > "/dev/stderr"
+}
+
+function err_prefix()
+{
+ printf("%s: %s: %d: ", ARGV[0], FILENAME, FNR) > "/dev/stderr"
+}
+
+function getnodename(str)
+{
+ sub(/@node[ \t]+/, "", str)
+ sub(/,.*/, "", str)
+ if (Debug == "nodenames")
+ printf("getnodename: return %s\n", str) > "/dev/stderr"
+ return str
+}
+
+Pass == 2 && /^@node/ \
+{
+ Name = getnodename($0)
+
+ # Top node is special. It's next is the first child
+ n = Node[Name ".next"]
+ if (Node[Name ".level"] == 0 && n == "")
+ n = Node[Name ".child"]
+
+ printf("@node %s, %s, %s, %s\n", Name, n,
+ Node[Name ".prev"] ? Node[Name ".prev"] : Node[Name ".up"],
+ Node[Name ".up"])
+ next
+}
+
+Pass == 2 && /^@menu/ \
+{
+ # First, nuke current contents of menu
+ do {
+ if ((getline) <= 0) {
+ err_prefix()
+ printf("unexpected EOF inside menu\n") > "/dev/stderr"
+ exit 1
+ }
+ } while (! /^@end[ \t]+menu/)
+
+ # next, compute maximum length of a node name
+ max = 0
+ for (n = Node[Name ".child"]; (n ".next") in Node; n = Node[n ".next"]) {
+ if ((n ".desc") in Node)
+ s = Node[n ".desc"] ": " n "."
+ else
+ s = n "::"
+ l = length(s)
+ if (l > max)
+ max = l
+ }
+ if (max < Min_menitem_length)
+ max = Min_menitem_length
+
+ # now dump the menu
+ print "@menu"
+
+ for (n = Node[Name ".child"]; (n ".next") in Node; n = Node[n ".next"]) {
+ print_menuitem(n, max)
+ }
+ print_menuitem(n, max)
+
+ if (Name == "Top") { # Master Menu
+ if (Maxlen < Min_menitem_length)
+ Maxlen = Min_menitem_length
+ print ""
+ for (i = 1; i <= Sequence; i++)
+ print_menuitem(List[i], Maxlen)
+ print ""
+ }
+ print "@end menu"
+ next
+}
+
+Pass == 2 # print
+
+
+function print_menuitem(n, max, nodesc, i, dwords, count, p)
+{
+ nodesc = FALSE
+ if (! ((n ".longdesc") in Node)) {
+ err_prefix()
+ printf("warning: %s: no long description\n", n) > "/dev/stderr"
+ nodesc = TRUE
+ } else {
+ for (i in dwords)
+ delete dwords[i]
+ count = split(Node[n ".longdesc"], dwords, "[ \t\n]+")
+ }
+ if ((n ".desc") in Node)
+ s = Node[n ".desc"] ": " n "."
+ else
+ s = n "::"
+ printf("* %-*s", max, s)
+
+ if (Debug == "mendescitem")
+ printf("<* %-*s>\n", max, s) > "/dev/stderr"
+
+ p = max + 2
+ if (! nodesc) {
+ for (i = 1; i <= count; i++) {
+ l = length(dwords[i])
+ if (l == 0)
+ continue
+ if (p + l + 1 > Menumargin) {
+ printf("\n%*s", max + 2, " ")
+ p = max + 2
+ }
+ printf(" %s", dwords[i])
+ p += l + 1
+ }
+ }
+ print ""
+}
diff --git a/Build/source/utils/texinfo/util/tex3patch b/Build/source/utils/texinfo/util/tex3patch
new file mode 100755
index 00000000000..046c7946459
--- /dev/null
+++ b/Build/source/utils/texinfo/util/tex3patch
@@ -0,0 +1,70 @@
+#!/bin/sh
+# Auxiliary script to work around TeX 3.0 bug. ---- tex3patch ----
+# patches texinfo.tex in current directory, or in directory given as arg.
+
+ANYVERSION=no
+
+for arg in $1 $2
+do
+ case $arg in
+ --dammit | -d ) ANYVERSION=yes ;;
+
+ * ) dir=$arg
+ esac
+done
+
+if [ -z "$dir" ]; then
+ dir='.'
+fi
+
+if [ 2 -lt $# ] || [ ! -f "$dir/texinfo.tex" ]; then
+ echo "To patch texinfo.tex for peaceful coexistence with Unix TeX 3.0,"
+ echo "run $0"
+ echo "with no arguments in the same directory as texinfo.tex; or run"
+ echo " $0 DIRECTORY"
+ echo "(where DIRECTORY is a path leading to texinfo.tex)."
+ exit
+fi
+
+if [ -z "$TMPDIR" ]; then
+ TMPDIR=/tmp
+fi
+
+echo "Checking for \`dummy.tfm'"
+
+( cd $TMPDIR; tex '\relax \batchmode \font\foo=dummy \bye' )
+
+grep -s '3.0' $TMPDIR/texput.log
+if [ 1 = "$?" ] && [ "$ANYVERSION" != "yes" ]; then
+ echo "You probably do not need this patch,"
+ echo "since your TeX does not seem to be version 3.0."
+ echo "If you insist on applying the patch, run $0"
+ echo "again with the option \`--dammit'"
+ exit
+fi
+
+grep -s 'file not found' $TMPDIR/texput.log
+if [ 0 = $? ]; then
+ echo "This patch requires the dummy font metric file \`dummy.tfm',"
+ echo "which does not seem to be part of your TeX installation."
+ echo "Please get your TeX maintainer to install \`dummy.tfm',"
+ echo "then run this script again."
+ exit
+fi
+rm $TMPDIR/texput.log
+
+echo "Patching $dir/texinfo.tex"
+
+sed -e 's/%%*\\font\\nullfont/\\font\\nullfont/' \
+ $dir/texinfo.tex >$TMPDIR/texinfo.tex
+mv $dir/texinfo.tex $dir/texinfo.tex-distrib; mv $TMPDIR/texinfo.tex $dir
+
+if [ 0 = $? ]; then
+ echo "Patched $dir/texinfo.tex to avoid TeX 3.0 bug."
+ echo "The original version is saved as $dir/texinfo.tex-distrib."
+else
+ echo "Patch failed. Sorry."
+fi
+----------------------------------------tex3patch ends
+
+
diff --git a/Build/source/utils/texinfo/util/texi-docstring-magic.el b/Build/source/utils/texinfo/util/texi-docstring-magic.el
new file mode 100644
index 00000000000..9cbca2b7591
--- /dev/null
+++ b/Build/source/utils/texinfo/util/texi-docstring-magic.el
@@ -0,0 +1,347 @@
+;; texi-docstring-magic.el -- munge internal docstrings into texi
+;;
+;; Keywords: lisp, docs, tex
+;; Author: David Aspinall <da@dcs.ed.ac.uk>
+;; Copyright (C) 1998 David Aspinall
+;; Maintainer: David Aspinall <da@dcs.ed.ac.uk>
+;;
+;; $Id: texi-docstring-magic.el,v 1.2 2004/04/11 17:56:47 karl Exp $
+;;
+;; This package is distributed under the terms of the
+;; GNU General Public License, Version 2.
+;; You should have a copy of the GPL with your version of
+;; GNU Emacs or the Texinfo distribution.
+;;
+;;
+;; This package generates Texinfo source fragments from Emacs
+;; docstrings. This avoids documenting functions and variables
+;; in more than one place, and automatically adds Texinfo markup
+;; to docstrings.
+;;
+;; It relies heavily on you following the Elisp documentation
+;; conventions to produce sensible output, check the Elisp manual
+;; for details. In brief:
+;;
+;; * The first line of a docstring should be a complete sentence.
+;; * Arguments to functions should be written in upper case: ARG1..ARGN
+;; * User options (variables users may want to set) should have docstrings
+;; beginning with an asterisk.
+;;
+;; Usage:
+;;
+;; Write comments of the form:
+;;
+;; @c TEXI DOCSTRING MAGIC: my-package-function-or-variable-name
+;;
+;; In your texi source, mypackage.texi. From within an Emacs session
+;; where my-package is loaded, visit mypackage.texi and run
+;; M-x texi-docstring-magic to update all of the documentation strings.
+;;
+;; This will insert @defopt, @deffn and the like underneath the
+;; magic comment strings.
+;;
+;; The default value for user options will be printed.
+;;
+;; Symbols are recognized if they are defined for faces, functions,
+;; or variables (in that order).
+;;
+;; Automatic markup rules:
+;;
+;; 1. Indented lines are gathered into @lisp environment.
+;; 2. Pieces of text `stuff' or surrounded in quotes marked up with @samp.
+;; 3. Words *emphasized* are made @strong{emphasized}
+;; 4. Words sym-bol which are symbols become @code{sym-bol}.
+;; 5. Upper cased words ARG corresponding to arguments become @var{arg}.
+;; In fact, you can any word longer than three letters, so that
+;; metavariables can be used easily.
+;; FIXME: to escape this, use `ARG'
+;; 6. Words 'sym which are lisp-quoted are marked with @code{'sym}.
+;;
+;; -----
+;;
+;; Useful key binding when writing Texinfo:
+;;
+;; (define-key TeXinfo-mode-map "C-cC-d" 'texi-docstring-magic-insert-magic)
+;;
+;; -----
+;;
+;; Useful enhancements to do:
+;;
+;; * Use customize properties (e.g. group, simple types)
+;; * Look for a "texi-docstring" property for symbols
+;; so TeXInfo can be defined directly in case automatic markup
+;; goes badly wrong.
+;; * Add tags to special comments so that user can specify face,
+;; function, or variable binding for a symbol in case more than
+;; one binding exists.
+;;
+;; ------
+
+(defun texi-docstring-magic-splice-sep (strings sep)
+ "Return concatenation of STRINGS spliced together with separator SEP."
+ (let (str)
+ (while strings
+ (setq str (concat str (car strings)))
+ (if (cdr strings)
+ (setq str (concat str sep)))
+ (setq strings (cdr strings)))
+ str))
+
+(defconst texi-docstring-magic-munge-table
+ '(;; 1. Indented lines are gathered into @lisp environment.
+ ("\\(^.*\\S-.*$\\)"
+ t
+ (let
+ ((line (match-string 0 docstring)))
+ (if (eq (char-syntax (string-to-char line)) ?\ )
+ ;; whitespace
+ (if in-quoted-region
+ line
+ (setq in-quoted-region t)
+ (concat "@lisp\n" line))
+ ;; non-white space
+ (if in-quoted-region
+ (progn
+ (setq in-quoted-region nil)
+ (concat "@end lisp\n" line))
+ line))))
+ ;; 2. Pieces of text `stuff' or surrounded in quotes
+ ;; are marked up with @samp. NB: Must be backquote
+ ;; followed by forward quote for this to work.
+ ;; Can't use two forward quotes else problems with
+ ;; symbols.
+ ;; Odd hack: because ' is a word constituent in text/texinfo
+ ;; mode, putting this first enables the recognition of args
+ ;; and symbols put inside quotes.
+ ("\\(`\\([^']+\\)'\\)"
+ t
+ (concat "@samp{" (match-string 2 docstring) "}"))
+ ;; 3. Words *emphasized* are made @strong{emphasized}
+ ("\\(\\*\\(\\w+\\)\\*\\)"
+ t
+ (concat "@strong{" (match-string 2 docstring) "}"))
+ ;; 4. Words sym-bol which are symbols become @code{sym-bol}.
+ ;; Must have at least one hyphen to be recognized,
+ ;; terminated in whitespace, end of line, or punctuation.
+ ;; (Only consider symbols made from word constituents
+ ;; and hyphen.
+ ("\\(\\(\\w+\\-\\(\\w\\|\\-\\)+\\)\\)\\(\\s\)\\|\\s-\\|\\s.\\|$\\)"
+ (or (boundp (intern (match-string 2 docstring)))
+ (fboundp (intern (match-string 2 docstring))))
+ (concat "@code{" (match-string 2 docstring) "}"
+ (match-string 4 docstring)))
+ ;; 5. Upper cased words ARG corresponding to arguments become
+ ;; @var{arg}
+ ;; In fact, include any word so long as it is more than 3 characters
+ ;; long. (Comes after symbols to avoid recognizing the
+ ;; lowercased form of an argument as a symbol)
+ ;; FIXME: maybe we don't want to downcase stuff already
+ ;; inside @samp
+ ;; FIXME: should - terminate? should _ be included?
+ ("\\([A-Z0-9\\-]+\\)\\(/\\|\)\\|}\\|\\s-\\|\\s.\\|$\\)"
+ (or (> (length (match-string 1 docstring)) 3)
+ (member (downcase (match-string 1 docstring)) args))
+ (concat "@var{" (downcase (match-string 1 docstring)) "}"
+ (match-string 2 docstring)))
+
+ ;; 6. Words 'sym which are lisp quoted are
+ ;; marked with @code.
+ ("\\(\\(\\s-\\|^\\)'\\(\\(\\w\\|\\-\\)+\\)\\)\\(\\s\)\\|\\s-\\|\\s.\\|$\\)"
+ t
+ (concat (match-string 2 docstring)
+ "@code{'" (match-string 3 docstring) "}"
+ (match-string 5 docstring)))
+ ;; 7,8. Clean up for @lisp environments left with spurious newlines
+ ;; after 1.
+ ("\\(\\(^\\s-*$\\)\n@lisp\\)" t "@lisp")
+ ("\\(\\(^\\s-*$\\)\n@end lisp\\)" t "@end lisp"))
+ "Table of regexp matches and replacements used to markup docstrings.
+Format of table is a list of elements of the form
+ (regexp predicate replacement-form)
+If regexp matches and predicate holds, then replacement-form is
+evaluated to get the replacement for the match.
+predicate and replacement-form can use variables arg,
+and forms such as (match-string 1 docstring)
+Match string 1 is assumed to determine the
+length of the matched item, hence where parsing restarts from.
+The replacement must cover the whole match (match string 0),
+including any whitespace included to delimit matches.")
+
+
+(defun texi-docstring-magic-munge-docstring (docstring args)
+ "Markup DOCSTRING for texi according to regexp matches."
+ (let ((case-fold-search nil))
+ (dolist (test texi-docstring-magic-munge-table docstring)
+ (let ((regexp (nth 0 test))
+ (predicate (nth 1 test))
+ (replace (nth 2 test))
+ (i 0)
+ in-quoted-region)
+
+ (while (and
+ (< i (length docstring))
+ (string-match regexp docstring i))
+ (setq i (match-end 1))
+ (if (eval predicate)
+ (let* ((origlength (- (match-end 0) (match-beginning 0)))
+ (replacement (eval replace))
+ (newlength (length replacement)))
+ (setq docstring
+ (replace-match replacement t t docstring))
+ (setq i (+ i (- newlength origlength))))))
+ (if in-quoted-region
+ (setq docstring (concat docstring "\n@end lisp"))))))
+ ;; Force a new line after (what should be) the first sentence,
+ ;; if not already a new paragraph.
+ (let*
+ ((pos (string-match "\n" docstring))
+ (needscr (and pos
+ (not (string= "\n"
+ (substring docstring
+ (1+ pos)
+ (+ pos 2)))))))
+ (if (and pos needscr)
+ (concat (substring docstring 0 pos)
+ "@*\n"
+ (substring docstring (1+ pos)))
+ docstring)))
+
+(defun texi-docstring-magic-texi (env grp name docstring args &optional endtext)
+ "Make a texi def environment ENV for entity NAME with DOCSTRING."
+ (concat "@def" env (if grp (concat " " grp) "") " " name
+ " "
+ (texi-docstring-magic-splice-sep args " ")
+ ;; " "
+ ;; (texi-docstring-magic-splice-sep extras " ")
+ "\n"
+ (texi-docstring-magic-munge-docstring docstring args)
+ "\n"
+ (or endtext "")
+ "@end def" env "\n"))
+
+(defun texi-docstring-magic-format-default (default)
+ "Make a default value string for the value DEFAULT.
+Markup as @code{stuff} or @lisp stuff @end lisp."
+ (let ((text (format "%S" default)))
+ (concat
+ "\nThe default value is "
+ (if (string-match "\n" text)
+ ;; Carriage return will break @code, use @lisp
+ (if (stringp default)
+ (concat "the string: \n@lisp\n" default "\n@end lisp\n")
+ (concat "the value: \n@lisp\n" text "\n@end lisp\n"))
+ (concat "@code{" text "}.\n")))))
+
+
+(defun texi-docstring-magic-texi-for (symbol)
+ (cond
+ ;; Faces
+ ((find-face symbol)
+ (let*
+ ((face symbol)
+ (name (symbol-name face))
+ (docstring (or (face-doc-string face)
+ "Not documented."))
+ (useropt (eq ?* (string-to-char docstring))))
+ ;; Chop off user option setting
+ (if useropt
+ (setq docstring (substring docstring 1)))
+ (texi-docstring-magic-texi "fn" "Face" name docstring nil)))
+ ((fboundp symbol)
+ ;; Functions.
+ ;; We don't handle macros, aliases, or compiled fns properly.
+ (let*
+ ((function symbol)
+ (name (symbol-name function))
+ (docstring (or (documentation function)
+ "Not documented."))
+ (def (symbol-function function))
+ (argsyms (cond ((eq (car-safe def) 'lambda)
+ (nth 1 def))))
+ (args (mapcar 'symbol-name argsyms)))
+ (if (commandp function)
+ (texi-docstring-magic-texi "fn" "Command" name docstring args)
+ (texi-docstring-magic-texi "un" nil name docstring args))))
+ ((boundp symbol)
+ ;; Variables.
+ (let*
+ ((variable symbol)
+ (name (symbol-name variable))
+ (docstring (or (documentation-property variable
+ 'variable-documentation)
+ "Not documented."))
+ (useropt (eq ?* (string-to-char docstring)))
+ (default (if useropt
+ (texi-docstring-magic-format-default
+ (default-value symbol)))))
+ ;; Chop off user option setting
+ (if useropt
+ (setq docstring (substring docstring 1)))
+ (texi-docstring-magic-texi
+ (if useropt "opt" "var") nil name docstring nil default)))
+ (t
+ (error "Don't know anything about symbol %s" (symbol-name symbol)))))
+
+(defconst texi-docstring-magic-comment
+ "@c TEXI DOCSTRING MAGIC:"
+ "Magic string in a texi buffer expanded into @defopt, or @deffn.")
+
+(defun texi-docstring-magic ()
+ "Update all texi docstring magic annotations in buffer."
+ (interactive)
+ (save-excursion
+ (goto-char (point-min))
+ (let ((magic (concat "^"
+ (regexp-quote texi-docstring-magic-comment)
+ "\\s-*\\(\\(\\w\\|\\-\\)+\\)$"))
+ p
+ symbol)
+ (while (re-search-forward magic nil t)
+ (setq symbol (intern (match-string 1)))
+ (forward-line)
+ (setq p (point))
+ ;; If comment already followed by an environment, delete it.
+ (if (and
+ (looking-at "@def\\(\\w+\\)\\s-")
+ (search-forward (concat "@end def" (match-string 1)) nil t))
+ (progn
+ (forward-line)
+ (delete-region p (point))))
+ (insert
+ (texi-docstring-magic-texi-for symbol))))))
+
+(defun texi-docstring-magic-face-at-point ()
+ (ignore-errors
+ (let ((stab (syntax-table)))
+ (unwind-protect
+ (save-excursion
+ (set-syntax-table emacs-lisp-mode-syntax-table)
+ (or (not (zerop (skip-syntax-backward "_w")))
+ (eq (char-syntax (char-after (point))) ?w)
+ (eq (char-syntax (char-after (point))) ?_)
+ (forward-sexp -1))
+ (skip-chars-forward "'")
+ (let ((obj (read (current-buffer))))
+ (and (symbolp obj) (find-face obj) obj)))
+ (set-syntax-table stab)))))
+
+(defun texi-docstring-magic-insert-magic (symbol)
+ (interactive
+ (let* ((v (or (variable-at-point)
+ (function-at-point)
+ (texi-docstring-magic-face-at-point)))
+ (val (let ((enable-recursive-minibuffers t))
+ (completing-read
+ (if v
+ (format "Magic docstring for symbol (default %s): " v)
+ "Magic docstring for symbol: ")
+ obarray '(lambda (sym)
+ (or (boundp sym)
+ (fboundp sym)
+ (find-face sym)))
+ t nil 'variable-history))))
+ (list (if (equal val "") v (intern val)))))
+ (insert "\n" texi-docstring-magic-comment " " (symbol-name symbol)))
+
+
+(provide 'texi-docstring-magic)
diff --git a/Build/source/utils/texinfo/util/texi2dvi b/Build/source/utils/texinfo/util/texi2dvi
new file mode 100755
index 00000000000..18f6f59322b
--- /dev/null
+++ b/Build/source/utils/texinfo/util/texi2dvi
@@ -0,0 +1,836 @@
+#! /bin/sh
+# texi2dvi --- produce DVI (or PDF) files from Texinfo (or LaTeX) sources.
+# $Id: texi2dvi,v 1.42 2005/02/11 13:35:14 karl Exp $
+#
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2001,
+# 2002, 2003, 2004, 2005 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 2, 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, you can either send email to this
+# program's maintainer or write to: The Free Software Foundation,
+# Inc.; 59 Temple Place, Suite 330; Boston, MA 02111-1307, USA.
+#
+# Original author: Noah Friedman.
+#
+# Please send bug reports, etc. to bug-texinfo@gnu.org.
+# If possible, please send a copy of the output of the script called with
+# the `--debug' option when making a bug report.
+
+test -f /bin/ksh && test -z "$RUNNING_KSH" \
+ && { UNAMES=`uname -s`; test "x$UNAMES" = xULTRIX; } 2>/dev/null \
+ && { RUNNING_KSH=true; export RUNNING_KSH; exec /bin/ksh $0 ${1+"$@"}; }
+unset RUNNING_KSH
+
+# This string is expanded by rcs automatically when this file is checked out.
+rcs_revision='$Revision: 1.42 $'
+rcs_version=`set - $rcs_revision; echo $2`
+program=`echo $0 | sed -e 's!.*/!!'`
+version="texi2dvi (GNU Texinfo 4.8) $rcs_version
+
+Copyright (C) 2005 Free Software Foundation, Inc.
+There is NO warranty. You may redistribute this software
+under the terms of the GNU General Public License.
+For more information about these matters, see the files named COPYING."
+
+usage="Usage: $program [OPTION]... FILE...
+
+Run each Texinfo or LaTeX FILE through TeX in turn until all
+cross-references are resolved, building all indices. The directory
+containing each FILE is searched for included files. The suffix of FILE
+is used to determine its language (LaTeX or Texinfo).
+
+Makeinfo is used to perform Texinfo macro expansion before running TeX
+when needed.
+
+Operation modes:
+ -b, --batch no interaction
+ -c, --clean remove all auxiliary files
+ -D, --debug turn on shell debugging (set -x)
+ -h, --help display this help and exit successfully
+ -o, --output=OFILE leave output in OFILE (implies --clean);
+ Only one input FILE may be specified in this case
+ -q, --quiet no output unless errors (implies --batch)
+ -s, --silent same as --quiet
+ -v, --version display version information and exit successfully
+ -V, --verbose report on what is done
+
+TeX tuning:
+ -@ use @input instead of \input; for preloaded Texinfo
+ -e, -E, --expand force macro expansion using makeinfo
+ -I DIR search DIR for Texinfo files
+ -l, --language=LANG specify the LANG of FILE (LaTeX or Texinfo)
+ -p, --pdf use pdftex or pdflatex for processing
+ -r, --recode call recode before TeX to translate input characters
+ -t, --command=CMD insert CMD in copy of input file
+ or --texinfo=CMD multiple values accumulate
+
+The values of the BIBTEX, LATEX (or PDFLATEX), MAKEINDEX, MAKEINFO,
+TEX (or PDFTEX), TEXINDEX, and THUMBPDF environment variables are used
+to run those commands, if they are set. Any CMD strings are added
+after @setfilename for Texinfo input, in the first line for LaTeX input.
+
+Email bug reports to <bug-texinfo@gnu.org>,
+general questions and discussion to <help-texinfo@gnu.org>.
+Texinfo home page: http://www.gnu.org/software/texinfo/"
+
+# Initialize variables for option overriding and otherwise.
+# Don't use `unset' since old bourne shells don't have this command.
+# Instead, assign them an empty value.
+batch=false # eval for batch mode
+clean=
+debug=
+escape='\'
+expand= # t for expansion via makeinfo
+miincludes= # makeinfo include path
+oformat=dvi
+oname= # --output
+quiet= # by default let the tools' message be displayed
+recode=false
+set_language=
+textra= # Extra TeX commands to insert in the input file.
+textra_cmd= # sed command to insert TEXTRA where appropriate
+tmpdir=${TMPDIR:-/tmp}/t2d$$ # avoid collisions on 8.3 filesystems.
+txincludes= # TEXINPUTS extensions, with trailing colon
+txiprereq=19990129 # minimum texinfo.tex version with macro expansion
+verb=false # echo for verbose mode
+
+orig_pwd=`pwd`
+
+# Systems which define $COMSPEC or $ComSpec use semicolons to separate
+# directories in TEXINPUTS -- except for Cygwin, where COMSPEC might be
+# inherited, but : is used.
+if test -n "$COMSPEC$ComSpec" && uname | grep -iv cygwin >/dev/null; then
+ path_sep=";"
+else
+ path_sep=":"
+fi
+
+# Pacify verbose cds.
+CDPATH=${ZSH_VERSION+.}$path_sep
+
+# In case someone crazy insists on using grep -E.
+: ${EGREP=egrep}
+
+# return true if program $1 is somewhere in PATH, else false.
+#
+findprog ()
+{
+ foundprog=false
+
+ saveIFS=$IFS
+ IFS=$path_sep # break path components at the path separator
+ for dir in $PATH; do
+ # use test -x rather than test -f for DJGPP, where test -x checks
+ # for .exe. But test -x will also return true for directories, so
+ # explicitly ignore those.
+ if test -x "$dir/$1" && test ! -d "$dir/$1"; then
+ foundprog=true
+ break
+
+ # But on cygwin, test -x foo will not find foo.exe. So also check
+ # for that.
+ elif test -x "$dir/$1.exe"; then
+ foundprog=true
+ break
+ fi
+ done
+ IFS=$saveIFS
+ $foundprog
+}
+
+# Report some information.
+report ()
+{
+ for i in "$@"
+ do
+ echo >&2 "$0: $i"
+ done
+}
+
+# Report some verbose information.
+verbose ()
+{
+ $verb >&2 "$0: $@"
+}
+
+# Report an error and exit with failure.
+fatal ()
+{
+ s=$1
+ shift
+ report "$@"
+ exit $s
+}
+
+# Save TEXINPUTS so we can construct a new TEXINPUTS path for each file.
+# Likewise for bibtex and makeindex.
+tex_envvars="BIBINPUTS BSTINPUTS INDEXSTYLE TEXINPUTS"
+for var in $tex_envvars; do
+ eval ${var}_orig=\$$var
+ export $var
+done
+
+
+# Push a token among the arguments that will be used to notice when we
+# ended options/arguments parsing.
+# Use "set dummy ...; shift" rather than 'set - ..." because on
+# Solaris set - turns off set -x (but keeps set -e).
+# Use ${1+"$@"} rather than "$@" because Digital Unix and Ultrix 4.3
+# still expand "$@" to a single argument (the empty string) rather
+# than nothing at all.
+arg_sep="$$--$$"
+set dummy ${1+"$@"} "$arg_sep"; shift
+
+#
+# Parse command line arguments.
+while test x"$1" != x"$arg_sep"; do
+
+ # Handle --option=value by splitting apart and putting back on argv.
+ case "$1" in
+ --*=*)
+ opt=`echo "$1" | sed -e 's/=.*//'`
+ val=`echo "$1" | sed -e 's/[^=]*=//'`
+ shift
+ set dummy "$opt" "$val" ${1+"$@"}; shift
+ ;;
+ esac
+
+ # This recognizes --quark as --quiet. So what.
+ case "$1" in
+ -@ ) escape=@;;
+ # Silently and without documentation accept -b and --b[atch] as synonyms.
+ -b | --b*) batch=true;;
+ -c | --c*) clean=t;;
+ -D | --d*) debug=t;;
+ -e | -E | --e*) expand=t;;
+ -h | --h*) echo "$usage"; exit 0;;
+ -I | --I*)
+ shift
+ miincludes="$miincludes -I $1"
+ txincludes="$txincludes$1$path_sep"
+ ;;
+ -l | --l*) shift; set_language=$1;;
+ -o | --o*)
+ shift
+ clean=t
+ case "$1" in
+ /* | ?:/*) oname=$1;;
+ *) oname="$orig_pwd/$1";;
+ esac;;
+ -p | --p*) oformat=pdf;;
+ -q | -s | --q* | --s*) quiet=t; batch=true;;
+ -r | --r*) recode=true;;
+ -t | --tex* | --com* ) shift; textra="$textra\\
+"`echo "$1" | sed 's/\\\\/\\\\\\\\/g'`;;
+ -v | --vers*) echo "$version"; exit 0;;
+ -V | --verb*) verb=echo;;
+ --) # What remains are not options.
+ shift
+ while test x"$1" != x"$arg_sep"; do
+ set dummy ${1+"$@"} "$1"; shift
+ shift
+ done
+ break;;
+ -*)
+ fatal 1 "Unknown or ambiguous option \`$1'." \
+ "Try \`--help' for more information."
+ ;;
+ *) set dummy ${1+"$@"} "$1"; shift;;
+ esac
+ shift
+done
+# Pop the token
+shift
+
+# Interpret remaining command line args as filenames.
+case $# in
+ 0)
+ fatal 2 "Missing file arguments." "Try \`--help' for more information."
+ ;;
+ 1) ;;
+ *)
+ if test -n "$oname"; then
+ fatal 2 "Can't use option \`--output' with more than one argument."
+ fi
+ ;;
+esac
+
+
+# We can't do much without tex.
+#
+if findprog ${TEX:-tex}; then :; else cat <<EOM
+You don't have a working TeX binary (${TEX:-tex}) installed anywhere in
+your PATH, and texi2dvi cannot proceed without one. If you want to use
+this script, you'll need to install TeX (if you don't have it) or change
+your PATH or TEX environment variable (if you do). See the --help
+output for more details.
+
+For information about obtaining TeX, please see http://www.tug.org. If
+you happen to be using Debian, you can get it with this command:
+ apt-get install tetex-bin
+EOM
+ exit 1
+fi
+
+
+# We want to use etex (or pdftex) if they are available, and the user
+# didn't explicitly specify. We don't check for elatex and pdfelatex
+# because (as of 2003), the LaTeX team has asked that new distributions
+# use etex by default anyway.
+#
+# End up with the TEX and PDFTEX variables set to what we are going to use.
+if test -z "$TEX"; then
+ if findprog etex; then TEX=etex; else TEX=tex; fi
+fi
+#
+if test -z "$PDFTEX"; then
+ if findprog pdfetex; then PDFTEX=pdfetex; else PDFTEX=pdftex; fi
+fi
+
+
+# Prepare the temporary directory. Remove it at exit, unless debugging.
+if test -z "$debug"; then
+ trap "cd / && rm -rf $tmpdir" 0 1 2 15
+fi
+
+# Create the temporary directory with strict rights
+(umask 077 && mkdir $tmpdir) || exit 1
+
+# Prepare the tools we might need. This may be extra work in some
+# cases, but improves the readability of the script.
+utildir=$tmpdir/utils
+mkdir $utildir || exit 1
+
+# A sed script that preprocesses Texinfo sources in order to keep the
+# iftex sections only. We want to remove non TeX sections, and comment
+# (with `@c texi2dvi') TeX sections so that makeinfo does not try to
+# parse them. Nevertheless, while commenting TeX sections, don't
+# comment @macro/@end macro so that makeinfo does propagate them.
+# Unfortunately makeinfo --iftex --no-ifinfo doesn't work well enough
+# (yet), makeinfo can't parse the TeX commands, so work around with sed.
+#
+comment_iftex_sed=$utildir/comment.sed
+cat <<EOF >$comment_iftex_sed
+/^@tex/,/^@end tex/{
+ s/^/@c texi2dvi/
+}
+/^@iftex/,/^@end iftex/{
+ s/^/@c texi2dvi/
+ /^@c texi2dvi@macro/,/^@c texi2dvi@end macro/{
+ s/^@c texi2dvi//
+ }
+}
+/^@ifnottex/,/^@end ifnottex/{
+ s/^/@c (texi2dvi)/
+}
+/^@ifinfo/,/^@end ifinfo/{
+ /^@node/p
+ /^@menu/,/^@end menu/p
+ t
+ s/^/@c (texi2dvi)/
+}
+s/^@ifnotinfo/@c texi2dvi@ifnotinfo/
+s/^@end ifnotinfo/@c texi2dvi@end ifnotinfo/
+EOF
+# Uncommenting is simple: Remove any leading `@c texi2dvi'.
+uncomment_iftex_sed=$utildir/uncomment.sed
+cat <<EOF >$uncomment_iftex_sed
+s/^@c texi2dvi//
+EOF
+
+# Compute the list of xref files.
+# Takes the filename (without extension) of which we look for xref
+# files as argument. The index files must be reported last.
+get_xref_files ()
+{
+ # Get list of xref files (indexes, tables and lists).
+ # Find all files having root filename with a two-letter extension,
+ # saves the ones that are really Texinfo-related files. .?o? catches
+ # many files: .toc, .log, LaTeX tables and lists, FiXme's .lox, maybe more.
+ for this_file in "$1".?o? "$1".aux "$1".?? "$1".idx; do
+ # If file is empty, skip it.
+ test -s "$this_file" || continue
+ # If the file is not suitable to be an index or xref file, don't
+ # process it. It's suitable if the first character is a
+ # backslash or right quote or at, as long as the first line isn't
+ # \input texinfo.
+ first_character=`sed -n '1s/^\(.\).*$/\1/p;q' $this_file`
+ if (test "x$first_character" = "x\\" \
+ && sed 1q $this_file | grep -v '^\\input *texinfo' >/dev/null) \
+ || test "x$first_character" = "x'" \
+ || test "x$first_character" = "x@"; then
+ xref_files="$xref_files ./$this_file"
+ fi
+ done
+ echo "$xref_files"
+}
+
+# Convert relative paths to absolute paths, so we can run in another
+# directory (e.g., in --clean mode, or during the macro-support detection.)
+#
+# Empty path components are meaningful to tex. We rewrite them
+# as `EMPTY' so they don't get lost when we split on $path_sep.
+# Hopefully no one will have an actual directory named EMPTY.
+absolute_filenames ()
+{
+ replace_empty="-e 's/^$path_sep/EMPTY$path_sep/g' \
+ -e 's/$path_sep\$/${path_sep}EMPTY/g' \
+ -e 's/$path_sep$path_sep/${path_sep}EMPTY:/g'"
+ _res=`echo "$1" | eval sed $replace_empty`
+ save_IFS=$IFS
+ IFS=$path_sep
+ set x $_res; shift
+ _res=.
+ for dir
+ do
+ case $dir in
+ EMPTY)
+ _res=$_res$path_sep
+ ;;
+ [\\/]* | ?:[\\/]*) # Absolute paths don't need to be expanded.
+ _res=$_res$path_sep$dir
+ ;;
+ *)
+ abs=`cd "$dir" && pwd` && _res=$_res$path_sep$abs
+ ;;
+ esac
+ done
+ echo "$_res"
+}
+
+
+# run_tex ()
+# ----------
+# Run TeX as "$tex $tex_args $filename_input", taking care of errors
+# and logs.
+run_tex ()
+{
+ # Note that this will be used via an eval: quote properly.
+ cmd=$tex
+
+ # If possible, make TeX report error locations in GNU format.
+ tex_args=
+ case $tex_help in
+ *file-line-error*) cmd="$cmd --file-line-error";;
+ esac
+
+ # Tell TeX to be batch if requested.
+ if $batch; then
+ # \batchmode does not show terminal output at all, so we don't
+ # want that. And even in batch mode, TeX insists on having input
+ # from the user. Close its stdin to make it impossible.
+ cmd="$cmd </dev/null '${escape}nonstopmode' '${escape}input'"
+ fi
+
+ cmd="$cmd '$filename_input'"
+
+ verbose "Running $cmd ..."
+ if eval "$cmd" >&5; then :; else
+ test "$clean" = t \
+ && cp "$filename_noext.log" "$orig_pwd"
+ fatal 1 "$tex exited with bad status, quitting." \
+ "see $filename_noext.log for errors."
+ fi
+}
+
+# File descriptor usage:
+# 0 standard input
+# 1 standard output (--verbose messages)
+# 2 standard error
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 5 tools output (turned off by --quiet)
+# 6 tracing/debugging (set -x output, etc.)
+
+# Tools' output. If quiet, discard, else redirect to the message flow.
+if test "$quiet" = t; then
+ exec 5>/dev/null
+else
+ exec 5>&1
+fi
+
+# Enable tracing
+if test "$debug" = t; then
+ exec 6>&1
+ set -x
+else
+ exec 6>/dev/null
+fi
+
+#
+# TeXify files.
+
+for command_line_filename in ${1+"$@"}; do
+ verbose "Processing $command_line_filename ..."
+
+ # If the COMMAND_LINE_FILENAME is not absolute (e.g., --debug.tex),
+ # prepend `./' in order to avoid that the tools take it as an option.
+ echo "$command_line_filename" | $EGREP '^(/|[A-z]:/)' >&6 \
+ || command_line_filename="./$command_line_filename"
+
+ # See if the file exists. If it doesn't we're in trouble since, even
+ # though the user may be able to reenter a valid filename at the tex
+ # prompt (assuming they're attending the terminal), this script won't
+ # be able to find the right xref files and so forth.
+ if test ! -r "$command_line_filename"; then
+ report "Could not read $command_line_filename, skipping."
+ continue
+ fi
+
+ # Get the name of the current directory. We want the full path
+ # because in clean mode we are in tmp, in which case a relative
+ # path has no meaning.
+ filename_dir=`echo $command_line_filename | sed 's!/[^/]*$!!;s!^$!.!'`
+ filename_dir=`cd "$filename_dir" >/dev/null && pwd`
+
+ # Strip directory part but leave extension.
+ filename_ext=`basename "$command_line_filename"`
+ # Strip extension.
+ filename_noext=`echo "$filename_ext" | sed 's/\.[^.]*$//'`
+ ext=`echo "$filename_ext" | sed 's/^.*\.//'`
+
+ # _src. Use same basename since we want to generate aux files with
+ # the same basename as the manual. If --expand, then output the
+ # macro-expanded file to here, else copy the original file.
+ tmpdir_src=$tmpdir/src
+ filename_src=$tmpdir_src/$filename_noext.$ext
+
+ # _xtr. The file with the user's extra commands.
+ tmpdir_xtr=$tmpdir/xtr
+ filename_xtr=$tmpdir_xtr/$filename_noext.$ext
+
+ # _rcd. The Texinfo file recoded in 7bit.
+ tmpdir_rcd=$tmpdir/rcd
+ filename_rcd=$tmpdir_rcd/$filename_noext.$ext
+
+ # _bak. Copies of the previous xref files (another round is run if
+ # they differ from the new one).
+ tmpdir_bak=$tmpdir/bak
+
+ # Make all those directories and give up if we can't succeed.
+ mkdir $tmpdir_src $tmpdir_xtr $tmpdir_rcd $tmpdir_bak || exit 1
+
+ # Source file might include additional sources.
+ # We want `.:$orig_pwd' before anything else. (We'll add `.:' later
+ # after all other directories have been turned into absolute paths.)
+ # `.' goes first to ensure that any old .aux, .cps,
+ # etc. files in ${directory} don't get used in preference to fresher
+ # files in `.'. Include orig_pwd in case we are in clean mode, where
+ # we've cd'd to a temp directory.
+ common="$orig_pwd$path_sep$filename_dir$path_sep$txincludes"
+ for var in $tex_envvars; do
+ eval ${var}="\$common\$${var}_orig"
+ export $var
+ done
+
+ # Convert relative paths to absolute paths, so we can run in another
+ # directory (e.g., in --clean mode, or during the macro-support detection.)
+ TEXINPUTS=`absolute_filenames "$TEXINPUTS"`
+ verbose "TEXINPUTS: $TEXINPUTS"
+ BIBINPUTS=`absolute_filenames "$BIBINPUTS"`
+ verbose "BIBINPUTS: $BIBINPUTS"
+ BSTINPUTS=`absolute_filenames "$BSTINPUTS"`
+ verbose "BSTINPUTS: $BSTINPUTS"
+ INDEXSTYLE=`absolute_filenames "$INDEXSTYLE"`
+ verbose "INDEXSTYLE: $INDEXSTYLE"
+
+ # If the user explicitly specified the language, use that.
+ # Otherwise, if the first line is \input texinfo, assume it's texinfo.
+ # Otherwise, guess from the file extension.
+ if test -n "$set_language"; then
+ language=$set_language
+ elif sed 1q "$command_line_filename" | grep 'input texinfo' >&6; then
+ language=texinfo
+ else
+ language=
+ fi
+
+ # Get the type of the file (latex or texinfo) from the given language
+ # we just guessed, or from the file extension if not set yet.
+ case ${language:-$filename_ext} in
+ [lL]a[tT]e[xX] | *.ltx | *.tex)
+ # Assume a LaTeX file. LaTeX needs bibtex and uses latex for
+ # compilation. No makeinfo.
+ language=latex
+ bibtex=${BIBTEX:-bibtex}
+ makeinfo= # no point in running makeinfo on latex source.
+ texindex=${MAKEINDEX:-makeindex}
+ textra_cmd=1i
+ if test $oformat = dvi; then
+ tex=${LATEX:-latex}
+ else
+ tex=${PDFLATEX:-pdflatex}
+ fi
+ thumbpdf=${THUMBPDF:-thumbpdf}
+ ;;
+
+ *)
+ # Assume a Texinfo file. Texinfo files need makeinfo, texindex and tex.
+ language=texinfo
+ bibtex=
+ texindex=${TEXINDEX:-texindex}
+ textra_cmd='/^@setfilename/a'
+ if test $oformat = dvi; then
+ # MetaPost also uses the TEX environment variable. If the user
+ # has set TEX=latex for that reason, don't bomb out.
+ if echo $TEX | grep 'latex$' >/dev/null; then
+ tex=tex # don't bother trying to find etex
+ else
+ tex=$TEX
+ fi
+ else
+ tex=$PDFTEX
+ fi
+ # Unless required by the user, makeinfo expansion is wanted only
+ # if texinfo.tex is too old.
+ if test "$expand" = t; then
+ makeinfo=${MAKEINFO:-makeinfo}
+ else
+ # Check if texinfo.tex performs macro expansion by looking for
+ # its version. The version is a date of the form YEAR-MO-DA.
+ # We don't need to use [0-9] to match the digits since anyway
+ # the comparison with $txiprereq, a number, will fail with non
+ # digits.
+ # Run in the tmpdir to avoid leaving files.
+ (
+ cd $tmpdir
+ echo '\input texinfo.tex @bye' >txiversion.tex
+ # Be sure that if tex wants to fail, it is not interactive:
+ # close stdin.
+ $tex txiversion.tex </dev/null
+ ) >$tmpdir/txiversion.out 2>$tmpdir/txiversion.err
+ if test $? != 0; then
+ cat $tmpdir/txiversion.out
+ cat $tmpdir/txiversion.err >&2
+ fatal 1 "texinfo.tex appears to be broken, quitting."
+ fi
+ eval `sed -n 's/^.*\[\(.*\)version \(....\)-\(..\)-\(..\).*$/txiformat=\1 txiversion="\2\3\4"/p' $tmpdir/txiversion.out`
+ verbose "texinfo.tex preloaded as \`$txiformat', version is \`$txiversion' ..."
+ if test "$txiprereq" -le "$txiversion" >/dev/null 2>&1; then
+ makeinfo=
+ else
+ makeinfo=${MAKEINFO:-makeinfo}
+ fi
+ # As long as we had to run TeX, offer the user this convenience:
+ test "$txiformat" = Texinfo && escape=@
+ fi
+ thumbpdf=${THUMBPDF:-thumbpdf}
+ ;;
+ esac
+
+ # Go to $tmpdir to try --help, since old versions that don't accept
+ # --help will generate a texput.log.
+ tex_help=`cd $tmpdir >/dev/null && $tex --help </dev/null 2>&1`
+
+ # Expand macro commands in the original source file using Makeinfo.
+ # Always use `end' footnote style, since the `separate' style
+ # generates different output (arguably this is a bug in -E).
+ # Discard main info output, the user asked to run TeX, not makeinfo.
+ if test -n "$makeinfo"; then
+ verbose "Macro-expanding $command_line_filename to $filename_src ..."
+ sed -f $comment_iftex_sed "$command_line_filename" \
+ | $makeinfo --footnote-style=end -I "$filename_dir" $miincludes \
+ -o /dev/null --macro-expand=- \
+ | sed -f $uncomment_iftex_sed >"$filename_src"
+ filename_input=$filename_src
+ fi
+
+ # If makeinfo failed (or was not even run), use the original file as input.
+ if test $? -ne 0 \
+ || test ! -r "$filename_src"; then
+ verbose "Reverting to $command_line_filename ..."
+ filename_input=$filename_dir/$filename_ext
+ fi
+
+ # Used most commonly for @finalout, @smallbook, etc.
+ if test -n "$textra"; then
+ verbose "Inserting extra commands: $textra"
+ sed "$textra_cmd\\
+$textra" "$filename_input" >"$filename_xtr"
+ filename_input=$filename_xtr
+ fi
+
+ # If this is a Texinfo file with a specified input encoding, and
+ # recode is available, then recode to plain 7 bit Texinfo.
+ if test $language = texinfo; then
+ pgm='s/^ *@documentencoding *\([^ ][^ ]*\) *$/\1/
+ t found
+ d
+ :found
+ q'
+ encoding=`sed -e "$pgm" "$filename_input"`
+ if $recode && test -n "$encoding" && findprog recode; then
+ verbose "Recoding from $encoding to Texinfo."
+ if recode "$encoding"..texinfo <"$filename_input" >"$filename_rcd" \
+ && test -s "$filename_rcd"; then
+ filename_input=$filename_rcd
+ else
+ verbose "Recoding failed, using original input."
+ fi
+ fi
+ fi
+
+ # If clean mode was specified, then move to the temporary directory.
+ if test "$clean" = t; then
+ verbose "cd $tmpdir_src"
+ cd "$tmpdir_src" || exit 1
+ fi
+
+ while :; do # will break out of loop below
+ orig_xref_files=`get_xref_files "$filename_noext"`
+
+ # Save copies of originals for later comparison.
+ if test -n "$orig_xref_files"; then
+ verbose "Backing up xref files: `echo $orig_xref_files | sed 's|\./||g'`"
+ cp $orig_xref_files $tmpdir_bak
+ fi
+
+ # Run bibtex on current file.
+ # - If its input (AUX) exists.
+ # - If AUX contains both `\bibdata' and `\bibstyle'.
+ # - If some citations are missing (LOG contains `Citation').
+ # or the LOG complains of a missing .bbl
+ #
+ # We run bibtex first, because I can see reasons for the indexes
+ # to change after bibtex is run, but I see no reason for the
+ # converse.
+ #
+ # Don't try to be too smart. Running bibtex only if the bbl file
+ # exists and is older than the LaTeX file is wrong, since the
+ # document might include files that have changed. Because there
+ # can be several AUX (if there are \include's), but a single LOG,
+ # looking for missing citations in LOG is easier, though we take
+ # the risk to match false messages.
+ if test -n "$bibtex" \
+ && test -r "$filename_noext.aux" \
+ && test -r "$filename_noext.log" \
+ && (grep '^\\bibdata[{]' "$filename_noext.aux" \
+ && grep '^\\bibstyle[{]' "$filename_noext.aux" \
+ && (grep 'Warning:.*Citation.*undefined' "$filename_noext.log" \
+ || grep 'No file .*\.bbl\.' "$filename_noext.log")) \
+ >&6 2>&1; \
+ then
+ verbose "Running $bibtex $filename_noext ..."
+ $bibtex "$filename_noext" >&5 ||
+ fatal 1 "$bibtex exited with bad status, quitting."
+ fi
+
+ # What we'll run texindex on -- exclude non-index files.
+ # Since we know index files are last, it is correct to remove everything
+ # before .aux and .?o?. But don't really do <anything>o<anything>
+ # -- don't match whitespace as <anything>.
+ # Otherwise, if orig_xref_files contains something like
+ # foo.xo foo.whatever
+ # the space after the o will get matched.
+ index_files=`echo "$orig_xref_files" \
+ | sed "s!.*\.aux!!g;
+ s!./$filename_noext\.[^ ]o[^ ]!!g;
+ s/^[ ]*//;s/[ ]*$//"`
+ # Run texindex (or makeindex) on current index files. If they
+ # already exist, and after running TeX a first time the index
+ # files don't change, then there's no reason to run TeX again.
+ # But we won't know that if the index files are out of date or
+ # nonexistent.
+ if test -n "$texindex" && test -n "$index_files"; then
+ verbose "Running $texindex $index_files ..."
+ $texindex $index_files 2>&5 1>&2 ||
+ fatal 1 "$texindex exited with bad status, quitting."
+ fi
+
+ # Finally, run TeX.
+ run_tex
+
+ # Decide if looping again is needed.
+ finished=t
+
+ # LaTeX (and the package changebar) report in the LOG file if it
+ # should be rerun. This is needed for files included from
+ # subdirs, since texi2dvi does not try to compare xref files in
+ # subdirs. Performing xref files test is still good since LaTeX
+ # does not report changes in xref files.
+ if grep "Rerun to get" "$filename_noext.log" >&6 2>&1; then
+ finished=
+ fi
+
+ # Check if xref files changed.
+ new_xref_files=`get_xref_files "$filename_noext"`
+ verbose "Original xref files = `echo $orig_xref_files | sed 's|\./||g'`"
+ verbose "New xref files = `echo $new_xref_files | sed 's|\./||g'`"
+
+ # If old and new lists don't at least have the same file list,
+ # then one file or another has definitely changed.
+ test "x$orig_xref_files" != "x$new_xref_files" && finished=
+
+ # File list is the same. We must compare each file until we find
+ # a difference.
+ if test -n "$finished"; then
+ for this_file in $new_xref_files; do
+ verbose "Comparing xref file `echo $this_file | sed 's|\./||g'` ..."
+ # cmp -s returns nonzero exit status if files differ.
+ if cmp -s "$this_file" "$tmpdir_bak/$this_file"; then :; else
+ # We only need to keep comparing until we find one that
+ # differs, because we'll have to run texindex & tex again no
+ # matter how many more there might be.
+ finished=
+ verbose "xref file `echo $this_file | sed 's|\./||g'` differed ..."
+ test "$debug" = t && diff -c "$tmpdir_bak/$this_file" "$this_file"
+ break
+ fi
+ done
+ fi
+
+ # If finished, exit the loop, else rerun the loop.
+ test -n "$finished" && break
+ done # while :;
+
+ # If we were using thumbpdf and producing PDF, then run thumbpdf
+ # and TeX one last time.
+ if test $oformat = pdf \
+ && test -r "$filename_noext.log" \
+ && grep 'thumbpdf\.sty' "$filename_noext.log" >&6 2>&1; \
+ then
+ verbose "Running $thumbpdf $filename_noext ..."
+ $thumbpdf "$filename_noext" >&5 ||
+ fatal 1 "$thumbpdf exited with bad status, quitting."
+ run_tex
+ fi
+
+
+ # If we were in clean mode, compilation was in a tmp directory.
+ # Copy the DVI (or PDF) file into the directory where the compilation
+ # has been done. (The temp dir is about to get removed anyway.)
+ # We also return to the original directory so that
+ # - the next file is processed in correct conditions
+ # - the temporary file can be removed
+ if test -n "$clean"; then
+ if test -n "$oname"; then
+ dest=$oname
+ else
+ dest=$orig_pwd
+ fi
+ verbose "Copying $oformat file from `pwd` to $dest"
+ cp -p "./$filename_noext.$oformat" "$dest"
+ cd / # in case $orig_pwd is on a different drive (for DOS)
+ cd $orig_pwd || exit 1
+ fi
+
+ # Remove temporary files.
+ if test "x$debug" = "x"; then
+ verbose "Removing $tmpdir_src $tmpdir_xtr $tmpdir_bak ..."
+ cd /
+ rm -rf $tmpdir_src $tmpdir_xtr $tmpdir_bak
+ fi
+done
+
+verbose "done."
+exit 0 # exit successfully, not however we ended the loop.
diff --git a/Build/source/utils/texinfo/util/texi2pdf b/Build/source/utils/texinfo/util/texi2pdf
new file mode 100755
index 00000000000..492128325db
--- /dev/null
+++ b/Build/source/utils/texinfo/util/texi2pdf
@@ -0,0 +1,19 @@
+#!/bin/sh
+# $Id: texi2pdf,v 1.1 2004/07/11 01:02:35 karl Exp $
+# Written by Thomas Esser. Public domain.
+# Execute texi2dvi --pdf.
+
+test -f /bin/sh5 && test -z "$RUNNING_SH5" \
+ && { UNAMES=`uname -s`; test "x$UNAMES" = xULTRIX; } 2>/dev/null \
+ && { RUNNING_SH5=true; export RUNNING_SH5; exec /bin/sh5 $0 ${1+"$@"}; }
+unset RUNNING_SH5
+
+test -f /bin/bsh && test -z "$RUNNING_BSH" \
+ && { UNAMES=`uname -s`; test "x$UNAMES" = xAIX; } 2>/dev/null \
+ && { RUNNING_BSH=true; export RUNNING_BSH; exec /bin/bsh $0 ${1+"$@"}; }
+unset RUNNING_BSH
+
+# hack around a bug in zsh:
+test -n "${ZSH_VERSION+set}" && alias -g '${1+"$@"}'='"$@"'
+
+texi2dvi --pdf ${1+"$@"}
diff --git a/Build/source/utils/texinfo/util/texindex.c b/Build/source/utils/texinfo/util/texindex.c
new file mode 100644
index 00000000000..569f877be0d
--- /dev/null
+++ b/Build/source/utils/texinfo/util/texindex.c
@@ -0,0 +1,1628 @@
+/* texindex -- sort TeX index dribble output into an actual index.
+ $Id: texindex.c,v 1.11 2004/04/11 17:56:47 karl Exp $
+
+ Copyright (C) 1987, 1991, 1992, 1996, 1997, 1998, 1999, 2000, 2001,
+ 2002, 2003, 2004 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 2, 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307. */
+
+#include "system.h"
+#include <getopt.h>
+
+static char *program_name = "texindex";
+
+#if defined (emacs)
+# include "../src/config.h"
+/* Some s/os.h files redefine these. */
+# undef read
+# undef close
+# undef write
+# undef open
+#endif
+
+#if !defined (HAVE_MEMSET)
+#undef memset
+#define memset(ptr, ignore, count) bzero (ptr, count)
+#endif
+
+char *mktemp (char *);
+
+#if !defined (SEEK_SET)
+# define SEEK_SET 0
+# define SEEK_CUR 1
+# define SEEK_END 2
+#endif /* !SEEK_SET */
+
+struct linebuffer;
+
+/* When sorting in core, this structure describes one line
+ and the position and length of its first keyfield. */
+struct lineinfo
+{
+ char *text; /* The actual text of the line. */
+ union {
+ char *text; /* The start of the key (for textual comparison). */
+ long number; /* The numeric value (for numeric comparison). */
+ } key;
+ long keylen; /* Length of KEY field. */
+};
+
+/* This structure describes a field to use as a sort key. */
+struct keyfield
+{
+ int startwords; /* Number of words to skip. */
+ int startchars; /* Number of additional chars to skip. */
+ int endwords; /* Number of words to ignore at end. */
+ int endchars; /* Ditto for characters of last word. */
+ char ignore_blanks; /* Non-zero means ignore spaces and tabs. */
+ char fold_case; /* Non-zero means case doesn't matter. */
+ char reverse; /* Non-zero means compare in reverse order. */
+ char numeric; /* Non-zeros means field is ASCII numeric. */
+ char positional; /* Sort according to file position. */
+ char braced; /* Count balanced-braced groupings as fields. */
+};
+
+/* Vector of keyfields to use. */
+struct keyfield keyfields[3];
+
+/* Number of keyfields stored in that vector. */
+int num_keyfields = 3;
+
+/* Vector of input file names, terminated with a null pointer. */
+char **infiles;
+
+/* Vector of corresponding output file names, or NULL, meaning default it
+ (add an `s' to the end). */
+char **outfiles;
+
+/* Length of `infiles'. */
+int num_infiles;
+
+/* Pointer to the array of pointers to lines being sorted. */
+char **linearray;
+
+/* The allocated length of `linearray'. */
+long nlines;
+
+/* Directory to use for temporary files. On Unix, it ends with a slash. */
+char *tempdir;
+
+/* Number of last temporary file. */
+int tempcount;
+
+/* Number of last temporary file already deleted.
+ Temporary files are deleted by `flush_tempfiles' in order of creation. */
+int last_deleted_tempcount;
+
+/* During in-core sort, this points to the base of the data block
+ which contains all the lines of data. */
+char *text_base;
+
+/* Initially 0; changed to 1 if we want initials in this index. */
+int need_initials;
+
+/* Remembers the first initial letter seen in this index, so we can
+ determine whether we need initials in the sorted form. */
+char first_initial;
+
+/* Additional command switches .*/
+
+/* Nonzero means do not delete tempfiles -- for debugging. */
+int keep_tempfiles;
+
+/* Forward declarations of functions in this file. */
+void decode_command (int argc, char **argv);
+void sort_in_core (char *infile, int total, char *outfile);
+void sort_offline (char *infile, off_t total, char *outfile);
+char **parsefile (char *filename, char **nextline, char *data, long int size);
+char *find_field (struct keyfield *keyfield, char *str, long int *lengthptr);
+char *find_pos (char *str, int words, int chars, int ignore_blanks);
+long find_value (char *start, long int length);
+char *find_braced_pos (char *str, int words, int chars, int ignore_blanks);
+char *find_braced_end (char *str);
+void writelines (char **linearray, int nlines, FILE *ostream);
+int compare_field (struct keyfield *keyfield, char *start1,
+ long int length1, long int pos1, char *start2,
+ long int length2, long int pos2);
+int compare_full (const void *, const void *);
+long readline (struct linebuffer *linebuffer, FILE *stream);
+int merge_files (char **infiles, int nfiles, char *outfile);
+int merge_direct (char **infiles, int nfiles, char *outfile);
+void pfatal_with_name (const char *name);
+void fatal (const char *format, const char *arg);
+void error (const char *format, const char *arg);
+void *xmalloc (), *xrealloc ();
+char *concat (char *s1, char *s2);
+void flush_tempfiles (int to_count);
+
+#define MAX_IN_CORE_SORT 500000
+
+int
+main (int argc, char **argv)
+{
+ int i;
+
+ tempcount = 0;
+ last_deleted_tempcount = 0;
+
+#ifdef HAVE_SETLOCALE
+ /* Set locale via LC_ALL. */
+ setlocale (LC_ALL, "");
+#endif
+
+ /* Set the text message domain. */
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+
+ /* In case we write to a redirected stdout that fails. */
+ /* not ready atexit (close_stdout); */
+
+ /* Describe the kind of sorting to do. */
+ /* The first keyfield uses the first braced field and folds case. */
+ keyfields[0].braced = 1;
+ keyfields[0].fold_case = 1;
+ keyfields[0].endwords = -1;
+ keyfields[0].endchars = -1;
+
+ /* The second keyfield uses the second braced field, numerically. */
+ keyfields[1].braced = 1;
+ keyfields[1].numeric = 1;
+ keyfields[1].startwords = 1;
+ keyfields[1].endwords = -1;
+ keyfields[1].endchars = -1;
+
+ /* The third keyfield (which is ignored while discarding duplicates)
+ compares the whole line. */
+ keyfields[2].endwords = -1;
+ keyfields[2].endchars = -1;
+
+ decode_command (argc, argv);
+
+ /* Process input files completely, one by one. */
+
+ for (i = 0; i < num_infiles; i++)
+ {
+ int desc;
+ off_t ptr;
+ char *outfile;
+ struct stat instat;
+
+ desc = open (infiles[i], O_RDONLY, 0);
+ if (desc < 0)
+ pfatal_with_name (infiles[i]);
+
+ if (stat (infiles[i], &instat))
+ pfatal_with_name (infiles[i]);
+ if (S_ISDIR (instat.st_mode))
+ {
+#ifdef EISDIR
+ errno = EISDIR;
+#endif
+ pfatal_with_name (infiles[i]);
+ }
+
+ lseek (desc, (off_t) 0, SEEK_END);
+ ptr = (off_t) lseek (desc, (off_t) 0, SEEK_CUR);
+
+ close (desc);
+
+ outfile = outfiles[i];
+ if (!outfile)
+ outfile = concat (infiles[i], "s");
+
+ need_initials = 0;
+ first_initial = '\0';
+
+ if (ptr < MAX_IN_CORE_SORT)
+ /* Sort a small amount of data. */
+ sort_in_core (infiles[i], (int)ptr, outfile);
+ else
+ sort_offline (infiles[i], ptr, outfile);
+ }
+
+ flush_tempfiles (tempcount);
+ xexit (0);
+ return 0; /* Avoid bogus warnings. */
+}
+
+typedef struct
+{
+ char *long_name;
+ char *short_name;
+ int *variable_ref;
+ int variable_value;
+ char *arg_name;
+ char *doc_string;
+} TEXINDEX_OPTION;
+
+TEXINDEX_OPTION texindex_options[] = {
+ { "--help", "-h", (int *)NULL, 0, (char *)NULL,
+ N_("display this help and exit") },
+ { "--keep", "-k", &keep_tempfiles, 1, (char *)NULL,
+ N_("keep temporary files around after processing") },
+ { "--no-keep", 0, &keep_tempfiles, 0, (char *)NULL,
+ N_("do not keep temporary files around after processing (default)") },
+ { "--output", "-o", (int *)NULL, 0, "FILE",
+ N_("send output to FILE") },
+ { "--version", (char *)NULL, (int *)NULL, 0, (char *)NULL,
+ N_("display version information and exit") },
+ { (char *)NULL, (char *)NULL, (int *)NULL, 0, (char *)NULL }
+};
+
+void
+usage (int result_value)
+{
+ register int i;
+ FILE *f = result_value ? stderr : stdout;
+
+ fprintf (f, _("Usage: %s [OPTION]... FILE...\n"), program_name);
+ fprintf (f, _("Generate a sorted index for each TeX output FILE.\n"));
+ /* Avoid trigraph nonsense. */
+ fprintf (f,
+_("Usually FILE... is specified as `foo.%c%c\' for a document `foo.texi'.\n"),
+ '?', '?'); /* avoid trigraph in cat-id-tbl.c */
+ fprintf (f, _("\nOptions:\n"));
+
+ for (i = 0; texindex_options[i].long_name; i++)
+ {
+ putc (' ', f);
+
+ if (texindex_options[i].short_name)
+ fprintf (f, "%s, ", texindex_options[i].short_name);
+
+ fprintf (f, "%s %s",
+ texindex_options[i].long_name,
+ texindex_options[i].arg_name
+ ? texindex_options[i].arg_name : "");
+
+ fprintf (f, "\t%s\n", _(texindex_options[i].doc_string));
+ }
+ fputs (_("\n\
+Email bug reports to bug-texinfo@gnu.org,\n\
+general questions and discussion to help-texinfo@gnu.org.\n\
+Texinfo home page: http://www.gnu.org/software/texinfo/"), f);
+ fputs ("\n", f);
+
+ xexit (result_value);
+}
+
+/* Decode the command line arguments to set the parameter variables
+ and set up the vector of keyfields and the vector of input files. */
+
+void
+decode_command (int argc, char **argv)
+{
+ int arg_index = 1;
+ char **ip;
+ char **op;
+
+ /* Store default values into parameter variables. */
+
+ tempdir = getenv ("TMPDIR");
+ if (tempdir == NULL)
+ tempdir = getenv ("TEMP");
+ if (tempdir == NULL)
+ tempdir = getenv ("TMP");
+ if (tempdir == NULL)
+ tempdir = DEFAULT_TMPDIR;
+ else
+ tempdir = concat (tempdir, "/");
+
+ keep_tempfiles = 0;
+
+ /* Allocate ARGC input files, which must be enough. */
+
+ infiles = (char **) xmalloc (argc * sizeof (char *));
+ outfiles = (char **) xmalloc (argc * sizeof (char *));
+ ip = infiles;
+ op = outfiles;
+
+ while (arg_index < argc)
+ {
+ char *arg = argv[arg_index++];
+
+ if (*arg == '-')
+ {
+ if (strcmp (arg, "--version") == 0)
+ {
+ printf ("texindex (GNU %s) %s\n", PACKAGE, VERSION);
+ puts ("");
+ puts ("Copyright (C) 2004 Free Software Foundation, Inc.");
+ printf (_("There is NO warranty. You may redistribute this software\n\
+under the terms of the GNU General Public License.\n\
+For more information about these matters, see the files named COPYING.\n"));
+ xexit (0);
+ }
+ else if ((strcmp (arg, "--keep") == 0) ||
+ (strcmp (arg, "-k") == 0))
+ {
+ keep_tempfiles = 1;
+ }
+ else if ((strcmp (arg, "--help") == 0) ||
+ (strcmp (arg, "-h") == 0))
+ {
+ usage (0);
+ }
+ else if ((strcmp (arg, "--output") == 0) ||
+ (strcmp (arg, "-o") == 0))
+ {
+ if (argv[arg_index] != (char *)NULL)
+ {
+ arg_index++;
+ if (op > outfiles)
+ *(op - 1) = argv[arg_index];
+ }
+ else
+ usage (1);
+ }
+ else
+ usage (1);
+ }
+ else
+ {
+ *ip++ = arg;
+ *op++ = (char *)NULL;
+ }
+ }
+
+ /* Record number of keyfields and terminate list of filenames. */
+ num_infiles = ip - infiles;
+ *ip = (char *)NULL;
+ if (num_infiles == 0)
+ usage (1);
+}
+
+/* Return a name for temporary file COUNT. */
+
+static char *
+maketempname (int count)
+{
+ static char *tempbase = NULL;
+ char tempsuffix[10];
+
+ if (!tempbase)
+ {
+ int fd;
+ tempbase = concat (tempdir, "txidxXXXXXX");
+
+ fd = mkstemp (tempbase);
+ if (fd == -1)
+ pfatal_with_name (tempbase);
+ }
+
+ sprintf (tempsuffix, ".%d", count);
+ return concat (tempbase, tempsuffix);
+}
+
+
+/* Delete all temporary files up to TO_COUNT. */
+
+void
+flush_tempfiles (int to_count)
+{
+ if (keep_tempfiles)
+ return;
+ while (last_deleted_tempcount < to_count)
+ unlink (maketempname (++last_deleted_tempcount));
+}
+
+
+/* Compare LINE1 and LINE2 according to the specified set of keyfields. */
+
+int
+compare_full (const void *p1, const void *p2)
+{
+ char **line1 = (char **) p1;
+ char **line2 = (char **) p2;
+ int i;
+
+ /* Compare using the first keyfield;
+ if that does not distinguish the lines, try the second keyfield;
+ and so on. */
+
+ for (i = 0; i < num_keyfields; i++)
+ {
+ long length1, length2;
+ char *start1 = find_field (&keyfields[i], *line1, &length1);
+ char *start2 = find_field (&keyfields[i], *line2, &length2);
+ int tem = compare_field (&keyfields[i], start1, length1,
+ *line1 - text_base,
+ start2, length2, *line2 - text_base);
+ if (tem)
+ {
+ if (keyfields[i].reverse)
+ return -tem;
+ return tem;
+ }
+ }
+
+ return 0; /* Lines match exactly. */
+}
+
+/* Compare LINE1 and LINE2, described by structures
+ in which the first keyfield is identified in advance.
+ For positional sorting, assumes that the order of the lines in core
+ reflects their nominal order. */
+int
+compare_prepared (const void *p1, const void *p2)
+{
+ struct lineinfo *line1 = (struct lineinfo *) p1;
+ struct lineinfo *line2 = (struct lineinfo *) p2;
+ int i;
+ int tem;
+ char *text1, *text2;
+
+ /* Compare using the first keyfield, which has been found for us already. */
+ if (keyfields->positional)
+ {
+ if (line1->text - text_base > line2->text - text_base)
+ tem = 1;
+ else
+ tem = -1;
+ }
+ else if (keyfields->numeric)
+ tem = line1->key.number - line2->key.number;
+ else
+ tem = compare_field (keyfields, line1->key.text, line1->keylen, 0,
+ line2->key.text, line2->keylen, 0);
+ if (tem)
+ {
+ if (keyfields->reverse)
+ return -tem;
+ return tem;
+ }
+
+ text1 = line1->text;
+ text2 = line2->text;
+
+ /* Compare using the second keyfield;
+ if that does not distinguish the lines, try the third keyfield;
+ and so on. */
+
+ for (i = 1; i < num_keyfields; i++)
+ {
+ long length1, length2;
+ char *start1 = find_field (&keyfields[i], text1, &length1);
+ char *start2 = find_field (&keyfields[i], text2, &length2);
+ int tem = compare_field (&keyfields[i], start1, length1,
+ text1 - text_base,
+ start2, length2, text2 - text_base);
+ if (tem)
+ {
+ if (keyfields[i].reverse)
+ return -tem;
+ return tem;
+ }
+ }
+
+ return 0; /* Lines match exactly. */
+}
+
+/* Like compare_full but more general.
+ You can pass any strings, and you can say how many keyfields to use.
+ POS1 and POS2 should indicate the nominal positional ordering of
+ the two lines in the input. */
+
+int
+compare_general (char *str1, char *str2, long int pos1, long int pos2, int use_keyfields)
+{
+ int i;
+
+ /* Compare using the first keyfield;
+ if that does not distinguish the lines, try the second keyfield;
+ and so on. */
+
+ for (i = 0; i < use_keyfields; i++)
+ {
+ long length1, length2;
+ char *start1 = find_field (&keyfields[i], str1, &length1);
+ char *start2 = find_field (&keyfields[i], str2, &length2);
+ int tem = compare_field (&keyfields[i], start1, length1, pos1,
+ start2, length2, pos2);
+ if (tem)
+ {
+ if (keyfields[i].reverse)
+ return -tem;
+ return tem;
+ }
+ }
+
+ return 0; /* Lines match exactly. */
+}
+
+/* Find the start and length of a field in STR according to KEYFIELD.
+ A pointer to the starting character is returned, and the length
+ is stored into the int that LENGTHPTR points to. */
+
+char *
+find_field (struct keyfield *keyfield, char *str, long int *lengthptr)
+{
+ char *start;
+ char *end;
+ char *(*fun) ();
+
+ if (keyfield->braced)
+ fun = find_braced_pos;
+ else
+ fun = find_pos;
+
+ start = (*fun) (str, keyfield->startwords, keyfield->startchars,
+ keyfield->ignore_blanks);
+ if (keyfield->endwords < 0)
+ {
+ if (keyfield->braced)
+ end = find_braced_end (start);
+ else
+ {
+ end = start;
+ while (*end && *end != '\n')
+ end++;
+ }
+ }
+ else
+ {
+ end = (*fun) (str, keyfield->endwords, keyfield->endchars, 0);
+ if (end - str < start - str)
+ end = start;
+ }
+ *lengthptr = end - start;
+ return start;
+}
+
+/* Return a pointer to a specified place within STR,
+ skipping (from the beginning) WORDS words and then CHARS chars.
+ If IGNORE_BLANKS is nonzero, we skip all blanks
+ after finding the specified word. */
+
+char *
+find_pos (char *str, int words, int chars, int ignore_blanks)
+{
+ int i;
+ char *p = str;
+
+ for (i = 0; i < words; i++)
+ {
+ char c;
+ /* Find next bunch of nonblanks and skip them. */
+ while ((c = *p) == ' ' || c == '\t')
+ p++;
+ while ((c = *p) && c != '\n' && !(c == ' ' || c == '\t'))
+ p++;
+ if (!*p || *p == '\n')
+ return p;
+ }
+
+ while (*p == ' ' || *p == '\t')
+ p++;
+
+ for (i = 0; i < chars; i++)
+ {
+ if (!*p || *p == '\n')
+ break;
+ p++;
+ }
+ return p;
+}
+
+/* Like find_pos but assumes that each field is surrounded by braces
+ and that braces within fields are balanced. */
+
+char *
+find_braced_pos (char *str, int words, int chars, int ignore_blanks)
+{
+ int i;
+ int bracelevel;
+ char *p = str;
+ char c;
+
+ for (i = 0; i < words; i++)
+ {
+ bracelevel = 1;
+ while ((c = *p++) != '{' && c != '\n' && c)
+ /* Do nothing. */ ;
+ if (c != '{')
+ return p - 1;
+ while (bracelevel)
+ {
+ c = *p++;
+ if (c == '{')
+ bracelevel++;
+ if (c == '}')
+ bracelevel--;
+ if (c == 0 || c == '\n')
+ return p - 1;
+ }
+ }
+
+ while ((c = *p++) != '{' && c != '\n' && c)
+ /* Do nothing. */ ;
+
+ if (c != '{')
+ return p - 1;
+
+ if (ignore_blanks)
+ while ((c = *p) == ' ' || c == '\t')
+ p++;
+
+ for (i = 0; i < chars; i++)
+ {
+ if (!*p || *p == '\n')
+ break;
+ p++;
+ }
+ return p;
+}
+
+/* Find the end of the balanced-brace field which starts at STR.
+ The position returned is just before the closing brace. */
+
+char *
+find_braced_end (char *str)
+{
+ int bracelevel;
+ char *p = str;
+ char c;
+
+ bracelevel = 1;
+ while (bracelevel)
+ {
+ c = *p++;
+ if (c == '{')
+ bracelevel++;
+ if (c == '}')
+ bracelevel--;
+ if (c == 0 || c == '\n')
+ return p - 1;
+ }
+ return p - 1;
+}
+
+long
+find_value (char *start, long int length)
+{
+ while (length != 0L)
+ {
+ if (isdigit (*start))
+ return atol (start);
+ length--;
+ start++;
+ }
+ return 0l;
+}
+
+/* Vector used to translate characters for comparison.
+ This is how we make all alphanumerics follow all else,
+ and ignore case in the first sorting. */
+int char_order[256];
+
+void
+init_char_order (void)
+{
+ int i;
+ for (i = 1; i < 256; i++)
+ char_order[i] = i;
+
+ for (i = '0'; i <= '9'; i++)
+ char_order[i] += 512;
+
+ for (i = 'a'; i <= 'z'; i++)
+ {
+ char_order[i] = 512 + i;
+ char_order[i + 'A' - 'a'] = 512 + i;
+ }
+}
+
+/* Compare two fields (each specified as a start pointer and a character count)
+ according to KEYFIELD.
+ The sign of the value reports the relation between the fields. */
+
+int
+compare_field (struct keyfield *keyfield, char *start1, long int length1,
+ long int pos1, char *start2, long int length2, long int pos2)
+{
+ if (keyfields->positional)
+ {
+ if (pos1 > pos2)
+ return 1;
+ else
+ return -1;
+ }
+ if (keyfield->numeric)
+ {
+ long value = find_value (start1, length1) - find_value (start2, length2);
+ if (value > 0)
+ return 1;
+ if (value < 0)
+ return -1;
+ return 0;
+ }
+ else
+ {
+ char *p1 = start1;
+ char *p2 = start2;
+ char *e1 = start1 + length1;
+ char *e2 = start2 + length2;
+
+ while (1)
+ {
+ int c1, c2;
+
+ if (p1 == e1)
+ c1 = 0;
+ else
+ c1 = *p1++;
+ if (p2 == e2)
+ c2 = 0;
+ else
+ c2 = *p2++;
+
+ if (char_order[c1] != char_order[c2])
+ return char_order[c1] - char_order[c2];
+ if (!c1)
+ break;
+ }
+
+ /* Strings are equal except possibly for case. */
+ p1 = start1;
+ p2 = start2;
+ while (1)
+ {
+ int c1, c2;
+
+ if (p1 == e1)
+ c1 = 0;
+ else
+ c1 = *p1++;
+ if (p2 == e2)
+ c2 = 0;
+ else
+ c2 = *p2++;
+
+ if (c1 != c2)
+ /* Reverse sign here so upper case comes out last. */
+ return c2 - c1;
+ if (!c1)
+ break;
+ }
+
+ return 0;
+ }
+}
+
+/* A `struct linebuffer' is a structure which holds a line of text.
+ `readline' reads a line from a stream into a linebuffer
+ and works regardless of the length of the line. */
+
+struct linebuffer
+{
+ long size;
+ char *buffer;
+};
+
+/* Initialize LINEBUFFER for use. */
+
+void
+initbuffer (struct linebuffer *linebuffer)
+{
+ linebuffer->size = 200;
+ linebuffer->buffer = (char *) xmalloc (200);
+}
+
+/* Read a line of text from STREAM into LINEBUFFER.
+ Return the length of the line. */
+
+long
+readline (struct linebuffer *linebuffer, FILE *stream)
+{
+ char *buffer = linebuffer->buffer;
+ char *p = linebuffer->buffer;
+ char *end = p + linebuffer->size;
+
+ while (1)
+ {
+ int c = getc (stream);
+ if (p == end)
+ {
+ buffer = (char *) xrealloc (buffer, linebuffer->size *= 2);
+ p += buffer - linebuffer->buffer;
+ end += buffer - linebuffer->buffer;
+ linebuffer->buffer = buffer;
+ }
+ if (c < 0 || c == '\n')
+ {
+ *p = 0;
+ break;
+ }
+ *p++ = c;
+ }
+
+ return p - buffer;
+}
+
+/* Sort an input file too big to sort in core. */
+
+void
+sort_offline (char *infile, off_t total, char *outfile)
+{
+ /* More than enough. */
+ int ntemps = 2 * (total + MAX_IN_CORE_SORT - 1) / MAX_IN_CORE_SORT;
+ char **tempfiles = (char **) xmalloc (ntemps * sizeof (char *));
+ FILE *istream = fopen (infile, "r");
+ int i;
+ struct linebuffer lb;
+ long linelength;
+ int failure = 0;
+
+ initbuffer (&lb);
+
+ /* Read in one line of input data. */
+
+ linelength = readline (&lb, istream);
+
+ if (lb.buffer[0] != '\\' && lb.buffer[0] != '@')
+ {
+ error (_("%s: not a texinfo index file"), infile);
+ return;
+ }
+
+ /* Split up the input into `ntemps' temporary files, or maybe fewer,
+ and put the new files' names into `tempfiles' */
+
+ for (i = 0; i < ntemps; i++)
+ {
+ char *outname = maketempname (++tempcount);
+ FILE *ostream = fopen (outname, "w");
+ long tempsize = 0;
+
+ if (!ostream)
+ pfatal_with_name (outname);
+ tempfiles[i] = outname;
+
+ /* Copy lines into this temp file as long as it does not make file
+ "too big" or until there are no more lines. */
+
+ while (tempsize + linelength + 1 <= MAX_IN_CORE_SORT)
+ {
+ tempsize += linelength + 1;
+ fputs (lb.buffer, ostream);
+ putc ('\n', ostream);
+
+ /* Read another line of input data. */
+
+ linelength = readline (&lb, istream);
+ if (!linelength && feof (istream))
+ break;
+
+ if (lb.buffer[0] != '\\' && lb.buffer[0] != '@')
+ {
+ error (_("%s: not a texinfo index file"), infile);
+ failure = 1;
+ goto fail;
+ }
+ }
+ fclose (ostream);
+ if (feof (istream))
+ break;
+ }
+
+ free (lb.buffer);
+
+fail:
+ /* Record number of temp files we actually needed. */
+
+ ntemps = i;
+
+ /* Sort each tempfile into another tempfile.
+ Delete the first set of tempfiles and put the names of the second
+ into `tempfiles'. */
+
+ for (i = 0; i < ntemps; i++)
+ {
+ char *newtemp = maketempname (++tempcount);
+ sort_in_core (tempfiles[i], MAX_IN_CORE_SORT, newtemp);
+ if (!keep_tempfiles)
+ unlink (tempfiles[i]);
+ tempfiles[i] = newtemp;
+ }
+
+ if (failure)
+ return;
+
+ /* Merge the tempfiles together and indexify. */
+
+ merge_files (tempfiles, ntemps, outfile);
+}
+
+/* Sort INFILE, whose size is TOTAL,
+ assuming that is small enough to be done in-core,
+ then indexify it and send the output to OUTFILE (or to stdout). */
+
+void
+sort_in_core (char *infile, int total, char *outfile)
+{
+ char **nextline;
+ char *data = (char *) xmalloc (total + 1);
+ char *file_data;
+ long file_size;
+ int i;
+ FILE *ostream = stdout;
+ struct lineinfo *lineinfo;
+
+ /* Read the contents of the file into the moby array `data'. */
+
+ int desc = open (infile, O_RDONLY, 0);
+
+ if (desc < 0)
+ fatal (_("failure reopening %s"), infile);
+ for (file_size = 0;;)
+ {
+ i = read (desc, data + file_size, total - file_size);
+ if (i <= 0)
+ break;
+ file_size += i;
+ }
+ file_data = data;
+ data[file_size] = 0;
+
+ close (desc);
+
+ if (file_size > 0 && data[0] != '\\' && data[0] != '@')
+ {
+ error (_("%s: not a texinfo index file"), infile);
+ return;
+ }
+
+ init_char_order ();
+
+ /* Sort routines want to know this address. */
+
+ text_base = data;
+
+ /* Create the array of pointers to lines, with a default size
+ frequently enough. */
+
+ nlines = total / 50;
+ if (!nlines)
+ nlines = 2;
+ linearray = (char **) xmalloc (nlines * sizeof (char *));
+
+ /* `nextline' points to the next free slot in this array.
+ `nlines' is the allocated size. */
+
+ nextline = linearray;
+
+ /* Parse the input file's data, and make entries for the lines. */
+
+ nextline = parsefile (infile, nextline, file_data, file_size);
+ if (nextline == 0)
+ {
+ error (_("%s: not a texinfo index file"), infile);
+ return;
+ }
+
+ /* Sort the lines. */
+
+ /* If we have enough space, find the first keyfield of each line in advance.
+ Make a `struct lineinfo' for each line, which records the keyfield
+ as well as the line, and sort them. */
+
+ lineinfo = malloc ((nextline - linearray) * sizeof (struct lineinfo));
+
+ if (lineinfo)
+ {
+ struct lineinfo *lp;
+ char **p;
+
+ for (lp = lineinfo, p = linearray; p != nextline; lp++, p++)
+ {
+ lp->text = *p;
+ lp->key.text = find_field (keyfields, *p, &lp->keylen);
+ if (keyfields->numeric)
+ lp->key.number = find_value (lp->key.text, lp->keylen);
+ }
+
+ qsort (lineinfo, nextline - linearray, sizeof (struct lineinfo),
+ compare_prepared);
+
+ for (lp = lineinfo, p = linearray; p != nextline; lp++, p++)
+ *p = lp->text;
+
+ free (lineinfo);
+ }
+ else
+ qsort (linearray, nextline - linearray, sizeof (char *), compare_full);
+
+ /* Open the output file. */
+
+ if (outfile)
+ {
+ ostream = fopen (outfile, "w");
+ if (!ostream)
+ pfatal_with_name (outfile);
+ }
+
+ writelines (linearray, nextline - linearray, ostream);
+ if (outfile)
+ fclose (ostream);
+
+ free (linearray);
+ free (data);
+}
+
+/* Parse an input string in core into lines.
+ DATA is the input string, and SIZE is its length.
+ Data goes in LINEARRAY starting at NEXTLINE.
+ The value returned is the first entry in LINEARRAY still unused.
+ Value 0 means input file contents are invalid. */
+
+char **
+parsefile (char *filename, char **nextline, char *data, long int size)
+{
+ char *p, *end;
+ char **line = nextline;
+
+ p = data;
+ end = p + size;
+ *end = 0;
+
+ while (p != end)
+ {
+ if (p[0] != '\\' && p[0] != '@')
+ return 0;
+
+ *line = p;
+
+ /* Find the first letter of the first field of this line. If it
+ is different from the first letter of the first field of the
+ first line, we need initial headers in the output index. */
+ while (*p && *p != '{')
+ p++;
+ if (p == end)
+ return 0;
+ p++;
+ if (first_initial)
+ {
+ if (first_initial != toupper (*p))
+ need_initials = 1;
+ }
+ else
+ first_initial = toupper (*p);
+
+ while (*p && *p != '\n')
+ p++;
+ if (p != end)
+ p++;
+
+ line++;
+ if (line == linearray + nlines)
+ {
+ char **old = linearray;
+ linearray = xrealloc (linearray, sizeof (char *) * (nlines *= 4));
+ line += linearray - old;
+ }
+ }
+
+ return line;
+}
+
+/* Indexification is a filter applied to the sorted lines
+ as they are being written to the output file.
+ Multiple entries for the same name, with different page numbers,
+ get combined into a single entry with multiple page numbers.
+ The first braced field, which is used for sorting, is discarded.
+ However, its first character is examined, folded to lower case,
+ and if it is different from that in the previous line fed to us
+ a \initial line is written with one argument, the new initial.
+
+ If an entry has four braced fields, then the second and third
+ constitute primary and secondary names.
+ In this case, each change of primary name
+ generates a \primary line which contains only the primary name,
+ and in between these are \secondary lines which contain
+ just a secondary name and page numbers. */
+
+/* The last primary name we wrote a \primary entry for.
+ If only one level of indexing is being done, this is the last name seen. */
+char *lastprimary;
+/* Length of storage allocated for lastprimary. */
+int lastprimarylength;
+
+/* Similar, for the secondary name. */
+char *lastsecondary;
+int lastsecondarylength;
+
+/* Zero if we are not in the middle of writing an entry.
+ One if we have written the beginning of an entry but have not
+ yet written any page numbers into it.
+ Greater than one if we have written the beginning of an entry
+ plus at least one page number. */
+int pending;
+
+/* The initial (for sorting purposes) of the last primary entry written.
+ When this changes, a \initial {c} line is written */
+
+char *lastinitial;
+
+int lastinitiallength;
+
+/* When we need a string of length 1 for the value of lastinitial,
+ store it here. */
+
+char lastinitial1[2];
+
+/* Initialize static storage for writing an index. */
+
+void
+init_index (void)
+{
+ pending = 0;
+ lastinitial = lastinitial1;
+ lastinitial1[0] = 0;
+ lastinitial1[1] = 0;
+ lastinitiallength = 0;
+ lastprimarylength = 100;
+ lastprimary = (char *) xmalloc (lastprimarylength + 1);
+ memset (lastprimary, '\0', lastprimarylength + 1);
+ lastsecondarylength = 100;
+ lastsecondary = (char *) xmalloc (lastsecondarylength + 1);
+ memset (lastsecondary, '\0', lastsecondarylength + 1);
+}
+
+/* Indexify. Merge entries for the same name,
+ insert headers for each initial character, etc. */
+
+void
+indexify (char *line, FILE *ostream)
+{
+ char *primary, *secondary, *pagenumber;
+ int primarylength, secondarylength = 0, pagelength;
+ int nosecondary;
+ int initiallength;
+ char *initial;
+ char initial1[2];
+ register char *p;
+
+ /* First, analyze the parts of the entry fed to us this time. */
+
+ p = find_braced_pos (line, 0, 0, 0);
+ if (*p == '{')
+ {
+ initial = p;
+ /* Get length of inner pair of braces starting at `p',
+ including that inner pair of braces. */
+ initiallength = find_braced_end (p + 1) + 1 - p;
+ }
+ else
+ {
+ initial = initial1;
+ initial1[0] = toupper (*p);
+ initial1[1] = 0;
+ initiallength = 1;
+ }
+
+ pagenumber = find_braced_pos (line, 1, 0, 0);
+ pagelength = find_braced_end (pagenumber) - pagenumber;
+ if (pagelength == 0)
+ fatal (_("No page number in %s"), line);
+
+ primary = find_braced_pos (line, 2, 0, 0);
+ primarylength = find_braced_end (primary) - primary;
+
+ secondary = find_braced_pos (line, 3, 0, 0);
+ nosecondary = !*secondary;
+ if (!nosecondary)
+ secondarylength = find_braced_end (secondary) - secondary;
+
+ /* If the primary is different from before, make a new primary entry. */
+ if (strncmp (primary, lastprimary, primarylength))
+ {
+ /* Close off current secondary entry first, if one is open. */
+ if (pending)
+ {
+ fputs ("}\n", ostream);
+ pending = 0;
+ }
+
+ /* If this primary has a different initial, include an entry for
+ the initial. */
+ if (need_initials &&
+ (initiallength != lastinitiallength ||
+ strncmp (initial, lastinitial, initiallength)))
+ {
+ fprintf (ostream, "\\initial {");
+ fwrite (initial, 1, initiallength, ostream);
+ fputs ("}\n", ostream);
+ if (initial == initial1)
+ {
+ lastinitial = lastinitial1;
+ *lastinitial1 = *initial1;
+ }
+ else
+ {
+ lastinitial = initial;
+ }
+ lastinitiallength = initiallength;
+ }
+
+ /* Make the entry for the primary. */
+ if (nosecondary)
+ fputs ("\\entry {", ostream);
+ else
+ fputs ("\\primary {", ostream);
+ fwrite (primary, primarylength, 1, ostream);
+ if (nosecondary)
+ {
+ fputs ("}{", ostream);
+ pending = 1;
+ }
+ else
+ fputs ("}\n", ostream);
+
+ /* Record name of most recent primary. */
+ if (lastprimarylength < primarylength)
+ {
+ lastprimarylength = primarylength + 100;
+ lastprimary = (char *) xrealloc (lastprimary,
+ 1 + lastprimarylength);
+ }
+ strncpy (lastprimary, primary, primarylength);
+ lastprimary[primarylength] = 0;
+
+ /* There is no current secondary within this primary, now. */
+ lastsecondary[0] = 0;
+ }
+
+ /* Should not have an entry with no subtopic following one with a
+ subtopic. */
+
+ if (nosecondary && *lastsecondary)
+ error (_("entry %s follows an entry with a secondary name"), line);
+
+ /* Start a new secondary entry if necessary. */
+ if (!nosecondary && strncmp (secondary, lastsecondary, secondarylength))
+ {
+ if (pending)
+ {
+ fputs ("}\n", ostream);
+ pending = 0;
+ }
+
+ /* Write the entry for the secondary. */
+ fputs ("\\secondary {", ostream);
+ fwrite (secondary, secondarylength, 1, ostream);
+ fputs ("}{", ostream);
+ pending = 1;
+
+ /* Record name of most recent secondary. */
+ if (lastsecondarylength < secondarylength)
+ {
+ lastsecondarylength = secondarylength + 100;
+ lastsecondary = (char *) xrealloc (lastsecondary,
+ 1 + lastsecondarylength);
+ }
+ strncpy (lastsecondary, secondary, secondarylength);
+ lastsecondary[secondarylength] = 0;
+ }
+
+ /* Here to add one more page number to the current entry. */
+ if (pending++ != 1)
+ fputs (", ", ostream); /* Punctuate first, if this is not the first. */
+ fwrite (pagenumber, pagelength, 1, ostream);
+}
+
+/* Close out any unfinished output entry. */
+
+void
+finish_index (FILE *ostream)
+{
+ if (pending)
+ fputs ("}\n", ostream);
+ free (lastprimary);
+ free (lastsecondary);
+}
+
+/* Copy the lines in the sorted order.
+ Each line is copied out of the input file it was found in. */
+
+void
+writelines (char **linearray, int nlines, FILE *ostream)
+{
+ char **stop_line = linearray + nlines;
+ char **next_line;
+
+ init_index ();
+
+ /* Output the text of the lines, and free the buffer space. */
+
+ for (next_line = linearray; next_line != stop_line; next_line++)
+ {
+ /* If -u was specified, output the line only if distinct from
+ previous one. */
+ if (next_line == linearray
+ /* Compare previous line with this one, using only the
+ explicitly specd keyfields. */
+ || compare_general (*(next_line - 1), *next_line, 0L, 0L,
+ num_keyfields - 1))
+ {
+ char *p = *next_line;
+ char c;
+
+ while ((c = *p++) && c != '\n')
+ /* Do nothing. */ ;
+ *(p - 1) = 0;
+ indexify (*next_line, ostream);
+ }
+ }
+
+ finish_index (ostream);
+}
+
+/* Assume (and optionally verify) that each input file is sorted;
+ merge them and output the result.
+ Returns nonzero if any input file fails to be sorted.
+
+ This is the high-level interface that can handle an unlimited
+ number of files. */
+
+#define MAX_DIRECT_MERGE 10
+
+int
+merge_files (char **infiles, int nfiles, char *outfile)
+{
+ char **tempfiles;
+ int ntemps;
+ int i;
+ int value = 0;
+ int start_tempcount = tempcount;
+
+ if (nfiles <= MAX_DIRECT_MERGE)
+ return merge_direct (infiles, nfiles, outfile);
+
+ /* Merge groups of MAX_DIRECT_MERGE input files at a time,
+ making a temporary file to hold each group's result. */
+
+ ntemps = (nfiles + MAX_DIRECT_MERGE - 1) / MAX_DIRECT_MERGE;
+ tempfiles = (char **) xmalloc (ntemps * sizeof (char *));
+ for (i = 0; i < ntemps; i++)
+ {
+ int nf = MAX_DIRECT_MERGE;
+ if (i + 1 == ntemps)
+ nf = nfiles - i * MAX_DIRECT_MERGE;
+ tempfiles[i] = maketempname (++tempcount);
+ value |= merge_direct (&infiles[i * MAX_DIRECT_MERGE], nf, tempfiles[i]);
+ }
+
+ /* All temporary files that existed before are no longer needed
+ since their contents have been merged into our new tempfiles.
+ So delete them. */
+ flush_tempfiles (start_tempcount);
+
+ /* Now merge the temporary files we created. */
+
+ merge_files (tempfiles, ntemps, outfile);
+
+ free (tempfiles);
+
+ return value;
+}
+
+/* Assume (and optionally verify) that each input file is sorted;
+ merge them and output the result.
+ Returns nonzero if any input file fails to be sorted.
+
+ This version of merging will not work if the number of
+ input files gets too high. Higher level functions
+ use it only with a bounded number of input files. */
+
+int
+merge_direct (char **infiles, int nfiles, char *outfile)
+{
+ struct linebuffer *lb1, *lb2;
+ struct linebuffer **thisline, **prevline;
+ FILE **streams;
+ int i;
+ int nleft;
+ int lossage = 0;
+ int *file_lossage;
+ struct linebuffer *prev_out = 0;
+ FILE *ostream = stdout;
+
+ if (outfile)
+ {
+ ostream = fopen (outfile, "w");
+ }
+ if (!ostream)
+ pfatal_with_name (outfile);
+
+ init_index ();
+
+ if (nfiles == 0)
+ {
+ if (outfile)
+ fclose (ostream);
+ return 0;
+ }
+
+ /* For each file, make two line buffers. Also, for each file, there
+ is an element of `thisline' which points at any time to one of the
+ file's two buffers, and an element of `prevline' which points to
+ the other buffer. `thisline' is supposed to point to the next
+ available line from the file, while `prevline' holds the last file
+ line used, which is remembered so that we can verify that the file
+ is properly sorted. */
+
+ /* lb1 and lb2 contain one buffer each per file. */
+ lb1 = (struct linebuffer *) xmalloc (nfiles * sizeof (struct linebuffer));
+ lb2 = (struct linebuffer *) xmalloc (nfiles * sizeof (struct linebuffer));
+
+ /* thisline[i] points to the linebuffer holding the next available
+ line in file i, or is zero if there are no lines left in that file. */
+ thisline = (struct linebuffer **)
+ xmalloc (nfiles * sizeof (struct linebuffer *));
+ /* prevline[i] points to the linebuffer holding the last used line
+ from file i. This is just for verifying that file i is properly
+ sorted. */
+ prevline = (struct linebuffer **)
+ xmalloc (nfiles * sizeof (struct linebuffer *));
+ /* streams[i] holds the input stream for file i. */
+ streams = (FILE **) xmalloc (nfiles * sizeof (FILE *));
+ /* file_lossage[i] is nonzero if we already know file i is not
+ properly sorted. */
+ file_lossage = (int *) xmalloc (nfiles * sizeof (int));
+
+ /* Allocate and initialize all that storage. */
+
+ for (i = 0; i < nfiles; i++)
+ {
+ initbuffer (&lb1[i]);
+ initbuffer (&lb2[i]);
+ thisline[i] = &lb1[i];
+ prevline[i] = &lb2[i];
+ file_lossage[i] = 0;
+ streams[i] = fopen (infiles[i], "r");
+ if (!streams[i])
+ pfatal_with_name (infiles[i]);
+
+ readline (thisline[i], streams[i]);
+ }
+
+ /* Keep count of number of files not at eof. */
+ nleft = nfiles;
+
+ while (nleft)
+ {
+ struct linebuffer *best = 0;
+ struct linebuffer *exch;
+ int bestfile = -1;
+ int i;
+
+ /* Look at the next avail line of each file; choose the least one. */
+
+ for (i = 0; i < nfiles; i++)
+ {
+ if (thisline[i] &&
+ (!best ||
+ 0 < compare_general (best->buffer, thisline[i]->buffer,
+ (long) bestfile, (long) i, num_keyfields)))
+ {
+ best = thisline[i];
+ bestfile = i;
+ }
+ }
+
+ /* Output that line, unless it matches the previous one and we
+ don't want duplicates. */
+
+ if (!(prev_out &&
+ !compare_general (prev_out->buffer,
+ best->buffer, 0L, 1L, num_keyfields - 1)))
+ indexify (best->buffer, ostream);
+ prev_out = best;
+
+ /* Now make the line the previous of its file, and fetch a new
+ line from that file. */
+
+ exch = prevline[bestfile];
+ prevline[bestfile] = thisline[bestfile];
+ thisline[bestfile] = exch;
+
+ while (1)
+ {
+ /* If the file has no more, mark it empty. */
+
+ if (feof (streams[bestfile]))
+ {
+ thisline[bestfile] = 0;
+ /* Update the number of files still not empty. */
+ nleft--;
+ break;
+ }
+ readline (thisline[bestfile], streams[bestfile]);
+ if (thisline[bestfile]->buffer[0] || !feof (streams[bestfile]))
+ break;
+ }
+ }
+
+ finish_index (ostream);
+
+ /* Free all storage and close all input streams. */
+
+ for (i = 0; i < nfiles; i++)
+ {
+ fclose (streams[i]);
+ free (lb1[i].buffer);
+ free (lb2[i].buffer);
+ }
+ free (file_lossage);
+ free (lb1);
+ free (lb2);
+ free (thisline);
+ free (prevline);
+ free (streams);
+
+ if (outfile)
+ fclose (ostream);
+
+ return lossage;
+}
+
+/* Print error message and exit. */
+
+void
+fatal (const char *format, const char *arg)
+{
+ error (format, arg);
+ xexit (1);
+}
+
+/* Print error message. FORMAT is printf control string, ARG is arg for it. */
+void
+error (const char *format, const char *arg)
+{
+ printf ("%s: ", program_name);
+ printf (format, arg);
+ if (format[strlen (format) -1] != '\n')
+ printf ("\n");
+}
+
+void
+perror_with_name (const char *name)
+{
+ fprintf (stderr, "%s: ", program_name);
+ perror (name);
+}
+
+void
+pfatal_with_name (const char *name)
+{
+ perror_with_name (name);
+ xexit (1);
+}
+
+
+/* Return a newly-allocated string concatenating S1 and S2. */
+
+char *
+concat (char *s1, char *s2)
+{
+ int len1 = strlen (s1), len2 = strlen (s2);
+ char *result = (char *) xmalloc (len1 + len2 + 1);
+
+ strcpy (result, s1);
+ strcpy (result + len1, s2);
+ *(result + len1 + len2) = 0;
+
+ return result;
+}
diff --git a/Build/source/utils/texinfo/util/texindex.rc b/Build/source/utils/texinfo/util/texindex.rc
new file mode 100644
index 00000000000..0cee04d15bf
--- /dev/null
+++ b/Build/source/utils/texinfo/util/texindex.rc
@@ -0,0 +1,36 @@
+/* texindex.rc: texindex resources -*- C++ -*-
+
+ Copyright (C) 1996-2003 Fabrice Popineau <fabrice.popineau@supelec.fr>
+
+ This 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 2, or (at your
+ option) any later version.
+
+ This 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 file; if not, write to the Free Software
+ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ USA. */
+
+#include <texlive-version.h>
+
+#define VER_FILEVERSION TEXLIVE_MAJOR_VERSION,TEXLIVE_MINOR_VERSION,TEXLIVE_BETA_NUMBER,TEXLIVE_ALPHA_NUMBER
+#define VER_FILEVERSION_STR TEXLIVE_PRODUCTVERSION_STR " texindex 4.3a"
+
+#define VER_INTERNALNAME_STR "texindex"
+#define VER_ORIGINALFILENAME_STR "texindex.exe"
+
+#define VER_LEGALCOPYRIGHT_STR "Copyright (C) 1987, 91-92, 1996-2002 Free Software Foundation, Inc."
+
+#define VER_FILEDESCRIPTION_STR "TeX index generator"
+
+#define VER_COMPANYNAME_STR "Free Software Foundation, Inc."
+
+#include "texlive.version"
+
+/* texlive.rc ends here */
diff --git a/Build/source/utils/texinfo/util/texinfo-cat.in b/Build/source/utils/texinfo/util/texinfo-cat.in
new file mode 100644
index 00000000000..f0f0674ec8b
--- /dev/null
+++ b/Build/source/utils/texinfo/util/texinfo-cat.in
@@ -0,0 +1,3 @@
+OVERRIDE YES
+
+PUBLIC "-//GNU//DTD TexinfoML V__VERSION__//EN" "texinfo.dtd"
diff --git a/Build/source/utils/texinfo/util/texinfo.dtd b/Build/source/utils/texinfo/util/texinfo.dtd
new file mode 100644
index 00000000000..617992a59f6
--- /dev/null
+++ b/Build/source/utils/texinfo/util/texinfo.dtd
@@ -0,0 +1,484 @@
+<!-- $Id: texinfo.dtd,v 1.4 2004/12/19 15:08:55 karl Exp $
+ Document Type Definition for Texinfo.
+
+ Author: Philippe Martin (feloy@free.fr)
+ Contributors:
+ Karl Eichwalder (keichwa@gmx.net)
+ Alper Ersoy (dirt@gtk.org)
+
+ Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved.
+
+-->
+
+<!-- ENTITIES -->
+
+<!-- Meta-information -->
+<!ENTITY % metainformation "setfilename | settitle | dircategory
+ | documentdescription">
+<!ENTITY % variables "setvalue | clearvalue">
+
+<!-- Document language -->
+<!ENTITY % lang "documentlanguage">
+
+<!-- Language codes -->
+<!ENTITY % languagecodes "aa|ab|af|am|ar|as|ay|az|ba|be|bg|bh|bi|bn|bo|br|ca|co|cs|cy|da|de|dz|el|en|eo|es|et|eu|fa|fi|fj|fo|fr|fy|ga|gd|gl|gn|gu|ha|he|hi|hr|hu|hy|ia|id|ie|ik|is|it|iu|ja|jw|ka|kk|kl|km|kn|ko|ks|ku|ky|la|ln|lo|lt|lv|mg|mi|mk|ml|mn|mo|mr|ms|mt|my|na|ne|nl|no|oc|om|or|pa|pl|ps|pt|qu|rm|rn|ro|ru|rw|sa|sd|sg|sh|si|sk|sl|sm|sn|so|sq|sr|ss|st|su|sv|sw|ta|te|tg|th|ti|tk|tl|tn|to|tr|ts|tt|tw|ug|uk|ur|uz|vi|vo|wo|xh|yi|yo|za|zh|zu">
+
+<!-- ToC -->
+<!ENTITY % toc "contents | shortcontents">
+
+<!-- Title page -->
+<!ENTITY % titlepage_cmds "author | booktitle | booksubtitle">
+
+<!-- block -->
+<!-- ***** -->
+<!ENTITY % block "menu | para | quotation | example | smallexample | lisp
+ | smalllisp | cartouche | copying
+ | format | smallformat | display
+ | smalldisplay | itemize | enumerate | sp | center | group
+ | table | multitable | definition">
+
+<!-- API definitions -->
+<!-- *************** -->
+<!ENTITY % definition.cmds "defcategory | deffunction | defvariable | defparam
+ | defdelimiter | deftype | defparamtype | defdatatype
+ | defclass | defclassvar | defoperation">
+
+<!-- Headings -->
+<!-- ******** -->
+<!ENTITY % headings "majorheading | chapheading | heading | subheading
+ | subsubheading">
+
+
+<!-- Sectioning -->
+<!-- ********** -->
+<!ENTITY % section.level1 "top | chapter | unnumbered | appendix">
+
+<!ENTITY % section.level2 "section | unnumberedsec | appendixsec">
+
+<!ENTITY % section.level3 "subsection | unnumberedsubsec | appendixsubsec">
+
+<!ENTITY % section.level4 "subsubsection | unnumberedsubsubsec
+ | appendixsubsubsec">
+
+<!ENTITY % section.all "%section.level1; | %section.level2; | %section.level3;
+ | %section.level4;">
+
+
+<!ENTITY % section.level1.content "(%block;
+ | %section.level2;
+ | %section.level3;
+ | %section.level4;
+ | verbatim | titlepage | %toc;
+ | %lang; | %variables;
+ | %headings;
+ | printindex)*">
+
+<!ENTITY % section.level2.content "(%block;
+ | %section.level3;
+ | %section.level4;
+ | verbatim | titlepage | %toc;
+ | %lang; | %variables;
+ | %headings;)*">
+
+<!ENTITY % section.level3.content "(%block;
+ | %section.level4;
+ | verbatim | titlepage | %toc;
+ | %lang; | %variables;
+ | %headings;)*">
+
+<!ENTITY % section.level4.content "(%block;
+ | verbatim | titlepage | %toc;
+ | %lang; | %variables;
+ | %headings;)*">
+
+
+<!-- Inline -->
+<!-- ****** -->
+<!ENTITY % Inline.emphasize "strong | emph">
+<!ENTITY % Inline.fonts "b | i | r | sansserif | slanted | titlefont | tt">
+<!ENTITY % Inline.footnote "footnote">
+<!ENTITY % Inline.markup "code | command | env | file | option | samp
+ | dfn | cite | key | kbd | var | acronym | url">
+<!ENTITY % Inline.math "math">
+<!ENTITY % Inline.reference "xref | inforef | indexterm | email | uref">
+<!ENTITY % Inline.smallcaps "sc">
+
+<!ENTITY % Inline.phrase
+ "%Inline.emphasize; | %Inline.smallcaps; | %Inline.fonts;
+ | %Inline.markup; | %Inline.math; | %Inline.reference;
+ | %Inline.footnote; ">
+
+
+<!-- ************ -->
+<!-- * ELEMENTS * -->
+<!-- ************ -->
+
+<!-- TOP Level Element -->
+<!-- ***************** -->
+<!ELEMENT texinfo ((%metainformation; | titlepage | node | %block; | %toc;
+ | %variables; | %lang;)* )>
+<!ATTLIST texinfo xml:lang (%languagecodes;) 'en'>
+
+<!-- meta-information -->
+<!ELEMENT setfilename (#PCDATA)>
+<!ELEMENT settitle (#PCDATA | %Inline.phrase; | footnote)*>
+<!ELEMENT dircategory (#PCDATA)>
+
+<!ELEMENT setvalue (#PCDATA | %Inline.phrase;)*>
+<!ELEMENT clearvalue EMPTY>
+<!ATTLIST setvalue
+ name CDATA #REQUIRED>
+<!ATTLIST clearvalue
+ name CDATA #REQUIRED>
+
+<!-- ToC -->
+<!ELEMENT contents EMPTY>
+<!ELEMENT shortcontents EMPTY>
+
+<!-- Document language -->
+<!ELEMENT documentlanguage EMPTY>
+<!ATTLIST documentlanguage xml:lang (%languagecodes;) 'en'>
+
+<!-- Titlepage -->
+<!ELEMENT titlepage (%titlepage_cmds; | %block;)*>
+<!ELEMENT author (#PCDATA | %Inline.phrase;)*>
+<!ELEMENT booktitle (#PCDATA | %Inline.phrase;)*>
+<!ELEMENT booksubtitle (#PCDATA | %Inline.phrase;)*>
+
+<!-- NODES -->
+<!-- ***** -->
+<!ELEMENT node (nodename, nodenext?, nodeprev?, nodeup?,
+ (%section.all; | %block; | %toc; | %lang; | image)*) >
+
+<!ELEMENT nodename (#PCDATA)>
+<!ELEMENT nodenext (#PCDATA)>
+<!ELEMENT nodeprev (#PCDATA)>
+<!ELEMENT nodeup (#PCDATA)>
+
+<!-- SECTIONING -->
+<!-- ********** -->
+
+<!ELEMENT top (title?, (%section.level1.content;))>
+
+<!ELEMENT chapter (title?, (%section.level1.content;))>
+<!ELEMENT section (title?, (%section.level2.content;))>
+<!ELEMENT subsection (title?, (%section.level3.content;))>
+<!ELEMENT subsubsection (title?, (%section.level4.content;))>
+
+<!ELEMENT unnumbered (title?, (%section.level1.content;))>
+<!ELEMENT unnumberedsec (title?, (%section.level2.content;))>
+<!ELEMENT unnumberedsubsec (title?, (%section.level3.content;))>
+<!ELEMENT unnumberedsubsubsec (title?, (%section.level4.content;))>
+
+<!ELEMENT appendix (title?, (%section.level1.content;))>
+<!ELEMENT appendixsec (title?, (%section.level2.content;))>
+<!ELEMENT appendixsubsec (title?, (%section.level3.content;))>
+<!ELEMENT appendixsubsubsec (title?, (%section.level4.content;))>
+
+<!-- Headings and titles -->
+<!ELEMENT majorheading (#PCDATA | %Inline.phrase; | footnote)*>
+<!ELEMENT chapheading (#PCDATA | %Inline.phrase; | footnote)*>
+<!ELEMENT heading (#PCDATA | %Inline.phrase; | footnote)*>
+<!ELEMENT subheading (#PCDATA | %Inline.phrase; | footnote)*>
+<!ELEMENT subsubheading (#PCDATA | %Inline.phrase; | footnote)*>
+<!ELEMENT title (#PCDATA | %Inline.phrase; | footnote)*>
+
+<!-- Negative Indentation in Blocks -->
+<!ELEMENT exdent (#PCDATA | %Inline.phrase;)*>
+
+<!-- BLOCK Elements -->
+<!-- ************** -->
+
+<!ELEMENT quotation (%block; | %Inline.phrase; | exdent)*>
+<!ELEMENT documentdescription (#PCDATA | %block; | %Inline.phrase;)*>
+<!ELEMENT example (#PCDATA | %block; | %Inline.phrase; | exdent)*>
+<!ELEMENT smallexample (#PCDATA | %block; | %Inline.phrase; | exdent)*>
+<!ELEMENT lisp (#PCDATA | %block; | %Inline.phrase; | exdent)*>
+<!ELEMENT smalllisp (#PCDATA | %block; | %Inline.phrase; | exdent)*>
+<!ELEMENT cartouche (#PCDATA | %block; | %Inline.phrase; | exdent)*>
+<!ELEMENT copying (#PCDATA | %block; | %Inline.phrase; | exdent)*>
+<!ELEMENT format (#PCDATA | %block; | %Inline.phrase; | exdent)*>
+<!ELEMENT smallformat (#PCDATA | %block; | %Inline.phrase; | exdent)*>
+<!ELEMENT display (#PCDATA | %block; | %Inline.phrase; | exdent)*>
+<!ELEMENT smalldisplay (#PCDATA | %block; | %Inline.phrase; | exdent)*>
+<!ELEMENT center (#PCDATA | %block; | %Inline.phrase; | exdent)*>
+<!ELEMENT group (#PCDATA | %block; | %Inline.phrase; | exdent)*>
+
+<!ELEMENT image (alttext)>
+<!ELEMENT alttext (#PCDATA)>
+<!ATTLIST image
+ name CDATA #REQUIRED
+ extension CDATA #REQUIRED
+ width CDATA #REQUIRED
+ height CDATA #REQUIRED>
+
+<!-- Whitespace in these elements are always preserved -->
+<!ATTLIST example xml:space (preserve) #FIXED 'preserve'>
+<!ATTLIST smallexample xml:space (preserve) #FIXED 'preserve'>
+<!ATTLIST lisp xml:space (preserve) #FIXED 'preserve'>
+<!ATTLIST smalllisp xml:space (preserve) #FIXED 'preserve'>
+<!ATTLIST display xml:space (preserve) #FIXED 'preserve'>
+<!ATTLIST smalldisplay xml:space (preserve) #FIXED 'preserve'>
+<!ATTLIST format xml:space (preserve) #FIXED 'preserve'>
+<!ATTLIST smallformat xml:space (preserve) #FIXED 'preserve'>
+
+<!ELEMENT verbatim (#PCDATA)>
+<!ATTLIST verbatim xml:space (preserve) #FIXED 'preserve'>
+
+<!ELEMENT para (#PCDATA | %Inline.phrase; | footnote | %lang;)*>
+<!ATTLIST para
+ role CDATA #IMPLIED>
+
+<!ELEMENT menu (menuentry | detailmenu | para)*>
+<!ELEMENT detailmenu (menuentry | para)*>
+<!ELEMENT menuentry (menunode?, menutitle?, menucomment?)>
+<!ELEMENT menunode (#PCDATA)>
+<!ELEMENT menutitle (#PCDATA)>
+<!ELEMENT menucomment (#PCDATA | para)*>
+
+<!-- Floating displays -->
+<!ELEMENT float (floattype, floatpos, (%block;)*, caption?)>
+<!ATTLIST float
+ name CDATA #IMPLIED>
+<!ELEMENT floattype (#PCDATA)>
+<!ELEMENT floatpos (#PCDATA)>
+<!ELEMENT caption (#PCDATA | %Inline.phrase;)*>
+<!ELEMENT listoffloats EMPTY>
+<!ATTLIST listoffloats
+ type CDATA #IMPLIED>
+
+<!-- Lists -->
+<!ELEMENT itemize (itemfunction, (item | itemize | enumerate | indexterm)*)>
+<!ELEMENT enumerate (enumarg?, (item | itemize | enumerate)*)>
+<!ATTLIST enumerate
+ first CDATA #IMPLIED>
+
+<!ELEMENT item (%block;)*>
+<!ELEMENT enumarg (#PCDATA)>
+
+<!ELEMENT itemfunction (#PCDATA | %Inline.phrase;)*>
+
+<!-- Tables -->
+<!ELEMENT table (tableitem | indexterm)+>
+<!ELEMENT tableitem ((tableterm, indexterm*)+, item?)>
+<!ELEMENT tableterm (#PCDATA | %Inline.phrase;)*>
+
+<!ELEMENT multitable (columnfraction*, thead?, tbody)>
+<!ELEMENT columnfraction (#PCDATA)>
+<!ELEMENT thead (row+)>
+<!ELEMENT tbody (row+)>
+<!ELEMENT row (entry*)>
+<!ELEMENT entry (#PCDATA | %Inline.phrase;)*>
+
+<!-- API definitions -->
+<!ELEMENT definition (definitionterm | definitionitem)+>
+<!ELEMENT definitionterm (%definition.cmds; | indexterm)+>
+<!ELEMENT definitionitem (%block;)*>
+
+<!ELEMENT defcategory (#PCDATA | %Inline.phrase; | footnote)*>
+<!ELEMENT deffunction (#PCDATA | %Inline.phrase; | footnote)*>
+<!ELEMENT defvariable (#PCDATA | %Inline.phrase; | footnote)*>
+<!ELEMENT defparam (#PCDATA | %Inline.phrase; | footnote)*>
+<!ELEMENT defdelimiter (#PCDATA | %Inline.phrase; | footnote)*>
+<!ELEMENT deftype (#PCDATA | %Inline.phrase; | footnote)*>
+<!ELEMENT defparamtype (#PCDATA | %Inline.phrase; | footnote)*>
+<!ELEMENT defdatatype (#PCDATA | %Inline.phrase; | footnote)*>
+<!ELEMENT defclass (#PCDATA | %Inline.phrase; | footnote)*>
+<!ELEMENT defclassvar (#PCDATA | %Inline.phrase; | footnote)*>
+<!ELEMENT defoperation (#PCDATA | %Inline.phrase; | footnote)*>
+
+<!-- INLINE Elements -->
+<!-- *************** -->
+
+<!-- Emphasize -->
+<!ELEMENT strong (#PCDATA | %Inline.phrase;)*>
+<!ELEMENT emph (#PCDATA | %Inline.phrase;)*>
+
+<!-- small caps -->
+<!ELEMENT sc (#PCDATA | %Inline.phrase;)*>
+
+<!-- fonts -->
+<!ELEMENT i (#PCDATA | %Inline.phrase;)*>
+<!ELEMENT b (#PCDATA | %Inline.phrase;)*>
+<!ELEMENT tt (#PCDATA | %Inline.phrase;)*>
+<!ELEMENT r (#PCDATA | %Inline.phrase;)*>
+<!ELEMENT notfixedwidth (#PCDATA | %Inline.phrase;)*>
+<!ELEMENT titlefont (#PCDATA | %Inline.phrase;)*>
+
+<!-- markup -->
+<!ELEMENT code (#PCDATA | %Inline.phrase;)*>
+<!ELEMENT command (#PCDATA | %Inline.phrase;)*>
+<!ELEMENT env (#PCDATA | %Inline.phrase;)*>
+<!ELEMENT file (#PCDATA | %Inline.phrase;)*>
+<!ELEMENT option (#PCDATA | %Inline.phrase;)*>
+<!ELEMENT samp (#PCDATA | %Inline.phrase;)*>
+<!ELEMENT dfn (#PCDATA | %Inline.phrase;)*>
+<!ELEMENT cite (#PCDATA | %Inline.phrase;)*>
+<!ELEMENT key (#PCDATA | %Inline.phrase;)*>
+<!ELEMENT kbd (#PCDATA | %Inline.phrase;)*>
+<!ELEMENT var (#PCDATA | %Inline.phrase;)*>
+<!ELEMENT url (#PCDATA | %Inline.phrase;)*>
+
+<!ELEMENT acronym (acronymword, acronymdesc?)>
+<!ELEMENT acronymword (#PCDATA | %Inline.phrase;)*>
+<!ELEMENT acronymdesc (#PCDATA | %Inline.phrase;)*>
+
+<!ELEMENT abbrev (abbrevword, abbrevdesc?)>
+<!ELEMENT abbrevword (#PCDATA | %Inline.phrase;)*>
+<!ELEMENT abbrevdesc (#PCDATA | %Inline.phrase;)*>
+
+<!-- math -->
+<!ELEMENT math (#PCDATA | %Inline.phrase;)*>
+
+<!-- reference -->
+<!ELEMENT anchor EMPTY>
+<!ATTLIST anchor
+ name CDATA #IMPLIED>
+
+<!ELEMENT xref (xrefnodename | xrefinfoname | xrefinfofile
+ | xrefprintedname | xrefprinteddesc)*>
+<!ELEMENT xrefnodename (#PCDATA | %Inline.phrase;)*>
+<!ELEMENT xrefinfoname (#PCDATA | %Inline.phrase;)*>
+<!ELEMENT xrefinfofile (#PCDATA | %Inline.phrase;)*>
+<!ELEMENT xrefprintedname (#PCDATA | %Inline.phrase;)*>
+<!ELEMENT xrefprinteddesc (#PCDATA | %Inline.phrase;)*>
+
+<!ELEMENT inforef (inforefnodename | inforefrefname | inforefinfoname)*>
+<!ELEMENT inforefnodename (#PCDATA | %Inline.phrase;)*>
+<!ELEMENT inforefrefname (#PCDATA | %Inline.phrase;)*>
+<!ELEMENT inforefinfoname (#PCDATA | %Inline.phrase;)*>
+
+<!ELEMENT indexterm (#PCDATA | %Inline.phrase;)*>
+<!ATTLIST indexterm
+ index CDATA #IMPLIED>
+
+<!ELEMENT email (emailaddress, emailname?)>
+<!ELEMENT emailaddress (#PCDATA | %Inline.phrase;)*>
+<!ELEMENT emailname (#PCDATA | %Inline.phrase;)*>
+
+<!ELEMENT uref (urefurl, urefdesc?, urefreplacement?)>
+<!ELEMENT urefurl (#PCDATA | %Inline.phrase;)*>
+<!ELEMENT urefdesc (#PCDATA | %Inline.phrase;)*>
+<!ELEMENT urefreplacement (#PCDATA | %Inline.phrase;)*>
+
+<!ELEMENT footnote (para)>
+
+
+<!ELEMENT neos EMPTY>
+
+<!ENTITY tex "TeX"> <!-- Should become an element. -->
+<!ENTITY latex "LaTeX"> <!-- Should become an element. -->
+<!ENTITY ellipsis "&#x2026;">
+<!ENTITY lt "&#x3c;">
+<!ENTITY gt "&#x3e;">
+<!ENTITY bullet "&#x2022;">
+<!ENTITY copyright "&#xa9;">
+<!ENTITY registered "&#xae;">
+<!ENTITY euro "&#x20ac;">
+<!ENTITY pounds "&#xa3;">
+<!ENTITY minus "&#x2212;">
+<!ENTITY linebreak "&#xa;"> <!-- Should become an element. -->
+<!ENTITY space " "> <!-- Should become an element. -->
+<!ENTITY dots "&#x2026;<neos/>">
+<!ENTITY enddots "&#x2026;">
+<!ENTITY amp "&#x26;">
+<!ENTITY ldquo "&#x201c;">
+<!ENTITY rdquo "&#x201d;">
+<!ENTITY mdash "&#x2014;">
+<!ENTITY ndash "&#x2013;">
+<!ENTITY period ".<neos/>">
+<!ENTITY eosperiod ".">
+<!ENTITY quest "?<neos/>">
+<!ENTITY eosquest "?">
+<!ENTITY excl "!<neos/>">
+<!ENTITY eosexcl "!">
+
+<!ENTITY auml "&#xe4;">
+<!ENTITY ouml "&#xf6;">
+<!ENTITY uuml "&#xfc;">
+<!ENTITY Auml "&#xc4;">
+<!ENTITY Ouml "&#xd6;">
+<!ENTITY Uuml "&#xdc;">
+<!ENTITY Euml "&#xcb;">
+<!ENTITY euml "&#xeb;">
+<!ENTITY Iuml "&#xcf;">
+<!ENTITY iuml "&#xef;">
+<!ENTITY yuml "&#xff;">
+<!ENTITY uml "&#xa8;">
+
+<!ENTITY Aacute "&#xc1;">
+<!ENTITY Eacute "&#xc9;">
+<!ENTITY Iacute "&#xcd;">
+<!ENTITY Oacute "&#xd3;">
+<!ENTITY Uacute "&#xda;">
+<!ENTITY Yacute "&#xdd;">
+<!ENTITY aacute "&#xe1;">
+<!ENTITY eacute "&#xe9;">
+<!ENTITY iacute "&#xed;">
+<!ENTITY oacute "&#xf3;">
+<!ENTITY uacute "&#xfa;">
+<!ENTITY yacute "&#xfd;">
+
+<!ENTITY ccedil "&#xe7;">
+<!ENTITY Ccedil "&#xc7;">
+
+<!ENTITY Acirc "&#xc2;">
+<!ENTITY Ecirc "&#xca;">
+<!ENTITY Icirc "&#xc3;">
+<!ENTITY Ocirc "&#xd4;">
+<!ENTITY Ucirc "&#xdb;">
+<!ENTITY acirc "&#xe2;">
+<!ENTITY ecirc "&#xea;">
+<!ENTITY icirc "&#xee;">
+<!ENTITY ocirc "&#xf4;">
+<!ENTITY ucirc "&#xfb;">
+
+<!ENTITY Agrave "&#xc0;">
+<!ENTITY Egrave "&#xc8;">
+<!ENTITY Igrave "&#xcc;">
+<!ENTITY Ograve "&#xd2;">
+<!ENTITY Ugrave "&#xd9;">
+<!ENTITY agrave "&#xe0;">
+<!ENTITY egrave "&#xe8;">
+<!ENTITY igrave "&#xec;">
+<!ENTITY ograve "&#xf2;">
+<!ENTITY ugrave "&#xf9;">
+
+<!ENTITY Atilde "&#xc3;">
+<!ENTITY Ntilde "&#xd1;">
+<!ENTITY Otilde "&#xd5;">
+<!ENTITY atilde "&#xe3;">
+<!ENTITY ntilde "&#xf1;">
+<!ENTITY otilde "&#xf5;">
+
+<!ENTITY oslash "&#xf8;">
+<!ENTITY Oslash "&#xd8;">
+
+<!ENTITY ordm "&#xba;">
+<!ENTITY ordf "&#xaa;">
+
+<!ENTITY iexcl "&#xa1;">
+<!ENTITY pound "&#xa3;">
+<!ENTITY iquest "&#xbf;">
+<!ENTITY AElig "&#xc6;">
+<!ENTITY aelig "&#xe6;">
+<!ENTITY OElig "&#x152;">
+<!ENTITY oelig "&#x153;">
+<!ENTITY Aring "&#xc5;">
+<!ENTITY aring "&#xe5;">
+<!ENTITY szlig "&#xdf;">
+
+<!ENTITY macr "&#xaf;">
+
+
+<!-- fixxme: not yet classified -->
+
+<!ELEMENT sp (#PCDATA)>
+<!ATTLIST sp
+ lines CDATA #IMPLIED>
+<!ELEMENT printindex (#PCDATA)>
+
diff --git a/Build/source/utils/texinfo/util/texinfo.xsl b/Build/source/utils/texinfo/util/texinfo.xsl
new file mode 100644
index 00000000000..5225517ec7b
--- /dev/null
+++ b/Build/source/utils/texinfo/util/texinfo.xsl
@@ -0,0 +1,242 @@
+<?xml version='1.0'?>
+<!-- $Id: texinfo.xsl,v 1.1 2004/04/11 17:56:47 karl Exp $ -->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version="1.0">
+
+<xsl:output method="html" indent="yes"/>
+
+<!-- root rule -->
+<xsl:template match="/">
+ <html>
+ <head><title>
+ <xsl:apply-templates select="TEXINFO/SETTITLE" mode="head"/>
+ </title></head>
+ <body bgcolor="#FFFFFF"><xsl:apply-templates/>
+</body></html>
+</xsl:template>
+
+
+<xsl:template match="TEXINFO">
+ <xsl:apply-templates/>
+</xsl:template>
+
+
+<xsl:template match="TEXINFO/SETFILENAME">
+</xsl:template>
+
+<xsl:template match="TEXINFO/SETTITLE" mode="head">
+ <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="TEXINFO/SETTITLE">
+ <h1><xsl:apply-templates/></h1>
+</xsl:template>
+
+
+<xsl:template match="TEXINFO/DIRCATEGORY">
+</xsl:template>
+
+<xsl:template match="//PARA">
+ <p><xsl:apply-templates/></p>
+</xsl:template>
+
+<xsl:template match="//EMPH">
+ <i><xsl:apply-templates/></i>
+</xsl:template>
+
+<!-- The node -->
+<xsl:template match="TEXINFO/NODE">
+ <hr/>
+ <p>
+ <xsl:apply-templates select="NODENAME" mode="select"/>
+ <xsl:apply-templates select="NODEPREV" mode="select"/>
+ <xsl:apply-templates select="NODEUP" mode="select"/>
+ <xsl:apply-templates select="NODENEXT" mode="select"/>
+ <xsl:apply-templates/>
+ <h2>Footnotes</h2>
+ <ol>
+ <xsl:apply-templates select=".//FOOTNOTE" mode="footnote"/>
+ </ol>
+ </p>
+</xsl:template>
+
+<xsl:template match="TEXINFO/NODE/NODENAME" mode="select">
+<h2>
+ <a>
+ <xsl:attribute name="name">
+ <xsl:apply-templates/>
+ </xsl:attribute>
+ <xsl:apply-templates/>
+ </a>
+</h2>
+</xsl:template>
+
+<xsl:template match="TEXINFO/NODE/NODENAME"/>
+
+
+<xsl:template match="TEXINFO/NODE/NODEPREV" mode="select">
+ [ <b>Previous: </b>
+ <a>
+ <xsl:attribute name="href">
+ <xsl:text>#</xsl:text>
+ <xsl:apply-templates/>
+ </xsl:attribute>
+ <xsl:apply-templates/>
+ </a> ]
+</xsl:template>
+
+<xsl:template match="TEXINFO/NODE/NODEPREV"/>
+
+<xsl:template match="TEXINFO/NODE/NODEUP" mode="select">
+ [ <b>Up: </b>
+ <a>
+ <xsl:attribute name="href">
+ <xsl:text>#</xsl:text>
+ <xsl:apply-templates/>
+ </xsl:attribute>
+ <xsl:apply-templates/>
+ </a> ]
+</xsl:template>
+
+<xsl:template match="TEXINFO/NODE/NODEUP"/>
+
+<xsl:template match="TEXINFO/NODE/NODENEXT" mode="select">
+ [ <b>Next: </b>
+ <a>
+ <xsl:attribute name="href">
+ <xsl:text>#</xsl:text>
+ <xsl:apply-templates/>
+ </xsl:attribute>
+ <xsl:apply-templates/>
+ </a> ]
+</xsl:template>
+
+<xsl:template match="TEXINFO/NODE/NODENEXT"/>
+
+<!-- Menu -->
+<xsl:template match="//MENU">
+ <h3>Menu</h3>
+ <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="//MENU/MENUENTRY">
+ <a>
+ <xsl:attribute name="href">
+ <xsl:text>#</xsl:text>
+ <xsl:apply-templates select="MENUNODE"/>
+ </xsl:attribute>
+ <xsl:apply-templates select="MENUTITLE"/>
+ </a>:
+ <xsl:apply-templates select="MENUCOMMENT"/>
+ <br/>
+</xsl:template>
+
+<xsl:template match="//MENU/MENUENTRY/MENUNODE">
+ <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="//MENU/MENUENTRY/MENUTITLE">
+ <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="//MENU/MENUENTRY/MENUCOMMENT">
+ <xsl:apply-templates mode="menucomment"/>
+</xsl:template>
+
+<xsl:template match="PARA" mode="menucomment">
+ <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="//PARA">
+ <p><xsl:apply-templates/></p>
+</xsl:template>
+
+<!-- LISTS -->
+<xsl:template match="//ITEMIZE">
+ <ul>
+ <xsl:apply-templates/>
+ </ul>
+</xsl:template>
+
+<xsl:template match="//ITEMIZE/ITEM">
+ <li>
+ <xsl:apply-templates/>
+ </li>
+</xsl:template>
+
+<xsl:template match="//ENUMERATE">
+ <ol>
+ <xsl:apply-templates/>
+ </ol>
+</xsl:template>
+
+<xsl:template match="//ENUMERATE/ITEM">
+ <li>
+ <xsl:apply-templates/>
+ </li>
+</xsl:template>
+
+<!-- INLINE -->
+<xsl:template match="//CODE">
+ <tt>
+ <xsl:apply-templates/>
+ </tt>
+</xsl:template>
+
+<xsl:template match="//DFN">
+ <i><b>
+ <xsl:apply-templates/>
+ </b></i>
+</xsl:template>
+
+<xsl:template match="//STRONG">
+ <b>
+ <xsl:apply-templates/>
+ </b>
+</xsl:template>
+
+<xsl:template match="//CENTER">
+ <center>
+ <xsl:apply-templates/>
+ </center>
+</xsl:template>
+
+<xsl:template match="//VAR">
+ <i>
+ <xsl:apply-templates/>
+ </i>
+</xsl:template>
+
+<xsl:template match="//KBD">
+ <tt>
+ <xsl:apply-templates/>
+ </tt>
+</xsl:template>
+
+<xsl:template match="//KEY">
+ <b>
+ <xsl:apply-templates/>
+ </b>
+</xsl:template>
+
+<!-- BLOCKS -->
+<xsl:template match="//DISPLAY">
+ <pre>
+ <xsl:apply-templates/>
+ </pre>
+</xsl:template>
+
+
+<!-- INDEX -->
+<xsl:template match="//INDEXTERM">
+</xsl:template>
+
+<!-- FOOTNOTE -->
+<xsl:template match="//FOOTNOTE">
+</xsl:template>
+
+<xsl:template match="//FOOTNOTE" mode="footnote">
+ <li><xsl:apply-templates/></li>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/Build/source/utils/texinfo/util/txitextest b/Build/source/utils/texinfo/util/txitextest
new file mode 100755
index 00000000000..4542bc23641
--- /dev/null
+++ b/Build/source/utils/texinfo/util/txitextest
@@ -0,0 +1,77 @@
+#!/bin/sh
+# $Id: txitextest,v 1.5 2004/04/11 17:56:47 karl Exp $
+# Test texinfo.tex changes by running various manuals through with an
+# old version, saving the .ps result from dvips, doing the same with a
+# new version, and comparing. Idea from Stepan Kasal.
+#
+# Another option is to run the manuals all the way through using
+# texi2dvi, which tests in another way.
+
+tsrc=/u/texinfo/src
+PATH=$tsrc/util:$PATH
+
+tdoc=$tsrc/doc
+default_manuals="$tdoc/texinfo.txi $tdoc/info.texi $tdoc/info-stnd.texi"
+
+olddir=$HOME/gnu/src/gnulib/config
+newdir=$tdoc
+tempdir=/u/texinfo/@tests/testdir
+full=false
+manuals=
+
+while test $# -gt 0; do
+ case $1 in
+ --f*) full=true;;
+ --o*) shift; olddir="$1";;
+ --n*) shift; newdir="$1";;
+ --t*) shift; tempdir="$1";;
+ -*) echo "$0: unknown option \`$1'." >&2; exit 1;;
+ *) manuals="$manuals $1";;
+ esac
+ shift
+done
+
+test -z "$manuals" && manuals=$default_manuals
+initial_dir=`pwd`
+
+cd $tempdir || exit 1
+rm -f *
+
+run_tex() \
+{
+ TEXINPUTS=.:$mandir: tex $manual \
+ || { echo "tex $manual failed." >&2; exit 1; }
+}
+
+for manual in $manuals; do
+ mandir=`dirname $manual`
+ test $mandir = . && mandir=$initial_dir
+ manual_base=`basename "$manual" | sed 's/\.[^.]*$//'`
+
+ rm -f $manual_base.* texinfo.tex
+ ln -s $newdir/texinfo.tex texinfo.tex
+
+ if $full; then
+ # instead of comparing, do full test of just the new texinfo.tex.
+ echo "$0: testing $manual_base... (tex)"
+ texi2dvi $manual || { echo "texi2dvi $manual failed." >&2; exit 1; }
+ echo "$0: testing $manual_base... (pdf)"
+ texi2dvi --pdf $manual \
+ || { echo "texi2dvi --pdf $manual failed." >&2; exit 1; }
+
+ else
+ echo "$0: testing $manual_base... (new)"
+ run_tex
+ dvips $manual_base -o || exit 1
+ mv $manual_base.ps new.$manual_base.ps
+
+ echo "$0: testing $manual_base... (old)"
+ rm -f $manual_base.* texinfo.tex
+ ln -s $olddir/texinfo.tex texinfo.tex
+ run_tex
+ dvips $manual_base -o || exit 1
+ mv $manual_base.ps old.$manual_base.ps
+
+ diff -U0 old.$manual_base.ps new.$manual_base.ps
+ fi
+done
diff --git a/Build/source/utils/texinfo/util/win32.mak b/Build/source/utils/texinfo/util/win32.mak
new file mode 100644
index 00000000000..ce49b96764d
--- /dev/null
+++ b/Build/source/utils/texinfo/util/win32.mak
@@ -0,0 +1,60 @@
+################################################################################
+#
+# Makefile : TeXInfo / Utils
+# Author : Fabrice Popineau <Fabrice.Popineau@supelec.fr>
+# Platform : Win32, Microsoft VC++ 6.0, depends upon fpTeX 0.5 sources
+# Time-stamp: <02/02/01 11:16:42 popineau>
+#
+################################################################################
+root_srcdir = ..\..\..
+!ifdef DEVELOPMENT
+INCLUDE=$(INCLUDE);$(root_srcdir)\texk.development
+!else
+INCLUDE=$(INCLUDE);$(root_srcdir)\texk
+!endif
+
+# Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+USE_ZLIB=1
+USE_GNUW32=1
+
+!include <msvc/common.mak>
+
+DEFS = -I.. -DHAVE_CONFIG_H -DKPATHSEA=1 $(DEFS) -I../lib
+
+libtxi = ..\lib\$(objdir)\libtxi.lib
+
+install_info_objects=$(objdir)\install-info.obj
+texindex_objects = $(objdir)\texindex.obj
+
+programs = $(objdir)\install-info.exe $(objdir)\texindex.exe
+
+default all: $(objdir) $(programs)
+
+$(objdir)\install-info.exe: $(install_info_objects) $(libtxi) $(gnuw32lib)
+ $(link) $(**) $(conlibs)
+
+$(objdir)\texindex.exe: $(texindex_objects) $(libtxi) $(gnuw32lib)
+ $(link) $(**) $(setargvobj) $(conlibs)
+
+$(libtxi): ../lib/*.c ../lib/*.h
+ pushd ..\lib & $(make) all & popd
+
+..\config.h: ..\config.in
+ pushd .. & $(make) configure & popd
+
+!include <msvc/config.mak>
+!include <msvc/install.mak>
+
+install:: install-exec
+
+!include <msvc/clean.mak>
+!include <msvc/rdepend.mak>
+!include "./depend.mak"
+
+#
+# Local Variables:
+# mode: makefile
+# End: \ No newline at end of file