From a3d3111bfe26b8e5f5bc6049dfb2a4ca2edc7881 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Tue, 17 Jan 2006 21:16:42 +0000 Subject: utils 1 git-svn-id: svn://tug.org/texlive/trunk@1484 c570f23f-e606-0410-a88d-b1316a301751 --- Build/source/utils/texinfo/util/Makefile.am | 45 + Build/source/utils/texinfo/util/Makefile.in | 579 +++++++ Build/source/utils/texinfo/util/README | 14 + Build/source/utils/texinfo/util/depend.mak | 17 + Build/source/utils/texinfo/util/deref.c | 209 +++ Build/source/utils/texinfo/util/dir-example | 482 ++++++ Build/source/utils/texinfo/util/fix-info-dir | 317 ++++ Build/source/utils/texinfo/util/fixfonts | 84 + Build/source/utils/texinfo/util/fixref.gawk | 145 ++ Build/source/utils/texinfo/util/gdoc | 914 +++++++++++ Build/source/utils/texinfo/util/gen-dir-node | 212 +++ Build/source/utils/texinfo/util/gendocs.sh | 285 ++++ Build/source/utils/texinfo/util/gendocs_template | 100 ++ Build/source/utils/texinfo/util/infosrch | 104 ++ Build/source/utils/texinfo/util/install-info-html | 157 ++ Build/source/utils/texinfo/util/install-info.c | 1590 +++++++++++++++++++ Build/source/utils/texinfo/util/outline.gawk | 145 ++ Build/source/utils/texinfo/util/prepinfo.awk | 356 +++++ Build/source/utils/texinfo/util/tex3patch | 70 + .../utils/texinfo/util/texi-docstring-magic.el | 347 +++++ Build/source/utils/texinfo/util/texi2dvi | 836 ++++++++++ Build/source/utils/texinfo/util/texi2pdf | 19 + Build/source/utils/texinfo/util/texindex.c | 1628 ++++++++++++++++++++ Build/source/utils/texinfo/util/texindex.rc | 36 + Build/source/utils/texinfo/util/texinfo-cat.in | 3 + Build/source/utils/texinfo/util/texinfo.dtd | 484 ++++++ Build/source/utils/texinfo/util/texinfo.xsl | 242 +++ Build/source/utils/texinfo/util/txitextest | 77 + Build/source/utils/texinfo/util/win32.mak | 60 + 29 files changed, 9557 insertions(+) create mode 100644 Build/source/utils/texinfo/util/Makefile.am create mode 100644 Build/source/utils/texinfo/util/Makefile.in create mode 100644 Build/source/utils/texinfo/util/README create mode 100644 Build/source/utils/texinfo/util/depend.mak create mode 100644 Build/source/utils/texinfo/util/deref.c create mode 100644 Build/source/utils/texinfo/util/dir-example create mode 100755 Build/source/utils/texinfo/util/fix-info-dir create mode 100755 Build/source/utils/texinfo/util/fixfonts create mode 100644 Build/source/utils/texinfo/util/fixref.gawk create mode 100644 Build/source/utils/texinfo/util/gdoc create mode 100755 Build/source/utils/texinfo/util/gen-dir-node create mode 100755 Build/source/utils/texinfo/util/gendocs.sh create mode 100755 Build/source/utils/texinfo/util/gendocs_template create mode 100755 Build/source/utils/texinfo/util/infosrch create mode 100644 Build/source/utils/texinfo/util/install-info-html create mode 100644 Build/source/utils/texinfo/util/install-info.c create mode 100644 Build/source/utils/texinfo/util/outline.gawk create mode 100644 Build/source/utils/texinfo/util/prepinfo.awk create mode 100755 Build/source/utils/texinfo/util/tex3patch create mode 100644 Build/source/utils/texinfo/util/texi-docstring-magic.el create mode 100755 Build/source/utils/texinfo/util/texi2dvi create mode 100755 Build/source/utils/texinfo/util/texi2pdf create mode 100644 Build/source/utils/texinfo/util/texindex.c create mode 100644 Build/source/utils/texinfo/util/texindex.rc create mode 100644 Build/source/utils/texinfo/util/texinfo-cat.in create mode 100644 Build/source/utils/texinfo/util/texinfo.dtd create mode 100644 Build/source/utils/texinfo/util/texinfo.xsl create mode 100755 Build/source/utils/texinfo/util/txitextest create mode 100644 Build/source/utils/texinfo/util/win32.mak (limited to 'Build/source/utils/texinfo/util') 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 +#include +#include + +/* 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<&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<" 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 based on the function +# prefix. For example, a function gss_init_sec_context will generate +# an include statement of #include . +# +# -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, "\$1", + $type_func, "\$1", + $type_struct, "\$1", + $type_param, "\$1" ); +$blankline_html = "

"; + +%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, "\$1", + $type_func, "\$1", + $type_struct, "\$1", + $type_env, "\$1", + $type_param, "\$1" ); +$blankline_sgml = "\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 

Function

+\n"; + + print "".$args{'functiontype'}."\n"; + print "".$args{'function'}."\n"; + print "("; + $count = 0; + foreach $parameter (@{$args{'parameterlist'}}) { + print "".$args{'parametertypes'}{$parameter}." ".$parameter. +"\n"; + if ($count != $#{$args{'parameterlist'}}) { + $count++; + print ", "; + } + } + print ")\n"; + + print "

Arguments

\n"; + print "
\n"; + foreach $parameter (@{$args{'parameterlist'}}) { + print "
".$args{'parametertypes'}{$parameter}." ".$parame +ter."\n"; + print "
"; + output_highlight($args{'parameters'}{$parameter}); + } + print "
\n"; + foreach $section (@{$args{'sectionlist'}}) { + print "

$section

\n"; + print "
    \n"; + output_highlight($args{'sections'}{$section}); + print "
\n"; + } + print "
\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 "\n"; + print "\n"; + print "".$args{'function'}."\n"; + print "\n"; + print "\n"; + print " ".$args{'function'}."\n"; + print " \n"; + print " ".$args{'purpose'}."\n"; + print " \n"; + print "\n"; + + print "\n"; + print " Synopsis\n"; + print " \n"; + print " ".$args{'functiontype'}." "; + print "".$args{'function'}." "; + print "\n"; + +# print "\n"; +# print " Synopsis\n"; +# print " \n"; +# print " ".$args{'functiontype'}." "; +# print "".$args{'function'}." "; +# print "\n"; + + $count = 0; + if ($#{$args{'parameterlist'}} >= 0) { + foreach $parameter (@{$args{'parameterlist'}}) { + print " ".$args{'parametertypes'}{$parameter}; + print " $parameter\n"; + } + } else { + print " \n"; + } + print " \n"; + print "\n"; +# print "\n"; + + # print parameters + print "\n Arguments\n"; +# print "\nArguments\n"; + if ($#{$args{'parameterlist'}} >= 0) { + print " \n"; + foreach $parameter (@{$args{'parameterlist'}}) { + print " \n $parameter\n"; + print " \n \n"; + $lineprefix=" "; + output_highlight($args{'parameters'}{$parameter}); + print " \n \n \n"; + } + print " \n"; + } else { + print " \n None\n \n"; + } + print "\n"; + + # print out each section + $lineprefix=" "; + foreach $section (@{$args{'sectionlist'}}) { + print "\n $section\n \n"; +# print "\n$section\n"; + if ($section =~ m/EXAMPLE/i) { + print "\n"; + } + output_highlight($args{'sections'}{$section}); +# print ""; + if ($section =~ m/EXAMPLE/i) { + print "\n"; + } + print " \n\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 () { + $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 , who thinks it came from +# zoo@winternet.com (david d `zoo' zuhn) + +# modified 7 April 1995 by Joe Harrington 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" 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 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%%

+ +
Free Software Foundation
+
last updated %%DATE%%
+

+ +  [image of the head of a GNU] + +(no gifs due to patent problems) +

+
+ +

This manual (%%PACKAGE%%) is available in the following formats:

+ + + +

(This page generated by the %%SCRIPTNAME%% +script.)

+ + + + + 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 . + +($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(){ + 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 </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 < +Info documentation index + +

Info documentation index

+This is the directory file \`index.html' a.k.a. \`DIR', which contains the +topmost node of the HTML Info hierarchy. +

+This is all very much Work in Progress (WiP). +

+

    +EOF + +#list +for i in $document_dirs; do + echo "
  • $i
  • " +done >> $index_file + +# foot +cat >> $index_file < + + +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 + +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\" 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 +;; Copyright (C) 1998 David Aspinall +;; Maintainer: David Aspinall +;; +;; $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 , +general questions and discussion to . +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 <$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 <$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 &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 $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 &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 o + # -- don't match whitespace as . + # 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 + +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 + + 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 + +#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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +"> + + + + + + +"> + +"> + +"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + <xsl:apply-templates select="TEXINFO/SETTITLE" mode="head"/> + + + + + + + + + + + + + + + + + + + +

    +
    + + + + + + +

    +
    + + + + + + + +
    +

    + + + + + +

    Footnotes

    +
      + +
    +

    +
    + + +

    + + + + + + +

    +
    + + + + + + [ Previous: + + + # + + + + ] + + + + + + [ Up: + + + # + + + + ] + + + + + + [ Next: + + + # + + + + ] + + + + + + +

    Menu

    + +
    + + + + + # + + + + : + +
    +
    + + + + + + + + + + + + + + + + + + +

    +
    + + + +
      + +
    +
    + + +
  • + +
  • +
    + + +
      + +
    +
    + + +
  • + +
  • +
    + + + + + + + + + + + + + + + + + + + + + +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + +
    +  
    + 
    +
    + + + + + + + + + + + +
  • +
    + +
    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 +# 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 + +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 +!include + +install:: install-exec + +!include +!include +!include "./depend.mak" + +# +# Local Variables: +# mode: makefile +# End: \ No newline at end of file -- cgit v1.2.3