texinfo-3.12/0000775000175000017500000000000013751602721010357 5ustar ggtexinfo-3.12/Makefile.in0000664000175000017500000002432713751602100012423 0ustar gg# Makefile.in generated automatically by automake 1.2f from Makefile.am # Copyright (C) 1994, 1995, 1996, 1997, 1998 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. # Be sure we're using the right version of Automake. # 1.2f was the first version that supported .txi as a Texinfo suffix. SHELL = /bin/sh srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ bindir = @bindir@ sbindir = @sbindir@ libexecdir = @libexecdir@ datadir = @datadir@ sysconfdir = @sysconfdir@ sharedstatedir = @sharedstatedir@ localstatedir = @localstatedir@ libdir = @libdir@ infodir = @infodir@ mandir = @mandir@ includedir = @includedir@ oldincludedir = /usr/include pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = . ACLOCAL = @ACLOCAL@ AUTOCONF = @AUTOCONF@ AUTOMAKE = @AUTOMAKE@ AUTOHEADER = @AUTOHEADER@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ transform = @program_transform_name@ NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : CATALOGS = @CATALOGS@ CATOBJEXT = @CATOBJEXT@ CC = @CC@ DATADIRNAME = @DATADIRNAME@ GENCAT = @GENCAT@ GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ GT_NO = @GT_NO@ GT_YES = @GT_YES@ INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@ INSTOBJEXT = @INSTOBJEXT@ INTLDEPS = @INTLDEPS@ INTLLIBS = @INTLLIBS@ INTLOBJS = @INTLOBJS@ MAKEINFO = @MAKEINFO@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ PACKAGE = @PACKAGE@ POFILES = @POFILES@ POSUB = @POSUB@ RANLIB = @RANLIB@ TERMLIBS = @TERMLIBS@ TEXCONFIG = @TEXCONFIG@ TEXMF = @TEXMF@ USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ l = @l@ AUTOMAKE_OPTIONS = 1.2f # Additional files to distribute. EXTRA_DIST = INTRODUCTION dir-example # All subdirectories. # Do intl/ and lib/ first since the C programs depend on them. # Do doc/ last so makeinfo will be built when we get there. # Others are alphabetical. SUBDIRS = intl lib info makeinfo po util doc ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = DIST_COMMON = README ABOUT-NLS AUTHORS COPYING ChangeLog INSTALL \ Makefile.am Makefile.in NEWS TODO acconfig.h aclocal.m4 config.guess \ config.h.in config.sub configure configure.in install-sh missing \ mkinstalldirs stamp-h.in texinfo.tex DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) TAR = tar GZIP = --best default: all .SUFFIXES: $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) \ && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status $(ACLOCAL_M4): configure.in cd $(srcdir) && $(ACLOCAL) config.status: $(srcdir)/configure $(SHELL) ./config.status --recheck $(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) cd $(srcdir) && $(AUTOCONF) config.h: stamp-h @: stamp-h: $(srcdir)/config.h.in $(top_builddir)/config.status cd $(top_builddir) \ && CONFIG_FILES= CONFIG_HEADERS=config.h \ $(SHELL) ./config.status @echo timestamp > stamp-h $(srcdir)/config.h.in: $(srcdir)/stamp-h.in $(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) acconfig.h cd $(top_srcdir) && $(AUTOHEADER) @echo timestamp > $(srcdir)/stamp-h.in mostlyclean-hdr: clean-hdr: distclean-hdr: -rm -f config.h maintainer-clean-hdr: # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. @SET_MAKE@ all-recursive install-data-recursive install-exec-recursive \ installdirs-recursive install-recursive uninstall-recursive \ check-recursive installcheck-recursive info-recursive dvi-recursive: @set fnord $(MAKEFLAGS); amf=$$2; \ list='$(SUBDIRS)'; for subdir in $$list; do \ target=`echo $@ | sed s/-recursive//`; \ echo "Making $$target in $$subdir"; \ (cd $$subdir && $(MAKE) $$target) \ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ done && test -z "$$fail" mostlyclean-recursive clean-recursive distclean-recursive \ maintainer-clean-recursive: @set fnord $(MAKEFLAGS); amf=$$2; \ rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \ rev="$$subdir $$rev"; \ done; \ for subdir in $$rev; do \ target=`echo $@ | sed s/-recursive//`; \ echo "Making $$target in $$subdir"; \ (cd $$subdir && $(MAKE) $$target) \ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ (cd $$subdir && $(MAKE) tags); \ done tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) here=`pwd` && cd $(srcdir) \ && mkid -f$$here/ID $(SOURCES) $(HEADERS) $(LISP) TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) $(LISP) tags=; \ here=`pwd`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ done; \ list='$(SOURCES) $(HEADERS)'; \ unique=`for i in $$list; do echo $$i; done | \ awk ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(ETAGS_ARGS)config.h.in$$unique$(LISP)$$tags" \ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags config.h.in $$unique $(LISP) -o $$here/TAGS) mostlyclean-tags: clean-tags: distclean-tags: -rm -f TAGS ID maintainer-clean-tags: distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist -rm -rf $(distdir) GZIP=$(GZIP) $(TAR) zxf $(distdir).tar.gz mkdir $(distdir)/=build mkdir $(distdir)/=inst dc_install_base=`cd $(distdir)/=inst && pwd`; \ cd $(distdir)/=build \ && ../configure --with-included-gettext --srcdir=.. --prefix=$$dc_install_base \ && $(MAKE) \ && $(MAKE) dvi \ && $(MAKE) check \ && $(MAKE) install \ && $(MAKE) installcheck \ && $(MAKE) dist -rm -rf $(distdir) @echo "========================"; \ echo "$(distdir).tar.gz is ready for distribution"; \ echo "========================" dist: distdir -chmod -R a+r $(distdir) GZIP=$(GZIP) $(TAR) chozf $(distdir).tar.gz $(distdir) -rm -rf $(distdir) dist-all: distdir -chmod -R a+r $(distdir) GZIP=$(GZIP) $(TAR) chozf $(distdir).tar.gz $(distdir) -rm -rf $(distdir) distdir: $(DISTFILES) -rm -rf $(distdir) mkdir $(distdir) -chmod 755 $(distdir) @for file in $(DISTFILES); do \ d=$(srcdir); \ test -f $(distdir)/$$file \ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ || cp -p $$d/$$file $(distdir)/$$file; \ done for subdir in $(SUBDIRS); do \ test -d $(distdir)/$$subdir \ || mkdir $(distdir)/$$subdir \ || exit 1; \ chmod 755 $(distdir)/$$subdir; \ (cd $$subdir && $(MAKE) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \ || exit 1; \ done info: info-recursive dvi: dvi-recursive check: all-am $(MAKE) check-recursive installcheck: installcheck-recursive all-recursive-am: config.h $(MAKE) all-recursive all-am: Makefile config.h install-exec: install-exec-recursive @$(NORMAL_INSTALL) install-data: install-data-recursive @$(NORMAL_INSTALL) install: install-recursive @: uninstall: uninstall-recursive all: all-recursive-am all-am install-strip: $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install installdirs: installdirs-recursive mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -rm -f Makefile $(DISTCLEANFILES) -rm -f config.cache config.log stamp-h stamp-h[0-9]* -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) mostlyclean-am: mostlyclean-hdr mostlyclean-tags mostlyclean-generic clean-am: clean-hdr clean-tags clean-generic mostlyclean-am distclean-am: distclean-hdr distclean-tags distclean-generic clean-am maintainer-clean-am: maintainer-clean-hdr maintainer-clean-tags \ maintainer-clean-generic distclean-am mostlyclean: mostlyclean-recursive mostlyclean-am clean: clean-recursive clean-am distclean: distclean-recursive distclean-am -rm -f config.status maintainer-clean: maintainer-clean-recursive maintainer-clean-am @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." -rm -f config.status .PHONY: default mostlyclean-hdr distclean-hdr clean-hdr \ maintainer-clean-hdr install-data-recursive uninstall-data-recursive \ install-exec-recursive uninstall-exec-recursive installdirs-recursive \ uninstalldirs-recursive all-recursive check-recursive \ installcheck-recursive info-recursive dvi-recursive \ mostlyclean-recursive distclean-recursive clean-recursive \ maintainer-clean-recursive tags tags-recursive mostlyclean-tags \ distclean-tags clean-tags maintainer-clean-tags distdir info dvi \ installcheck all-recursive-am all-am install-exec install-data install \ uninstall all installdirs mostlyclean-generic distclean-generic \ clean-generic maintainer-clean-generic clean mostlyclean distclean \ maintainer-clean # 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: texinfo-3.12/ChangeLog0000664000175000017500000037153506477056647012170 0ustar ggTue Mar 3 13:29:17 1998 Karl Berry * configure.in: Version 3.12. * po/de.po: New version. * po/POTFILES.in: Do not include doc.c; that gets built at runtime, thus causing texinfo.pot to try to get rebuilt. Besides, it doesn't have any translatable strings. Sun Mar 1 10:38:47 1998 Karl Berry * util/install-info.c: No need for i18n on version message. From ke@suse.de. Fri Feb 27 16:06:23 1998 Karl Berry * configure.in: Run texconfig conf instead of confall. * doc/Makefile.am (INSTALL_INFO): New variable. (install-info-am): Use install-info from our distribution. * info/info.c (info_minor_version): Increment. * (info_patch_level), * info/info.h (info_patch_level): Remove. * info/info.c (program_name): Move decl. * util/install-info.c (ensure_dirfile_exists): Use commas and \t instead of an explicit tab, which make dist expands. * doc/texinfo.txi: @prep.ai.mit.edu -> @gnu.org. * info/info.c: Make help messages consistent with others. * util/install-info.c (print_help): Format consistently. (readfile): Support gzipped files via libz. From: Elliot Lee Date: Mon, 1 Sep 1997 23:37:14 -0400 (EDT) Thu Feb 26 16:13:14 1998 Karl Berry * info/echo-area.c: Whoops, _ might not start with parens. * configure.in: Check for libz. Do not output emacs/Makefile. * Makefile.am (AUTOMAKE_OPTIONS): Set to 1.2f. * util/texi2dvi: Always remove temporary directories. (From Akim.) Formatting changes. Wed Feb 25 15:26:26 1998 Karl Berry * util/texi2dvi: New options --batch, --clean. From: Akim Demaille Date: 15 Aug 1997 18:05:33 +0200 * doc/texinfo.txi (Format with texi2dvi): Mention --help. Applied this: 1997-08-09 Andreas Schwab * makeinfo/makeinfo.c (me_executing_string): New variable. (me_execute_string): Use it instead of executing_string. (popfile): Check for me_executing_string as well as executing_string. (get_until_in_line): Likewise. (insert_and_underscore): Do not write any expansion output if executing a string. (cm_node, cm_include, index_add_arg, cm_footnote, execute_macro, cm_macro, cm_unmacro): Likewise. (cm_footnote): Include the footnote marker in the expansion output. (append_to_expansion_output): Do nothing if the input_text wasn't a remembered text. (defun_internal): Make the index entry even if expanding macros. (expansion): Don't reset macro_expansion_output_stream around call to execute_string. (apply): Fix typo. Tue Feb 24 17:33:44 1998 Karl Berry 1997-11-10 Andreas Schwab * makeinfo/makeinfo.c (get_until_in_line): Don't use xstrdup on the unterminated input_text. * makeinfo/makeinfo.c: Don't assume all \'s in macro bodies are arguments. From: Mathias.Herberts@irisa.fr (Mathias Herberts) Date: Tue, 6 Jan 1998 18:54:26 +0100 * configure.in: Check for sigblock in libc before libbsd. * From: hjl@lucon.org (H.J. Lu) * Date: Fri, 23 Jan 1998 21:50:25 -0800 (PST) Mon Feb 23 16:26:31 1998 Karl Berry * info/window.c (character_width): If ISO_Latin_p is set, make printable_limit 255, not 160. ISO Latin 1 uses essentially all of the 256 characters. Reported by: Marius Groeger Date: Wed, 17 Dec 1997 16:05:27 +0100 * info/info.c: Improve help message. Sun Feb 22 17:38:32 1998 Karl Berry * Makefile.am (SUBDIRS): Remove emacs; we'll just distribute the Elisp files with Emacs. * doc/Makefile.am (info_TEXINFOS, texinfo): Rename manual to texinfo.txi to avoid DOS filename clash with texinfo.tex. * info/tilde.c: Copy slightly updated alloca stuff from makeinfo. * util/texindex.c (main): Declare as returning int to placate warnings. * info/Makefile.am: Uncomment BUILT_SOURCES stuff and add missing _. From: "Joel N. Weber II" Date: Fri, 30 Jan 1998 17:21:38 -1000 * util/texindex.c, * util/install-info.c, * makeinfo/makeinfo.c, * info/info.c: Change help address to @gnu.org. 1998-01-22 Andreas Schwab * makeinfo/makeinfo.c (usage): Fix order of arguments to help format string. * makeinfo/makeinfo.c (cm_top): Error message wording. * doc/texinfo.texi (Functions in Typed Languages): Remove duplicate description of @deftypemethod. From: KHMarbaise@p69.ks.fido.de (Karl Heinz Marbaise) Date: Wed, 07 Jan 1998 11:11:50 +0100 * info/session.c (info_get_input_char) [EINTR]: Keep reading if we get EINTR. From: Andreas Schwab Date: 22 Dec 1997 10:32:53 +0100 Sat Feb 21 17:41:26 1998 Karl Berry * makeinfo/makeinfo.c (find_and_load): Malloc enough room for the null as well as the newline. From: "John W. Eaton" Date: Tue, 30 Sep 1997 21:12:01 -0500 * util/texindex.c (--version), * makeinfo/makeinfo.c (cm_today), * makeinfo/makeinfo.c (print_version_info): Version strings etc. do not need translation. From: Karl Eichwalder Date: 13 Sep 1997 16:20:02 +0200 * info/echo-area.c: Rewrite pluralization to be translatable. From: Karl Eichwalder Date: 13 Sep 1997 16:20:02 +0200 * util/texindex.c, * info/info.c, * makeinfo/makeinfo.c, * util/install-info.c: --version: Give year as argument to printf, to reduce the number of translations needed. From: Ulrich Drepper Date: 02 Sep 1997 18:01:26 +0200 * util/texindex.c: Remove the fnctl.h and sys/file.h conditional #includes, they are already in lib/system.h. From: "Philippe De Muyter" Date: Thu, 21 Aug 1997 20:16:49 +0200 (MET DST) * info/terminal.c (terminal_begin_using_terminal, terminal_end_using_terminal): #ifdef SIGWINCH settings for m68k-motorola-sysv. From: "Philippe De Muyter" Date: Thu, 21 Aug 1997 20:16:49 +0200 (MET DST) * info/filesys.c (info_suffixes): Add /index as a possibility for subdirectories. From: Matthew Wilcox Date: Wed, 6 Aug 1997 15:55:16 +0100 (BST) * configure.in: Redirect texconfig input from /dev/null to avoid stoppage. From: Thomas Esser Date: Mon, 4 Aug 1997 18:15:49 +0200 * makeinfo/makeinfo.c (find_and_load): Null-terminate the input text. From: Kenneth Stailey . * info/Makefile.am (INCLUDES): Add -I.. -I$(srcdir). Fri Aug 22 16:24:59 1997 Karl Berry * doc/texinfo.texi: Adjust ISBN, edition number for print run. Mon Aug 4 16:12:42 1997 Karl Berry * info/info.c (main) [INFODIR]: Add this to infopath, if set. * info/Makefile.am (DEFS): New define, include -DINFODIR. From: Larry Schwimmer . * util/install-info.c (ensure_dirfile_exists): Use tabs instead of spaces on the File: dir line. Bug from: Dave Love . Sat Aug 2 12:43:57 1997 Karl Berry * makeinfo/makeinfo.c (cm_value, cm_email, cm_uref): Have to cast from unsigned char * to char * or IRIX cc complains. From: "Kaveh R. Ghazi" . Fri Aug 1 14:05:10 1997 Karl Berry * Makefile.am (EXTRA_DIST): Remove README-alpha. From: "ir. Mark M._Kettenis" . 1997-07-31 Andreas Schwab * configure.in: Use AC_CHECK_HEADERS, not AC_CHECK_HEADER. Thu Jul 31 11:57:46 1997 Karl Berry * Version 3.11. * info/man.c (reap_children): Declare status as int, not unsigned, since that's what POSIX says the arg to wait should be. * makeinfo/makeinfo.c (cm_uref, cm_email): Rewrite to do macro expansion in the arguments. * makeinfo/makeinfo.c (main): setlocale LC_MESSAGES and LC_TIME, instead of LC_ALL. From: Akim Demaille . * makeinfo/makeinfo.c (cm_today): Let the %d %s %d be translated, so other languages can change the order of day/month/year. From: Akim Demaille . * info/infomap.c: Doc fix. * lib/system.h [!O_RDONLY]: Prefer to . * configure.in (AC_CHECK_HEADERS): Check for fcntl.h. * doc/Makefile.am (install-data-local): Suggest tex/generic/dvips for epsf.tex. From: Tim Mooney . * configure.in (TEXMF): Move check to block with other program checks. Wed Jul 30 11:20:37 1997 Karl Berry * makeinfo/makeinfo.c (defun_internal): Allow extra text after most @def... commands, for tzname[2] in libc.texinfo. * info/info.c: Include indices.h. * configure.in (AC_CHECK_HEADERS): Test for sys/wait.h, info/man.c uses it. From: Erick Branderhorst . Tue Jul 29 15:55:19 1997 Karl Berry * configure.in: Version 3.9j. * info/terminal.c (output_character_function): Return int (the arg), not void. * info/infomap.c: Don't define term_kP as 'v', since that's undefined. From: Tom Hageman . * makeinfo/makeinfo.c: Parameterize some messages to avoid duplicate translations. * info/terminal.c: Only try to declare ospeed, PC, tputs, etc. if we don't have or . * makeinfo/makeinfo.c (cm_email): New function, like cm_uref. Sun Jul 27 17:09:20 1997 Karl Berry * configure.in: Only check for if we're using -lncurses. From: Bo Johansson . * info/dir.c (new_dir_file_p): Avoid automatic struct initialization, SunOS 4 etc. cc can't handle it. From: "Kaveh R. Ghazi" . Sat Jul 26 15:08:13 1997 Karl Berry * Version 3.9i. * configure.in: Check for termcap.h and ncurses/termcap.h. From: bo.johansson@mbox2.swipnet.se. Fri Jul 25 14:09:05 1997 Karl Berry * doc/texinfo.texi: Document new second optional arg to email. * info/infodoc.c: Document CTRL-x 0 as the way to get out of help. * info/dir.c (maybe_build_dir_node): Really check for the same dir file twice, not just by name. (new_dir_file_p): New function. * util/install-info.c: Tell them about --help in doc strings. Thu Jul 24 14:25:44 1997 Karl Berry * util/texindex.c (memory_error): Move to avoid incorrect implicit decl. * makeinfo/makeinfo.c, * makeinfo/multi.c, * util/install-info.c, * util/texindex.c, * info/tilde.c, * info/man.c, * info/gc.c, * info/session.c (info_replace_key_to_typeahead): Remove unused function, * info/nodemenu.c, * info/man.c, * info/m-x.c, * info/footnotes.c * info/info.c * info/indices.c, * info/filesys.c: Parenthesize to avoid -Wall warnings remove unused variables, make return types explicit, printf type corrections. * lib/system.h: : Include this. * util/texindex.c, * makeinfo/makeinfo.c, * info/echo-area.c, * info/display.c: ctype.h: Included in system.h now. * info/echo-area.c: Parenthesize to avoid -Wall warnings. (ctype.h): #include for isprint. (echo_area_stack_depth): Remove unused function. * info/display.c: Parenthesize to avoid -Wall warnings. (ctype.h): #include for isprint. * info/dir.c: Parenthesize to avoid -Wall warnings. (build_dir_node_internal): Remove declaration of nonexistent function. From: Erick Branderhorst . * configure.in (TEXMF): Call texconfig to discover the default value, for the sake of the warning in doc/Makefile. From: Tim Mooney . * doc/Makefile.am (TEXMF): New variable. (install-data-local): Use it in warning. From: Tim Mooney . * info/session.c (initialize_info_session): Only call terminal_prep_terminal if clear_screen is true. Otherwise, failed --index-searches prep the terminal but do not unprep it. From: William Edward Webber . * info/nodemenu.c: Doc fix. Mon Jul 21 17:11:09 1997 Karl Berry * doc/texinfo.texi: Comment out @smallbook and @set smallbook so people at other sites can print it the way they want. From: Thomas Walter Sun Jul 20 07:52:25 1997 Karl Berry * configure.in: 3.9h. * doc/Makefile.am (install-info-am, distclean-aminfo): New targets to avoid assuming info files are in srcdir. * lib/system.h (xstrdup): Returns char *, not void *. * doc/Makefile.am (.texi.info), * doc/Makefile.am (texinfo): Don't run in $(srcdir). * util/install-info.c (main): Remove unnecessary decl of strrchr. * info/tilde.c: Include info.h (for config.h) before alloca stuff. * makeinfo/makeinfo.c (validate_file): Rename `valid' to `valid_p' to avoid conflict with SunOS 4 header files. From: "Kaveh R. Ghazi" . * info/session.c (initialize_info_session): Call terminal_prep_terminal here (before calling terminal_clear_screen). (info_session): Instead of here. From: William Edward Webber . * Makefile.am (EXTRA_DIST): Add README-alpha. Sat Jul 19 13:50:27 1997 Karl Berry * info/terminal.c: Use `keypad transmit' sequence if it's defined: (term_keypad_on, term_keypad_off): New statics. (terminal_begin_using_terminal): If term_keypad_on, send it. (terminal_end_using_terminal): If term_keypad_off, send it. (terminal_initialize_terminal): Look up ks and ke termcap strings. From: William Edward Webber . * info/infomap.c (initialize_info_keymaps): Initialize hardwired cases for arrow keys a la readline. Found by John Eaton, jwe@bevo.che.wisc.edu. * makeinfo/makeinfo.c (output_pending_notes): Remove footnote macro expansion code I #if 0'd out some time ago. And doc fixes. * Applied this patch: Sat Jul 19 16:29:01 1997 Karl Eichwalder * info/info.c (main): setlocale, bindtextdomain, and textdomain. Fri Jul 18 10:02:18 1997 Karl Berry * doc/Makefile.am (install-data-local), * emacs/Makefile.am (install-data-local): Give subdir in warning. * configure.in: Version 3.9f. * doc/texinfo.texi: Correct \^ to @^. From Andreas S. * Merged these changes: 1997-07-17 Andreas Schwab * info/display.c (display_cursor_at_point): Flush ouput. 1997-07-17 Andreas Schwab * info/session.c (remember_window_and_node): Don't crash when the current window has no current node. 1997-07-17 Andreas Schwab * util/texindex.c (usage): Translate the doc strings. * makeinfo/makeinfo.c (cm_today): Translate the month names. * info/variables.c (describe_variable): Translate the doc strings. * info/nodes.h: Don't translate the strings defining the info format. 1997-07-17 Andreas Schwab * makeinfo/makeinfo.c (get_item_function): Remove superfluous call to canon_white after get_rest_of_line. (cm_end): Likewise. (handle_variable): Likewise. (cm_item): Likewise. (cm_unmacro): Likewise. 1997-07-17 Andreas Schwab * info/nodemenu.c (list_visited_nodes): Don't clear the internal flag, this and other functions depend on it. Don't insist on displaying the menu below the current window. 1997-07-17 Andreas Schwab * makeinfo/makeinfo.c (cm_uref): Fix memory leaks. (cm_inforef): Likewise. Handle empty cross reference name. 1997-07-17 Andreas Schwab * info/echo-area.c (ea_possible_completions): Check that the current window can actually be split. Thu Jul 17 17:19:34 1997 Karl Berry * emacs/Makefile.am (*clean-lisp): Define, as Automake didn't. From: Kenneth Stailey . * doc/Makefile.am: Do not distribute info.1. * makeinfo/macros: Do not distribute this directory, it's merged into the main documentation. * doc/makeinfo.texi: Don't distribute this either, it's in the main manual. * util/install-info.c: Use \n\ for multiline string constant. From: Tim Mooney . Wed Jul 16 15:29:50 1997 Karl Berry * doc/texinfo.texi: @set must be after @setfilename, I guess. Noted by Erick Branderhorst. * Applied this change: Tue Nov 12 22:20:22 1996 John Eaton * makeinfo.c (INDEX_ALIST): Use two indices, read_index and write_index, instead of just one. (find_index_offset): If a match is found, return index to the current INDEX_ALIST struct, not the index pointing to the list of index entries. (translate_index): Return read_index from the matching INDEX_ALIST. (undefindex): Delete the list of index elements pointed to by read_index from the INDEX_ALIST that matches name. (defindex): Initialize read_index and write_index. (index_add_arg): Add entries to the list pointed to by write_index from the INDEX_ALIST matching name. (index_append): Delete unused function. (cm_synindex): Don't merge indcies, just make the write_index for redirectee the same as the write_index for redirector. Tue Jul 15 09:32:04 1997 Karl Berry * doc/texinfo.texi: Bump edition number for 2.24. * util/Makefile.am (localedir): Define. * info/window.h: Rename __window__ to window_struct. * info/window.h, * info/variables.h, * info/search.h, * info/man.h, * info/info-utils.h, * info/gc.h, * info/footnotes.h, * info/filesys.h, * info/echo-area.h, * info/display.h: Avoid leading _ in #define for #include protection. * makeinfo/makeinfo.c: Version 1.68. * info/info.c: Version 2.17. * Most all files: Untabify. * doc/Makefile.am (texinfo): Add explicit target. * emacs/Makefile.am (noinst_LISP): Remove the obsolete detexinfo.el (makeinfo --no-headers is better) and texnfo-tex.el (now handled by TeX modes in general). Mon Jul 14 15:21:03 1997 Karl Berry * util/texi2dvi: Update RCS file from 3.9 distribution. * util/Makefile.am (EXTRA_DIST): Add update-info, from rhawes@dmapub.dma.org Sun Jul 13 17:05:03 1997 Karl Berry * info/signals.c: Use RETSIGTYPE instead of hardwiring void. From: "Jeffery L. JT Vogt" . * info/session.c (info_history_node): Rewrite as info_kill_node (current_node). (kill_node, read_nodename_to_kill): New functions from info_kill_node. (info_kill_node): Now this just calls them. Fri Jul 11 11:56:58 1997 Karl Berry * doc/texinfo.texi: Fix `Conditionals' xref. Thu Jul 10 17:58:12 1997 Karl Berry * doc/info.texi: Don't say SPC clears ? screen. Sun Jul 6 16:26:41 1997 Karl Berry * doc/info-stnd.texi: Document --index-search. * info/tilde.c, * info/session.c: Remove redundant getenv decl. * Installed following change: Tue Nov 12 14:44:00 1996 John W. Eaton * info/info.c (main): Handle new option, --index-search STRING. (index_search_p, index_search_string): New static variables, used to handle --index-search option. * info/session.c (initialize_info_session): New arg, clear_screen. Change all callers. * info/indices.h (do_info_index_search, index_intry_exists): Provide declarations here. * info/indices.c (do_info_index_search): New function, extracted from info_index_search. (info_index_search): Simply call do_info_index_search() with search_string set to NULL. (index_entry_exists): New function. Sat Jul 5 17:17:14 1997 Karl Berry * doc/texinfo.texi: Document @kbdinputstyle. * makeinfo/makeinfo.c (kbdinputstyle): New command. (cm_no_op_line_arg): New function. * info/termdep.h (HAVE_TERMIOS_H) [NeXT]: #undef. From: Gregor Hoffleit et al. Fri Jul 4 14:18:08 1997 Karl Berry * info/Makefile.am (EXTRA_DIST), * util/Makefile.am (EXTRA_DIST), * makeinfo/Makefile.am (EXTRA_DIST), * lib/Makefile.am (EXTRA_DIST): Include README. * doc/texinfo.texi (makeinfo options): Document --paragraph-indent values more completely. * makeinfo/makeinfo.c (set_paragraph_indent): Allow translated asis or none, improve doc. From ke. * doc/Makefile.am (dist-info): New empty target so that we do not distribute info files. From Erick Branderhorst. * doc/texinfo.texi (Invoking install-info): Document that the dir file is created now if need be. * Makefile.am (EXTRA_DIST): No longer need dir. * util/install-info.c (ensure_dirfile_exists): New routine. (main): Call it before trying to open dirfile for reading. * doc/texinfo.texi: Document install-info --delete a little better. * util/install-info.c: Set something_deleted when we delete a normal line. Bug from: Denis Kosygin . * util/install-info.c: If no info dir entry, give warning and exit 0. Wed Jul 2 06:35:17 1997 Karl Berry * configure.in (ALL_LINGUAS): Add fr. * makeinfo/makeinfo.h (insertion_type, insertion_type_names): Add ifnot... entries. Alphabetize. Tue Jul 1 17:21:54 1997 Karl Berry * makeinfo/makeinfo.c (sort_index): Set defining_line and input_filename so errors in index entries are reported at the correct location. From rms. * makeinfo/makeinfo.c (cm_ifnothtml, etc.): Routines for new commands. Sun Jun 29 09:44:01 1997 Karl Berry * doc/texinfo.texi: Document new @ifnot... commands, etc. * doc/texinfo.texi: Document @image, etc. Thu Jun 26 17:57:37 1997 Karl Berry * makeinfo/makeinfo.c (cm_image): New routine for new command @image. (cm_end): Move to better place, doesn't need its own page. Doc fixes. Mon Jun 23 16:54:03 1997 Karl Berry * Makefile.am (SUBDIRS): Do intl first. * doc/Makefile.am (EXTRA_DIST): Include epsf.tex. (install-data-local): Suggest possible installation directory. * epsf.tex: New file. Wed Jun 18 17:51:52 1997 Karl Berry * doc/texinfo.texi: Document texinfo.cnf. Sun Jun 15 14:37:58 1997 Karl Berry * doc/texinfo.texi (Command List): Various commands missing or erroneous. From: Karl_Heinz_Marbaise@p69.ks.fido.de. * makeinfo/makeinfo.c: Oops, failed to break out of loop. * util/texindex.c: Use not "getopt.h". * All source files: Merge gettext changes from Karl E.; his ChangeLog entries below. Sat Jun 14 17:04:28 1997 Karl Berry * Makefile.am, * makeinfo/Makefile.am: Doc fix. * util/Makefile.am (EXTRA_DIST): Add texi2dvi. From Karl E. Fri Jun 13 17:39:34 1997 Karl Berry * makeinfo/makeinfo.c [WIN32]: Handle read bogosity and c:\ absolute paths. From: Eric Hanchrow . * configure.in (AC_CHECK_HEADERS): Check for pwd.h. * info/tilde.c (pwd.h): Move #include to system.h. * makeinfo/makeinfo.c (main): New option -P to prepend to search path. From: Kenneth Stailey . * doc/texinfo.texi (Invoking makeinfo), * doc/makeinfo.texi: Mention -P. Thu Jun 12 16:25:40 1997 Karl Berry * info/signals.h (SIGCHLD): #define as SIGCLD if undefined, for sysV68. From: "Philippe De Muyter" . * util/install-info.c (O_RDONLY): Remove this stuff, it's in system.h. (main): Handle existing entry in dir file having .info extension. From: "Bradley C. Kuszmaul" . * makeinfo/makeinfo.c (get_char_len): Don't count 8-bit characters as two chars in the output. From: Sung-Hyun Nam . Wed Jun 11 16:36:51 1997 Karl Berry * doc/texinfo.texi (Other Info Directories): Document new trailing : in INFOPATH feature. * info/info.c (main): Have trailing : in INFOPATH expand to the default path. Fri Jun 6 13:22:02 1997 Karl Berry * doc/texinfo.texi (uref): New node for new command. Thu Jun 5 18:13:48 1997 Karl Berry * makeinfo/makeinfo.c (cm_uref): New function to accept optional second argument. Call it in command table. Sat Jun 14 10:54:16 1997 Karl Eichwalder * mkinstalldirs: Update from automake-1.1p. * configure.in: Touch po/ChangeLog (gettext needs it). Thu Jun 12 08:37:52 1997 Karl Eichwalder * util/texindex.c: Include system.h, remove config.h. * po/POTFILES.in: Fill it. * makeinfo/multi.c: Include system.h. * info/Makefile.am: * makeinfo/Makefile.am: * util/Makefile.am: (localedir): Set. (INCLUDES): Add intl/ and LOCALEDIR. (LDADD): Add @INTLLIBS@. * makeinfo/makeinfo.c (main): * util/texindex.c (main): * util/install-info.c (main): setlocale, bindtextdomain, and textdomain. * lib/system.h: Include locale.h and libintl.h. * acconfig.h: Include libintl.h. (_, N_): Define. Add ENABLE_NLS, HAVE_CATGETS, HAVE_GETTEXT, HAVE_LC_MESSAGES, HAVE_STPCPY for libintl. Add @TOP@ and @BOTTOM@. * configure.in (AM_GNU_GETTEXT): Add. (AC_OUTPUT): Process Makefiles in intl/ and po/. (ALL_LINGUAS): Available languages. * Makefile.am (AUTOMAKE_OPTIONS): Now use 1.1p. Wed Jun 11 17:05:37 1997 Karl Eichwalder * Makefile.am (SUBDIRS): Add intl/ and po/ for NLS. * run `gettextize -c' to get the i18n skeleton. Wed Jun 4 17:51:08 1997 Karl Berry * makeinfo/makeinfo.c (uref): New command, another alias for @code for now. Wed Jun 4 02:02:33 1997 Miles Bader * doc/texinfo.texi (email): { and } need @ escapes. Sun Jun 1 16:34:12 1997 Karl Berry * doc/texinfo.texi (itemx): @itemx should always follow @item. * makeinfo/makeinfo.c (cm_item): Insert blank line if two consecutive @item's. From: Karl Eichwalder . Also various doc fixes. Tue May 27 17:20:44 1997 Karl Berry * doc/texinfo.texi (various): Document @deftypemethod. (email): @ should have been @@ in the example. From: Mate Wierdl Mon May 26 16:56:26 1997 Karl Berry * makeinfo/multi.c (setup_multitable_parameters): Avoid use of %n for sake of m68k-hp-bsd. From: Derek L Davies . * info/terminal.c (terminal_begin_using_terminal, terminal_end_using_terminal): Call fflush and sleep to handle cmdtool/shelltool with scrollbars. Also ignore SIGWINCH so we do not prematurely exit. Move call. (terminal_prep_terminal): Disable LNEXT (CTRL-V). From: strube@physik3.gwdg.de (Hans Werner Strube). * configure.in (AC_TYPE_SIGNAL): Check this. Sun May 25 16:49:58 1997 Karl Berry * makeinfo/makeinfo.c (discard_insertions): Take arg saying whether ifinfo/ifset/etc. are ok. (convert_from_loaded_file): At `finished', call discard_insertions. (handle_variable_internal): Complain if we reach eof before the @end for a false condition. From: HERBERT@boevm4.vnet.ibm.com. * info/Makefile.am (ginfo_SOURCES): Add doc.h. * lib/Makefile.am (libtxi_a_SOURCES): Add system.h. Sat May 24 18:08:27 1997 Karl Berry * makeinfo/makeinfo.c: Check that we have macro_expansion_filename before using strcmp. Thu May 22 17:59:46 1997 Karl Berry * doc/makeinfo.texi: Minimally document --force. * makeinfo/makeinfo.c (--force): New option. (-E): Allow stdout via `-'. (convert_from_loaded_file): Unlink output files if errors and !force. Tue May 20 17:48:42 1997 Karl Berry * makeinfo/makeinfo.c: Change all strdup calls to xstrdup. (xmalloc, xrealloc, memory_error): Remove these functions, they're in lib. (set_paragraph_indent, cm_paragraph_indent): Move to misc page. (cm_footnote): Expand macros in the arg for the macro expansion output. Fri May 16 17:26:59 1997 Karl Berry * makeinfo/makeinfo.c (cm_macro): Allocate an empty body if the macro was empty. (cm_unmacro): Allocate one more byte for the null. From: Robert Hoehne . Sun May 11 17:51:21 1997 Andreas Schwab * makeinfo/makeinfo.c (cm_printindex): Fix calculation of the length of an index line. Sun May 11 14:47:42 1997 Tom Tromey * makeinfo/makeinfo.c (main): Don't unconditionally run usage when -e specified. Sun May 11 17:47:42 1997 Karl Berry * makeinfo/makeinfo.c (init_indices): Free the source for an @synindex. (undefindex): Do not go further if the target was already freed. (free_index): Do not free the node names, as init_tags already did. (cm_synindex, index_add_arg): Improve error message. (program_index, function_index, etc.): Remove these unused #defines. Tue May 6 17:53:37 1997 Karl Berry * makeinfo/makeinfo.c (init_internals): Do not free current_node, it already is, at least when multiple input files are specified. From: Karl Eichwalder . Mon May 5 16:14:39 1997 Karl Berry * doc/texinfo.texi: Mention both alignment and non-alignment of continuation description lines in menus (Arnold). Sun Apr 27 16:12:44 1997 Karl Berry * makeinfo/makeinfo.c (apply): Handle body being `\string'. Also, avoid dereferencing a null pointer when a macro has no named parameters. From: Eli Zaretskii . * makeinfo/makeinfo.c: Wording changes/fixes in warnings. * info/session.c (info_get_input_char): Do not mix stdio with raw I/O. From: Egil Kvaleberg . From Tom Hageman . These changes make arrow keys work: * info/infomap.c: Add arrow key bindings. (keymap_bind_keyseq): New support function. (initialize_info_keymaps): Use it. (term_ku,term_kd,term_kl,term_kr): Remove explicit declarations; use #include "terminal.h" instead. * info/session.c (initialize_info_session): Unbuffer stdin. (info_get_another_input_char): Fix bug in `ready' logic. * info/terminal.h, * info/terminal.c (term_kP, term_kN): New variables to hold PageUp, PageDown key sequences. (terminal_initialize_terminal): Set them. * util/texindex.c (main), * util/install-info.c (main), * makeinfo/makeinfo.c (print_version_info), * info/info.c (main): Use PACKAGE and VERSION from Automake for printing version number. Sat Apr 26 19:19:46 1997 Karl Berry * makeinfo/makeinfo.c (get_until_in_line): Do not expand if executing_string. Also, free temporary strings. Also, untabify entire file. * doc/texinfo.texi: Many corrections from Arnold. Thu Apr 24 16:31:09 1997 Karl Berry * makeinfo/multi.c (draw_horizontal_separator): Account for indent here also. From Ulrich. Wed Apr 23 15:15:34 1997 Karl Berry * makeinfo/makeinfo.c (cm_today): Use time_t instead of long; everyone else does. (LOCALTIME_CAST): Remove kludge, we'll always use time_t now. * info/Makefile.am (ginfo_SOURCES): Remove general.h, that got merged into system.h. Mon Apr 21 17:13:25 1997 Karl Berry * makeinfo/multi.c (output_multitable_row): Account for column_indent, both the global one and for each column. (setup_multitable_parameters): Account for column_indent in the table width in the columnfrac case, but don't bother with the template case for now. Sun Apr 20 16:32:00 1997 Karl Berry * makeinfo/makeinfo.c (output_stream): Remove redundant definition; it's in makeinfo.h, and a vaxstation-ultrix4.3 fails to link because of the two defns. From: Anders Olofsson . * makeinfo/makeinfo.c (expansion): Inhibit appending to the macro expansion stream. (get_until_in_line): Possibly expand the text. Change caller in get_node_token to do the expansion, all other calls to remain the same. * makeinfo/makeinfo.c (cm_node): No need to call strlen to check for the empty string. * doc/texinfo.texi: Restore missing @c for initial comment. Fri Apr 18 17:41:36 1997 Karl Berry * doc/texinfo.texi: Mention that .info is unnecessary in the info file name argument of an xref. * doc/texinfo.texi: Mention texi2dvi -t instead of embedding @smallbook or @afourpaper in the document source. Sun Apr 13 15:19:08 1997 Karl Berry * lib/system.h (_GNU_SOURCE): #define. Mon Apr 7 16:30:11 1997 Karl Berry * doc/info.texi, * doc/info-stnd.texi, * doc/texinfo.texi: Do not make (dir) the previous ptr from the top node, and tell people not to do that in the manual. From: rmedina@kanojo.ivic.ve (Rodrigo Medina), confirmed by rms. Fri Apr 4 16:30:33 1997 Karl Berry * makeinfo/makeinfo.c: Move error page to top to avoid prototypes, and do add prototypes for add_word_args and execute_string, so we can use . * info/makedoc.c, * info/nodemenu.c: Use %ld instead of %d for file offsets. * makeinfo/makeinfo.c (delete_macro): Decrement macro_list_len. (get_macro_args): Decrement line number if see \n. * utils/texindex.c (indexify): Use fputs instead of fprintf for constant string. From: Eli Zaretskii . Thu Apr 3 17:40:52 1997 Karl Berry * configure.in (AC_CHECK_HEADERS): No need to check for vararg.h here, AC_FUNC_VPRINTF does it. (AC_CHECK_FUNCS): Likewise for vsprintf and vfprintf. * makeinfo/makeinfo.c (add_word_args, execute_string): Rewrite like the error functions. Wed Apr 2 17:46:28 1997 Karl Berry * configure.in: Add AC_FUNC_VPRINTF. * makeinfo/makeinfo.c (error, line_error, warning): Rewrite a la error.c from the *utils to use if available. Tue Apr 1 11:48:40 1997 Karl Berry * doc/texinfo.texi: Tabs are a bad idea. * doc/userdoc.texi, * doc/info.texi: Untabify. Sun Mar 30 17:36:47 1997 Karl Berry * makeinfo/makeinfo.c (end_of_sentence_p): New function. (add_char): Call it, instead of simply sentence_ender. (post_sentence): New macro. Also, remove some #include's now in system.h. * lib/system.h [VMS]: #include , from makeinfo. Thu Mar 27 17:41:03 1997 Karl Berry * info/search.c (skip_node_characters): Do not arbitrarily strip trailing period from end of node name; this is valid. Mon Mar 24 16:44:42 1997 Karl Berry * configure.in (AC_OUTPUT): Don't need to create stamp-h here, tromey says AM_CONFIG_HEADER will do it. * info/Makefile.am, util/Makefile.am, makeinfo/Makefile.am (INCLUDES): Don't need -I.. (for config.h) or -I$(srcdir), says tromey. Automake includes those already. Fri Mar 14 15:05:17 1997 Karl Berry * info/Makefile.am: Build as ginfo, install as info, to avoid conflict with the standard info target. * lib/system.h: New file. * makeinfo/makeinfo.c (strerror): Remove declaration, include system.h, remove other redundant #if stuff. * info/general.h: Include system.h instead of doing common stuff. * util/install-info.c (my_strerror): Remove this, use strerror, include system.h. * info/terminal.c (terminal_prep_terminal): Only use OCRNL and ONLCR if they are defined. Reported by many people. * Installed: Sun Dec 1 19:23:54 1996 Karl Eichwalder * configure.in (TERMLIBS): Add ncurses. Thu Mar 13 13:59:45 1997 Karl Berry * lib/Makefile.am (libtxi_a_SOURCES): Add xstrdup.c. * info/*.c: Use xstrdup instead of strdup everywhere. * info/tilde.c: Do not include clib.h, move stdlib.h include to * info/general.h: here. * configure.in (AC_CONFIG_HEADER): Use this, to avoid hugely long compile line with all the -D's. * info/general.h: Include . * emacs/Makefile.am (install, install-data): Do @echo to tell the user to compile/install the elisp manually. * configure.in (AC_REPLACE_FUNCS): Move strerror check to here. (AC_CHECK_FUNCS): From here. * lib/strerror.c: New file, from enscript (et al.) distribution. Tue Mar 11 16:36:25 1997 Karl Berry * info/Makefile.am (info_SOURCES): Add doc.c, dribble.c, infodoc.c. (LDADD): Add @TERMLIBS@. * info/info.h: HANDLE_MAN_PAGES, NAMED_FUNCTIONS: Define these. * info/filesys.h: Spurious ! when DEFAULT_INFOPATH is not defined. * configure.in (AC_OUTPUT): Do lib first and doc last. * info/echo-area.c, * info/echo-area.h, * info/info.h: Rename echo_area to echo-area. Mon Mar 10 17:59:05 1997 Karl Berry * */Makefile.am: Write Makefile.am files for Automake. * doc: New subdirectory, move all manuals and texinfo.tex there. * AUTHORS, THANKS, config.guess, config.sub, mkinstalldirs: New files, required by Automake. * lib/xmalloc.c: Move from info/. Fri Oct 4 07:49:49 1996 Karl Berry * Version 3.9. * Makefile.in (install): Say to install texinfo.tex manually. * util/texi2dvi, * util/texindex.c, * makeinfo/makeinfo.c, * info/info.c: Include only the current year in the copyright message. * util/texi2dvi: Exit successfully. From: Andreas Schwab . Thu Oct 3 12:58:32 1996 Karl Berry * Rename install.sh to the preferred install-sh. * Makefile.in (VERSION), * util/texi2dvi, * util/texindex.c, * util/install-info.c, * makeinfo/makeinfo.c (minor_version, print_version_info), * info/info.c: Update version number. * util/texi2dvi: Only show diff if verbose. * util/install-info.c (main): Check for a missing dir file as well as a missing info files. (main): At start of a node, completely initialize the newly-malloced node structure. * texinfo.texi: Fix incorrect uses of @key, insert missing newline in Installing Dir Entries' @menu item, document install-info invocation. * Makefile.in (DISTFILES): Do not put .gdbinit's in distribution. (dist): Use || instead of && (and invert sense) so make doesn't think the command failed. (dist): Exclude more junk. * makeinfo/makeinfo.c (cm_xref): Back out patch from Tom T., since we generate a good-enough error message that is suppressible without it. * util/gen-dir-node: The recommended name for the top-level info file is dir, not dir.info. * util/install-info.c (main): At `Mark the end of the Top node', make sure the node name is non-NULL before comparing it. From lvirden@cas.org. * configure.in (AC_REPLACE_FUNCS): Use this for memcpy, memmove, and strdup. (AC_CHECK_FUNCS): Instead of this. Because both bcopy and memmove are missing on the 3b2, as reported by Gaylen Miller , hence we must provide our own. * libtxi/Makefile.in (LIBOBJS): New variable. (OBJS): Include it. * libtxi/memcpy.c, libtxi/memmove.c, libtxi/strdup.c: New files, taken from fileutils 3.13. * makeinfo/makeinfo.c, * info/clib.c (strdup): Move to libtxi. Wed Oct 2 18:23:30 1996 Karl Berry * info/info-utils.h (memcpy) [!HAVE_MEMCPY], * info/termdep.h (memcpy) [!HAVE_MEMCPY], * makeinfo/makeinfo.c (memmove) [!HAVE_MEMMOVE]: Remove this #ifdef, as we now include it in libtxi if missing. Tue Oct 1 17:41:52 1996 Karl Berry * makeinfo/Makefile.in (install), * info/Makefile.in (install), * Makefile.in (install): Use new option name --info-dir instead of --infodir. * makeinfo/multi.c (out_char): New fn. Replace all calls to putc/fprintf with calls to this. * util/install-info.c: Rename --infodir to info-dir. Mon Sep 30 10:07:21 1996 Karl Berry * Version 3.8. * texinfo.tex: Untabify. * texinfo.tex (\ptexl, \ptexL): Do not save, we have our own commands now. (\onepageout): Reformat for readability, and call \indexdummies to avoid expansion of Texinfo commands (e.g., accents) in \write's. (\,, \dotaccent, \ringaccent, \tieaccent, \ubaraccent, udotaccent, \questiondown, \exclamdown, \dotless): New macros. (\l): Let plain TeX definition remain, instead of switching to ``lisp'' font. (\multitable): Ensure space between the columns, insert struts to make interline spacing constant, use real strut instead of a box containing `Xy'. (\indexdummies): Do not define \rm, \char, but do define \@, \{, \}, \dotless, and \,. And \t should generate \t, not \r. (\indexnofonts): Define \, and \dotless as \indexdummyfont, and let \@ be @. (\doind): Reformat for readability, and use temp control sequence names that actually make sense. (\doublecolumnout, \pagesofar, \enddoublecolumns): Restore Knuth's original code to avoid spurious overfull vbox messages. (No boxes are actually overfull). (\shortcontents): Do not allow hyphenations. (\dochapentry, \tocentry): Make glue above and below flexible, to allow better page breaks. (\tex): Reset \, to its plain TeX meaning, and do not reset \l. * COPYING: Update for new FSF address (from gcc dist). * libtxi/Makefile.in: Various simplifications. Sun Sep 29 12:58:44 1996 Karl Berry * util/texi2dvi: Use $progname instead of $0 for --version. * util/install-info.c (xmalloc, xrealloc): Declare malloc and realloc as returning void *, to avoid ptr/int problems on Digital Unix. * info/tilde.c (tilde_expand_word): Declare getenv as returning char *, to avoid warning on Digital Unix. * makeinfo/multi.c (multitable_active): Declare extern here to avoid ld warning on rs6000. * util/texindex.c (usage): Avoid ??' trigraph. * util/install-info.c: Include or , according to HAVE_SYS_FCNTL_H, and only include if HAVE_SYS_FILE_H. (readlines): Oops, had NULL's and 0's reversed for ptr/int members. * info/terminal.c (terminal_goto_xy): Remove spurious extra ;. * util/install-info.c: Untabify. (input_sections): Initialize. (find_lines): Initialize the terminating element of the array. (print_help): Document --infodir. (main): Compare the basename of infile sans .info to the dir entry, not infile itself. * util/Makefile.in (clean): Remove the install-info binary. * info/Makefile.in (distclean): Remove *.info* files. * Makefile.in (install), * info/Makefile.in (install), * makeinfo/Makefile.in (install): Use --infodir instead of --info-file. * info/info.c, * makeinfo/makeinfo.c: Avoid newlines in string constants for the sake of SunOS cc. * makeinfo/multi.c: Do not assume ANSI C. * info/info.texi: Oops, need @end vtable for a @vtable. Sat Sep 28 16:31:28 1996 Karl Berry * Makefile.in (texinfo): Do not depend on sub-all, as then makeinfo is always run. Instead, depend on texinfo.texi. * makeinfo/Makefile.in (info, dvi): New targets. makeinfo.info, makeinfo.dvi: Do not depend on macro.texi for now. * info/Makefile.in (install): Must call install-info twice. * info/info-stnd.texi, * info/info.texi, * makeinfo/makeinfo.texi: Include direntry. * emacs/Makefile.in: Use && after cd, etc. * texinfo.texi: Kludges so makeinfo -E will not create spurious differences. Add new direntries. * util/install-info.c, * util/texindex.c, * makeinfo/makeinfo.c, * info/info.c: Standardize --version output. * makeinfo/makeinfo.c (defun_internal): Don't insert index command if expanding macros. (cm_footnotestyle): Don't change the footnote style if it was set on the command line. * util/texi2dvi: Recompute original index files each time through loop. Make indentation uniform. Use same basename for the temp input files. Standardize --version output. * info/Makefile.in (install), * makeinfo/Makefile.in (install): Insert $(POST_INSTALL). Fri Sep 27 13:27:30 1996 Karl Berry * texinfo.texi (Format with texi2dvi): Rewrite now that the script runs in a loop. * info/Makefile.in (MAKEINFO): Simplify to ../makeinfo/makeinfo. Fri Sep 27 00:26:03 1996 Miles Bader * info/terminal.c [HAVE_TERMIOS_H] (terminal_prep_terminal, terminal_unprep_terminal): Add code for termios. [HAVE_TERMIOS_H] (original_termios, ttybuff): New variables. * info/termdep.h: [HAVE_TERMIOS_H]: Add include of . * configure.in: Add check for . Thu Sep 26 10:46:34 1996 Karl Berry * emacs/texnfo-upd.el, * emacs/texinfo.el, * emacs/texinfmt.el: Update from bob for new Texinfo commands, etc. * emacs/info.el, emacs/informat.el, emacs/makeinfo.el, emacs/texnfo-tex.el: Update from Emacs 19.34 dist. * emacs/elisp-comp: Use TMPDIR if set. * util/Makefile.in (libdir): Remove. * makeinfo/Makefile.in (install), * Makefile.in (install), * info/Makefile.in (install): Run install-info. (libdir): Remove. * texinfo.texi: Various fixes as I make this go through TeX. * util/install-info.c: Quote newlines in help message. * util/texi2dvi (texi2dvi): Run TeX until the aux/index files stabilize, instead of just twice. From: David Shaw . Tue Sep 24 14:43:03 1996 Karl Berry * dir: Blank dir file for installation on new systems. Mon Sep 23 12:18:43 1996 Karl Berry * makeinfo/makeinfo.c (args_from_string): Do not back up at a }; that leads to an infinite loop. Sat Sep 21 17:48:04 1996 Karl Berry * makeinfo/makeinfo.c (cm_xref): Do not seg fault if outside of any node. From: Tom Tromey . (cm_ctrl): Make obsolete. Tue Sep 17 13:30:08 1996 Karl Berry * texinfo.tex (\inforef): Move to more appropriate place. (\pounds): Remove spurious extra $. (\email): Typeset argument in angle brackets. (\macro): Use \doignore for robustness, instead of just letting TeX parse the argument. (\unmacro): Define. Sat Sep 14 16:17:35 1996 Karl Berry * texinfo.texi: Document multitables, new ISBN number. Wed Sep 11 18:01:24 1996 Karl Berry * makeinfo/multi.c (struct env): Remove unused output_position field; this needs to be global. (setup_multitable_parameters): Implement template-defined multitables. (output_multitable_row): Remove trailing whitespace. * makeinfo/makeinfo.c (_READ_BUFFER_GROWTH, struct _defines): Remove leading underscore for POSIX/ANSI pedants. (init_conversion): Initialize output_position here. (init_paragraph): Instead of here, where it loses with the multitable calls, eventually resulting in negative counts to the write call when the output file is split. * texinfo.texi: First cut at macro documentation. Change accent doc to use tables. Remove whitespace experiments, they are now the default. Mon Sep 9 14:16:24 1996 Karl Berry * makeinfo/makeinfo.c: Use putc instead of fprintf where possible. (cm_accent): Put _ from @ubaraccent after argument. * util/texindex.c (strerror) [!strerror]: Conditionalize declaration. Sat Sep 7 14:13:24 1996 Karl Berry * makeinfo/makeinfo.c (commandTable): Obsolete @setchapterstyle. Thu Sep 5 15:45:11 1996 Karl Berry * makeinfo/makeinfo.c (convert_from_loaded_file): Oops, fix wording of initial output comment. * makeinfo/makeinfo.c (cm_angle_brackets): Rename from cm_key. (commandTable): @email should produce angle brackets. @key: Change name. Tue Sep 3 14:52:17 1996 Karl Berry * texinfo.tex (\hsize): Decrease. (\hoffset): Increase. (\setleading): Decrease dramatically. This change affects 8.5x11 format only. * texinfo.texi: Document accent commands. Mon Sep 2 11:10:49 1996 Karl Berry * makeinfo/makeinfo.c (commandTable): Deprecate @ichapter and @titlespec. Move all the deprecated @i
commands to the end of the list. * texinfo.texi: Document @pounds{} and @centerchap{}. * texinfo.tex (\centerchfplain): Rewrite to use \chfplain, and to actually center. (\unnchfplain): Just call \chfplain. (\chfplain): Rewrite to be generally callable. (\centerparametersmaybe): Hook, a no-op except with @centerchap. Sun Sep 1 15:01:49 1996 Karl Berry * texinfo.texi: Document @, rearrange spacing section. * makeinfo.c (commandTable): Make @. @? @! insert themselves, not be sentence-non-enders. They are sentence *enders*. Also, make @\t and @\n insert a normal space character, not themselves. Also, define @hyphenation. (insert_space): New function. (cm_ignore_sentence_ender): Remove this. (flush_output): Check only for META-SPC, not META-. Fri Aug 30 18:55:30 1996 Karl Berry * texinfo.texi: Document @- and @hyphenation{}. Miscellanous fixes. * makeinfo/makeinfo.c (commandTable): Define @- as cm_no_op, since makeinfo doesn't do hyphenation. Thu Aug 29 13:05:38 1996 Karl Berry * texinfo.tex (\key): Do not uppercase the argument; key names can be mixed case, e.g., `Control'. * makeinfo/makeinfo.c: @infotop, @infounnumbered, @infounnumberedsec, @infounnumberedsubsec, @infounnumberedsubsubsec, @infoappendix, @infoappendixsec, @infoappendixsubsec, @infoappendixsubsubsec, @infochapter, @infosection, @infosubsection, @infosubsubsection: Remove these long-since obsolete commands. @iappendix, @iappendixsection, @iappendixsec, @iappendixsubsec, @iappendixsubsubsec, @ichapter, @isection, @isubsection, @isubsubsection, @iunnumbered, @iunnumberedsec, @iunnumberedsubsec, @iunnumberedsubsubsec: Deprecate these. @infoinclude: Obsolete this. @,: Have to take an argument, since have to do @,{c} not c@,; can't feasibly implement the latter in TeX. * makeinfo/makeinfo.c: Rename @d to @udotaccent, since this is relatively infrequently used. Tue Aug 27 14:58:56 1996 Karl Berry * info/info.c (print_short_help), * util/install-info.c (print_help), * util/texi2dvi, * makeinfo/makeinfo.c (usage) Include bug reporting address. Mon Aug 26 15:27:17 1996 Karl Berry * makeinfo/makeinfo.c (commandTable): Remove @input, @medbreak, @smallbreak, @overfullrule, @br. Sun Aug 25 17:25:48 1996 Karl Berry * makeinfo/makeinfo.c (commandTable): Unify commands that perform the same operation, such as cm_file, cm_samp, cm_email, etc., which all do cm_code. * texinfo.texi: Document @ifhtml ... @end ifhtml. Change `PlainTeX' to `plain TeX'. Fri Aug 23 16:03:16 1996 Karl Berry * texinfo.tex (\pounds): New Texinfo command @pounds{}. (\parskip): New smaller value. (\chapheadingskip, \secheadingskip, \subsecheadingskip): New smaller values, both for 8.5x11 and @smallbook formats. From Bob. * makeinfo/makeinfo.c (cm_special_char): @pounds{} prints a #. (commandTable): Add new command @pounds. Tue Aug 20 13:47:20 1996 Karl Berry * makeinfo/makeinfo.c (CommandTable): Restore "!", accidentally removed previously. * texinfo.tex (\key): Typeset a lozenge around the argument (from gildea@intouchsys.com). * makeinfo/makeinfo.c (cm_key): Surround arg with <...> to match new lozenge style in TeX. Wed Aug 14 16:59:23 1996 Karl Berry * texinfo.texi: Propagate change from rms. Tue Aug 13 11:33:27 1996 Karl Berry * texinfo.texi: Propagate change from rms. * texinfo.texi: Document other @headings options. Sun Aug 11 13:19:42 1996 Karl Berry * makeinfo/makeinfo.c (cm_accent, cm_special_char, cm_dotless): New functions. (CommandTable): Add new commands for all of plain.tex's accents and non-English characters. Fri Aug 9 14:12:07 1996 Karl Berry * makeinfo/makeinfo.c (convert_from_loaded_file): Say we're making ``text'' file if no_headers. Also, use `input_filename' instead of just `name' for clarity. (suffixes): Check for no suffix last, i.e., prefer `foo.texi' as an input file to `foo'. (The latter is probably a binary.) Mon Aug 5 13:52:39 1996 Karl Berry * texinfo.tex (\heading, \subheading, \subsubheading): Can no longer call the nonexistent \*secheadingi series. Instead, call \plain*secheading. (\plainsubsecheading, \plainsubsubsecheading): New macros, by analogy with \plainsecheading. (\unnumberedsubseczzz, \unnumberedsubsubseczzz): Call them. Sun Aug 4 16:46:10 1996 Karl Berry * makeinfo/makeinfo.c (flush_output): Mask out eighth bit, that we turned on in non-sentence enders. Sat Aug 3 14:03:10 1996 Karl Berry * texinfo.tex (\HEADINGSdouble, \HEADINGSsingle, HEADINGSdoubleafter, \HEADINGSsingleafter, \CHAPPAGoff, \CHAPPAGon, \CHAPPAGodd): Set \contentsalignmacro, analogous to \pagealignmacro. (\startcontents): Call \contentsalignmacro instead of \pagealignmacro. Mon Jul 29 14:44:33 1996 Karl Berry * texinfo.tex (\indexfonts): Make leading be 12pt. Otherwise, it's too crammed. (\smalllispx): Remove \setleading{10pt}. That was too small. (\doprintindex): Do not call \tex ... \Etex. Index files are Texinfo source, not TeX source, except for using \ instead of @ as the escape character (for now). Sun Jul 28 13:37:05 1996 Karl Berry * texinfo.tex (paragraphindent): Move to more reasonable place in the source file. (chapfonts, secfonts, subsecfonts, indexfonts): Call \setleading. (\chfplain, \secheading, \plainsecheading, \subsecheading, \subsubheading): Rewrite to properly \hangindent the title. (\sectionheading): New generic macro to print section titles. * texinfo.texi: Update the `Obtaining TeX' node. Fri Jul 26 14:11:48 1996 Karl Berry * util/texi2dvi: Do macro expansion with makeinfo before running TeX. Various expansion safety measures added for test; avoid use of -o. * makeinfo/makeinfo.c (usage): More usage message tweaks. Fri Jul 26 11:55:37 1996 Karl Berry * util/texi2dvi: Format usage message to conform to the other *utils. Thu Jul 25 17:05:47 1996 Karl Berry * emacs/Makefile.in: Do not compile the Elisp by default. We don't install it, so it confuses people to compile it. Sun Jul 21 07:20:09 1996 Karl Berry * util/Makefile.in (install-info): Dependency should be install-info.o, not install-info. Also, update copyright years. * makeinfo/makeinfo.c (cm_printindex): Don't call execute_string to print index entries, we've already done the expansion now. * makeinfo/makeinfo.h: Add copyright. Finish merge of rms changes. * makeinfo/makeinfo.c: Finish merge, add my expansion changes again. * makeinfo/multi.c: Add copyright message. Fri Jul 19 10:35:22 1996 Karl Berry * info/info.c: Update copyright date. * info/info.texi, * util/install-info.c, * emacs/Makefile.in, * emacs/texnfo-tex.el, * emacs/Makefile.in: Change FSF address. * Merged changes from bfox -- below, plus multitable changes, plus lots more. Sun Apr 14 08:49:50 1996 Brian J. Fox * makeinfo/makeinfo.c (remember_node_reference): Numerous commands call remember_node_reference. If a node has not yet been defined, use the empty string as the current node for those cases. Mon Feb 12 17:35:38 1996 Brian J. Fox * makeinfo/makeinfo.c (push_node_filename): Clean up calls to xmalloc and xrealloc. Only have to call xrealloc. Fri Jan 26 08:00:38 1996 Brian J. Fox * info/session.c (info_input_buffer_space_available): Fix typo which forced the limitation of the sizeof (int) instead of sizeof (buffer). * Makefile.in (PACKVER): now at 3.8. Add TERMIOS support to Info. Minor bugs fixed in Makeinfo. Sat Jul 13 11:58:57 1996 Karl Berry * texinfo.texi (ftable vtable): Mention example. Sun Jun 30 14:59:51 1996 Karl Berry * makeinfo/makeinfo.c (cm_email): New function for new @email command. * texinfo.texi (email): New node documenting it. Wed Apr 17 18:07:34 1996 Richard Stallman * makeinfo/makeinfo.c (cm_kbd): Do nothing if in @example or @code. (struct brace_element): New field in_fixed_with_font. (remember_brace_1): Save in_fixed_with_font. (pop_and_call_brace): Restore in_fixed_with_font. (cm_code): Don't decrement in_fixed_with_font at end of construct. (struct istack_elt): New field in_fixed_with_font. (push_insertion, pop_insertion): Save and restore in_fixed_with_font. (end_insertion): Don't decrement in_fixed_with_font here. (not_fixed_width): New function. (cm_sc, cm_var, cm_italic, cm_roman, cm_titlefont): Use not_fixed_width. Sat Apr 13 23:22:05 1996 Richard Stallman * util/install-info.c (main): Fatal error if no input file spec'd. Look for START-INFO-DIR-ENTRY, not BEGIN-INFO-DIR-ENTRY. Thu Apr 11 18:21:50 1996 Richard Stallman * makeinfo/makeinfo.c (cm_enddots): New function. (self_delimiting): Accept -, ^ and ". (CommandTable): Add commands -, ^, ", enddots, centerchap. Sun Mar 24 12:18:32 1996 Richard Stallman * makeinfo/makeinfo.c (enum insertion_type): Add `direntry'. (insertion_type_names): Add "direntry". (cm_dircategory): New function. (cm_direntry): New function. (CommandTable): Add "dircategory" and "direntry". (insert_string): New function. (end_insertion): Handle direntry. (begin_insertion): Handle direntry. Sun Mar 24 11:10:05 1996 Karl Berry * makeinfo/makeinfo.c (cm_url): New function for new @url command. Fri Feb 23 21:14:40 1996 Richard Stallman * info/Makefile.in (install, uninstall): Use manprefix. Fri Feb 23 19:50:18 1996 Richard Stallman * util/Makefile.in (install-info, install-info.o): New targets. (all): Depend on install-info. (install, uninstall): Operate on install-info. * install-info.c: New file. Wed Jan 3 10:01:45 1996 Brian J. Fox * makeinfo/makeinfo.c (make_index_entries_unique): Be a little bit stricter about what makes two index entries identical. Fri Dec 29 13:00:24 1995 Brian J. Fox * makeinfo/makeinfo.c (Whole File): Add @detailmenu for allowing detailed menu listings to appear while still defaulting nodes. Wed Dec 27 13:54:30 1995 Brian Fox * makeinfo/makeinfo.c (cm_code): Always notice that we are in fixed_width_font, even if other formatting changes are not to take place. Sat Dec 23 11:48:43 1995 Brian J. Fox * info/man.c: (clean_manpage) Remove ^L's from page. * makeinfo/makeinfo.c (get_brace_args): Change some memcpy's to memmoves. * info/info.c (main): Prefer caseless matches over partial matches. * Makefile.in (All Subdir Targets): Change suggested by Debian people which allows errors in recursive makes to kill the top-level make. * makeinfo/Makefile.in (makeinfo.dvi): New target. * info/info.c (main): Print version of containing texinfo package. * makeinfo/makeinfo.c (flush_output): Don't strip high-bit from sentence_enders. Print the version number of the containing texinfo package. * info/man.c (locate_manpage_xref): Count the 0th entry. * makeinfo/makeinfo.c (cm_menu): If a menu is seen before a node has been defined, warn, and create the node `Top'. Wed Jun 21 03:19:39 1995 Brian Fox * makeinfo/makeinfo.c (cm_infoinclude): Clean up after printing error if the file couldn't be included. (discard_braces): Print errors only for those unmatched open braces that belong to a texinfo command. * */Makefile.in: Use @CFLAGS@ and @LDFLAGS@. * makeinfo/makeinfo.c: End `node_search_string' and friends with a terminating null character. Wed Jun 21 01:23:49 1995 Jim Meyering (meyering@comco.com) * makeinfo/makeinfo.c: Close comment after #endif. Tue Jun 20 04:58:26 1995 Brian Fox * emacs/Makefile.in (install): Fix typo: "fle" -> "file". * Makefile.in (VERSION): Bump to 3.6 * info/clib.c: Include general.h for `info_toupper' and friends. * info/clib.h: strncmp and strncascmp return an int. What kind of drugs was I on? Mon Jun 19 23:34:47 1995 Brian Fox * makeinfo/makeinfo.c (make_index_entries_unique): Copy the last index entry. Mon Jun 19 21:55:49 1995 Noah Friedman * util/texi2dvi (--version): New option. Cosmetic changes. Mon Jun 19 16:06:40 1995 Brian Fox * makeinfo/makeinfo.c (cm_macro): Fix typo. `x != y' is not the same as `x |= y'. * info/Makefile.in (exec_prefix): Use @exec_prefix@ not $(prefix). * makeinfo/Makefile.in (exec_prefix): Use @exec_prefix@ not $(prefix). * util/Makefile.in (exec_prefix): Use @exec_prefix@ not $(prefix). * libtxi/Makefile.in (exec_prefix): Use @exec_prefix@ not $(prefix). * emacs/Makefile.in (uninstall): New target. (install): Use the definition of $(lispdir), don't dynamically find it. Use INSTALL_DATA not cp. (exec_prefix): use @exec_prefix@ not $(prefix). * makeinfo/makeinfo.c (apply): If there isn't an actual argument for a named argument, default it to "". * Makefile.in (VERSION): Now at 3.5. (texinfo): Make ./makeinfo/makeinfo depend on sub-all for parallel makes. * emacs/Makefile.in (ELISP_OBJS): Explictly declare .el and .elc in the SUFFIXES list. * makeinfo/makeinfo.c (cm_today): Special case for losing alpha. * (minor_version): Increase to 63. * info/info.c (version_string): Now at 2.14. * info/tilde.c: Declare getenv to return (char *). * info/window.c (build_message_buffer): Jump through hoops to keep DEC Alpha's happy. * info/xmalloc.c: Declare malloc and realloc as (void *) returning functions. Sun Jun 18 12:47:21 1995 Richard Stallman * emacs/detexinfo.el (detexinfo-line-cmds-without-arg): Handle ifhtml. Fri Jun 16 13:48:14 1995 Brian Fox * util/texindex.c: Update TEXINDEX_VERSION_STRING for texinfo 3.4 * (All *.c *.h *.in): Change FSF old address to new. * texinfo.texi (Obtaining TeX): Change FSF old address to new address. Change Old phone numbers to new phone numbers. * Makefile.in (VERSION): Change to 3.4. Thu Jun 15 22:49:07 1995 Robert J. Chassell * texinfo.texi, emacs/=development/cover.texi: update Texinfo distribution package version number Thu Jun 15 09:23:02 1995 Brian J. Fox * info/info.c: (minor_version): Set to 13. * info/clib.c,h: New files gather together replacement functions for those POSIX-style C library functions that are not present on the target system. * info/Makefile.in (SRCS): Add clib.c and clib.h. makedoc now needs clib.o to build on systems missing various string.h stuff. * info/variables.c (whole file): Call strdup, not savestring. * info/tilde.c (whole file): Call strdup, not savestring. * info/search.c (whole file): Call strdup, not savestring. * info/nodes.c (whole file): Call strdup, not savestring. * info/nodemenu.c (whole file): Call strdup, not savestring. * info/man.c (whole file): Call strdup, not savestring. * info/makedoc.c (whole file): Call strdup, not savestring. * info/m-x.c (whole file): Call strdup, not savestring. * info/info.c (whole file): Call strdup, not savestring. * info/indices.c (whole file): Call strdup, not savestring. * info/echo_area.c (whole file): Call strdup, not savestring. * info/session.c (whole file): Call strdup, not savestring. * info/filesys.c (whole file): Call strdup, not savestring. * makeinfo/makeinfo.c (minor_version): Change to 1.62. * makeinfo/makeinfo.c (get_execution_string): Initialize `i' to 0 in case there are no execution_strings. Wed Jun 14 17:48:06 1995 Brian J. Fox * texinfo.texi: include "texinfo.tex", not "texinfo". * info/session.c (forget_window_and_nodes): Place a sequence point in between "info_windows[i] = info_windows[++i];" as per various compiler experts. * makeinfo/makeinfo.c (strdup): Create this function if the system doesn't have it. (discard_insertions): Use the insertion's filename, not the current input file. (push_insertion): Remember the current input file with each insertion. (pop_insertion): Free storage used by remembered input file. * makeinfo/makeinfo.c (whole file): Use `strdup' instead of `savestring'. * configure.in: Check for `strdup'. Wed Jun 14 15:58:51 1995 Brian Fox * libtxi/Makefile.in (prefix): Use @prefix@, not /usr/local/ Wed Jun 14 10:50:57 1995 Brian J. Fox * Makefile.in (DISTFILES): Don't include *.elc files in the list of files to distribute. (installdirs): Include `emacs' in the list of sub-dirs with Makefile.in's. * emacs/elisp-comp: Shell script which batch compiles the *.el files. * emacs/Makefile.in: New file contains targets to build the elc files. * configure.in: Add `emacs/Makefile' to the list of created makefiles. * makeinfo/makeinfo.c (whole file): Give every function a return type. All cm_xxx functions are now void. Add declarations for functions to top of file. Mon Jun 12 12:00:57 1995 Brian J. Fox * info/man.c (reference_section_starters): Add versions of "SEE ALSO" and "RELATED INFORMATION" with tabs instead of spaces as well. * util/texindex.c: Back out changes for OFF_T. Explicity coerce the result of lseek to a long, and use longs everywhere. * texinfo.texi: Change "@end shorttitlepage" to "@end titlepage". * makeinfo/makeinfo.c: Make @shorttitlepage ignore the rest of the line. * util/texindex.c (strrchr): Create if not present. Test for HAVE_STRCHR and HAVE_STRING_H. (main): Make PROGRAM_NAME be just the last path componenet of argv[0]. (decode_command): Rewrite. (usage): Rewrite. Now texindex handles --version. * makeinfo/makeinfo.c (make_index_entries_unique): Rewrite from scratch. * Don't distribute created info files with texinfo. After all, the user will have the tools necessary to create them, yes? * Makefile.in (distclean): Remove *.log * info/man.c (read_from_fd): Change timeout value for select to 15 seconds. Some systems (e.g., albert.ai.mit.edu) actually need more than 10 seconds to format a man page. * info/tilde.c: Fix typo in declaration for `tilde_expansion_failure_hook'. Wed Jun 7 13:36:53 1995 Brian Fox * info/tilde.h: Change type of tilde_expansion_failure_hook to a pointer to a function returning a (char *). * info/tilde.c: Change type of tilde_expansion_failure_hook to a pointer to function returning a (char *). * makeinfo/makeinfo.c (get_execution_string): Don't use `i' in the latter assignment, use `execution_strings_index' instead. * info/man.c (read_from_fd): Change logic to avoid using FIONREAD. * info/xmalloc.c (xrealloc): Use (void *), not (caddr_t *). * info/xmalloc.c (xmalloc): Use (void *), not (caddr_t *). * Makefile.in (DISTFILES): Don't find RCS no "=" directories. * util/Makefile.in (prefix): Use @prefix@ as the value. * info/Makefile.in (prefix): Use @prefix@ as the value. * makeinfo/Makefile.in (prefix): Use @prefix@ as the value. Wed Jun 7 12:29:28 1995 Robert J. Chassell * texinfo.texi: Correct minor typos. * emacs/texinfmt.el: Don't require @shorttitlepage to be inside of @iftex ... @end iftex Mon May 8 18:33:52 1995 Brian J. Fox * info/nodes.c: #include "man.h" if HANDLE_MAN_PAGES. (info_get_node_of_file_buffer): If the file buffer is one associated with manpages, call the manpage node finding function instead. (info_find_file_internal): If the file buffer is one associated with manpages, avoid doing any file I/O. (info_reload_file_buffer_contents): Ditto. (info_find_file_internal): Call create_manpage_file_buffer instead of info_load_file_internal. * info/info.c: #include "man.h" if HANDLE_MAN_PAGES. (main): If the initial node cannot be found, perhaps find it as a manpage. * info/info-utils.c: #include "man.h" if HANDLE_MAN_PAGES. (info_xrefs_of_node): If handling man pages, and this is a manpage node, use xrefs_of_manpage. * info/session.c (info_set_input_from_file): Only fclose (stream) if it is non-null and not stdin. #include "man.h" if HANDLE_MAN_PAGES. (info_menu_or_ref_item): If handling man pages, and this is a manpage node, get the xrefs from manpage_xrefs_in_binding. (info_man): Compile in for M-x man if handling man pages. (info_move_to_xref): If handling man pages, and the current node is a manpage node, use locate_manpage_xref to get xrefs. Thu May 4 08:55:23 1995 Brian J. Fox * info/info.c (main): If the output device is not a terminal, and no output filename has been specified, make user_output_filename be "-", so that the info is written to stdout, and turn on the dumping of subnodes. Thu Apr 13 18:05:06 1995 Daniel Hagerty * texinfo.texi: Fixed @end titlepage/@end shorttitlepage Sat Apr 8 12:51:49 1995 Roland McGrath * makeinfo/makeinfo.c [! HAVE_STRERROR] (strerror): New function, snarfed from ../info/filesys.c. (cm_infoinclude): Use strerror instead of sys_errlist. Tue Apr 4 18:44:00 1995 Brian J. Fox * util/texindex.c (sort_offline): Change TOTAL to be an off_t. * util/texindex.c (sort_in_core): Change TOTAL to be an off_t. * util/texindex.c (MAX_IN_CORE_SORT): Cast to off_t. Sun Apr 2 16:20:13 1995 Brian J. Fox * info/Makefile.in: Define DEFAULT_INFOPATH in case we are compiling in the current directory. * info/Makefile.in (info.o): Add filesys.h because of DEFAULT_INFOPATH. * info/(search.c,h, nodes.c info-utils.c) Use strcasecmp and strncasecmp instead of stricmp and strnicmp. Define strcasecmp and strncasecmp in search.c if !HAVE_STRCASECMP. * info/search.c: If HAVE_STRING_H include it. * info/nodes.c: If HAVE_STRING_H include it. * info/info-utils.c: If HAVE_STRING_H include it. * info/info.h: If HAVE_STRING_H include it. * configure.in (AC_HAVE_FUNCS): Check for strcasecmp. * makeinfo/makeinfo.c (strcasecmp): Define if !HAVE_STRCASECMP. * makeinfo/makeinfo.c (entire file): Use `strcasecmp' instead of `stricmp'. * makeinfo/makeinfo.c (cm_ifeq): New command takes three args. Compares first two, executes remainder if the first two are string-wise eq. * makeinfo/makeinfo.c (ifhtml): Add to command list. Shouldn't be used, but it is by people who don't want to hack macros. Sat Apr 1 09:20:14 1995 Brian J. Fox * makeinfo/makeinfo.c (begin_insertion): Fix reversed arguments to line_error. * info/info-stnd.texi: Use "end" footnote style instead of "separate". * info/Makefile.in: Change "rm -f" to $(RM). * info/general.h: Define zero_mem in terms of memset if we have it, else in terms of bzero if we have that, else as inline code. * info/NEWS: Updated to reflect changes in 2.11. Fri Mar 31 22:38:31 1995 Brian J. Fox * Makefile (DISTFILES): Don't include *.a, *orig, nor *.e files. (DISTFILES): Sat Mar 4 12:16:29 1995 Brian J. Fox * Makefile.in: Use @prefix@ instead of hardwired `/usr/local'. Clean up makefile rules which make in subdirs. (ALL_SUBDIRS): Add makeinfo/macros to list of subdirectories. * configure.in (AC_CHECK_FUNCS): Add `bcopy' to list of things to check for. Fri Mar 3 13:54:10 1995 Robert J. Chassell * texinfo.texi: Minor changes for incremental new edition 2.20. Fri Mar 3 19:01:36 1995 Brian J. Fox * filesys.c (filesys_read_info_file): Local variable ST_SIZE is a long which has the value of finfo->st_size casted to it. * nodes.c (whole file): Similar changes. These changes and the following for makedoc.c were required for proper operation on HPm68k NetBSD. Mon Feb 27 15:16:27 1995 Brian J. Fox * makedoc.c (process_one_file): Local variable FILE_SIZE is a long which has the value of finfo.st_size casted to it. Fri Mar 3 18:58:38 1995 Brian J. Fox * makeinfo.c (find_and_load): Cast fileinfo.st_size to a long for internal use. This makes things work on NetBSD. Fri Mar 3 13:54:10 1995 Robert J. Chassell * texinfo.texi: Minor changes for incremental new edition 2.20. Fri Mar 3 09:41:39 1995 Brian J. Fox * configure.in (TERMLIBS): Use AC_CHECK_LIB instead of AC_HAVE_LIBRARY. Mon Jan 9 16:55:31 1995 Brian Fox * Makefile.in (DISTFILES): Add the directory EMACS-BACKUPS to the list of things to avoid distributing. Tue Nov 29 17:48:37 1994 David J. MacKenzie * configure.in: Check for off_t. * util/texindex.c (main): Use it. Fri Nov 11 14:46:28 1994 David J. MacKenzie * configure.in: Update for Autoconf v2. Thu Oct 13 02:17:38 1994 Richard Stallman * emacs/detexinfo.el (detexinfo): Handle @!, @?, @^, @". Mon Aug 1 03:26:13 1994 Richard Stallman * texindex.c: Move the memset define down past string.h include. Tue Jun 28 14:21:43 1994 David J. MacKenzie (djm@churchy.gnu.ai.mit.edu) * makeinfo/makeinfo.c: Add --help option. (usage): Take args for stream and error code. Change callers. (print_version_info): Write to stdout, not stderr. Wed May 18 18:55:24 1994 Brian J. Fox (bfox@ai.mit.edu) * info/session.c (forget_window_and_nodes): Negate test for internal_info_node_p. We only want to free the text if it is not an internal node. Thu Mar 10 03:07:18 1994 Richard Stallman (rms@mole.gnu.ai.mit.edu) * texindex.c (memset): Fix invalid parm name (was 0). Thu Feb 10 12:56:52 1994 Noah Friedman (friedman@prep.ai.mit.edu) * makeinfo/makeinfo.c (current_item_function): Don't loop if elt is NULL. Wed Feb 9 12:21:09 1994 Brian J. Fox (bfox@ai.mit.edu) * makeinfo/makeinfo.c (minor_version): Release now at 1.60. * makeinfo/makeinfo.c (expand_filename): Additional fixes. Now when called with NULL filename, makes an output filename from the input filename. (convert_from_loaded_file): If REQUIRE_SETFILENAME is #defined (no longer the default case) then error if no @setfilename was found in the file. If REQUIRE_SETFILENAME is not #defined, the input file starts either at the first line, or at the second line if the first line contains the text "\input", and the output filename is the input file name without directory and with ".info" replacing any extension found. (convert_from_loaded_file): Fixed bug in search for first occurence of "@setfilename". Tue Feb 8 14:16:58 1994 Noah Friedman (friedman@prep.ai.mit.edu) * configure.in: Check for sys/file.h. info/dir.c, info/filesys.c, info/makedoc.c, info/nodes.c, info/session.c, info/termdep.h, makeinfo/makeinfo.c [HAVE_SYS_FILE_H]: Include . * makeinfo/makeinfo.c (convert_from_loaded_file): Print real_output_filename instead of output_filename, so user knows exactly where output file is going. Fri Jun 11 14:34:30 1993 Ian Lance Taylor (ian@cygnus.com) * configure.in: Check for sigprocmask and sigsetmask. * info/signals.h (HAVE_SIGSETMASK): Don't define. (HAVE_SIGPROCMASK): Use instead of _POSIX_VERSION. (BLOCK_SIGNAL, UNBLOCK_SIGNAL): If neither HAVE_SIGPROCMASK nor HAVE_SIGSETMASK is defined, define these to do nothing. * info/signals.c (sigprocmask): Don't compile if HAVE_SIGSETMASK is not defined. * info/terminal.c (terminal_prep_terminal): Don't clobber VINTR and VQUIT in conditionals. Mon Feb 7 18:10:22 1994 Brian J. Fox (bfox@ai.mit.edu) * makeinfo/makeinfo.c (full_pathname): Correct to really return the full pathname of the input argument. Now makeinfo /foo/bar.texi, where /foo/bar.texi contains "@setfilename bar.info", correctly leaves the output file in "./bar.info". Note that "@setfilename ../bar.info" still works; this is already an absolute pathname. Sat Feb 5 13:04:05 1994 Brian J. Fox (bfox@ai.mit.edu) * makeinfo/makeinfo.c: Version 1.59 released. * makeinfo/makeinfo.c (whole file): Large number of changes allow the "-E filename" option to be used to write a macro expanded output file. On a file which contains no @include's and no @macro's, the output file is identical to the input file. * makeinfo/makeinfo.c (declarations): Remove cm_tex (). It is never used since it is implemented with `command_name_condition'. * makeinfo/makeinfo.c (add_char): Shift braces following the current break point if we have deleted any characters. (adjust_braces_following): New function adjusts all of the markers in the brace stack which follow HERE by AMOUNT. This fixes a bug where (for example) @var{} immediately following a line break which is the end of a sentence modified the output incorrectly. Wed Feb 2 14:14:03 1994 Brian J. Fox (bfox@ai.mit.edu) * makeinfo: Version 1.58. * makeinfo/makeinfo.c (cm_node): Add extra hair to allow backtracking through execution strings. Add extra hair to allow the first node seen after a @top node is seen to adjust the sectioning level of the @top node and associated menus. Fix a few typos. Add facility for macros to invoke the original definition. This works by not allowing a single macro to recurse. Mutual recursion is also disallowed with this plan. * makeinfo/macros: New directory contains shippable macros. * makeinfo/macros/simpledoc.texi: Macros which simplify the most common uses of TeXinfo. See the example file. Macros are now a reasonable way to get people started using TeXinfo. Mon Jan 31 12:54:36 1994 Brian J. Fox (bfox@ai.mit.edu) * makeinfo/makeinfo.c (minor_version): Increase to 57. * makeinfo/makeinfo.c (cm_node): Call execute_string on the node, next, prev, and up pointers. (reader_loop): Change logic for `@bye'. No longer required at the ends of executed strings. (execute_string): Do not append `@bye' to the string to execute. * makeinfo/makeinfo.c (whole file): Use COMMAND_PREFIX instead of hardcoding `@' character in strings and searches. * makeinfo/makeinfo.c (read_command): If HAVE_MACROS is defined, then recognize and execute macros here. (CommandTable): Add "macro" and "unmacro" to table if HAVE_MACROS is defined. * makeinfo/makeinfo.c (cm_macro, cm_unmacro, execute_macro) makeinfo/makeinfo.c (get_macro_args, find_macro, add_macro) makeinfo/makeinfo.c (delete_macro, array_len, apply): New functions implement macro facility if HAVE_MACROS is defined. * makeinfo/macro.texi (new file): Examples of using the new macro facility. Mon Jan 31 10:24:52 1994 Noah Friedman (friedman@prep.ai.mit.edu) * makeinfo/makeinfo.c (executing_string): Restore global declaration. Mon Jan 24 23:48:26 1994 Noah Friedman (friedman@prep.ai.mit.edu) * texinfo.texi: Various typo fixes from Bob Chassell . Thu Jan 6 13:34:21 1994 Noah Friedman (friedman@prep.ai.mit.edu) * texinfo.texi: Turned on smallbook format and @set smallbook. Wed Dec 15 20:08:43 1993 Noah Friedman (friedman@prep.ai.mit.edu) * info/filesys.h (DEFAULT_INFOPATH): Added /usr/local/info, /opt/gnu/info, /usr/share/info, and /usr/local/share/info. Tue Dec 14 19:10:20 1993 Noah Friedman (friedman@prep.ai.mit.edu) * libtxi/Makefile.in (ALLOCA): Define from configure. Fri Dec 10 04:33:12 1993 Noah Friedman (friedman@prep.ai.mit.edu) * util/texi2dvi: Put under RCS control. Sun Dec 26 11:55:46 1993 Brian J. Fox (bfox@ai.mit.edu) * info/session.c (info_numeric_digit_arg_loop): Fix doc string. * info/infodoc.c (create_internal_info_help_node): Print out list of functions which have to keystroke equivalent if we support NAMED_FUNCTIONS. * info/filesys.c (compress_suffixes): Add ".gz" for "gunzip" to alist. * info/footnotes.c (make_footnotes_node): If refs[i] doesn't have a nodename, then it couldn't be a reference to a footnote. * info/nodemenu.c (get_visited_nodes): Handle the case where filter_func has left no possible buffers to select. Sat Dec 25 10:35:56 1993 Brian J. Fox (bfox@ai.mit.edu) * info/infodoc.c (create_internal_info_help_node): Conditionalize generation of the help node based on the #define HELP_NODE_GETS_REGENERATED. When this is not set (the default) the help node is generated exactly once, and is not gc'able. Otherwise, a new node is always created for the help window, and the old node gets garbage collected by the gc system. (info_find_or_create_help_window): Conditionalize window node selected based on the #define HELP_NODE_GETS_REGENERATED. * info/dir.c (add_menu_to_file_buffer): Place exactly one blank line between directory entries. * info/info.c (version_string): Update minor version to "11". * info/info.h: Update comment to "2.11". * info/dir.c (maybe_build_dir_node): Only add the contents of a new file if it is not identical to the file of the DIR buffer. * info/nodes.c (info_get_node): Call `maybe_build_dir_node' on "dir" as well as "localdir" to mimic emacs-19.22 "dir" merging behaviour. Fri Dec 3 13:41:44 1993 Brian J. Fox (bfox@ai.mit.edu) * info/info-utils.c (canonicalize_whitespace): Suppress whitespace found at the start of STRING. Sat Nov 20 14:00:50 1993 Brian J. Fox (bfox@hippie) * info/indices.c (DECLARE_INFO_COMMAND): Fix typo in assignment to `old_offset' (= instead of ==). Tue Nov 2 12:22:40 1993 Brian J. Fox (bfox@ai.mit.edu) * makeinfo/makeinfo.c (make_index_entries_unique): New function makes a sorted array have all unique entries by appending numbers to the ends of strings. (sort_index): Call `make_index_entries_unique'. Mon Sep 20 12:04:05 1993 Brian J. Fox (bfox@ai.mit.edu) * makeinfo/makeinfo.c (get_execution_string): New Function returns a pointer to an EXECUTION_STRING structure. (execute_string): No longer uses a static string; call `get_execution_string' instead in order to get a free buffer for consing. Sun May 23 07:00:20 1993 Noah Friedman (friedman@prep.ai.mit.edu) * Texinfo 3.1 released. Sat May 22 18:21:27 1993 Noah Friedman (friedman@prep.ai.mit.edu) * info/info.c (info_patch_level): Increment constant to 1. * info/Makefile.in (DEFAULT_INFOPATH): Default definition deleted. Makefile.in: Put it here instead. * Makefile.in (MDEFINES): Add DEFAULT_INFOPATH. * configure.in: check for vfprintf and vsprintf. * makeinfo/makeinfo.c: Version 1.55. * makeinfo/makeinfo.c (add_word_args, execute_string) [HAVE_VARARGS_H]: Don't use this definition unless HAVE_VSPRINTF is also defined. (error, line_error, warning) [HAVE_VARARGS_H]: Don't use this definition unless HAVE_VFPRINTF is also defined. Remove indentation of all cpp directives, except for #pragma. Fri May 21 14:34:24 1993 Noah Friedman (friedman@prep.ai.mit.edu) * texinfo.texi: Rename to texi.texi. Change @setfilenname and START-INFO-DIR-ENTRY to `texi.info'. * Makefile.in (MDEFINES): Pass LDFLAGS to sub-makes. (realclean): Delete `configure'. Changed all references to texinfo.info to texi.info * configure.in: Add AC_PROG_RANLIB, and AC_CONST. Check for `rindex' function. Check for varargs.h. Clean up symbol names for header files so a single AC_HAVE_HEADERS can be used. (AC_INIT): Use texi.texi instead of makeinfo/makeinfo.c * info/info-utils.h: Copy definitions of bcopy, index, and rindex (with appropriate #ifdef wrappers) from termdep.h. These are included by a mutually exclusive set of files. * info/termdep.h [HAVE_SYS_PTEM]: Use HAVE_SYS_PTEM_H instead. * info/terminal.c, info/termdep.h [HAVE_TERMIO]: Use HAVE_TERMIO_H instead. * info/makedoc.c, info/filesys.c [!O_RDONLY]: Include fcntl.h or sys/fnctl.h, depending on whether HAVE_SYS_FCNTL_H is set. * info/termdep.h: Remove all indentation in #-exprs. Remove old assumptions about bcopy, index, and rindex. [HAVE_BCOPY]: Define bcopy. [HAVE_RINDEX]: Define index and rindex. * info/nodes.c (info_get_node): Don't call stricmp if nodename is NULL. Remove indentation in #-exprs. * info/echo_area.c (echo_area_stack_depth): Declare static. * info/Makefile.in (DEFAULT_INFOPATH): Make separate Makefile variable so it can be overridden more easily by the user. Add `.' to beginning of path. (clean): Delete core.* (386bsd core files). (MAKEDOC): Variable removed. Refer to `makedoc' explicitly. (funs.h): Add `:' commands after if, to avoid spurious nonzero exit statuses. * info/userdoc.texi: Improved comments explaining its purpose. * makeinfo/makeinfo.c [HAVE_VARARGS_H]: Include varargs.h. (error, line_error, warning, add_word_args, execute_string)[HAVE_VARARGS_H]: New versions that use varargs. From bfox. * makeinfo/Makefile.in (clean): Delete core.* (386bsd core files). * util/Makefile.in (clean): Remove core.* (386bsd core files). * libtxi/Makefile.in: Remove all references to $(common). (RANLIB): New variable, set from autoconf. (libtxi.a): Use $(RANLIB) instead of `ranlib' in target rules. (clean): Delete core.* (386bsd core files). Tue May 18 12:08:24 1993 Robert J. Chassell (bob at grackle.stockbridge.ma.us) * emacs/texinfmt.el (texinfo-format-refill): Do not fill a section title line with the asterisks, hyphens, etc. that underline it in any circumstance. Sun May 16 13:53:43 1993 Noah Friedman (friedman@prep.ai.mit.edu) * util/mkinstalldirs: handle relative pathnames. Fri May 14 20:18:49 1993 Noah Friedman (friedman@prep.ai.mit.edu) * util/mkinstalldirs: initialize IFS if unset. Tue May 11 06:33:14 1993 Noah Friedman (friedman@prep.ai.mit.edu) * makeinfo/makeinfo.c (cm_item): don't dereference item_func if NULL. Mon May 10 14:50:31 1993 Noah Friedman (friedman@prep.ai.mit.edu) * Texinfo 3.0 released. * Makefile.in (ALLOCA): Provide for substitution. Mon May 10 10:12:53 1993 Noah Friedman (friedman@prep.ai.mit.edu) * emacs/texinfmt.el (texinfmt-version): Updated year. Fri Apr 16 04:48:03 1993 Noah Friedman (friedman@prep.ai.mit.edu) * makeinfo/makeinfo.c: Version 1.54 from bfox. * util/fixfonts: Replace instances of `[..]' with `test'. Use more portable `test' arguments: `z$foo = z' instead of `! $foo'. Robustify quoting in eval assignments. (textfmdir, texpkdir, texgfdir): Don't override definition from environment, if any. Trap EXIT, SIGHUP, SIGINT, SIGQUIT, SIGTERM to delete temp files instead of trying to remove them explicitly before calling exit. When changing cwd, do so in subshell, in case various tex*dir variables are relative. Don't use `head', `dirname', or `basename'. These don't behave consistently and/or don't even exist on some systems. They can all be emulated with `sed' anyway. (tempfile2_line1): New variable. Use it instead of running process to extract first line out of tempfile2 multiple times. Eliminate some gratuitous uses of $tempfile2, such as in for loops. Fri Mar 26 23:25:13 1993 Noah Friedman (friedman@prep.ai.mit.edu) * texinfo.texi: @setfilename texinfo.info. * makeinfo/makeinfo.c (reader_loop, end_insertion): Fix typos in comments. (handle_variable_internal): Handle the case that there further menu text after a false ifset/ifclear. * util/texi2dvi: Version 0.4 Replace all instances of `[ ... ]' with `test'. Updated bug-reporting address. Thu Mar 25 12:31:30 1993 Noah Friedman (friedman@prep.ai.mit.edu) * info/Makefile.in (install): Install info.1 man page. (uninstall): Remove installed info.1 man page. * info/infoman.texi: Standalone manual renamed to info-stnd.texi. Makefile.in: Targets updated appropriately. * info/Makefile.in (LDEFS): New variable. Use it for info-local macros, since DEFS will be inherited from parent make and any local definitions will get clobbered. * info/RELEASE: Renamed to info/NEWS. * README: New file. * Makefile.in (topclean): New target. * Getting-started: Renamed to INTRODUCTION. Former name is too long (over 14 chars). * New-features: Renamed to NEWS. * Makefile.in (MDEFINES): Set it. * Makefile.in (dist): Use --gzip option to tar to make sure resulting file is compressed with gzip. Change tar file extension from `.Z' to `.z'. * Makefile.in (DISTFILES): Filter out any file or directory names starting with `='. * fixfonts: Moved to util/fixfonts. * RELEASE: Deleted. * makeinfo/Makefile.in (VPATH): Use $(srcdir), not @srcdir@. (common): Use ../libtxi, not ../common. (makeinfo.in): Run makeinfo with --no-split. * makeinfo/makeinfo.texi: Changes from bob. * util/Makefile.in (VPATH): Use $(srcdir), not @srcdir@. (common): Use ../libtxi, not ../common. * util/fixfonts: Moved from top-level directory. Wed Mar 24 10:21:31 1993 Robert J. Chassell (bob at grackle) * emacs/texinfmt.el (texinfo-format-region): Do not require `@setfilename' line; delete `\input texinfo' line if part of region. * emacs/texinfmt.el (texinfo-raise-lower-sections): Raise or lower the hierarchical level of chapters, sections, etc. according to `@raisesections' and `@lowersections' commands. Thu Mar 18 16:02:27 1993 Robert J. Chassell (bob at grackle) * emacs/texinfo.el (texinfo-show-structure): Indent *Occur* buffer according to the structure of the file. Sat Mar 6 05:16:44 1993 Noah Friedman (friedman@prep.ai.mit.edu) * util/texi2dvi: use ${1+"$@"}, not just "$@". Tue Feb 2 08:38:06 1993 Noah Friedman (friedman@prep.ai.mit.edu) * info/Makefile.in: Replace all "--nosplit" arguments to makeinfo with "--no-split" Sun Jan 31 18:16:58 1993 Noah Friedman (friedman@prep.ai.mit.edu) * util/texi2dvi: Don't put .dvi and related auxillary files in same directory as source files. Put them in current directory instead. (TEXINPUTS_orig): New variable. (file_texi): Variable removed. (filename_texi): New variable. (command_line_filename): Use this wherever references to file_texi occured except in setting filename_noext. (TEXINPUTS): Current directory and source directory where input file resides prepended to standard path before invoking TeX. Wed Jan 27 16:24:37 1993 Noah Friedman (friedman@prep.ai.mit.edu) * util/Makefile.in: overhauled. Tue Jan 26 21:04:23 1993 Noah Friedman (friedman@prep.ai.mit.edu) * Makefile.in, info/Makefile.in, makeinfo/Makefile.in: Overhauled. * configure.in: Renamed from texinfo.in. Incorporated makeinfo/makeinfo.in, info/info.in, and util/util.in. Create all child Makefiles. * makeinfo/makeinfo.in, info/info.in: Deleted (incorporated into top configure.in). * util/util.in: Deleted (incorporated into ../configure.in). Mon Jan 25 10:59:49 1993 Brian Fox (bfox@cubit) * info/info.c: New version 2.9; new variable INFO_PATCH_LEVEL appears in the version string if it is non-zero. New function version_string () produces the current version string, as in 2.8-p1. * info/dir.c: New file implements Gillespies `localdir' hacks. * info/nodes.c (info_get_node): Now calls maybe_build_dir_node () if the file name to look for is "dir". * info/nodes.h: New flag N_CannotGC unconditionally prevents garbage collection of a file buffer's contents. Used when "dir" is made from at least one "localdir". Fri Jan 22 11:36:42 1993 Brian Fox (bfox@cubit) * info/footnotes.c: Do not declare auto_footnotes_p as "extern" in this file. Thu Jan 21 08:57:08 1993 Brian Fox (bfox@cubit) * info/info.c: New version 2.8. * info/userdoc.texi, info/infoman.texi, info/info.texi: Fully document Info; create both online and printed manual versions. "userdoc.texi" contains exactly the documentation for GNU Info 2.x. "infoman.texi" is a wrapper for that file; it is meant to produce printed documentation. "info.texi" has the user documentation as a complete chapter within itself, but continues to contain the Info tutorial. * info/makedoc.c: Convert "ea_" into "echo_area_" when creating the command name. Fri Jan 15 16:50:35 1993 Brian Fox (bfox@cubit) * info/search.c (skip_node_characters): New argument NEWLINES_OKAY if non-zero says that newlines should be skipped over during parsing. * info/info-utils.c (info_parse_node): New argument NEWLINES_OKAY if non-zero says that newlines should be skipped while parsing out the nodename specification. Wed Jan 13 14:42:33 1993 Brian Fox (bfox@cubit) * info/makedoc.c: Remove "info_" from the front of the command name before installing it. * info/session.c (info_menu_or_ref_item): A label of "Menu" is okay if the builder is not info_menu_of_node (); * info/m-x.c: New function replace_in_documentation () replaces \\[foo] with the keystrokes you type to get that command. Now used in indices.c, info.c, infodoc.c. Mon Jan 11 10:27:41 1993 Brian Fox (bfox@cubit) * info/variables.c, h: New files contain describe-variable and stuff moved out of m-x.c. * info/m-x.c: Move VARIABLE_ALIST and variable functions into variables.c. Add documentation string to variable definition. * info/echo_area.c (push_echo_area): Zero the contents of echo_area_completion_items after pushing the vars. Sat Jan 9 11:59:47 1993 Brian Fox (bfox@cubit) * info/Makefile.in: Add footnotes.c,h,o to the appropriate Makefile variables. * info/window.c (window_tile_windows): New function divides the available space among the visible windows. * info/session.c (info_tile_windows): New function calls window_tile_windows. * info/footnotes.c, footnotes.h: New file implements functions for aiding automatic footnote display when entering a node which has footnotes. * info/m-x.c: New user-variable "automatic-footnotes". * info/window.c (window_physical_lines) New function counts the carriage returns found in NODE. Wed Jan 6 11:24:19 1993 Brian Fox (bfox@cubit) * info/general.h: #include if we have it. Tue Jan 5 11:12:33 1993 Brian Fox (bfox@cubit) * info/info-utils.c (info_concatenate_references): If either arg is NULL, return the other arg. * info/indices.c (info_indices_of_file_buffer): Simplified and corrected loop through tags/nodes of file buffer looking for indices. * info/search.c (skip_node_characters): Rewrite "if" statement for clarification and conciseness. Fri Jan 1 03:18:26 1993 Brian Fox (bfox@cubit) * info/info.in: Check for setvbuf (), and check to see whether the args are reversed. * info/dribble.c (open_dribble_file) Check HAVE_SETVBUF and SETVBUF_REVERSED when setting the buffering on info_dribble_file. Thu Dec 31 20:14:13 1992 Brian Fox (bfox@cubit) * info/session.c (info_select_reference) If the node couldn't be found, look for the label as a filename (i.e., "(LABEL)Top"). Wed Dec 30 01:57:50 1992 Brian Fox (bfox@cubit) * New Version 2.7 Beta. * info/echo_area.c: Numerous functions now do something with the numeric argument. Kill ring implemented, as well as yank and yank_pop. Also transpose-chars. * info/window.c (window_make_modeline): Check node->flags for N_IsCompressed and display "zz" in the modeline if the node comes from a file which is compressed on disk. Mon Dec 28 17:33:12 1992 Brian Fox (bfox@cubit) * info/filesys.c, info/nodes.c: New member of FILE_BUFFER "FILESIZE" contains the size of file_buffer->contents. finfo.st_size is no longer relied upon to read the contents of files, since the new function (filesys_read_info_file) can read compressed files. * info/filesys.c (info_find_fullpath) If a file starts with a slash (or tilde expansion causes it to start with a slash) still call info_find_file_in_path () on it so that we can find files with compression suffixes. * info/m-x.c: New variable "gc-compressed-files". Tue Dec 22 03:45:28 1992 Brian Fox (bfox@cubit) * info/info.c: Version 2.6 Beta. * info/indices.c (info_index_next): Improve the final search for the matched index entry. * info/session.c (move_to_screen_line): New function implements `M-r'. Given a numeric argument, move point to the start of that line in the current window; without an arg, move to the center line. * infomap.c: Put move_to_screen_line () on `M-r'. * info/nodes.c (adjust_nodestart): Don't set N_UpdateTags unless the node came from a tags table. * info/nodes.c (info_find_file_internal): If the filename being looked for doesn't start with a `/', then additionally compare the filename against the fullpath of the file buffer sans the directory name. This can happen when selecting nodemenu items. Mon Dec 21 10:07:18 1992 Brian Fox (bfox@cubit) * info/session.c, info/display.c: Remove all references to active_window_ch, active_window_cv, cursor_h, and cursor_v. The single function display_cursor_at_point () is used for all cursor movement, and to place the terminal's cursor at the right location on the screen. Sat Dec 19 12:01:33 1992 Brian Fox (bfox@cubit) * info/nodemenu.c: New file implements a few functions for manipulating previously visited nodes. `list-visited-nodes' produces a menu of the nodes that could be reached by info_history_node () in some window. `select-visited-node' is similar to `list-visited-node' followed by `info-menu-item', but doesn't display a window with the visited nodes menu. * info/session.c (info_numeric_arg_digit_loop): If redisplay had been interrupted, then redisplay all of the windows while waiting for input. * info/display.c (display_was_interrupted_p): New variable keeps track of interrupted display. Used in info/session.c:info_numeric_arg_digit_loop (). * info/session.c (info_global_next, info_global_prev): Use the numeric argument passed to determine how many nodes to move. * info/session.c (info_scroll_forward, info_scroll_backward): If the invoking key is not SPC or DEL only do Page Only scrolling. Thu Dec 17 01:34:22 1992 Brian Fox (bfox@cubit) * info/display.c (display_update_one_window): Allow W_NoWrap to affect window display. * info/window.c (calculate_line_starts): Now takes a WINDOW * as an argument, and simply does the calculation, placing the results into window->line_starts and window->line_count. It also handles W_NoWrap in window->flags. Mon Dec 14 02:18:55 1992 Brian Fox (bfox@cubit) * info/session.c (info_backward_scroll): Don't try to get previous node if the top of the node isn't currently being displayed. * info/window.c (window_adjust_pagetop) Use new variable "window_scroll_step" to attempt to control the amount which the window scrolls. * info/m-x.c (info_variables) Add "scroll-step" to the list. Thu Dec 10 08:52:10 1992 Brian Fox (bfox@cubit) * info/m-x.c: New variable entry show-index-matches. When set to non-zero the matched portion of the search string is indicated with ` and '. Perhaps I should use `|' inst|ea|d? * info/echo_area.c (ea_possible_completions): Always build completions before checking to see how many there were. * info/info-utils.c: (info_concatenate_references): New utility function concatenates references. * info/Makefile.in: Add indices.c and indices.h to SRCS and HDRS. Add indices.c to CMDFILES. * info/indices.c, info/indices.h: New file implements `i' and `,' commands of info, and provides index searching capabilities. * info/echo_area.c (info_read_completing_in_echo_area): Split off into separate callable function info_read_completing_internal (). * info/echo_area.c (info_read_maybe_completing): New function calls info_read_completing_internal () with non-forcing argument. * info/session.c: Rename down_next_upnext_or_error () and prev_up_or_error () to forward_move_node_structure (), and backward_move_node_structure (). Implement new commands info_global_next () and info_global_prev (). * info/infomap.c (initialize_info_keymaps): Bind `[' and `]' to backward_, forward_move_node_structure () respectively. * info/session.c (info_menu_digit): Called with "0" as arg, select the last menu item. * info/infomap.c (initialize_info_keymaps): "0" calls info_menu_digit (). * info/session.c (info_move_to_xref): Take dir into account when there are xrefs and menu items in the node and we are wrapping backwards. Tue Dec 8 09:57:58 1992 Brian Fox (bfox@cubit) * info/info.c: Version 2.5 Beta. * info/terminal.c (terminal_insert_lines, terminal_delete_lines) Do not expect tgoto to return a new string; it returns the address of a static buffer. * info/infodoc.c (info_find_or_create_help_window) Correct check for prior existing help node. * info/m-x.c (set_variable): Allow variables to have a list of choices. Add new variable scroll-behaviour. * info/session.c (down_next_upnext_or_error, prev_up_or_error) New functions implement user-controlled behaviour when attempting to scroll past the bottom or top of a node. New variable info_scroll_behaviour is user visible as "scroll-behaviour". * info/session.c (info_scroll_forward, info_scroll_backward) Call new functions for user-controlled scroll behaviour. * info/terminal.c (terminal_initialize_terminal) Set PC from BC not from BUFFER. Mon Dec 7 11:26:12 1992 Brian Fox (bfox@cubit) * util/texindex.c: Change EXIT_SUCCESS and EXIT_FATAL to TI_NO_ERROR and TI_FATAL_ERROR respectively. This avoids namespace conflicts on NeXT 2.0. Sat Dec 5 00:07:59 1992 Brian Fox (bfox@cubit) * info/info.c: New option "--subnodes" says to recursively dump the menus of the nodes that you wish to dump. Menu items which point to external nodes are not dumped, and no node is dumped twice. Thu Dec 3 16:11:02 1992 Brian Fox (bfox@cubit) * info/session.c (info_error) Don't ring the bell if info_error_rings_bell_p is zero. (info_abort_key) Ring the bell if printing "Quit" in the echo area wouldn't do it. * info/m-x.c (set_variable) New functions allows setting of variables in the echo area. Currently, only visilble-bell and errors-ring-bell are implemented. Wed Dec 2 13:11:37 1992 Brian Fox (bfox@cubit) * info/nodes.c, info/makedoc.c: If O_RDONLY is not defined by sys/file.h, include sys/fcntl.h. * info/filesys.c (info_file_in_path): Expand leading tildes found within directory names. * info/terminal.c (terminal_initialize_terminal) Set ospeed to 13 if not settable any other way. It is an index into an array of output speeds. * info/display.c (free_display) Do not free a NULL display. * info/display.c (string_width): New functions returns the width of STRING when printed at HPOS. Sun Nov 29 01:24:42 1992 Brian Fox (bfox@cubit) * info/info.c: New version 2.4 beta. * info/general.h: #define info_toupper and info_tolower which check their arguments before performing any conversion. * info/search.c, info/echo_area.c: Use info_toupper. Sat Nov 28 14:23:24 1992 Brian Fox (bfox@cubit) * info/session.c (info_scroll_forward, info_scroll_backward) If at last/first page of the node, and the last command was forward/backward, do info_next/prev/_node. * info/session.c: New function info_select_reference_this_line gets menu or cross reference immediately. * info/infomap.c (initialize_info_keymaps): Add info_keymap[LFD] to invoke info_select_reference_this_line (). * info/session.c (info_last_reference) Rename to info_history_reference. Wrote info_last_reference, and info_first_reference which go to the last or first node of an info file. Fri Nov 27 00:59:02 1992 Brian Fox (bfox@cubit) * info/info.c: New version 2.3. Completed implementing contents of TODO file. * info/session.c (info_redraw_display): Fix C-l with numeric arg. Thu Nov 26 20:14:18 1992 Brian Fox (bfox@cubit) * info/m-x.c: New file implements reading named commands in the echo area, along with a new function "info-set-screen-height". Compilation of this file and some code in others controlled by the Makefile variable NAMED_COMMANDS (set to -DNAMED_COMMANDS). * info/window.c (window_new_screen_size) Rewrite from scratch, allowing clean growth and shrinkage of the screen. New variable window_deletion_notifier is a pointer to a function to call when the screen changes size, and some windows have to get deleted. The function is called with the window to be deleted as an argument, and it should clean up dangling references to that window. * info/session.c (initialize_info_session): Set window_deletion_function to forget_window_and_nodes. * info/display.c (display_update_one_window): If the first row of the window to display wouldn't appear in the_screen, don't try to display it. This happens when the screen has been made unreasonably small, and we attempt to display the echo area. Tue Nov 24 00:47:20 1992 Brian Fox (bfox@cubit) * Release Info 2.2. * info/session.c: New functions implement reading typeahead and implement C-g flushing typed ahead characters. (info_search_internal): allows C-g to exit multi-file searches. Mon Nov 23 01:53:35 1992 Brian Fox (bfox@cubit) * info/nodes.c: Remove calls to sscanf (), replacing them with calls to atol (), since that is much faster. (get_nodes_of_tags_table) Only check for "(Indirect)" if we haven't parsed any nodes out of the tags table. Increase the amount that file_buffer->nodes grows to 100 from 50. These two together sufficiently speed up the parsing process. * info/nodes.c: info_get_node_of_file_buffer_tags (), info_get_node_of_file_buffer_nodes (): Search the appropriate list and return a node. This was simply a cut and paste edit to functionalize the code. * info/TODO: Remove suggestion for partial tag parsing, since tag parsing is much faster now. Sat Nov 21 02:48:23 1992 Brian Fox (bfox@cubit) * info/makedoc.c: New File replaces makedoc.sh shell script. * info/infomap.c: Install info_isearch (on C-s) and info_reverse_isearch (on C-r) for Info windows. * info/session.c (incremental_search, info_isearch, info_reverse_isearch) New functions implement incremental searching. Fri Nov 20 00:01:35 1992 Brian Fox (bfox@cubit) * info/terminal.c (terminal_initialize_terminal): Declare and set up `ospeed'. Turn off C-s and C-q processing. * info/session.c (info_show_point) When this function is called, the desired result is to show the point immediately. So now it calls set_window_pagetop () if the new pagetop is not the same as the old one. This means that info_prev_line (), info_next_line (), info_forward_word (), and info_backward_word () can all scroll the window if they have to. Thu Nov 19 12:27:07 1992 Brian Fox (bfox@cubit) * info/session.c (set_window_pagetop): Add scrolling to make this faster. * info/echo_area.c (push/pop_echo_area): Remember the list of items to complete over. * info/session.c (info_forward_char): Don't let point get equal to nodelen, only to nodelen - 1. * info/display.c: New function display_scroll_display () scrolls the rmembered display as well as the text on the actual display. * info/terminal.c: New functions terminal_scroll_terminal (), terminal_scroll_down (), and terminal_scroll_up (). All implemented using "al" and "dl" termcap capabilities. (i.e., insert and delete line). Wed Nov 18 15:05:14 1992 Brian Fox (bfox@cubit) * info/termdep.h: Only define HAVE_FCNTL_H if !aix and !ultrix. Tue Nov 17 20:35:08 1992 Brian Fox (bfox@cubit) * First Beta Release of Info 2.0. Sun Nov 1 02:21:05 1992 Noah Friedman (friedman@prep.ai.mit.edu) * util/texi2dvi (--force): Option removed. Always run tex at least once, don't bother checking if .dvi file is newer than source. Fri Oct 30 02:16:28 1992 Noah Friedman (friedman@prep.ai.mit.edu) * util/texi2dvi (-D): debugging option renamed from '-d'. Made check to enable debugging more terse. When checking if index files have changed, use variable $this_file instead of $file in for loop. (file_texi): wherever the variable $file was used to reference the texinfo file, substituted $file_texi. Sat Oct 17 07:30:34 1992 Brian J. Fox (bfox@helios) * util/texindex.c: Remove references to USG replacing them with a define declaring the actual feature required or missing. Thu Oct 15 16:17:47 1992 Robert J. Chassell (bob@nutrimat.gnu.ai.mit.edu) * emacs/texinfmt.el (texinfo-format-setfilename): Remove date from Info file header so regression testing is easier. Tue Sep 15 16:28:35 1992 Robert J. Chassell (bob at grackle) * emacs/texinfmt.el (texinfmt-version): New variable. (texinfo-format-setfilename): Include date and version in Info file header. Better documentation for @definfoenclose Handle whitespace after @end iftex, etc. Thu Sep 3 09:25:37 1992 Robert J. Chassell (bob at grackle) * emacs/texnfo-upd.el: Fix typo re `texinfo-sequential-node-update.' Tue Aug 18 08:56:24 1992 Robert J. Chassell (bob at grackle) * emacs/texinfmt.el (texinfo-value): Revise syntax. * emacs/texnfo-upd.el (texinfo-start-menu-description): New function to insert title as description in a menu. (texinfo-make-menu-list): Remove automatic title insertion. * emacs/texinfo.el (texinfo-mode-map): Add keybinding for texinfo-start-menu-description. Wed Jul 29 11:58:53 1992 Robert J. Chassell (bob at grackle) * emacs/texinfmt.el (texinfo-set): Revise to set a string to the flag. (texinfo-value): @value{flag}: New command which inserts the string to which the flag is set. Tue Jul 7 15:10:52 1992 Robert J. Chassell (bob at grackle) * emacs/texnfo-upd.el (texinfo-master-menu): Error message if file contains too few nodes for a master menu. (texinfo-insert-master-menu-list): Only attempt to insert detailed master menu if there is one. Wed Jun 10 15:26:18 1992 Robert J. Chassell (bob at grackle) * emacs/texinfmt.el (texinfo-append-refill): Refill properly when lines begin with within-paragraph @-commands. Tue Jun 9 12:28:11 1992 Robert J. Chassell (bob at grackle) * emacs/texinfmt.el: Add `texinfo-deffn-formatting-property' and `texinfo-defun-indexing-property' to @deffn commands. Mon Jun 8 11:52:01 1992 Robert J. Chassell (bob at grackle) * emacs/texnfo-upd.el: Replace `(mark-whole-buffer)' with `(push-mark (point-max) t) (goto-char (point-min))' to avoid `Mark set' messages. Fri Jun 5 15:15:16 1992 Robert J. Chassell (bob@kropotkin.gnu.ai.mit.edu) * emacs/texnfo-upd.el (texinfo-check-for-node-name): Offer section title as prompt. (texinfo-copy-next-section-title): Copy title correctly. Thu May 28 20:34:17 1992 Robert J. Chassell (bob@hill.gnu.ai.mit.edu) * emacs/texinfmt.el: @vtable defined, parallel to @ftable, for variables. (texinfo-append-refill): set case-fold-search nil so @TeX is not confused with @tex. Thu Mar 26 21:36:41 1992 Robert J. Chassell (bob@kropotkin.gnu.ai.mit.edu) * emacs/makeinfo.el: Rename temp buffer from `*Makeinfo*' back to `*compilation*' so `next-error' works; unfortunately, `*compilation*' is written into the code as the name `next-error' needs. Rename `makeinfo-recenter-makeinfo-buffer' back to `makeinfo-recenter-makeinfo-buffer' Thu May 14 21:14:25 1992 Noah Friedman (friedman@prep.ai.mit.edu) * util/fixfonts: Enclosed most variable references with "" to prevent potential globbing and other weirdness. Eliminated uses of ${var-value}, which unfortunately isn't portable. * util/texi2dvi: rewritten from scratch. Sat Apr 18 23:46:25 1992 Charles Hannum (mycroft@hal.gnu.ai.mit.edu) * util/fixfonts: Re-evaluate prefix and libdir if inherited (to resolve variable references from make). (texlibdir): Don't add '/tex', since it's already there. Fri Apr 10 14:51:23 1992 Noah Friedman (friedman@prep.ai.mit.edu) * util/fixfonts: set prefix and libdir only if they are not already defined (i.e. not inherited from the environment). Changed default path for libdir to be consistent with Makefile. Tue Mar 3 13:17:42 1992 Robert J. Chassell (bob at grackle) * emacs/texnfo-upd.el (texinfo-insert-master-menu-list): Insert a master menu only after `Top' node and before next node. (texinfo-copy-menu): Error message if menu empty. Mon Feb 24 15:47:49 1992 Robert J. Chassell (bob at grackle) * emacs/texinfmt.el (texinfo-format-region): Make sure region ends in a newline. (texinfo-itemize-item): Recognize all non-whitespace on same line as @item command. Sat Feb 22 02:15:00 1992 Brian Fox (bfox at gnuwest.fsf.org) * util/texindex.c: New version 1.45 has cleanups, should compile under VMS quietly. Wed Feb 12 10:50:51 1992 Robert J. Chassell (bob at grackle) * emacs/makeinfo.el: Rename temp buffer as *Makeinfo*. Rename `makeinfo-recenter-compilation-buffer'. (makeinfo-buffer): Offer to save buffer if it is modified. (makeinfo-compile): Do not offer to save other buffers. (makeinfo-compilation-sentinel): Switch to Info file. Tue Feb 4 13:07:39 1992 Robert J. Chassell (bob at grackle) * emacs/texinfmt.el (texinfo-print-index): Format so that node names in the index are lined up. Mon Feb 3 09:08:14 1992 Robert J. Chassell (bob at grackle) * emacs/texinfmt.el (texinfo-itemize-item): Format entry when text is on the same line as @item command. Also, handle @-commands. (texinfo-format-region, texinfo-format-buffer-1): Set fill column to local value of Texinfo buffer. * emacs/texnfo-upd.el (texinfo-pointer-name): Find only those section commands that are accompanied by `@node' lines. Tue Jan 14 16:10:16 1992 Robert J. Chassell (bob at grackle) * emacs/texnfo-upd.el: Ensure that no commands depend on the value of case-fold-search. Fri Jan 10 15:13:55 1992 Robert J. Chassell (bob at kropotkin) * emacs/texinfmt.el (texinfo-append-refill): Replace use of unsupported function `looking-at-backward' with `re-search-backward'. Mon Dec 23 23:46:42 1991 David J. MacKenzie (djm at wookumz.gnu.ai.mit.edu) * util/texindex.c: Change POSIX ifdefs to HAVE_UNISTD_H and _POSIX_VERSION. Mon Dec 16 15:01:36 1991 Robert J. Chassell (bob at grackle) * emacs/texinfmt.el (texinfo-append-refill): New function appends @refill to all appropriate paragraphs so you no longer need to append @refill command yourself. (texinfo-format-region, texinfo-format-buffer-1, texinfo-format-include): Call `texinfo-append-refill'. Fri Dec 6 01:25:09 1991 David J. MacKenzie (djm at wookumz.gnu.ai.mit.edu) * util/texindex.c: Conditionalize on _AIX (which is predefined) instead of AIX, just like makeinfo does. Tue Nov 26 10:21:04 1991 Robert J. Chassell (bob at grackle) * emacs/texnfo-upd.el (texinfo-section-types-regexp): `@subtitle' no longer treated as subsection. Sat Nov 16 08:27:42 1991 Richard Stallman (rms at mole.gnu.ai.mit.edu) * util/fixfonts: New file, from Karl Berry. Tue Nov 12 16:13:24 1991 Robert J. Chassell (bob at grackle) * emacs/texinfmt.el: Create @end smalllisp. Mon Nov 11 16:50:13 1991 Robert J. Chassell (bob at grackle) * emacs/texinfo.el (texinfo-environment-regexp): Add all other block enclosing Texinfo commands. Thu Nov 7 10:23:51 1991 Robert J. Chassell (bob at grackle) * emacs/texinfo.el (texinfo-insert-@end): Attempt to insert correct end command statement, eg, @end table. Fails with nested lists. (texinfo-insert-*): Accept prefix arg to surround following N words with braces for command. Thu Oct 31 21:31:41 1991 Robert J. Chassell (bob at kropotki) * emacs/texinfmt.el (texinfo-clear): Clear flag even if flag not previously set. Wed Oct 23 11:15:58 1991 Robert J. Chassell (bob at grackle) * emacs/texinfo.el (texinfo-mode): page-delimiter now finds top node as well as chapters. Tue Oct 22 11:46:12 1991 Robert J. Chassell (bob at grackle) * emacs/texinfmt.el (texinfo-do-flushright): Test whether a line is too long for the flush right command (line length must be less than the value of fill column). * emacs/texnfo-tex.el (texinfo-tex-buffer): Prompt for original file even if point moved to *texinfo-tex-shell*. texinfo-tex-original-file: variable to hold file name. Wed Oct 16 08:32:05 1991 Robert J. Chassell (bob at grackle) * emacs/texinfmt.el (texinfo-format-center): Expand string before centering so @-commands not included. Thu Oct 10 22:01:47 1991 Robert J. Chassell (bob at kropotki) * emacs/texnfo-tex.el (texinfo-show-tex-print-queue): Do not kill a running process; do start a process none exists. Thu Sep 26 21:58:47 1991 Robert J. Chassell (bob at kropotki) * util/texi2dvi: Misc. bugs fixed. * emacs/texinfo.el: Remove extraneous references to TeX. Thu Sep 19 20:45:29 1991 Robert J. Chassell (bob at kropotki) * emacs/texinfmt.el: add @cartouche as a noop (makes box with rounded corners in TeX) Tue Sep 10 20:44:57 1991 Robert J. Chassell (bob at grackle) * emacs/texnfo-upd.el (texinfo-make-one-menu): Copy node-name correctly for message. Thu Aug 29 17:54:07 1991 Robert J. Chassell (bob at kropotki) * emacs/texnfo-tex.el (texinfo-quit-tex-job): Do not set mark. Wed Aug 21 10:36:21 1991 Robert J. Chassell (bob at grackle) * emacs/texnfo-upd.el: (texinfo-copy-menu-title): Copy title as it should rather than node line. Mon Aug 5 15:27:12 1991 Robert J. Chassell (bob at grackle) * emacs/texinfmt.el (texinfo-format-convert): Changed regexp that looks for three hyphens in a row to find those between word constituent characters, as now, for Oxford Univ. style dashes and also between spaces, for Cambridge Univ. Press style dashes. * emacs/texnfo-tex.el (texinfo-tex-start-shell): Runs "/bin/sh" so `explicit-shell-file-name' is not set globally. * emacs/texnfo-upd.el: Rewrite messages. (texinfo-find-higher-level-node): Stop search at limit. (texinfo-copy-menu-title): Rewrite to handle outer include files. (texinfo-multi-file-update): Update all nodes properly; rewrite doc string and interactive. Sat Aug 3 10:46:13 1991 Robert J. Chassell (bob at grackle) * emacs/texnfo-upd.el (texinfo-all-menus-update): Fixed typo that caused the function to create a master menu when it shouldn't. * emacs/texinfo.el (texinfo-mode): Make `indent-tabs-mode' a local variable and set to nil to prevent TABs troubles with TeX. Wed Jul 31 11:07:08 1991 Robert J. Chassell (bob at grackle) * emacs/texnfo-tex.el (texinfo-quit-tex-job): New function: quit currently running TeX job, by sending an `x' to it. (texinfo-tex-shell-sentinel): New function to restart texinfo-tex-shell after it is killed. (texinfo-kill-tex-job): Rewrite to use kill-process rather than quit-process; uses `texinfo-tex-shell-sentinel' to restart texinfo-tex-shell after it is killed. (texinfo-tex-region, texinfo-tex-buffer): Replace texinfo-kill-tex-job with quit-process. * emacs/texinfo.el (texinfo-define-common-keys): Add keybinding for texinfo-quit-tex-job Wed Jul 10 15:15:03 1991 Robert J. Chassell (bob at grackle) * emacs/texinfmt.el: New commands @set, @clear, @ifset...@end ifset, and @ifclear...@end ifclear. Definition functions rewritten to make them easier to maintain. Wed Jul 3 19:37:04 1991 Robert J. Chassell (bob at kropotki) * emacs/texinfmt.el (texinfo-format-deftypefn-index): Remove reference to data-type to make consistent with texinfo.tex and makeinfo. texinfo.el: Fix page-delimiter and texinfo-chapter-level-regexp variables. Thu Jun 27 18:35:36 1991 Robert J. Chassell (bob at nutrimat) * emacs/texinfmt.el: Add @dmn as `texinfo-format-noop'. texinfo2.texi: Document @dmn. texinfmt.el (texinfo{,-end}-{eleterate,ecapitate} renamed {alphaenumerate, capsenumerate}. Fri Jun 14 12:46:32 1991 Robert J. Chassell (bob at churchy.gnu.ai.mit.edu) * emacs/texinfmt.el (texinfo-format-defun-1): @defivar prints name correctly. Thu Jun 6 21:38:33 1991 Robert J. Chassell (bob at churchy.gnu.ai.mit.edu) * emacs/texinfo.el (texinfo-mode): Set page delimiter to 'texinfo-chapter-level-regexp' so that page commands work by chapter or equivalent. * emacs/texinfmt.el (texinfo-format-defun-1): @defop prints name correctly. (batch-texinfo-format): replace unsupported 'buffer-disable-undo' with 'buffer-flush-undo' Fri Apr 5 15:17:17 1991 Robert J. Chassell (bob at wookumz.gnu.ai.mit.edu) * emacs/makeinfo.el (makeinfo-compilation-sentinel): Check for existance of makeinfo-temp-file to avoid harmless error message. texinfo2.texi: Minor typos fixed. Thu Mar 28 19:13:24 1991 Robert J. Chassell (bob at pogo.gnu.ai.mit.edu) * util/texi2dvi: Revised. Mon Mar 11 12:35:51 1991 Robert J. Chassell (bob at grackle) * emacs/texinfmt.el: (@footnotestyle): New command to set footnotestyle. (@paragraphindent): New command to set indentation. (texinfo-format-refill): Add indentation feature so as to indent paragraph or leave indentation asis before refilling according to value set by @paragraphindent command. (texinfo-format-region): Insert header, if any, into Info buffer. (texinfo-format-separate-node, texinfo-format-end-node): Run texinfo-format-scan on footnote text only once. (texinfo-format-scan): Shorten `---' to `--'. * emacs/texinfo.el: Define key for `texinfo-master-menu'; define start and end of header expressions. * emacs/texnfo-upd.el (texinfo-all-menus-update): Update pre-existing master menu, if there is one. Fri May 11 14:36:07 1990 Richard Stallman (rms at sugar-bombs.ai.mit.edu) * util/texindex.c: Rename `lines' to `nlines'. (bzero): Pass arg to lib$movc5 through non-register var. (perror_with_file, pfatal_with_file): Move extern decls and includes to top of file. [VMS]: If not using VMS C, define away `noshare' keyword. Include perror.h. Mon Jul 11 18:02:29 1988 Chris Hanson (cph at kleph) * util/texindex.c (indexify): when comparing to initial strings to decide whether to change the header, must use `strncmp' to avoid comparing entire strings of which initials are a substring. Sun Jun 26 18:46:16 1988 Richard Stallman (rms at sugar-bombs.ai.mit.edu) * util/texindex.c (sort_in_core, sort_offline, parsefile): Give up on input file if any line doesn't start with backslash. texinfo-3.12/COPYING0000664000175000017500000004310506335446443011424 0ustar gg GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy 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 Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. texinfo-3.12/mkinstalldirs0000755000175000017500000000133406350602146013162 0ustar gg#! /bin/sh # mkinstalldirs --- make directory hierarchy # Author: Noah Friedman # Created: 1993-05-16 # Public domain # $Id: mkinstalldirs,v 1.10 1996/05/03 07:37:52 friedman Exp $ errstatus=0 for file do set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` shift pathcomp= for d do pathcomp="$pathcomp$d" case "$pathcomp" in -* ) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" 1>&2 mkdir "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then errstatus=$lasterr fi fi pathcomp="$pathcomp/" done done exit $errstatus # mkinstalldirs ends here texinfo-3.12/dir-example0000444000175000017500000004231406475630120012510 0ustar ggThis 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. If you have dir entries for Texinfo manuals you'd like to be added here, please send them to karl@gnu.org. $Id: dir,v 1.9 1998/02/27 21:29:52 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: GNU packages * Bash: (bash). Bourne-Again SHell. * Cpio: (cpio). Copy-in-copy-out archiver. * DC: (dc). Postfix desk calculator. * Diff: (diff). Comparing and merging programs. * Ed: (ed). Line editor. * Emacs: (emacs). Extensible self-documenting text editor. * File utilities: (fileutils). GNU file utilities. * Finding files: (find). Operating on files matching certain criteria. * Font utilities: (fontu). Programs for font manipulation. * Gawk: (gawk.info). A text scanning and processing language. * Gcal: (gcal). GNU calendar program. * Gzip: (gzip). General (de)compression. * Identifier DB: (id-utils). Identifier database utilities. * Ispell: (ispell). Interactive spelling corrector. * M4: (m4). Macro processor. * Make: (make). Remake files automatically. * Ptx: (ptx). Permuted index generator. * Shar: (sharutils). Shell archiver, uudecode/uuencode. * Shell utilities: (sh-utils). GNU shell utilities. * tar: (tar). Making tape (or disk) archives. * Text utilities: (textutils). GNU text utilities. * Time: (time). Measuring program resource usage. * UUCP: (uucp). Copying between machines, offline. * Wdiff: (wdiff). Word-by-word comparison. * Wget: (wget). URL download. GNU programming tools * As: (as). Assembler. * Binutils: (binutils). ar/copy/objdump/nm/size/strip/ranlib. * Bison: (bison). LALR(1) parser generator. * CPP: (cpp). C preprocessor. * CVS: (cvs). Concurrent versions system for source control. * DejaGnu: (dejagnu). Testing framework. * Flex: (flex). A fast scanner generator. * Gasp: (gasp). GNU Assembler preprocessor. * Libtool: (libtool). Generic library support script. * GCC: (gcc). C compiler. * GDB: (gdb). Source-level debugger for C and C++. * Gettext Utilities: (gettext). GNU gettext utilities. * Gperf: (gperf). Perfect hash function generator. * Gprof: (gprof). Profiler. * Indent: (indent). Prettyprinter for programs. * Ld: (ld). Linker. Texinfo documentation system * Info: (info). Documentation browsing system. * Texinfo: (texinfo). The GNU documentation format. * info program: (info-stnd). Standalone Info-reading program. * install-info: (texinfo)Invoking install-info. Updating info/dir entries. * texi2dvi: (texinfo)Format with texi2dvi. Printing Texinfo documentation. * texindex: (texinfo)Format with tex/texindex. Sorting Texinfo index files. * makeinfo: (texinfo)makeinfo preferred. Translate Texinfo source. GNU Emacs Lisp * Elisp: (elisp). GNU Emacs Lisp reference manual. * Intro Elisp: (emacs-lisp-intro). Introduction to Elisp programming. * AUC TeX: (auctex). Editing (La)TeX files. * Calc: (calc). Calculator and more. * CC mode: (cc-mode). Editing C, C++, Objective C, and Java. * Common Lisp: (cl). Partial Common Lisp support for Emacs Lisp. * Dired-x: (dired-x). Extra directory editor features. * Edebug: (edebug). Source-level debugger for Emacs Lisp. * Ediff: (ediff). Comprehensive visual interface to diff & patch. * EDB: (edb). Database for Emacs. * Forms: (forms). Fill-in-the-form data entry. * Gmhist: (gmhist). Generic minibuffer history. * GNUS: (gnus). Netnews reading and posting. * Mailcrypt: (mailcrypt). Use PGP in Emacs. * MH-E: (mh-e). Emacs interface to the MH mail system. * PCL-CVS: (pcl-cvs). Emacs front end to CVS. * Supercite: (sc). Supercite for including other people's words. * VIP: (vip). vi emulation. * VIPER: (viper). The new VI-emulation mode in Emacs-19.29. * VM: (vm). Mail reader. * W3: (w3). WWW browser. GNU programming support * Autoconf: (autoconf). Automatic generation of package configuration. * Configure: (configure). Cygnus configure. * Gnats: (gnats). Cygnus bug tracking system. * Remsync: (remsync). Remote synchronization of directory trees. * Send PR: (send-pr). Cygnus bug reporting for Gnats. GNU libraries * Annotate: (annotate). High-level GDB to GUI's. * BFD: (bfd). Binary file descriptors for object file IO. * GDB library: (libgdb). Application programming interface to GDB. * GDBM: (gdbm). Hashed databases. * History: (history). Recall previous lines of input. * Iostream: (iostream). C++ input/output. * Libc: (libc). C library. * Libg++: (libg++). C++ classes. * Mmalloc: (mmalloc). Memory-mapped malloc. * Readline: (readline). General command-line interface. * Regex: (regex). Regular expressions. * Termcap: (termcap). All about /etc/termcap. GNU programming documentation * GDB internals: (gdbint). Debugger internals. * Ld internals: (ldint). GNU linker internals. * Maintaining: (maintain). Maintaining GNU software. * Source config: (cfg-paper). Some theory on configuring source packages. * Stabs: (stabs). Symbol table debugging information format. * Standards: (standards). GNU coding standards. Linux * dosemu: (dosemu). Linux DOS emulator. * gpm: (gpm). Linux general purpose mouse interface. * linux-faq: (linux-faq). The Linux FAQ List TeX things * Afm2tfm: (dvips)Invoking afm2tfm. Making Type 1 fonts available to TeX. * Dvips: (dvips). DVI-to-PostScript translator. * Eplain: (eplain). Expanding on plain TeX. * Kpathsearch: (kpathsea). File lookup along search paths. * LaTeX: (latex). LaTeX. * MakeIndex: (makeindex). Index creation for TeX. * Naming 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 * Demacs: (demacs). GNU Emacs for DOS. * GNUish: (gnuish). GNU utilities for DOS. Other things * Amd: (amdref). 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. * 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). Virtual screen manager. * UMB C.S. Dept.: (csinfo). UMass/Boston Computer Science Dept. info. 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. * automake: (automake). Making Makefile.in's. * autoreconf: (autoconf)Invoking autoreconf. Remake multiple configure's. * autoscan: (autoconf)Invoking autoscan. Automate initial configure.in. * awk: (gawk)Invoking gawk. Text processing and scanning. * basename: (sh-utils)basename invocation. Strip directory and suffix. * bibtex: (web2c)BibTeX invocation. Maintaining bibliographies. * c++filt: (binutils)c++filt. Demangle C++ symbols. * cat: (textutils)cat invocation. Concatenate and write files. * chgrp: (fileutils)chgrp invocation. Change file groups. * chmod: (fileutils)chmod invocation. Change file permissions. * chown: (fileutils)chown invocation. Change file owners/groups. * chroot: (sh-utils)chroot invocation. Specify the root directory. * cksum: (textutils)cksum invocation. Print POSIX CRC checksum. * cmp: (diff)Invoking cmp. Character-by-character diff. * comm: (textutils)comm invocation. Compare sorted files by line. * cp: (fileutils)cp invocation. Copy files. * csplit: (textutils)csplit invocation. Split by context. * cut: (textutils)cut invocation. Print selected parts of lines. * date: (sh-utils)date invocation. Print/set system date and time. * dd: (fileutils)dd invocation. Copy and convert a file. * df: (fileutils)df invocation. Report filesystem disk usage. * diff3: (diff)Invoking diff3. Three-way diff. * dir: (fileutils)dir invocation. List directories briefly. * dircolors: (fileutils)dircolors invocation. Color setup for ls. * dirname: (sh-utils)dirname invocation. Strip non-directory suffix. * dmp: (web2c)Dmp invocation. Troff->MPX (MetaPost pictures). * du: (fileutils)du invocation. Report on disk usage. * dvicopy: (web2c)DVIcopy invocation. Virtual font expansion * dvitomp: (web2c)DVItoMP invocation. DVI to MPX (MetaPost pictures). * dvitype: (web2c)DVItype invocation. DVI to human-readable text. * echo: (sh-utils)echo invocation. Print a line of text. * edit-pr: (gnats)Invoking edit-pr. Changing bugs. * eid: (id-utils)eid invocation. Invoking an editor on matches. * emacsclient: (emacs)Emacs Server. Connecting to a running Emacs. * emacsserver: (emacs)Emacs Server. Connecting to a running Emacs. * env: (sh-utils)env invocation. Modify the environment. * etags: (emacs)Create Tags Table. Creating a TAGS table. * expand: (textutils)expand invocation. Convert tabs to spaces. * expr: (sh-utils)expr invocation. Evaluate expressions. * factor: (sh-utils)factor invocation. Print prime factors * false: (sh-utils)false invocation. Do nothing, unsuccessfully. * 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: (textutils)fmt invocation. Reformat paragraph text. * fold: (textutils)fold invocation. Wrap long input lines. * g++: (gcc)Invoking G++. The GNU C++ compiler. * gcal2txt: (gcal)Invoking gcal2txt. Calendar resource to text file. * gettextize: (gettext)gettextize Invocation. Prepare a package for gettext. * 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: (sh-utils)groups invocation. Print group names a user is in. * gunzip: (gzip)Overview. Decompression. * head: (textutils)head invocation. Output the first part of files. * hostname: (sh-utils)hostname invocation. Print or set system name. * id: (sh-utils)id invocation. Print real/effective uid/gid. * idx: (id-utils)idx invocation. Testing mkid scanners. * ifnames: (autoconf)Invoking ifnames. List conditionals in source. * iid: (id-utils)iid invocation. Interactive complex queries. * inimf: (web2c)inimf invocation. Initial Metafont. * inimp: (web2c)inimp invocation. Initial MetaPost. * initex: (web2c)initex invocation. Initial TeX. * install: (fileutils)install invocation. Copy and change attributes. * join: (textutils)join invocation. Join lines on a common field. * kpsewhich: (kpathsea)Invoking kpsewhich. TeX file searching. * lid: (id-utils)lid invocation. Matching identifier patterns. * ln: (fileutils)ln invocation. Make links between files. * locate: (find)Invoking locate. Finding files in a database. * logname: (sh-utils)logname invocation. Print current login name. * ls: (fileutils)ls invocation. List directory contents. * 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: (textutils)md5sum invocation. Print or check message-digests. * mf: (web2c)mf invocation. Creating typeface families. * mft: (web2c)MFT invocation. Prettyprinting Metafont source. * mkdir: (fileutils)mkdir invocation. Create directories. * mkfifo: (fileutils)mkfifo invocation. Create FIFOs: (named pipes). * mkid: (id-utils)mkid invocation. Creating an ID database. * mknod: (fileutils)mknod invocation. Create special files. * mp: (web2c)mp invocation. Creating technical diagrams. * mpto: (web2c)MPto invocation. MetaPost label extraction. * msgfmt: (gettext)msgfmt Invocation. Make MO files out of PO files. * msgmerge: (gettext)msgmerge Invocation. Update two PO files into one. * mv: (fileutils)mv invocation. Rename files. * newer: (web2c)Newer invocation. Compare modification times. * nice: (sh-utils)nice invocation. Modify scheduling priority. * nl: (textutils)nl invocation. Number lines and write files. * nlmconv: (binutils)nlmconv. Convert object to NetWare LM. * nm: (binutils)nm. List symbols in object files. * nohup: (sh-utils)nohup invocation. Immunize to hangups. * objcopy: (binutils)objcopy. Copy/translate object files. * objdump: (binutils)objdump. Display info from object files. * od: (textutils)od invocation. Dump files in octal, etc. * paste: (textutils)paste invocation. Merge lines of files. * patch: (diff)Invoking patch. Automatically applying diffs. * patgen: (web2c)Patgen invocation. Creating hyphenation patterns. * pathchk: (sh-utils)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. * pr-addr: (gnats)pr-addr. Bug report address retrieval. * pr-edit: (gnats)pr-edit. The edit-pr driver. * pr: (textutils)pr invocation. Paginate or columnate files. * printenv: (sh-utils)printenv invocation. Print environment variables. * printf: (sh-utils)printf invocation. Format and print data. * pwd: (sh-utils)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. * rm: (fileutils)rm invocation. Remove files. * rmdir: (fileutils)rmdir invocation. Remove empty directories. * sdiff: (diff)Invoking sdiff. Interactively merge files. * send-pr: (gnats)Invoking send-pr. Submitting bugs. * seq: (sh-utils)seq invocation. Print numeric sequences * shar: (sharutils)shar invocation. Create shell archive. * size: (binutils)size. List object file section sizes. * sleep: (sh-utils)sleep invocation. Delay for a specified time. * sort: (textutils)sort invocation. Sort text files. * split: (textutils)split invocation. Split into fixed-size pieces. * strings: (binutils)strings. List printable strings. * strip: (binutils)strip. Discard symbols. * stty: (sh-utils)stty invocation. Print/change terminal settings. * su: (sh-utils)su invocation. Modify user and group id. * sum: (textutils)sum invocation. Print traditional checksum. * sync: (fileutils)sync invocation. Synchronize memory and disk. * tabs: (tput)Invoking tabs. Tab settings. * tac: (textutils)tac invocation. Reverse files. * tail: (textutils)tail invocation. Output the last part of files. * tangle: (web2c)Tangle invocation. WEB to Pascal. * tcal: (gcal)Invoking tcal. Run Gcal with tomorrow's date. * tee: (sh-utils)tee invocation. Redirect to multiple files. * test: (sh-utils)test invocation. File/string tests. * tex: (web2c)tex invocation. Typesetting. * tftopl: (web2c)TFtoPL invocation. TFM -> property list. * touch: (fileutils)touch invocation. Change file timestamps. * tput: (tput)Invoking tput. Termcap in shell scripts. * tr: (textutils)tr invocation. Translate characters. * true: (sh-utils)true invocation. Do nothing, successfully. * tty: (sh-utils)tty invocation. Print terminal name. * txt2gcal: (gcal)Invoking txt2gcal. Calendar text to resource file. * uname: (sh-utils)uname invocation. Print system information. * unexpand: (textutils)unexpand invocation. Convert spaces to tabs. * uniq: (textutils)uniq invocation. Uniqify files. * unshar: (sharutils)unshar invocation. Extract from shell archive. * updatedb: (find)Invoking updatedb. Building the locate database. * users: (sh-utils)users invocation. Print current user names. * vdir: (fileutils)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: (textutils)wc invocation. Byte, word, and line counts. * weave: (web2c)Weave invocation. WEB to TeX. * who: (sh-utils)who invocation. Print who is logged in. * whoami: (sh-utils)whoami invocation. Print effective user id. * xargs: (find)Invoking xargs. Operating on many files. * xgettext: (gettext)xgettext Invocation. Extract strings into a PO file. * yes: (sh-utils)yes invocation. Print a string indefinitely. * zcat: (gzip)Overview. Decompression to stdout. texinfo-3.12/AUTHORS0000664000175000017500000000015506311107422011420 0ustar ggRichard Stallman, Brian Fox, Bob Chassell, Noah Friedman, Paul Rubin, Karl Berry, and no doubt many others. texinfo-3.12/INSTALL0000664000175000017500000001705106053165061011412 0ustar ggBasic Installation ================== These are generic installation instructions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, a file `config.cache' that saves the results of its tests to speed up reconfiguring, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.in' is used to create `configure' by a program called `autoconf'. You only need `configure.in' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. If you're using `csh' on an old version of System V, you might need to type `sh ./configure' instead to prevent `csh' from trying to execute `configure' itself. Running `configure' takes awhile. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with the package. 4. Type `make install' to install the programs and any data files and documentation. 5. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is also a `make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. You can give `configure' initial values for variables by setting them in the environment. Using a Bourne-compatible shell, you can do that on the command line like this: CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure Or on systems that have the `env' program, you can do it like this: env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you must use a version of `make' that supports the `VPATH' variable, such as GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. If you have to use a `make' that does not supports the `VPATH' variable, you have to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use `make distclean' before reconfiguring for another architecture. Installation Names ================== By default, `make install' will install the package's files in `/usr/local/bin', `/usr/local/man', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PATH'. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you give `configure' the option `--exec-prefix=PATH', the package will use PATH as the prefix for installing programs and libraries. Documentation and other data files will still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=PATH' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories you can set and what kinds of files go in them. If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Optional Features ================= Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The `README' should mention any `--enable-' and `--with-' options that the package recognizes. For packages that use the X Window System, `configure' can usually find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. Specifying the System Type ========================== There may be some features `configure' can not figure out automatically, but needs to determine by the type of host the package will run on. Usually `configure' can figure that out, but if it prints a message saying it can not guess the host type, give it the `--host=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name with three fields: CPU-COMPANY-SYSTEM See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't need to know the host type. If you are building compiler tools for cross-compiling, you can also use the `--target=TYPE' option to select the type of system they will produce code for and the `--build=TYPE' option to select the type of system on which you are compiling the package. Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. Operation Controls ================== `configure' recognizes the following options to control how it operates. `--cache-file=FILE' Use and save the results of the tests in FILE instead of `./config.cache'. Set FILE to `/dev/null' to disable caching, for debugging `configure'. `--help' Print a summary of the options to `configure', and exit. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. `--srcdir=DIR' Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. `--version' Print the version of Autoconf used to generate the `configure' script, and exit. `configure' also accepts some other, not widely useful, options. texinfo-3.12/util/0000775000175000017500000000000006477056760011351 5ustar ggtexinfo-3.12/util/tex3patch0000775000175000017500000000346505354651173013202 0ustar gg#!/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 $# \) -o \ \( ! -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 = "$?" -a "$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 texinfo-3.12/util/deref.c0000664000175000017500000001075705302574253012600 0ustar gg/* * deref.c * compile command: gcc -g -o deref deref.c * execute command: deref filename.texi > newfile.texi * To: bob@gnu.ai.mit.edu * Subject: another tool * Date: 18 Dec 91 16:03:13 EST (Wed) * From: gatech!skeeve!arnold@eddie.mit.edu (Arnold D. Robbins) * * Here is deref.c. It turns texinfo cross references back into the * one argument form. It has the same limitations as fixref; one xref per * line and can't cross lines. You can use it to find references that do * cross a line boundary this way: * * deref < manual > /dev/null 2>errs * * (This assumes bash or /bin/sh.) The file errs will have list of lines * where deref could not find matching braces. * * A gawk manual processed by deref goes through makeinfo without complaint. * Compile with gcc and you should be set. * * Enjoy, * * Arnold * ----------- */ /* * deref.c * * Make all texinfo references into the one argument form. * * Arnold Robbins * arnold@skeeve.atl.ga.us * December, 1991 * * Copyright, 1991, Arnold Robbins */ /* * 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 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; } texinfo-3.12/util/install-info.c0000444000175000017500000010463506476300406014105 0ustar gg/* install-info -- create Info directory entry(ies) for an Info file. $Id: install-info.c,v 1.21 1998/03/01 15:38:45 karl Exp $ Copyright (C) 1996, 97, 98 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 #ifdef HAVE_LIBZ #include #endif /* Name this program was invoked with. */ char *progname; char *readfile (); struct line_data *findlines (); void fatal (); void insert_entry_here (); int compare_section_names (); struct spec_entry; /* 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; }; /* 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; }; /* Memory allocation and string operations. */ /* Like malloc but get fatal error if memory is exhausted. */ void * xmalloc (size) unsigned int size; { extern void *malloc (); void *result = malloc (size); if (result == NULL) fatal (_("virtual memory exhausted"), 0); return result; } /* Like realloc but get fatal error if memory is exhausted. */ void * xrealloc (obj, size) void *obj; unsigned int size; { extern void *realloc (); void *result = realloc (obj, size); if (result == NULL) fatal (_("virtual memory exhausted"), 0); return result; } /* Return a newly-allocated string whose contents concatenate those of S1, S2, S3. */ char * concat (s1, s2, s3) char *s1, *s2, *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 (string, size) 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; } /* Error message functions. */ /* Print error message. S1 is printf control string, S2 and S3 args for it. */ /* VARARGS1 */ void error (s1, s2, s3) char *s1, *s2, *s3; { fprintf (stderr, "%s: ", progname); fprintf (stderr, s1, s2, s3); putc ('\n', stderr); } /* VARARGS1 */ void warning (s1, s2, s3) char *s1, *s2, *s3; { fprintf (stderr, _("%s: warning: "), progname); fprintf (stderr, s1, s2, s3); putc ('\n', stderr); } /* Print error message and exit. */ void fatal (s1, s2, s3) char *s1, *s2, *s3; { error (s1, s2, s3); exit (1); } /* Print fatal error message based on errno, with file name NAME. */ void pfatal_with_name (name) char *name; { char *s = concat ("", strerror (errno), _(" for %s")); fatal (s, name); } /* Given the full text of a menu entry, null terminated, return just the menu item name (copied). */ char * extract_menu_item_name (item_text) 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 (item_text) 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); } void suggest_asking_for_help () { fprintf (stderr, _("\tTry `%s --help' for a complete list of options.\n"), progname); exit (1); } void print_help () { printf (_("Usage: %s [OPTION]... [INFO-FILE [DIR-FILE]]\n\ \n\ Install INFO-FILE in the Info directory file DIR-FILE.\n\ \n\ Options:\n\ --delete Delete existing entries in INFO-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\ \n\ Email bug reports to bug-texinfo@gnu.org.\n\ "), progname); } /* If DIRFILE does not exist, create a minimal one (or abort). If it already exists, do nothing. */ void ensure_dirfile_exists (dirfile) 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) { fputs (_("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\ \n\ File: dir,\tNode: Top,\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\ * Menu:\n\ "), f); 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)); exit (1); } } else close (desc); /* It already existed, so fine. */ } /* 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' }, { "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 } }; int main (argc, argv) int argc; char **argv; { char *infile = 0, *dirfile = 0; char *infile_sans_info; unsigned infilelen_sans_info; FILE *output; /* Record the text of the Info file, as a sequence of characters and as a sequence of lines. */ char *input_data; int input_size; struct line_data *input_lines; int input_nlines; /* 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 node_header_flag; int prefix_length; int i; progname = argv[0]; #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: Specify the Info directory only once.\n"), progname); suggest_asking_for_help (); } dirfile = optarg; break; case 'D': if (dirfile) { fprintf (stderr, _("%s: Specify the Info directory only once.\n"), progname); suggest_asking_for_help (); } dirfile = concat (optarg, "", "/dir"); break; case 'e': { struct spec_entry *next = (struct spec_entry *) xmalloc (sizeof (struct spec_entry)); if (! (*optarg != 0 && optarg[strlen (optarg) - 1] == '\n')) optarg = concat (optarg, "\n", ""); next->text = optarg; next->next = entries_to_add; entries_to_add = next; n_entries_to_add++; } break; case 'h': case 'H': print_help (); exit (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); printf (_("Copyright (C) %s Free Software Foundation, Inc.\n\ 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"), "1998"); exit (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]); } if (!infile) fatal (_("No input file specified; try --help for more information.")); if (!dirfile) fatal (_("No dir file specified; try --help for more information.")); /* Read the Info file and parse it into lines. */ input_data = readfile (infile, &input_size); input_lines = findlines (input_data, input_size, &input_nlines); /* Parse the input file to find the section names it specifies. */ if (input_sections == 0) { prefix_length = strlen ("INFO-DIR-SECTION "); for (i = 0; i < input_nlines; i++) { if (!strncmp ("INFO-DIR-SECTION ", input_lines[i].start, prefix_length)) { struct spec_section *next = (struct spec_section *) xmalloc (sizeof (struct spec_section)); next->name = copy_string (input_lines[i].start + prefix_length, input_lines[i].size - prefix_length); next->next = input_sections; next->missing = 1; input_sections = next; } } } /* Default to section "Miscellaneous" if no sections specified. */ if (input_sections == 0) { input_sections = (struct spec_section *) xmalloc (sizeof (struct spec_section)); input_sections->name = "Miscellaneous"; input_sections->next = 0; input_sections->missing = 1; } /* Now find the directory entries specified in the file and put them on entries_to_add. But not if entries were specified explicitly with command options. */ if (entries_to_add == 0) { char *start_of_this_entry = 0; for (i = 0; i < input_nlines; i++) { if (!strncmp ("START-INFO-DIR-ENTRY", input_lines[i].start, input_lines[i].size) && sizeof ("START-INFO-DIR-ENTRY") - 1 == input_lines[i].size) { if (start_of_this_entry != 0) fatal (_("START-INFO-DIR-ENTRY without matching END-INFO-DIR-ENTRY")); start_of_this_entry = input_lines[i + 1].start; } if (!strncmp ("END-INFO-DIR-ENTRY", input_lines[i].start, input_lines[i].size) && sizeof ("END-INFO-DIR-ENTRY") - 1 == input_lines[i].size) { if (start_of_this_entry != 0) { struct spec_entry *next = (struct spec_entry *) xmalloc (sizeof (struct spec_entry)); next->text = copy_string (start_of_this_entry, input_lines[i].start - start_of_this_entry); next->next = entries_to_add; entries_to_add = next; n_entries_to_add++; start_of_this_entry = 0; } else fatal (_("END-INFO-DIR-ENTRY without matching START-INFO-DIR-ENTRY")); } } if (start_of_this_entry != 0) fatal (_("START-INFO-DIR-ENTRY without matching END-INFO-DIR-ENTRY")); } 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); exit (0); } /* Now read in the Info dir file. */ ensure_dirfile_exists (dirfile); dir_data = readfile (dirfile, &dir_size); 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 any .info suffix. */ { unsigned basename_len; char *infile_basename = strrchr (infile, '/'); if (infile_basename) infile_basename++; else infile_basename = infile; basename_len = strlen (infile_basename); infile_sans_info = (strlen (infile_basename) > 5 && strcmp (infile_basename + basename_len - 5, ".info") == 0) ? copy_string (infile_basename, basename_len - 5) : infile_basename; infilelen_sans_info = strlen (infile_sans_info); } /* Parse the dir file. Find all the nodes, and their menus, and the sections of their menus. */ dir_nodes = 0; node_header_flag = 0; for (i = 0; i < dir_nlines; i++) { /* Parse node header lines. */ if (node_header_flag) { int j, end; for (j = 0; j < dir_lines[i].size; j++) /* Find the node name and store it in the `struct node'. */ if (!strncmp ("Node:", dir_lines[i].start + j, 5)) { char *line = dir_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++; dir_nodes->name = copy_string (line + j, end - j); } node_header_flag = 0; } /* Notice the start of a node. */ if (*dir_lines[i].start == 037) { struct node *next = (struct node *) xmalloc (sizeof (struct node)); next->next = dir_nodes; next->name = NULL; next->start_line = i; next->end_line = 0; next->menu_start = NULL; next->sections = NULL; next->last_section = NULL; if (dir_nodes != 0) dir_nodes->end_line = i; /* Fill in the end of the last menu section of the previous node. */ if (dir_nodes != 0 && dir_nodes->last_section != 0) dir_nodes->last_section->end_line = i; dir_nodes = next; /* The following line is the header of this node; parse it. */ node_header_flag = 1; } /* Notice the lines that start menus. */ if (dir_nodes != 0 && !strncmp ("* Menu:", dir_lines[i].start, 7)) dir_nodes->menu_start = dir_lines[i + 1].start; /* Notice sections in menus. */ if (dir_nodes != 0 && dir_nodes->menu_start != 0 && *dir_lines[i].start != '\n' && *dir_lines[i].start != '*' && *dir_lines[i].start != ' ' && *dir_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 (dir_lines[i].start, dir_lines[i].size); if (dir_nodes->sections) { dir_nodes->last_section->next = next; dir_nodes->last_section->end_line = i; } else dir_nodes->sections = next; dir_nodes->last_section = next; } /* Check for an existing entry that should be deleted. Delete all entries which specify this file name. */ if (*dir_lines[i].start == '*') { char *p = dir_lines[i].start; while (*p != 0 && *p != ':') p++; p++; while (*p == ' ') p++; if (*p == '(') { p++; if ((dir_lines[i].size > (p - dir_lines[i].start + infilelen_sans_info)) && !strncmp (p, infile_sans_info, infilelen_sans_info) && (p[infilelen_sans_info] == ')' || !strncmp (p + infilelen_sans_info, ".info)", 6))) { dir_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 && (*dir_lines[i].start == ' ' || *dir_lines[i].start == '\t')) { dir_lines[i].delete = dir_lines[i - 1].delete; something_deleted = 1; } } /* Finish the info about the end of the last node. */ if (dir_nodes != 0) { dir_nodes->end_line = dir_nlines; if (dir_nodes->last_section != 0) dir_nodes->last_section->end_line = dir_nlines; } /* 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) { int textlen = strlen (entry->text); /* 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, textlen, 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, textlen, 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); /* Output the old dir file, interpolating the new sections and/or new entries where appropriate. */ output = fopen (dirfile, "w"); if (!output) { perror (dirfile); exit (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; /* 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); /* Generate the new sections in alphabetical order. In each new section, output all of our entries. */ for (j = 0; j < n_sections; j++) { spec = sections[j]; if (spec->missing) { struct spec_entry *entry; putc ('\n', output); fputs (spec->name, output); putc ('\n', output); for (entry = entries_to_add; entry; entry = entry->next) fputs (entry->text, output); } } 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); } } fclose (output); exit (0); } /* Read all of file FILNAME into memory and return the address of the data. Store the size into SIZEP. If there is trouble, do a fatal error. */ char * readfile (filename, sizep) char *filename; int *sizep; { int desc; int data_size = 1024; char *data = (char *) xmalloc (data_size); int filled = 0; int nread = 0; #ifdef HAVE_LIBZ int isGZ = 0; gzFile zdesc; #endif desc = open (filename, O_RDONLY); if (desc < 0) pfatal_with_name (filename); #ifdef HAVE_LIBZ /* The file should always be two bytes long. */ if (read (desc, data, 2) != 2) pfatal_with_name (filename); /* Undo that read. */ lseek (desc, 0, SEEK_SET); /* If we see gzip magic, use gzdopen. */ if (data[0] == '\x1f' && data[1] == '\x8b') { isGZ = 1; zdesc = gzdopen (desc, "r"); if (zdesc == NULL) { close (desc); pfatal_with_name (filename); } } #endif /* HAVE_LIBZ */ while (1) { #ifdef HAVE_LIBZ if (isGZ) nread = gzread (zdesc, data + filled, data_size - filled); else #endif nread = read (desc, data + filled, data_size - filled); if (nread < 0) pfatal_with_name (filename); if (nread == 0) break; filled += nread; if (filled == data_size) { data_size *= 2; data = (char *) xrealloc (data, data_size); } } *sizep = filled; #ifdef HAVE_LIBZ if (isGZ) gzclose (zdesc); else #endif close(desc); return data; } /* 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 (data, size, nlinesp) char *data; int size; int *nlinesp; { struct line_data *lines; int lines_allocated = 512; int filled = 0; int i = 0; int lineflag; lines = (struct line_data *) xmalloc (lines_allocated * sizeof (struct line_data)); lineflag = 1; for (i = 0; i < size; i++) { if (lineflag) { if (filled == lines_allocated) { lines_allocated *= 2; lines = (struct line_data *) xrealloc (lines, lines_allocated * 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; } /* 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. */ int menu_line_lessp (line1, len1, line2, len2) 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. */ int menu_line_equal (line1, len1, line2, len2) 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; } /* This is the comparison function for qsort for a vector of pointers to struct spec_section. Compare the section names. */ int compare_section_names (sec1, sec2) struct spec_section **sec1, **sec2; { char *name1 = (*sec1)->name; char *name2 = (*sec2)->name; return strcmp (name1, name2); } /* 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 (entry, line_number, dir_lines, n_entries) struct spec_entry *entry; int line_number; struct line_data *dir_lines; int n_entries; { int i; 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; } for (i = 0; i < n_entries; i++) if (dir_lines[line_number].add_entries_before[i] == 0) break; if (i == n_entries) abort (); dir_lines[line_number].add_entries_before[i] = entry; } texinfo-3.12/util/Makefile.in0000664000175000017500000002101606477056757013424 0ustar gg# Makefile.in generated automatically by automake 1.2f from Makefile.am # Copyright (C) 1994, 1995, 1996, 1997, 1998 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. SHELL = /bin/sh srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ bindir = @bindir@ sbindir = @sbindir@ libexecdir = @libexecdir@ datadir = @datadir@ sysconfdir = @sysconfdir@ sharedstatedir = @sharedstatedir@ localstatedir = @localstatedir@ libdir = @libdir@ infodir = @infodir@ mandir = @mandir@ includedir = @includedir@ oldincludedir = /usr/include pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. ACLOCAL = @ACLOCAL@ AUTOCONF = @AUTOCONF@ AUTOMAKE = @AUTOMAKE@ AUTOHEADER = @AUTOHEADER@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ transform = @program_transform_name@ NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : CATALOGS = @CATALOGS@ CATOBJEXT = @CATOBJEXT@ CC = @CC@ DATADIRNAME = @DATADIRNAME@ GENCAT = @GENCAT@ GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ GT_NO = @GT_NO@ GT_YES = @GT_YES@ INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@ INSTOBJEXT = @INSTOBJEXT@ INTLDEPS = @INTLDEPS@ INTLLIBS = @INTLLIBS@ INTLOBJS = @INTLOBJS@ MAKEINFO = @MAKEINFO@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ PACKAGE = @PACKAGE@ POFILES = @POFILES@ POSUB = @POSUB@ RANLIB = @RANLIB@ TERMLIBS = @TERMLIBS@ TEXCONFIG = @TEXCONFIG@ TEXMF = @TEXMF@ USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ l = @l@ bin_PROGRAMS = install-info texindex bin_SCRIPTS = texi2dvi localedir = $(datadir)/locale INCLUDES = -I$(top_srcdir)/lib -I../intl -DLOCALEDIR=\"$(localedir)\" LDADD = ../lib/libtxi.a @INTLLIBS@ EXTRA_DIST = README deref.c fixfonts gen-dir-node tex3patch texi2dvi \ update-info mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = ../config.h CONFIG_CLEAN_FILES = PROGRAMS = $(bin_PROGRAMS) DEFS = @DEFS@ -I. -I$(srcdir) -I.. CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ install_info_SOURCES = install-info.c install_info_OBJECTS = install-info.o install_info_LDADD = $(LDADD) install_info_DEPENDENCIES = ../lib/libtxi.a install_info_LDFLAGS = texindex_SOURCES = texindex.c texindex_OBJECTS = texindex.o texindex_LDADD = $(LDADD) texindex_DEPENDENCIES = ../lib/libtxi.a texindex_LDFLAGS = SCRIPTS = $(bin_SCRIPTS) CFLAGS = @CFLAGS@ COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) LINK = $(CC) $(CFLAGS) $(LDFLAGS) -o $@ DIST_COMMON = README Makefile.am Makefile.in DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) TAR = tar GZIP = --best SOURCES = install-info.c texindex.c OBJECTS = install-info.o texindex.o default: all .SUFFIXES: .SUFFIXES: .S .c .o .s $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps util/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) \ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status mostlyclean-binPROGRAMS: clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) distclean-binPROGRAMS: maintainer-clean-binPROGRAMS: install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) $(mkinstalldirs) $(bindir) @list='$(bin_PROGRAMS)'; for p in $$list; do \ if test -f $$p; then \ echo " $(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p|sed '$(transform)'`"; \ $(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p|sed '$(transform)'`; \ else :; fi; \ done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) list='$(bin_PROGRAMS)'; for p in $$list; do \ rm -f $(bindir)/`echo $$p|sed '$(transform)'`; \ done .c.o: $(COMPILE) -c $< .s.o: $(COMPILE) -c $< .S.o: $(COMPILE) -c $< mostlyclean-compile: -rm -f *.o core *.core clean-compile: distclean-compile: -rm -f *.tab.c maintainer-clean-compile: install-info: $(install_info_OBJECTS) $(install_info_DEPENDENCIES) @rm -f install-info $(LINK) $(install_info_LDFLAGS) $(install_info_OBJECTS) $(install_info_LDADD) $(LIBS) texindex: $(texindex_OBJECTS) $(texindex_DEPENDENCIES) @rm -f texindex $(LINK) $(texindex_LDFLAGS) $(texindex_OBJECTS) $(texindex_LDADD) $(LIBS) install-binSCRIPTS: $(bin_SCRIPTS) @$(NORMAL_INSTALL) $(mkinstalldirs) $(bindir) @list='$(bin_SCRIPTS)'; for p in $$list; do \ if test -f $$p; then \ echo " $(INSTALL_SCRIPT) $$p $(bindir)/`echo $$p|sed '$(transform)'`"; \ $(INSTALL_SCRIPT) $$p $(bindir)/`echo $$p|sed '$(transform)'`; \ else if test -f $(srcdir)/$$p; then \ echo " $(INSTALL_SCRIPT) $(srcdir)/$$p $(bindir)/`echo $$p|sed '$(transform)'`"; \ $(INSTALL_SCRIPT) $(srcdir)/$$p $(bindir)/`echo $$p|sed '$(transform)'`; \ else :; fi; fi; \ done uninstall-binSCRIPTS: @$(NORMAL_UNINSTALL) list='$(bin_SCRIPTS)'; for p in $$list; do \ rm -f $(bindir)/`echo $$p|sed '$(transform)'`; \ done tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) here=`pwd` && cd $(srcdir) \ && mkid -f$$here/ID $(SOURCES) $(HEADERS) $(LISP) TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS)'; \ unique=`for i in $$list; do echo $$i; done | \ awk ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) mostlyclean-tags: clean-tags: distclean-tags: -rm -f TAGS ID maintainer-clean-tags: distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) subdir = util distdir: $(DISTFILES) @for file in $(DISTFILES); do \ d=$(srcdir); \ test -f $(distdir)/$$file \ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ || cp -p $$d/$$file $(distdir)/$$file; \ done install-info.o: install-info.c ../lib/system.h ../config.h \ ../lib/getopt.h texindex.o: texindex.c ../lib/system.h ../config.h ../lib/getopt.h info: dvi: check: all $(MAKE) installcheck: install-exec: install-binPROGRAMS install-binSCRIPTS @$(NORMAL_INSTALL) install-data: @$(NORMAL_INSTALL) install: install-exec install-data all @: uninstall: uninstall-binPROGRAMS uninstall-binSCRIPTS all: Makefile $(PROGRAMS) $(SCRIPTS) install-strip: $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install installdirs: $(mkinstalldirs) $(bindir) $(bindir) mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -rm -f Makefile $(DISTCLEANFILES) -rm -f config.cache config.log stamp-h stamp-h[0-9]* -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) mostlyclean: mostlyclean-binPROGRAMS mostlyclean-compile \ mostlyclean-tags mostlyclean-generic clean: clean-binPROGRAMS clean-compile clean-tags clean-generic \ mostlyclean distclean: distclean-binPROGRAMS distclean-compile distclean-tags \ distclean-generic clean -rm -f config.status maintainer-clean: maintainer-clean-binPROGRAMS maintainer-clean-compile \ maintainer-clean-tags maintainer-clean-generic \ distclean @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." .PHONY: default mostlyclean-binPROGRAMS distclean-binPROGRAMS \ clean-binPROGRAMS maintainer-clean-binPROGRAMS uninstall-binPROGRAMS \ install-binPROGRAMS mostlyclean-compile distclean-compile clean-compile \ maintainer-clean-compile uninstall-binSCRIPTS install-binSCRIPTS tags \ mostlyclean-tags distclean-tags clean-tags maintainer-clean-tags \ distdir info dvi installcheck install-exec install-data install \ uninstall all installdirs mostlyclean-generic distclean-generic \ clean-generic maintainer-clean-generic clean mostlyclean distclean \ maintainer-clean # 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: texinfo-3.12/util/texindex.c0000444000175000017500000012603106475626416013343 0ustar gg/* Prepare TeX index dribble output into an actual index. $Id: texindex.c,v 1.22 1998/02/22 23:00:09 karl Exp $ Copyright (C) 1987, 91, 92, 96, 97, 98 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 #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 (); #if defined (VMS) # include # define TI_NO_ERROR ((1 << 28) | 1) # define TI_FATAL_ERROR ((1 << 28) | 4) # define unlink delete #else /* !VMS */ # define TI_NO_ERROR 0 # define TI_FATAL_ERROR 1 #endif /* !VMS */ #if !defined (SEEK_SET) # define SEEK_SET 0 # define SEEK_CUR 1 # define SEEK_END 2 #endif /* !SEEK_SET */ /* 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; /* Start of filename to use for temporary files. */ char *tempbase; /* 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; /* Additional command switches .*/ /* Nonzero means do not delete tempfiles -- for debugging. */ int keep_tempfiles; /* The name this program was run with. */ char *program_name; /* Forward declarations of functions in this file. */ void decode_command (); void sort_in_core (); void sort_offline (); char **parsefile (); char *find_field (); char *find_pos (); long find_value (); char *find_braced_pos (); char *find_braced_end (); void writelines (); int compare_field (); int compare_full (); long readline (); int merge_files (); int merge_direct (); void pfatal_with_name (); void fatal (); void error (); void *xmalloc (), *xrealloc (); char *concat (); char *maketempname (); void flush_tempfiles (); char *tempcopy (); #define MAX_IN_CORE_SORT 500000 int main (argc, argv) int argc; char **argv; { int i; tempcount = 0; last_deleted_tempcount = 0; program_name = strrchr (argv[0], '/'); if (program_name != (char *)NULL) program_name++; else program_name = argv[0]; #ifdef HAVE_SETLOCALE /* Set locale via LC_ALL. */ setlocale (LC_ALL, ""); #endif /* Set the text message domain. */ bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); /* 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); tempbase = mktemp (concat ("txiXXXXXX", "", "")); /* Process input files completely, one by one. */ for (i = 0; i < num_infiles; i++) { int desc; long ptr; char *outfile; desc = open (infiles[i], O_RDONLY, 0); if (desc < 0) pfatal_with_name (infiles[i]); lseek (desc, (off_t) 0, SEEK_END); ptr = (long) lseek (desc, (off_t) 0, SEEK_CUR); close (desc); outfile = outfiles[i]; if (!outfile) { outfile = concat (infiles[i], "s", ""); } if (ptr < MAX_IN_CORE_SORT) /* Sort a small amount of data. */ sort_in_core (infiles[i], ptr, outfile); else sort_offline (infiles[i], ptr, outfile); } flush_tempfiles (tempcount); exit (TI_NO_ERROR); 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[] = { { "--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") }, { "--help", "-h", (int *)NULL, 0, (char *)NULL, N_("display this help and exit") }, { (char *)NULL, (char *)NULL, (int *)NULL, 0, (char *)NULL } }; void usage (result_value) 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 `foo.??\' for a document `foo.texi'.\n")); fprintf (f, _("\nOptions:\n")); for (i = 0; texindex_options[i].long_name; i++) { 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)); } puts (_("\nEmail bug reports to bug-texinfo@gnu.org.")); exit (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 (argc, argv) int argc; char **argv; { int arg_index = 1; char **ip; char **op; /* Store default values into parameter variables. */ tempdir = getenv ("TMPDIR"); #ifdef VMS if (tempdir == NULL) tempdir = "sys$scratch:"; #else if (tempdir == NULL) tempdir = "/tmp/"; else tempdir = concat (tempdir, "/", ""); #endif 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); printf (_("Copyright (C) %s Free Software Foundation, Inc.\n\ 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"), "1998"); exit (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 a temporary file. */ char * maketempname (count) int count; { char tempsuffix[10]; sprintf (tempsuffix, "%d", count); return concat (tempdir, tempbase, tempsuffix); } /* Delete all temporary files up to TO_COUNT. */ void flush_tempfiles (to_count) int to_count; { if (keep_tempfiles) return; while (last_deleted_tempcount < to_count) unlink (maketempname (++last_deleted_tempcount)); } /* Copy the input file open on IDESC into a temporary file and return the temporary file name. */ #define BUFSIZE 1024 char * tempcopy (idesc) int idesc; { char *outfile = maketempname (++tempcount); int odesc; char buffer[BUFSIZE]; odesc = open (outfile, O_WRONLY | O_CREAT, 0666); if (odesc < 0) pfatal_with_name (outfile); while (1) { int nread = read (idesc, buffer, BUFSIZE); write (odesc, buffer, nread); if (!nread) break; } close (odesc); return outfile; } /* Compare LINE1 and LINE2 according to the specified set of keyfields. */ int compare_full (line1, line2) char **line1, **line2; { 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 (line1, line2) struct lineinfo *line1, *line2; { 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 (str1, str2, pos1, pos2, use_keyfields) char *str1, *str2; long pos1, 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 (keyfield, str, lengthptr) struct keyfield *keyfield; char *str; long *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 (str, words, chars, ignore_blanks) char *str; int words, 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 (str, words, chars, ignore_blanks) char *str; int words, 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 (str) 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 (start, length) char *start; long 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 () { 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 (keyfield, start1, length1, pos1, start2, length2, pos2) struct keyfield *keyfield; char *start1; long length1; long pos1; char *start2; long length2; long 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 (linebuffer) 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 (linebuffer, stream) 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 (infile, nfiles, total, outfile) char *infile; int nfiles; long 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 (infile, total, outfile) char *infile; long 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 = (struct 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 (filename, nextline, data, size) char *filename; char **nextline; char *data; long 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; while (*p && *p != '\n') p++; if (p != end) p++; line++; if (line == linearray + nlines) { char **old = linearray; linearray = (char **) 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 () { 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 (line, ostream) 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] = *p; initial1[1] = 0; initiallength = 1; if (initial1[0] >= 'a' && initial1[0] <= 'z') initial1[0] -= 040; } pagenumber = find_braced_pos (line, 1, 0, 0); pagelength = find_braced_end (pagenumber) - pagenumber; if (pagelength == 0) abort (); 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 (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 (ostream) 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 (linearray, nlines, ostream) 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 (infiles, nfiles, outfile) 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 (infiles, nfiles, outfile) 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 (format, arg) char *format, *arg; { error (format, arg); exit (TI_FATAL_ERROR); } /* Print error message. FORMAT is printf control string, ARG is arg for it. */ void error (format, arg) char *format, *arg; { printf ("%s: ", program_name); printf (format, arg); if (format[strlen (format) -1] != '\n') printf ("\n"); } void perror_with_name (name) char *name; { char *s; s = strerror (errno); printf ("%s: ", program_name); printf ("%s; for file `%s'.\n", s, name); } void pfatal_with_name (name) char *name; { char *s; s = strerror (errno); printf ("%s: ", program_name); printf (_("%s; for file `%s'.\n"), s, name); exit (TI_FATAL_ERROR); } /* Return a newly-allocated string whose contents concatenate those of S1, S2, S3. */ char * concat (s1, s2, s3) char *s1, *s2, *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; } #if !defined (HAVE_STRERROR) extern char *sys_errlist[]; extern int sys_nerr; char * strerror (num) int num; { if (num >= sys_nerr) return (""); else return (sys_errlist[num]); } #endif /* !HAVE_STRERROR */ #if !defined (HAVE_STRCHR) char * strrchr (string, character) char *string; int character; { register int i; for (i = strlen (string) - 1; i > -1; i--) if (string[i] == character) return (string + i); return ((char *)NULL); } #endif /* HAVE_STRCHR */ void memory_error (callers_name, bytes_wanted) char *callers_name; int bytes_wanted; { char printable_string[80]; sprintf (printable_string, _("Virtual memory exhausted in %s ()! Needed %d bytes."), callers_name, bytes_wanted); error (printable_string); abort (); } /* Just like malloc, but kills the program in case of fatal error. */ void * xmalloc (nbytes) int nbytes; { void *temp = (void *) malloc (nbytes); if (nbytes && temp == (void *)NULL) memory_error ("xmalloc", nbytes); return (temp); } /* Like realloc (), but barfs if there isn't enough memory. */ void * xrealloc (pointer, nbytes) void *pointer; int nbytes; { void *temp; if (!pointer) temp = (void *)xmalloc (nbytes); else temp = (void *)realloc (pointer, nbytes); if (nbytes && !temp) memory_error ("xrealloc", nbytes); return (temp); } texinfo-3.12/util/update-info0000775000175000017500000005325206475624345013517 0ustar gg#!/bin/sh # update-info -- update dir file from all extant info pages. # # 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. # # Author: rhawes@dmapub.dma.org. Please report bugs to him. # # run this program to install update-info # ###SECTION 0### install script # These constants set the version numbers for both files: PROGRAM_VERSION="1.4" PACKAGE_VERSION="4.0" # ENVIRONMENT if test -z "$TMPDIR"; then TMPDIR="/usr/tmp" fi TMP_SED="$TMPDIR/uss$$.info" TMP_F_ADD_SECTION="$TMPDIR/ufa$$.info" TMP_F_DELETE_INVALID="$TMPDIR/ufd$$.info" TMP_F_INSERT_MISSING="$TMPDIR/ufi$$.info" TMP_FILES="$TMP_SED $TMP_F_ADD_SECTION $TMP_F_DELETE_INVALID\ $TMP_F_INSERT_MISSING" trap 'rm -f $TMP_FILES' 0 # file boundaries UPDATE_INFO="/^# _file: 'update-info'_/" UPDATE_INFO_F="/^# _file: 'update-info.f'_/" # @F_ADD_SECTION@ echo 'Item_Num=`expr "$Item_Num" + "1"` echo "$1">>"$TMP_SECTIONS" if test "$Item_Status"; then Item_Status=`echo "${Item_Status} X"` else Item_Status="X" fi '>$TMP_F_ADD_SECTION # @F_INSERT_MISSING@ echo 'if test -z "$Create_Node"; then rm -f ${Info_Node}.old cp $Info_Node ${Info_Node}.old echo "$BACKUP_MSG" fi echo "/$MENU_BEGIN/ +,$ d r $TMP_MENU w q"|ed -s $Info_Node>/dev/null'>$TMP_F_INSERT_MISSING # @F_DELETE_INVALID@ echo ' rm -f ${Info_Node}.old cp $Info_Node ${Info_Node}.old echo "$BACKUP_MSG" echo "/$MENU_BEGIN/ +,$ d w q"|ed -s $Info_Node>/dev/null sed -f "$TMP_SED" "$TMP_MENU">>"$Info_Node"'>$TMP_F_DELETE_INVALID cat<$TMP_SED s/@UPDATE_INFO_VERSION@/$PROGRAM_VERSION/g s/@TEXINFO_VERSION@/$PACKAGE_VERSION/g s/@SET_ITEM@/Item_Status=\`echo "\$Item_Status"|sed -e "\${1}s%^.*%\${2}%"\`/ /@F_ADD_SECTION@/r $TMP_F_ADD_SECTION /@F_ADD_SECTION@/d /@F_DELETE_INVALID@/r $TMP_F_DELETE_INVALID /@F_DELETE_INVALID@/d /@F_INSERT_MISSING@/r $TMP_F_INSERT_MISSING /@F_INSERT_MISSING@/d Sed_Script_EOF sed -e "1,${UPDATE_INFO}d" -e "$UPDATE_INFO_F,\$d" -f $TMP_SED $0>update-info sed -e "1,${UPDATE_INFO_F}d" -f $TMP_SED $0>update-info.f chmod +x update-info update-info.f echo "installed update-info, and update-info.f into `pwd`" rm -f $TMP_FILES exit # _file: 'update-info'_ #!/bin/sh #update-info (GNU texinfo @TEXINFO_VERSION@) @UPDATE_INFO_VERSION@ #Copyright (C) 1997 Free Software Foundation, Inc. #update-info comes with NO WARRANTY, to the extent permitted by law. #You may redistribute copies of update-info #under the terms of the GNU General Public License. #For more information about these matters, see the files named COPYING." #Author: Richard L. Hawes # ###SECTION 1### Constants set -h 2>/dev/null # ENVIRONMENT if test -z "$TMPDIR"; then TMPDIR="/usr/tmp" fi if test -z "$LINES"; then LINES=24 fi if test -z "$COLUMNS"; then COLUMNS=80 fi if test -z "$EDITOR"; then EDITOR=vi fi if test -z "$LINENO"; then LINENO="0" fi # constants redefined by update-info.f PROMPT1="(y=yes, Y=yes to all, n=no, N=No to all):" FUNCTIONS="" # ARGUMENTS="$*" DISPLAY_NUM=`expr "$LINES" - 4` CONTROL_D="{Ctrl-D}" DIR_SECTION="^INFO-DIR-SECTION" ENTRY_END="^END-INFO-DIR-ENTRY" ENTRY_START="^START-INFO-DIR-ENTRY" MENU_BEGIN='^\*\([ ]\)\{1,\}Menu:' MENU_ITEM='^\* ([^ ]).*:([ ])+\(' SECTION_TITLE="^[A-Za-z0-9]" MENU_FILTER1='s/^\*\([ ]\)\{1,\}/* /' MENU_FILTER2='s/\([ ]\)\{1,\}$//g' TMP_ITEM="${TMPDIR}/ui${$}.info" TMP_LIST="${TMPDIR}/ul${$}.info" TMP_MENU="${TMPDIR}/um${$}.info" TMP_SECTIONS="${TMPDIR}/us${$}.info" # used only in Detect_Missing TMP_SED="$TMP_SECTIONS" # used only in Detect_Invalid routines TMP_FILE1="${TMPDIR}/ux${$}.info" TMP_FILE2="${TMPDIR}/uy${$}.info" TMP_COUNT="$TMP_FILE2" TMP_FILE_LIST="$TMP_LIST $TMP_MENU $TMP_SECTIONS $TMP_FILE1 $TMP_FILE2\ $TMP_ITEM" TRY_HELP_MSG="Try --help for more information" if zcat --version 2>/dev/null>/dev/null; then CAT_COMMAND="zcat -f" else echo "$0:$LINENO: GNU zcat not found">&2 CAT_COMMAND="cat" fi # ###SECTION 100### main program #variables set by options Create_Node="" Debug=":" Interactive="" Load_Functions="y" Mode="" # Inserts="0" Inserts_Total="0" Invalid="0" Invalid_Total="0" Changed="" while test "$*" do case "$1" in -c) Create_Node="y";; -ci|-ic) Create_Node="y"; Interactive="y";; -cif|-cfi|-ifc|-icf|-fci|-fic) Create_Node="y" Interactive="y"; Load_Functions="";; --debug) set -eux; Debug="set>&2";; -d|--delete) Mode="Detect_Invalid";; -f) Load_Functions="";; -i|--interactive) Interactive="y";; -fi|-if) Load_Functions=""; Interactive="y";; -id|-di) Mode="Detect_Invalid"; Interactive="y";; +i|+d|+f);; --version) cat<&2 echo "$TRY_HELP_MSG">&2 exit 2;; *) break;; esac shift done if test "$#" -lt "1"; then echo "$0:$LINENO: Too few parameters">&2 echo "$TRY_HELP_MSG">&2 exit 2 elif test "$#" -gt "1"; then echo "$0:$LINENO: Too many parameters">&2 echo "$TRY_HELP_MSG">&2 exit 2 fi Info_Path="$1" Info_Node=`basename "$Info_Path"` if echo "$Info_Node"|grep ".*dir$">/dev/null; then : else echo "$0:$LINENO: $Info_Node is not a valid info node name">&2 exit 2 fi Info_Pathname=`dirname "$Info_Path"` cd "$Info_Pathname"||exit BACKUP_MSG="Backed up $Info_Node to ${Info_Node}.old." HANGUP_MSG="Hang up on \"update-info $ARGUMENTS\"" INSERT_MSG="menu item(s) were inserted (not counting duplicates)." INSERT_MSG2="total menu item(s) were inserted into `pwd`/$Info_Node" DELETE_MSG="invalid menu item(s) were removed (not counting duplicates)." DELETE_MSG2="total invalid menu item(s) were removed from `pwd`/$Info_Node" 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 if test -f "$Info_Node"; then rm -f ${Info_Node}.old mv "$Info_Node" "${Info_Node}.old" echo "$BACKUP_MSG" fi echo "Creating new Info Node: `pwd`/$Info_Node" cat>$Info_Node<" visits Texinfo topic, etc. Or click mouse button 2 on a menu item or cross reference to select it. --- PLEASE ADD DOCUMENTATION TO THIS TREE. (See INFO topic first.) --- * Menu: The list of major topics begins on the next line. NodeEndOfFile else if test ! -f "$Info_Node"; then echo "$0:$LINENO: $Info_Node is irregular or nonexistant">&2 exit 2 elif test ! -r "$Info_Node"; then echo "$0:$LINENO: $Info_Node is not readable">&2 exit 2 elif test ! -w "$Info_Node"; then echo "$0:$LINENO: $Info_Node is not writeable">&2 exit 2 fi fi if test "$Load_Functions" -a "$Interactive" -a -z "$Mode"; then if FUNCTIONS_VERSION=`( update-info.f )`; then if test `echo "$FUNCTIONS_VERSION"\ |cut -d' ' -f5` = "@UPDATE_INFO_VERSION@"; then echo "Loading functions..." . update-info.f else echo "$0:$LINENO: wrong version of update-info.f">&2 echo "(functions were not loaded)">&2 fi else echo "(functions were not loaded)">&2 fi fi trap ' eval "$Debug"; rm -f $TMP_FILE_LIST; exit ' 0 if test "$Interactive"; then if test ! -t "1"; then echo "$0:$LINENO: Cannot run in interactive mode "\ "standard out is redirected">&2 exit 2 fi trap ' ' 2 3 else trap ' rm -f $TMP_FILE_LIST echo "$0:$LINENO: received INT signal. All edits are canceled.">&2 exit ' 2 trap ' rm -f $TMP_FILE_LIST echo "$0:$LINENO: received QUIT signal. All edits are canceled.">&2 exit ' 3 fi if test -z "$Mode"; then trap ' if test "$Changed"; then { echo $HANGUP_MSG @F_INSERT_MISSING@ Inserts_Total=`wc -c<"$TMP_COUNT"` echo $Inserts_Total $INSERT_MSG2 }|mail "$LOGNAME" fi rm -f $TMP_FILE_LIST exit ' 1 else trap ' if test "$Changed"; then { echo $HANGUP_MSG @F_DELETE_INVALID@ Invalid_Total=`wc -l<"$TMP_SED"` echo $Invalid_Total $DELETE_MSG2 }|mail $LOGNAME fi rm -f $TMP_FILE_LIST exit ' 1 fi sed -e "1,/$MENU_BEGIN/d" -e "$MENU_FILTER1" -e "$MENU_FILTER2"<$Info_Node\ |tee $TMP_MENU\ |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 '/:$/d' -e '/^$/d' -e "/^${Info_Node}~\$/d"\ -e "/^${Info_Node}\$/d" -e "/^${Info_Node}.old\$/d"\ -e 's/\.gz$//' -e 's/\.info$//'|sort>$TMP_FILE2 if test -z "$Mode"; then #Detect Missing comm -13 $TMP_FILE1 $TMP_FILE2>$TMP_LIST cat$TMP_COUNT #get sections, initialize variables sed -n -e "/$SECTION_TITLE/p" "$TMP_MENU">"$TMP_SECTIONS" Item_Num=`wc -l<"$TMP_SECTIONS"|tr -d ' '` Item_Status=`echo\ |awk "BEGIN{for(i=1;i<=${Item_Num};i++)printf(\"_\n\")}"` Item_Dir="$Item_Num" for Info_Name in `cat $TMP_LIST` 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 fi #generate menu item echo|tr -d '\012'>$TMP_FILE1 eval $CAT_COMMAND "$Info_File"\ |sed -n -e "/$DIR_SECTION/w $TMP_FILE1"\ -e "/$ENTRY_START/,/$ENTRY_END/{ $MENU_FILTER1 p }"|awk "BEGIN{Mode=0} /^$/{if(Mode==1)exit} /^([ ])+([^ ])+/{if(Mode==1)print} /^[^ ]/{if(Mode==1)exit} /${MENU_ITEM}${Info_Name}\)\./{if(Mode==0){Mode++ print} else exit}">"$TMP_ITEM" if test ! -s "$TMP_ITEM"; then echo "* $Info_Name: ($Info_Name).">"$TMP_ITEM" fi Item_Status=`echo "$Item_Status"|sed -e '1,$s/^./_/'` if test -s "$TMP_FILE1"; then Item_Section=`sed -e "s/$DIR_SECTION[ ]*//"\ <$TMP_FILE1` else Item_Section=`echo "Miscellaneous"` fi Size=`echo "$Item_Section"|wc -l|tr -d ' '` # initialize variables, check for new sections Num1=1 while test "$Num1" -le "$Size" do Item=`echo "$Item_Section"|sed -n -e "${Num1}p"` if Num=`grep -in "^$Item$" "$TMP_SECTIONS"`; then Num=`echo "$Num"|sed -e 's/:.*$//g'` ##F#Set_Item set "$Num" "X" @SET_ITEM@ else set "$Item" @F_ADD_SECTION@ fi Num1=`expr "$Num1" + "1"` done if test "$Interactive"; then echo "$Item_Section" cat "$TMP_ITEM" echo "add menu item for $Info_File? " while true do echo "$PROMPT1"|tr -d '\012' read Answer case $Answer in y) break;; e) if test "$FUNCTIONS"; then Select_Sections break else echo "Can't edit. "\ "Functions are not loaded.">&2 fi;; Y) Interactive=""; break;; n) continue 2;; N) break 2;; *) echo "\"$Answer\" "\ "is an invalid response">&2;; esac done fi if echo "$Item_Status"|grep '^X'>/dev/null; then # edit $TMP_MENU Changed="y" ( trap ' ' 1 2 3 Tmp_Var=`echo "$Item_Status"|tr -d '\012'` Key=`awk -F':' ' FNR==1{ print $1}' $TMP_ITEM` # add new sections to 'dir' file if test "$Item_Num" -gt "$Item_Dir"; then if test "$Item_Dir" -ne "0"; then sed -e "1,${Item_Dir}d" -e 'i\ ' "$TMP_SECTIONS">>"$TMP_MENU" else sed -e 'i\ ' "$TMP_SECTIONS">>"$TMP_MENU" fi fi # awk determines the insertion points for each section awk -F":" "function Insert(Line){ if(Mode==2){ Mode=1;if(substr(\"$Tmp_Var\",Item++,1)==\"X\") print Line } } BEGIN{Mode=1;Item=1} /$SECTION_TITLE/{Insert(FNR-1);if(Mode>=1)Mode=2} /${MENU_ITEM}.*\)\./{if(\$1>Item_Name)Insert(FNR-1)} /^$/{Insert(FNR-1)} END{Insert(FNR)}" Item_Name="$Key" "$TMP_MENU"\ |sort -nr|sed -e "s%\$% r $TMP_ITEM%"|sed -e '$a\ w ' -e '$a\ q '|ed -s "$TMP_MENU" echo "$Item_Status"|tr -cd "X">>$TMP_COUNT ) Inserts=`expr "$Inserts" + "1"` echo "$Info_File installed into section(s):"\ |tr -d '\012' echo "$Item_Status"|awk '/X/{printf(" %d", FNR)}' echo Item_Dir="$Item_Num" else echo "$Info_File not installed (no section selected)" fi done # print summary trap ' ' 1 2 3 if test "$Changed"; then @F_INSERT_MISSING@ Inserts_Total=`wc -c<"$TMP_COUNT"|tr -d " "` if test "$Inserts" -ne "$Inserts_Total"; then echo "$Inserts $INSERT_MSG" fi echo "$Inserts_Total $INSERT_MSG2" fi else # Detect Invalid cat"$TMP_SED" comm -23 $TMP_FILE1 $TMP_FILE2>$TMP_LIST for Info_Name in `cat $TMP_LIST` do if test "$Interactive"; then # display invalid menu item(s) awk "BEGIN{Mode=1} /^([ ])+([^ ])+/{if(Mode==2)print} /^$/{if(Mode==2)Mode=1} /$SECTION_TITLE/{Section=\$0} /^[^ ]/{if(Mode==2)Mode=1} /${MENU_ITEM}${Info_Name}\)\./{if(Mode==1){Mode++ print Section print}}" $TMP_MENU echo "delete menu item for $Info_Name? " while true do echo\ "(y=yes, n=no, Y=yes to all, N=No to all):"\ |tr -d '\012' read Answer case "$Answer" in y) break;; Y) Interactive=""; break;; n) continue 2;; N) break 2;; *) echo "\"$Answer\" "\ "is an invalid reponse">&2;; esac done fi # remove menu item from $TMP_MENU Invalid=`expr "$Invalid" + "1"` Changed="y" ( trap ' ' 1 2 3 echo\ "invalid menu item for $Info_Name removed from section(s):"\ |tr -d '\012' awk "function Delete(Last){ printf(\"%d,%dd\n\",First,Last-1)>>\"$TMP_SED\"} BEGIN{Mode=1;Section=0} /^$/{if(Mode==2){Delete(FNR);Mode=1}} /$SECTION_TITLE/{Section++} /^[^ ]/{if(Mode==2){Delete(FNR);Mode=1}} /${MENU_ITEM}${Info_Name}\)\./{if(Mode==1){ First=FNR;printf(\" %d\",Section);Mode=2}} END{if(Mode==2)Delete(FNR+1)}" $TMP_MENU echo ) done # display a summary trap ' ' 1 2 3 if test "$Changed"; then Invalid_Total=`wc -l<"$TMP_SED"|tr -d ' '` @F_DELETE_INVALID@ if test "$Invalid" -ne "$Invalid_Total"; then echo "$Invalid $DELETE_MSG" fi echo "$Invalid_Total $DELETE_MSG2" fi fi if test -z "$Changed"; then echo "Nothing to do" fi rm -f $TMP_FILE_LIST eval "$Debug" exit 0 # _file: 'update-info.f'_ #update-info.f (GNU texinfo @TEXINFO_VERSION@) @UPDATE_INFO_VERSION@ #Copyright (C) 1997 Free Software Foundation, Inc. #update-info comes with NO WARRANTY, to the extent permitted by law. #You may redistribute copies of update-info #under the terms of the GNU General Public License. #For more information about these matters, see the files named COPYING." #Author: Richard L. Hawes # update-info.f functions for update-info # ###SECTION 1### functions used to insert missing menu items Set_Item (){ # set item status @SET_ITEM@ } Add_Section (){ # add a section @F_ADD_SECTION@ } # ###SECTION 2### functions for menu selection of sections Print (){ # print a line without a linefeed echo "$*"|tr -d '\012' } Get_Answer (){ # get an answer to question _gs_Valid="$1" _gs_Prompt="$2" set -f Answer="" while test -z "$Answer" do Print "$_gs_Prompt" if read Answer; then : else Answer="$CONTROL_D" echo fi if expr "$Answer" : "[$_gs_Valid]$">/dev/null; then : else Print "\"$Answer\" is not a valid response! --">&2 Answer="" fi done set +f } Do_Previous (){ # go to previous screen if test "$Previous"; then Next="$Top_Item" Top_Item="$Previous" if Previous=`expr "$Top_Item" - "$DISPLAY_NUM"`; then if test "$Previous" -le "0"; then Previous="" fi else Previous="" fi elif test "$Next"; then Last_Page else Print "There is no previous page. ">&2 fi } Do_Next (){ # process go to next if test "$Next"; then Previous="$Top_Item" Top_Item="$Next" Set_Next elif test "$Previous"; then Top_Item="1" Previous="" Set_Next else Print "There is no next page. ">&2 fi } Do_Add_Section (){ # process add section command echo echo "Please enter the name of the new section:" if read Answer; then Answer=`echo "$Answer"\ |sed -e 's/^\([ ]\)\{1,\}//g' -e "$MENU_FILTER2"` if test "$Answer"; then Add_Section "$Answer" Last_Page clear fi else Answer="" fi if test -z "$Answer"; then clear Print "no section added. " fi } Do_Edit (){ # process edit item command if test -t "2"; then _de_Done="" cp "$TMP_ITEM" "$TMP_FILE1" while test -z "$_de_Done" do eval $EDITOR "$TMP_FILE1" clear _de_Done="t" if sed -n -e "$MENU_FILTER1" -e '1p' "$TMP_FILE1"\ |egrep "${MENU_ITEM}${Info_Name}\)\.">/dev/null; then : else sed -n -e '1p' "$TMP_FILE1" echo "Pattern mismatch: `echo\ "/${MENU_ITEM}${Info_Name}\)\./"\ |tr -d "\011"`">&2 echo _de_Done="" fi if sed -n -e '2,$p' "$TMP_FILE1"|grep '^[^ ]'>&2; then echo "These lines must have leading spaces">&2 echo _de_Done="" fi if test -z "$_de_Done"; then Get_Answer "yn" "Invalid entry, cancel edits? (y or n):" if test "y" = "$Answer"; then clear Print "Canceling edits -- invalid entry ">&2 _de_Done="t" fi else sed -e "$MENU_FILTER1" -e "$MENU_FILTER2" -e '/^$/d'\ <"$TMP_FILE1">"$TMP_ITEM" fi done else Print "editor cannot run with error path redirected " fi } Do_Number (){ # process number _dn_Num="$1" if test "$_dn_Num" -ge 1 -a "$_dn_Num" -le "$Item_Num"; then if test `echo "$Item_Status"|sed -n -e "${_dn_Num}p"` = "_"; then Set_Item "$_dn_Num" "X" else Set_Item "$_dn_Num" "_" fi else Print "\"$_dn_Num\" is an invalid section number. ">&2 fi } Do_Help (){ # process menu help echo echo "\ Enter the following commands seperated by spaces and terminated by: # : (section number) toggle section a : add a new section e : edit item -- changes will not be accepted if you change the '(info_file_name).' or delete the key parts: '*' 'Menu Name' ':' h : get this help screen n : next page p : previous page q : quit and do not put into menu s : save and put into menu" Print "Press enter to continue:" read junk clear } Set_Next (){ # determine value of Next Next=`expr "$DISPLAY_NUM" + "$Top_Item"` if test "$Next" -gt "$Item_Num"; then Next="" fi } Last_Page (){ # go to last page of menu Top_Item=`echo|awk "BEGIN{printf(\"%d\", int((${Item_Num}-1)/${DISPLAY_NUM})*${DISPLAY_NUM}+1)}"` if test "$Top_Item" -gt "$DISPLAY_NUM"; then Previous=`expr "$Top_Item" '-' "$DISPLAY_NUM"` else Previous="" fi Set_Next } Select_Sections (){ # prompt user for which sections set -f Top_Item="1" Previous="" Set_Next clear echo "Default sections are selected." Done="" while test -z "$Done" do awk "FNR==1{printf(\"%s\n\", substr(\$0,1,${COLUMNS}))}" $TMP_ITEM Tmp_Var=`echo "$Item_Status"|tr -d '\012'` awk "BEGIN{Max=$Top_Item+$DISPLAY_NUM} FNR>=$Top_Item{if(FNR>=Max)exit printf(\"%2d:%s %s\n\",FNR,substr(\"$Tmp_Var\",FNR,1), substr(\$0,1,${COLUMNS}-5))}" "$TMP_SECTIONS" echo "Enter 1-${Item_Num}, add, edit, help," if test "$Previous" -o "$Next"; then Print "next, previous, " fi Print "quit, save :" read Command_List||Command_List="$CONTROL_D" Command_List=`echo "$Command_List"\ |tr '\011' ' '|tr ' ' '\012'|sed -e "/^$/d"` clear if test -z "$Command_List"; then Help="y" else Help="" fi while test "$Command_List" do Command=`echo "$Command_List"|sed -n -e '1p'` Command_List=`echo "$Command_List"|sed -e '1d'` case "$Command" in [0-9]|[0-9][0-9]) Do_Number "$Command";; n*) Do_Next;; p*) Do_Previous;; a*) Do_Add_Section;; e*) Do_Edit; break;; h*) Help="y";; s*) Done="s"; break;; q*) Done="q" Item_Status=`echo "$Item_Status"|sed -e '1,$s/^./_/'` break;; *) Print "$Command is not a valid command. ">&2 Help="y";; esac done if test "$Help"; then Do_Help fi echo done set +f # if new sections added, remove unused ones if test "$Item_Num" -gt "$Item_Dir"; then Tmp_Var=`echo "$Item_Status"|awk "FNR>$Item_Dir{ if(\\$0==\"_\")printf(\"%d\n\", FNR)}"` if test "$Tmp_Var"; then Tmp_Var1=`echo "$Tmp_Var"|sed -e 's/$/d/'` sed -e "$Tmp_Var1" "$TMP_SECTIONS">$TMP_FILE1 cp $TMP_FILE1 "$TMP_SECTIONS" Item_Status=`echo "$Item_Status"|sed -e "$Tmp_Var1"` Tmp_Var="" Tmp_Var1="" Item_Num=`wc -l<"$TMP_SECTIONS"|tr -d ' '` fi fi } # ###SECTION 100### Constants that redefine PROMPT1="(y=yes, e=edit, Y=yes to all, n=no, N=No to all):" FUNCTIONS="y" # echo "update-info.f (GNU texinfo @TEXINFO_VERSION@) @UPDATE_INFO_VERSION@" texinfo-3.12/util/fixfonts0000775000175000017500000000467005363505733013136 0ustar gg#!/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 texinfo-3.12/util/texi2dvi0000555000175000017500000003353606475355352013040 0ustar gg#! /bin/sh # texi2dvi --- smartly produce DVI files from texinfo sources # $Id: texi2dvi,v 0.8 1998/02/26 21:13:13 karl Exp $ # # Copyright (C) 1992, 93, 94, 95, 96, 97, 98 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. # # Commentary: # # 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. # # In the interest of general portability, some common bourne shell # constructs were avoided because they weren't guaranteed to be available # in some earlier implementations. I've tried to make this program as # portable as possible. Welcome to unix, where the lowest common # denominator is rapidly diminishing. # # Among the more interesting lossages I noticed among Bourne shells: # * No shell functions. # * No `unset' builtin. # * `shift' cannot take a numeric argument, and signals an error if # there are no arguments to shift. # # Code: # Name by which this script was invoked. progname=`echo "$0" | sed -e 's/[^\/]*\///g'` # This string is expanded by rcs automatically when this file is checked out. rcs_revision='$Revision: 0.8 $' version=`set - $rcs_revision; echo $2` # To prevent hairy quoting and escaping later. bq='`' eq="'" usage="Usage: $0 [OPTION]... FILE... Run a Texinfo document through TeX. Options: -b, --batch No interaction (\nonstopmode in TeX). -c, --clean Remove all auxiliary files. -D, --debug Turn on shell debugging ($bq${bq}set -x$eq$eq). -t, --texinfo CMD Insert CMD after @setfilename before running TeX. --verbose Report on what is done. -h, --help Display this help and exit. -v, --version Display version information and exit. The values of the TEX, TEXINDEX, and MAKEINFO environment variables are used to run those commands, if they are set. Email bug reports to bug-texinfo@gnu.org." # Initialize variables. # Don't use `unset' since old bourne shells don't have this command. # Instead, assign them an empty value. # Some of these, like TEX and TEXINDEX, may be inherited from the environment. backup_extension=.bak # these files get deleted if all goes well. batch= clean= debug= orig_pwd="`pwd`" textra= verbose=false makeinfo="${MAKEINFO-makeinfo}" texindex="${TEXINDEX-texindex}" tex="${TEX-tex}" # Save this so we can construct a new TEXINPUTS path for each file. TEXINPUTS_orig="$TEXINPUTS" export TEXINPUTS # Parse command line arguments. # Make sure that all wildcarded options are long enough to be unambiguous. # It's a good idea to document the full long option name in each case. # Long options which take arguments will need a `*' appended to the # canonical name to match the value appended after the `=' character. while :; do test $# -eq 0 && break case "$1" in -b | --batch | --b* ) batch=t; shift ;; -c | --clean | --c* ) clean=t; shift ;; -D | --debug | --d* ) debug=t; shift ;; -h | --help | --h* ) echo "$usage"; exit 0 ;; # OK, we should do real option parsing here, but be lazy for now. -t | --texinfo | --t*) shift; textra="$textra $1"; shift ;; -v | --vers* ) echo "$progname (GNU Texinfo 3.12) $version" echo "Copyright (C) 1998 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." exit 0 ;; --verb* ) verbose=echo; shift ;; -- ) # Stop option processing shift break ;; -* ) case "$1" in --*=* ) arg=`echo "$1" | sed -e 's/=.*//'` ;; * ) arg="$1" ;; esac exec 1>&2 echo "$progname: Unknown or ambiguous option $bq$arg$eq." echo "$progname: Try $bq--help$eq for more information." exit 1 ;; * ) break ;; esac done # See if there are any command line args left (which will be interpreted as # filename arguments). if test $# -eq 0; then exec 1>&2 echo "$progname: At least one file name is required as an argument." echo "$progname: Try $bq--help$eq for more information." exit 2 fi test "$debug" = t && set -x # Texify files for command_line_filename in ${1+"$@"}; do $verbose "Processing $command_line_filename ..." # See if 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 index files and so forth. if test ! -r "${command_line_filename}"; then echo "$0: Could not read ${command_line_filename}." >&2 continue fi # Roughly equivalent to `dirname ...`, but more portable directory="`echo ${command_line_filename} | sed 's/\/[^\/]*$//'`" filename_texi="`basename ${command_line_filename}`" # Strip off the last extension part (probably .texinfo or .texi) filename_noext="`echo ${filename_texi} | sed 's/\.[^.]*$//'`" # Use same basename since we want to generate aux files with the same # basename as the manual. Use extension .texi for the temp file so # that TeX will ignore it. Thus, we must use a subdirectory. # # Output the macro-expanded file to here. The vastly abbreviated # temporary directory name is so we don't have collisions on 8.3 or # 14-character filesystems. tmp_dir=${TMPDIR-/tmp}/txi2d.$$ filename_tmp=$tmp_dir/$filename_noext.texi # Output the file with the user's extra commands to here. tmp_dir2=${tmp_dir}.2 filename_tmp2=$tmp_dir2/$filename_noext.texi mkdir $tmp_dir $tmp_dir2 # Always remove the temporary directories. trap "rm -rf $tmp_dir $tmp_dir2" 1 2 15 # If directory and file are the same, then it's probably because there's # no pathname component. Set dirname to `.', the current directory. if test "z${directory}" = "z${command_line_filename}"; then directory=. fi # Source file might @include additional texinfo sources. Put `.' and # directory where source file(s) reside in TEXINPUTS before anything # else. `.' goes first to ensure that any old .aux, .cps, etc. files in # ${directory} don't get used in preference to fresher files in `.'. TEXINPUTS=".:${directory}:${TEXINPUTS_orig}" # Expand macro commands in the original source file using Makeinfo; # the macro syntax bfox implemented is impossible to implement in TeX. # 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. # Redirect output to /dev/null to throw away `Making info file...' msg. $verbose "Macro-expanding $command_line_filename to $filename_tmp ..." $makeinfo --footnote-style=end -E $filename_tmp -o /dev/null \ $command_line_filename >/dev/null # But if there were no macros, or makeinfo failed for some reason, # just use the original file. (It shouldn't make any difference, but # let's be safe.) if test $? -ne 0 || cmp -s $filename_tmp $command_line_filename; then $verbose "Reverting to $command_line_filename ..." cp -p $command_line_filename $filename_tmp fi filename_input=$filename_tmp dirname_input=$tmp_dir # Used most commonly for @finalout, @smallbook, etc. if test -n "$textra"; then $verbose "Inserting extra commands: $textra." sed '/^@setfilename/a\ '"$textra" $filename_input >$filename_tmp2 filename_input=$filename_tmp2 dirname_input=$tmp_dir2 fi # If clean mode was specified, then move to the temporary directory. if test "$clean" = t; then $verbose "cd $dirname_input" cd $dirname_input || exit 1 filename_input=`basename $filename_input` fi while true; do # will break out of loop below # "Unset" variables that might have values from previous iterations and # which won't be completely reset later. definite_index_files= # Find all files having root filename with a two-letter extension, # determine whether they're really index files, and save them. Foo.aux # is actually the cross-references file, but we need to keep track of # that too. possible_index_files="`eval echo ${filename_noext}.?? ${filename_noext}.aux`" for this_file in ${possible_index_files}; do # If file is empty, forget it. test -s "${this_file}" || continue # Examine first character of file. If it's not suitable to be an # index or xref file, don't process it. first_character="`sed -n '1s/^\(.\).*$/\1/p;q' ${this_file}`" if test "x${first_character}" = "x\\" \ || test "x${first_character}" = "x'"; then definite_index_files="${definite_index_files} ${this_file}" fi done orig_index_files="${definite_index_files}" orig_index_files_sans_aux="`echo ${definite_index_files} \ | sed 's/'${filename_noext}'\.aux//; s/^[ ]*//;s/[ ]*$//;'`" # Now save copies of original index files so we have some means of # comparison later. $verbose "Backing up current index files: $orig_index_files ..." for index_file_to_save in ${orig_index_files}; do cp "${index_file_to_save}" "${index_file_to_save}${backup_extension}" done # Run texindex 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 "${orig_index_files_sans_aux}"; then $verbose "Running $texindex $orig_index_files_sans_aux ..." ${texindex} ${orig_index_files_sans_aux} fi # Finally, run TeX. if test "$batch" = t; then tex_mode='\nonstopmode' else tex_mode= fi $verbose "Running $tex $filename_input ..." cmd="$tex $tex_mode \\input $filename_input" $cmd # Check if index files changed. # definite_index_files= # Get list of new index files. possible_index_files="`eval echo ${filename_noext}.?? ${filename_noext}.aux`" for this_file in ${possible_index_files}; do # If file is empty, forget it. test -s "${this_file}" || continue # Examine first character of file. If it's not a backslash or # single quote, then it's definitely not an index or xref file. # (Will have to check for @ when we switch to Texinfo syntax in # all these files...) first_character="`sed -n '1s/^\(.\).*$/\1/p;q' ${this_file}`" if test "x${first_character}" = "x\\" \ || test "x${first_character}" = "x'"; then definite_index_files="${definite_index_files} ${this_file}" fi done new_index_files="${definite_index_files}" new_index_files_sans_aux="`echo ${definite_index_files} \ | sed 's/'${filename_noext}'\.aux//; s/^[ ]*//;s/[ ]*$//;'`" # If old and new list don't at least have the same file list, then one # file or another has definitely changed. $verbose "Original index files =$orig_index_files" $verbose "New index files =$new_index_files" if test "z${orig_index_files}" != "z${new_index_files}"; then index_files_changed_p=t else # File list is the same. We must compare each file until we find a # difference. index_files_changed_p= for this_file in ${new_index_files}; do $verbose "Comparing index file $this_file ..." # cmp -s will return nonzero exit status if files differ. cmp -s "${this_file}" "${this_file}${backup_extension}" if test $? -ne 0; then # We only need to keep comparing until we find *one* that # differs, because we'll have to run texindex & tex no # matter what. index_files_changed_p=t $verbose "Index file $this_file differed:" test $verbose = echo \ && diff -c "${this_file}${backup_extension}" "${this_file}" break fi done fi # If index files have changed since TeX has been run, or if the aux # file wasn't present originally, run texindex and TeX again. if test "${index_files_changed_p}"; then :; else # Nothing changed. We're done with TeX. break fi done # If we were in clean mode, compilation was in a tmp directory. # Copy the DVI 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 $verbose "Copying DVI file from `pwd` to $orig_pwd" cp -p $filename_noext.dvi $orig_pwd cd $orig_pwd || exit 1 fi # Generate list of files to delete, then call rm once with the entire # list. This is significantly faster than multiple executions of rm. file_list= for file in ${orig_index_files}; do file_list="${file_list} ${file}${backup_extension}" done if test -n "${file_list}"; then $verbose "Removing $file_list $tmp_dir $tmp_dir2 ..." rm -f ${file_list} rm -rf $tmp_dir $tmp_dir2 fi done $verbose "$0 done." true # exit successfully. texinfo-3.12/util/gen-dir-node0000555000175000017500000001264406341141216013527 0ustar gg#!/bin/sh # $Id: gen-dir-node,v 1.1 1997/05/22 22:02:43 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 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 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 "d" returns here, "q" exits, "?" lists all INFO commands, "h" gives a primer for first-timers, "mTexinfo" visits Texinfo topic, etc. Or click mouse button 2 on a menu item or cross reference to select it. --- PLEASE ADD DOCUMENTATION TO THIS TREE. (See INFO topic first.) --- * 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}; ls | 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" -a ! -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" -a ! -z "$noext" ]; then fname=$file warn="### Warning: $ext and $noext both exist! Using ${file}. ###" elif [ ! \( -z "$ext" -a -z "$noext" \) ]; 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}: (${fname})." fi fi # remove the name from the directory listing infofiles=`echo ${infofiles} | sed -e "s/ ${fname} / /" \ -e "s/^${fname} //" \ -e "s/ ${fname}$//"` fi fi done line=`expr $line + 1` done if [ -z "${infofiles}" ] ; then exit 0 else echo fi for file in ${infofiles}; do case $file in *.gz) zcat=zcat; file=`echo $file|sed 's/\.gz$//'`; gz=.gz;; *) zcat=cat; gz=;; esac infoname=`echo $file | sed 's/\.info$//'` entry=`$zcat ${INFODIR}/${file}$gz \ |sed -e '1,/START-INFO-DIR-ENTRY/d' \ -e '/END-INFO-DIR-ENTRY/,$d'` if [ ! -z "${entry}" ] ; then echo "${entry}" else echo "* ${infoname}: (${file})." fi done texinfo-3.12/util/Makefile.am0000444000175000017500000000067106362746071013377 0ustar gg## Makefile.am for texinfo/util. ## $Id: Makefile.am,v 1.6 1997/07/15 19:15:05 karl Exp $ ## Run automake in .. to produce Makefile.in from this. bin_PROGRAMS = install-info texindex bin_SCRIPTS = texi2dvi localedir = $(datadir)/locale INCLUDES = -I$(top_srcdir)/lib -I../intl -DLOCALEDIR=\"$(localedir)\" LDADD = ../lib/libtxi.a @INTLLIBS@ EXTRA_DIST = README deref.c fixfonts gen-dir-node tex3patch texi2dvi \ update-info texinfo-3.12/util/README0000664000175000017500000000025106475365755012234 0ustar ggAssorted Texinfo-related programs and scripts. texindex, texi2dvi, and install-info get installed. The other items here are for your amusement and/or hacking pleasure. texinfo-3.12/doc/0000775000175000017500000000000006477056762011143 5ustar ggtexinfo-3.12/doc/Makefile.in0000664000175000017500000002213506477056761013212 0ustar gg# Makefile.in generated automatically by automake 1.2f from Makefile.am # Copyright (C) 1994, 1995, 1996, 1997, 1998 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. SHELL = /bin/sh srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ bindir = @bindir@ sbindir = @sbindir@ libexecdir = @libexecdir@ datadir = @datadir@ sysconfdir = @sysconfdir@ sharedstatedir = @sharedstatedir@ localstatedir = @localstatedir@ libdir = @libdir@ infodir = @infodir@ mandir = @mandir@ includedir = @includedir@ oldincludedir = /usr/include pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. ACLOCAL = @ACLOCAL@ AUTOCONF = @AUTOCONF@ AUTOMAKE = @AUTOMAKE@ AUTOHEADER = @AUTOHEADER@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ transform = @program_transform_name@ NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : CATALOGS = @CATALOGS@ CATOBJEXT = @CATOBJEXT@ CC = @CC@ DATADIRNAME = @DATADIRNAME@ GENCAT = @GENCAT@ GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ GT_NO = @GT_NO@ GT_YES = @GT_YES@ INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@ INSTOBJEXT = @INSTOBJEXT@ INTLDEPS = @INTLDEPS@ INTLLIBS = @INTLLIBS@ INTLOBJS = @INTLOBJS@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ PACKAGE = @PACKAGE@ POFILES = @POFILES@ POSUB = @POSUB@ RANLIB = @RANLIB@ TERMLIBS = @TERMLIBS@ TEXCONFIG = @TEXCONFIG@ USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ l = @l@ info_TEXINFOS = info-stnd.texi info.texi texinfo.txi # Use the programs built in our distribution. MAKEINFO = ../makeinfo/makeinfo INSTALL_INFO = ../util/install-info # Include our texinfo.tex, not Automake's. EXTRA_DIST = macro.texi userdoc.texi epsf.tex texinfo.tex # We try to discover this via configure just to give a better help message. TEXMF = @TEXMF@ mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = ../config.h CONFIG_CLEAN_FILES = TEXI2DVI = texi2dvi TEXINFO_TEX = $(srcdir)/texinfo.tex INFO_DEPS = info-stnd.info info.info texinfo DVIS = info-stnd.dvi info.dvi texinfo.dvi TEXINFOS = info-stnd.texi info.texi texinfo.txi DIST_COMMON = README $(info_TEXINFOS) Makefile.am Makefile.in \ texinfo.tex DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) TAR = tar GZIP = --best default: all .SUFFIXES: .SUFFIXES: .dvi .info .ps .texi .texinfo .txi $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps doc/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) \ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status info-stnd.info: info-stnd.texi info-stnd.dvi: info-stnd.texi info.info: info.texi $(info_TEXINFOS) info.dvi: info.texi $(info_TEXINFOS) texinfo: texinfo.txi texinfo.dvi: texinfo.txi DVIPS = dvips .texi.dvi: TEXINPUTS=$(srcdir):$$TEXINPUTS \ MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $< .texi: @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9] cd $(srcdir) \ && $(MAKEINFO) `echo $< | sed 's,.*/,,'` .texinfo.info: @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9] cd $(srcdir) \ && $(MAKEINFO) `echo $< | sed 's,.*/,,'` .texinfo: @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9] cd $(srcdir) \ && $(MAKEINFO) `echo $< | sed 's,.*/,,'` .texinfo.dvi: TEXINPUTS=$(srcdir):$$TEXINPUTS \ MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $< .txi.info: @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9] cd $(srcdir) \ && $(MAKEINFO) `echo $< | sed 's,.*/,,'` .txi.dvi: TEXINPUTS=$(srcdir):$$TEXINPUTS \ MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $< .txi: @cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9] cd $(srcdir) \ && $(MAKEINFO) `echo $< | sed 's,.*/,,'` .dvi.ps: $(DVIPS) $< -o $@ uninstall-info: $(PRE_UNINSTALL) @if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \ ii=yes; \ else ii=; fi; \ for file in $(INFO_DEPS); do \ test -z "$ii" \ || install-info --info-dir=$(infodir) --remove $$file; \ done @$(NORMAL_UNINSTALL) for file in $(INFO_DEPS); do \ (cd $(infodir) && rm -f $$file $$file-[0-9] $$file-[0-9][0-9]); \ done mostlyclean-aminfo: -rm -f info-stnd.aux info-stnd.cp info-stnd.cps info-stnd.dvi \ info-stnd.fn info-stnd.fns info-stnd.ky info-stnd.kys \ info-stnd.ps info-stnd.log info-stnd.pg info-stnd.toc \ info-stnd.tp info-stnd.tps info-stnd.vr info-stnd.vrs \ info-stnd.op info-stnd.tr info-stnd.cv info-stnd.cn info.aux \ info.cp info.cps info.dvi info.fn info.fns info.ky info.kys \ info.ps info.log info.pg info.toc info.tp info.tps info.vr \ info.vrs info.op info.tr info.cv info.cn texinfo.aux \ texinfo.cp texinfo.cps texinfo.dvi texinfo.fn texinfo.fns \ texinfo.ky texinfo.kys texinfo.ps texinfo.log texinfo.pg \ texinfo.toc texinfo.tp texinfo.tps texinfo.vr texinfo.vrs \ texinfo.op texinfo.tr texinfo.cv texinfo.cn clean-aminfo: distclean-aminfo: maintainer-clean-aminfo: for i in $(INFO_DEPS); do \ rm -f $$i; \ if test "`echo $$i-[0-9]*`" != "$$i-[0-9]*"; then \ rm -f $$i-[0-9]*; \ fi; \ done tags: TAGS TAGS: distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) subdir = doc distdir: $(DISTFILES) @for file in $(DISTFILES); do \ d=$(srcdir); \ test -f $(distdir)/$$file \ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ || cp -p $$d/$$file $(distdir)/$$file; \ done $(MAKE) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-info info: $(INFO_DEPS) dvi: $(DVIS) check: all $(MAKE) installcheck: install-exec: @$(NORMAL_INSTALL) install-data: install-info-am install-data-local @$(NORMAL_INSTALL) install: install-exec install-data all @: uninstall: uninstall-info all: Makefile $(INFO_DEPS) install-strip: $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install installdirs: $(mkinstalldirs) $(infodir) mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -rm -f Makefile $(DISTCLEANFILES) -rm -f config.cache config.log stamp-h stamp-h[0-9]* -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) mostlyclean: mostlyclean-aminfo mostlyclean-generic clean: clean-aminfo clean-generic mostlyclean distclean: distclean-aminfo distclean-generic clean -rm -f config.status maintainer-clean: maintainer-clean-aminfo maintainer-clean-generic \ distclean @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." .PHONY: default install-info-am uninstall-info mostlyclean-aminfo \ distclean-aminfo clean-aminfo maintainer-clean-aminfo tags distdir info \ dvi installcheck install-exec install-data install uninstall all \ installdirs mostlyclean-generic distclean-generic clean-generic \ maintainer-clean-generic clean mostlyclean distclean maintainer-clean install-data-local: @echo "WARNING: You must install texinfo.tex and epsf.tex manually," @echo "WARNING: perhaps in $(TEXMF)/tex/texinfo/" @echo "WARNING: and $(TEXMF)/tex/generic/dvips/ respectively." @echo "WARNING: See doc/README for some considerations." # Do not create info files for distribution. dist-info: # Do not try to build the info files in $(srcdir), # since we don't distribute them. .texi.info: $(MAKEINFO) -I$(srcdir) `echo $< | sed 's,.*/,,'` texinfo: $(srcdir)/texinfo.txi $(MAKEINFO) -I$(srcdir) texinfo.txi # Similarly, Do not try to install the info files from $(srcdir). install-info-am: $(INFO_DEPS) @$(NORMAL_INSTALL) $(mkinstalldirs) $(infodir) @for file in $(INFO_DEPS); do \ d=.; \ for ifile in `cd $$d && echo $$file $$file-[0-9] $$file-[0-9][0-9]`; do \ if test -f $$d/$$ifile; then \ echo " $(INSTALL_DATA) $$d/$$ifile $(infodir)/$$ifile"; \ $(INSTALL_DATA) $$d/$$ifile $(infodir)/$$ifile; \ else : ; fi; \ done; \ done @$(POST_INSTALL) @if $(SHELL) -c '$(INSTALL_INFO) --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \ for file in $(INFO_DEPS); do \ echo " $(INSTALL_INFO) --info-dir=$(infodir) $(infodir)/$$file";\ $(INSTALL_INFO) --info-dir=$(infodir) $(infodir)/$$file || :;\ done; \ else : ; fi # Remove the info files at make distclean. distclean-aminfo: rm -f texinfo texinfo-* info*.info* # 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: texinfo-3.12/doc/macro.texi0000664000175000017500000001200406223317451013114 0ustar gg@c This file is included in makeinfo.texi. @c @ifinfo @comment Here are some useful examples of the macro facility. @c Simply insert the right version of the texinfo name. @macro texinfo{} TeXinfo @end macro @macro dfn{text} @dfn{\text\} @cpindex \text\ @end macro @c Define a macro which expands to a pretty version of the name of the @c Makeinfo program. @macro makeinfo{} @code{Makeinfo} @end macro @c Define a macro which is used to define other macros. This one makes @c a macro which creates a node and gives it a sectioning command. Note @c that the created macro uses the original definition within the @c expansion text. This takes advantage of the non-recursion feature of @c macro execution. @macro node_define{orig-name} @macro \orig-name\{title} @node \title\ @\orig-name\ \title\ @end macro @end macro @c Now actually define a new set of sectioning commands. @node_define {chapter} @node_define {section} @node_define {subsection} @end ifinfo @chapter The Macro Facility This chapter describes the new macro facility. A @dfn{macro} is a command that you define in terms of other commands. It doesn't exist as a @texinfo{} command until you define it as part of the input file to @makeinfo{}. Once the command exists, it behaves much as any other @texinfo{} command. Macros are a useful way to ease the details and tedium of writing a `correct' info file. The following sections explain how to write and invoke macros. @menu * How to Use Macros in @texinfo{}:: How to use the macro facility. * Using Macros Recursively:: How to write a macro which does (or doesn't) recurse. * Using @texinfo{} Macros As Arguments:: Passing a macro as an argument. @end menu @section How to Use Macros in @texinfo{} Using macros in @texinfo{} is easy. First you define the macro. After that, the macro command is available as a normal @texinfo{} command. Here is what a definition looks like: @example @@macro @var{name}@{@var{arg1}, @var{@dots{}} @var{argn}@} @var{@texinfo{} commands@dots{}} @@end macro @end example The arguments that you specify that the macro takes are expanded with the actual parameters used when calling the macro if they are seen surrounded by backslashes. For example, here is a definition of @code{@@codeitem}, a macro which can be used wherever @code{@@item} can be used, but which surrounds its argument with @code{@@code@{@dots{}@}}. @example @@macro codeitem@{item@} @@item @@code@{\item\@} @@end macro @end example When the macro is expanded, all of the text between the @code{@@macro} and @code{@@end macro} is inserted into the document at the expansion point, with the actual parameters substituted for the named parameters. So, a call to the above macro might look like: @example @@codeitem@{Foo@} @end example and @makeinfo{} would execute the following code: @example @@item @@code@{Foo@} @end example A special case is made for macros which only take a single argument, and which are invoked without any brace characters (i.e., @samp{@{}@dots{}@samp{@}}) surrounding an argument; the rest of the line is supplied as is as the sole argument to the macro. This special case allows one to redefine some standard @texinfo{} commands without modifying the input file. Along with the non-recursive action of macro invocation, one can easily redefine the sectioning commands to also provide index entries: @example @@macro chapter@{name@} @@chapter \name\ @@findex \name\ @@end macro @end example Thus, the text: @example @@chapter strlen @end example will expand to: @example @@chapter strlen @@findex strlen @end example @section Using Macros Recursively Normally, while a particular macro is executing, any call to that macro will be seen as a call to a builtin @texinfo{} command. This allows one to redefine a builtin @texinfo{} command as a macro, and then use that command within the definition of the macro itself. For example, one might wish to make sure that whereever a term was defined with @code{@@dfn@{@dots{}@}}, the location of the definition would appear in the concept index for the manual. Here is a macro which redefines @code{@@dfn} to do just that: @example @@macro dfn@{text@} @@dfn@{\text\@} @@cpindex \text\ @@end macro @end example Note that we used the builtin @texinfo{} command @code{@@dfn} within our overriding macro definition. This behaviour itself can be overridden for macro execution by writing a special @dfn{macro control command} in the definition of the macro. The command is considered special because it doesn't affect the output text directly, rather, it affects the way in which the macro is defined. One such special command is @code{@@allow-recursion}. @example @@macro silly@{arg@} @@allow-recursion \arg\ @@end macro @end example Now @code{@@silly} is a macro that can be used within a call to itself: @example This text @@silly@{@@silly@{some text@}@} is ``some text''. @end example @section Using @texinfo{} Macros As Arguments @printindex cp How to use @texinfo{} macros as arguments to other @texinfo{} macros. @bye texinfo-3.12/doc/epsf.tex0000644000175000017500000005370006364200032012575 0ustar gg%%% ==================================================================== %%% This file is freely redistributable and placed into the %%% public domain by Tomas Rokicki. %%% @TeX-file{ %%% author = "Tom Rokicki", %%% version = "2.7k", %%% date = "19 July 1997", %%% time = "10:00:05 MDT", %%% filename = "epsf.tex", %%% address = "Tom Rokicki %%% Box 2081 %%% Stanford, CA 94309 %%% USA", %%% telephone = "+1 415 855 9989", %%% email = "rokicki@cs.stanford.edu (Internet)", %%% codetable = "ISO/ASCII", %%% keywords = "PostScript, TeX", %%% supported = "yes", %%% abstract = "This file contains macros to support the inclusion %%% of Encapsulated PostScript files in TeX documents.", %%% docstring = "This file contains TeX macros to include an %%% Encapsulated PostScript graphic. It works %%% by finding the bounding box comment, %%% calculating the correct scale values, and %%% inserting a vbox of the appropriate size at %%% the current position in the TeX document. %%% %%% To use, simply say %%% %%% \input epsf % somewhere early on in your TeX file %%% %%% % then where you want to insert a vbox for a figure: %%% \epsfbox{filename.ps} %%% %%% Alternatively, you can supply your own %%% bounding box by %%% %%% \epsfbox[0 0 30 50]{filename.ps} %%% %%% This will not read in the file, and will %%% instead use the bounding box you specify. %%% %%% The effect will be to typeset the figure as %%% a TeX box, at the point of your \epsfbox %%% command. By default, the graphic will have %%% its `natural' width (namely the width of %%% its bounding box, as described in %%% filename.ps). The TeX box will have depth %%% zero. %%% %%% You can enlarge or reduce the figure by %%% saying %%% %%% \epsfxsize= \epsfbox{filename.ps} %%% or %%% \epsfysize= \epsfbox{filename.ps} %%% %%% instead. Then the width of the TeX box will %%% be \epsfxsize and its height will be scaled %%% proportionately (or the height will be %%% \epsfysize and its width will be scaled %%% proportionately). %%% %%% The width (and height) is restored to zero %%% after each use, so \epsfxsize or \epsfysize %%% must be specified before EACH use of %%% \epsfbox. %%% %%% A more general facility for sizing is %%% available by defining the \epsfsize macro. %%% Normally you can redefine this macro to do %%% almost anything. The first parameter is %%% the natural x size of the PostScript %%% graphic, the second parameter is the %%% natural y size of the PostScript graphic. %%% It must return the xsize to use, or 0 if %%% natural scaling is to be used. Common uses %%% include: %%% %%% \epsfxsize % just leave the old value alone %%% 0pt % use the natural sizes %%% #1 % use the natural sizes %%% \hsize % scale to full width %%% 0.5#1 % scale to 50% of natural size %%% \ifnum #1>\hsize\hsize\else#1\fi %%% % smaller of natural, hsize %%% %%% If you want TeX to report the size of the %%% figure (as a message on your terminal when %%% it processes each figure), say %%% `\epsfverbosetrue'. %%% %%% If you only want to get the bounding box %%% extents, without producing any output boxes %%% or \special{}, then say %%% \epsfgetbb{filename}. The extents will be %%% saved in the macros \epsfllx \epsflly %%% \epsfurx \epsfury in PostScript units of %%% big points. %%% %%% Revision history: %%% %%% --------------------------------------------- %%% epsf.tex macro file: %%% Originally written by Tomas Rokicki of %%% Radical Eye Software, 29 Mar 1989. %%% %%% --------------------------------------------- %%% Revised by Don Knuth, 3 Jan 1990. %%% %%% --------------------------------------------- %%% Revised by Tomas Rokicki, 18 Jul 1990. %%% Accept bounding boxes with no space after %%% the colon. %%% %%% --------------------------------------------- %%% Revised by Nelson H. F. Beebe %%% , 03 Dec 1991 [2.0]. %%% Add version number and date typeout. %%% %%% Use \immediate\write16 instead of \message %%% to ensure output on new line. %%% %%% Handle nested EPS files. %%% %%% Handle %%BoundingBox: (atend) lines. %%% %%% Do not quit when blank lines are found. %%% %%% Add a few percents to remove generation of %%% spurious blank space. %%% %%% Move \special output to %%% \epsfspecial{filename} so that other macro %%% packages can input this one, then change %%% the definition of \epsfspecial to match %%% another DVI driver. %%% %%% Move size computation to \epsfsetsize which %%% can be called by the user; the verbose %%% output of the bounding box and scaled width %%% and height happens here. %%% %%% --------------------------------------------- %%% Revised by Nelson H. F. Beebe %%% , 05 May 1992 [2.1]. %%% Wrap \leavevmode\hbox{} around \vbox{} with %%% the \special so that \epsffile{} can be %%% used inside \begin{center}...\end{center} %%% %%% --------------------------------------------- %%% Revised by Nelson H. F. Beebe %%% , 09 Dec 1992 [2.2]. %%% Introduce \epsfshow{true,false} and %%% \epsfframe{true,false} macros; the latter %%% suppresses the insertion of the PostScript, %%% and instead just creates an empty box, %%% which may be handy for rapid prototyping. %%% %%% --------------------------------------------- %%% Revised by Nelson H. F. Beebe %%% , 14 Dec 1992 [2.3]. %%% Add \epsfshowfilename{true,false}. When %%% true, and \epsfshowfalse is specified, the %%% PostScript file name will be displayed %%% centered in the figure box. %%% %%% --------------------------------------------- %%% Revised by Nelson H. F. Beebe %%% , 20 June 1993 [2.4]. %%% Remove non-zero debug setting of \epsfframemargin, %%% and change margin handling to preserve EPS image %%% size and aspect ratio, so that the actual %%% box is \epsfxsize+\epsfframemargin wide by %%% \epsfysize+\epsfframemargin high. %%% Reduce output of \epsfshowfilenametrue to %%% just the bare file name. %%% %%% --------------------------------------------- %%% Revised by Nelson H. F. Beebe %%% , 13 July 1993 [2.5]. %%% Add \epsfframethickness for control of %%% \epsfframe frame lines. %%% %%% --------------------------------------------- %%% Revised by Nelson H. F. Beebe %%% , 02 July 1996 [2.6] %%% Add missing initialization \epsfatendfalse; %%% the lack of this resulted in the wrong %%% BoundingBox being picked up, mea culpa, sigh... %%% --------------------------------------------- %%% %%% --------------------------------------------- %%% Revised by Nelson H. F. Beebe %%% , 25 October 1996 [2.7] %%% Update to match changes in from dvips 5-600 %%% distribution: new user-accessible macros: %%% \epsfclipon, \epsfclipoff, \epsfdrafton, %%% \epsfdraftoff, change \empty to \epsfempty. %%% --------------------------------------------- %%% %%% Modified to avoid verbosity, give help. %%% --kb@cs.umb.edu, for Texinfo. %%% } %%% ==================================================================== % \ifx\epsfannounce\undefined \def\epsfannounce{\immediate\write16}\fi \epsfannounce{This is `epsf.tex' v2.7k <10 July 1997>}% % \newread\epsffilein % file to \read \newif\ifepsfatend % need to scan to LAST %%BoundingBox comment? \newif\ifepsfbbfound % success? \newif\ifepsfdraft % use draft mode? \newif\ifepsffileok % continue looking for the bounding box? \newif\ifepsfframe % frame the bounding box? \newif\ifepsfshow % show PostScript file, or just bounding box? \epsfshowtrue % default is to display PostScript file \newif\ifepsfshowfilename % show the file name if \epsfshowfalse specified? \newif\ifepsfverbose % report what you're making? \newdimen\epsfframemargin % margin between box and frame \newdimen\epsfframethickness % thickness of frame rules \newdimen\epsfrsize % vertical size before scaling \newdimen\epsftmp % register for arithmetic manipulation \newdimen\epsftsize % horizontal size before scaling \newdimen\epsfxsize % horizontal size after scaling \newdimen\epsfysize % vertical size after scaling \newdimen\pspoints % conversion factor % \pspoints = 1bp % Adobe points are `big' \epsfxsize = 0pt % default value, means `use natural size' \epsfysize = 0pt % ditto \epsfframemargin = 0pt % default value: frame box flush around picture \epsfframethickness = 0.4pt % TeX's default rule thickness % \def\epsfbox#1{\global\def\epsfllx{72}\global\def\epsflly{72}% \global\def\epsfurx{540}\global\def\epsfury{720}% \def\lbracket{[}\def\testit{#1}\ifx\testit\lbracket \let\next=\epsfgetlitbb\else\let\next=\epsfnormal\fi\next{#1}}% % % We use \epsfgetlitbb if the user specified an explicit bounding box, % and \epsfnormal otherwise. Because \epsfgetbb can be called % separately to retrieve the bounding box, we move the verbose % printing the bounding box extents and size on the terminal to % \epsfstatus. Therefore, when the user provided the bounding box, % \epsfgetbb will not be called, so we must call \epsfsetsize and % \epsfstatus ourselves. % \def\epsfgetlitbb#1#2 #3 #4 #5]#6{% \epsfgrab #2 #3 #4 #5 .\\% \epsfsetsize \epsfstatus{#6}% \epsfsetgraph{#6}% }% % \def\epsfnormal#1{% \epsfgetbb{#1}% \epsfsetgraph{#1}% }% % \newhelp\epsfnoopenhelp{The PostScript image file must be findable by TeX, i.e., somewhere in the TEXINPUTS (or equivalent) path.}% % \def\epsfgetbb#1{% % % The first thing we need to do is to open the % PostScript file, if possible. % \openin\epsffilein=#1 \ifeof\epsffilein \errhelp = \epsfnoopenhelp \errmessage{Could not open file #1, ignoring it}% \else %process the file {% %start a group to contain catcode changes % Make all special characters, except space, to be of type % `other' so we process the file in almost verbatim mode % (TeXbook, p. 344). \chardef\other=12 \def\do##1{\catcode`##1=\other}% \dospecials \catcode`\ =10 \epsffileoktrue %true while we are looping \epsfatendfalse %[02-Jul-1996]: add forgotten initialization \loop %reading lines from the EPS file \read\epsffilein to \epsffileline \ifeof\epsffilein %then no more input \epsffileokfalse %so set completion flag \else %otherwise process one line \expandafter\epsfaux\epsffileline:. \\% \fi \ifepsffileok \repeat \ifepsfbbfound \else \ifepsfverbose \immediate\write16{No BoundingBox comment found in % file #1; using defaults}% \fi \fi }% %end catcode changes \closein\epsffilein \fi %end of file processing \epsfsetsize %compute size parameters \epsfstatus{#1}% }% % % Clipping control: \def\epsfclipon{\def\epsfclipstring{ clip}}% \def\epsfclipoff{\def\epsfclipstring{\ifepsfdraft\space clip\fi}}% \epsfclipoff % default for dvips is OFF % % The special that is emitted by \epsfsetgraph comes from this macro. % It is defined separately to allow easy customization by other % packages that first \input epsf.tex, then redefine \epsfspecial. % This macro is invoked in the lower-left corner of a box of the % width and height determined from the arguments to \epsffile, or % from the %%BoundingBox in the EPS file itself. % % This version is for dvips: \def\epsfspecial#1{% \epsftmp=10\epsfxsize \divide\epsftmp\pspoints \ifnum\epsfrsize=0\relax \special{PSfile=\ifepsfdraft psdraft.ps\else#1\fi\space llx=\epsfllx\space lly=\epsflly\space urx=\epsfurx\space ury=\epsfury\space rwi=\number\epsftmp \epsfclipstring }% \else \epsfrsize=10\epsfysize \divide\epsfrsize\pspoints \special{PSfile=\ifepsfdraft psdraft.ps\else#1\fi\space llx=\epsfllx\space lly=\epsflly\space urx=\epsfurx\space ury=\epsfury\space rwi=\number\epsftmp rhi=\number\epsfrsize \epsfclipstring }% \fi }% % % \epsfframe macro adapted from the TeXbook, exercise 21.3, p. 223, 331. % but modified to set the box width to the natural width, rather % than the line width, and to include space for margins and rules \def\epsfframe#1% {% \leavevmode % so we can put this inside % a centered environment \setbox0 = \hbox{#1}% \dimen0 = \wd0 % natural width of argument \advance \dimen0 by 2\epsfframemargin % plus width of 2 margins \advance \dimen0 by 2\epsfframethickness % plus width of 2 rule lines \vbox {% \hrule height \epsfframethickness depth 0pt \hbox to \dimen0 {% \hss \vrule width \epsfframethickness \kern \epsfframemargin \vbox {\kern \epsfframemargin \box0 \kern \epsfframemargin }% \kern \epsfframemargin \vrule width \epsfframethickness \hss }% end hbox \hrule height 0pt depth \epsfframethickness }% end vbox }% % \def\epsfsetgraph#1% {% % % Make the vbox and stick in a \special that the DVI driver can % parse. \vfil and \hfil are used to place the \special origin at % the lower-left corner of the vbox. \epsfspecial can be redefined % to produce alternate \special syntaxes. % \leavevmode \hbox{% so we can put this in \begin{center}...\end{center} \ifepsfframe\expandafter\epsfframe\fi {\vbox to\epsfysize {% \ifepsfshow % output \special{} at lower-left corner of figure box \vfil \hbox to \epsfxsize{\epsfspecial{#1}\hfil}% \else \vfil \hbox to\epsfxsize{% \hss \ifepsfshowfilename {% \epsfframemargin=3pt % local change of margin \epsfframe{{\tt #1}}% }% \fi \hss }% \vfil \fi }% }}% % % Reset \epsfxsize and \epsfysize, as documented above. % \global\epsfxsize=0pt \global\epsfysize=0pt }% % % Now we have to calculate the scale and offset values to use. % First we compute the natural sizes. % \def\epsfsetsize {% \epsfrsize=\epsfury\pspoints \advance\epsfrsize by-\epsflly\pspoints \epsftsize=\epsfurx\pspoints \advance\epsftsize by-\epsfllx\pspoints % % If `epsfxsize' is 0, we default to the natural size of the picture. % Otherwise we scale the graph to be \epsfxsize wide. % \epsfxsize=\epsfsize{\epsftsize}{\epsfrsize}% \ifnum \epsfxsize=0 \ifnum \epsfysize=0 \epsfxsize=\epsftsize \epsfysize=\epsfrsize \epsfrsize=0pt % % We have a sticky problem here: TeX doesn't do floating point arithmetic! % Our goal is to compute y = rx/t. The following loop does this reasonably % fast, with an error of at most about 16 sp (about 1/4000 pt). % \else \epsftmp=\epsftsize \divide\epsftmp\epsfrsize \epsfxsize=\epsfysize \multiply\epsfxsize\epsftmp \multiply\epsftmp\epsfrsize \advance\epsftsize-\epsftmp \epsftmp=\epsfysize \loop \advance\epsftsize\epsftsize \divide\epsftmp 2 \ifnum \epsftmp>0 \ifnum \epsftsize<\epsfrsize \else \advance\epsftsize-\epsfrsize \advance\epsfxsize\epsftmp \fi \repeat \epsfrsize=0pt \fi \else \ifnum \epsfysize=0 \epsftmp=\epsfrsize \divide\epsftmp\epsftsize \epsfysize=\epsfxsize \multiply\epsfysize\epsftmp \multiply\epsftmp\epsftsize \advance\epsfrsize-\epsftmp \epsftmp=\epsfxsize \loop \advance\epsfrsize\epsfrsize \divide\epsftmp 2 \ifnum \epsftmp>0 \ifnum \epsfrsize<\epsftsize \else \advance\epsfrsize-\epsftsize \advance\epsfysize\epsftmp \fi \repeat \epsfrsize=0pt \else \epsfrsize=\epsfysize \fi \fi }% % % Issue some status messages if the user requested them % \def\epsfstatus#1{% arg = filename \ifepsfverbose \immediate\write16{#1: BoundingBox: llx = \epsfllx\space lly = \epsflly\space urx = \epsfurx\space ury = \epsfury\space}% \immediate\write16{#1: scaled width = \the\epsfxsize\space scaled height = \the\epsfysize}% \fi }% % % We still need to define the tricky \epsfaux macro. This requires % a couple of magic constants for comparison purposes. % {\catcode`\%=12 \global\let\epsfpercent=%\global\def\epsfbblit{%BoundingBox}}% \global\def\epsfatend{(atend)}% % % So we're ready to check for `%BoundingBox:' and to grab the % values if they are found. % % If we find a line % % %%BoundingBox: (atend) % % then we ignore it, but set a flag to force parsing all of the % file, so the last %%BoundingBox parsed will be the one used. This % is necessary, because EPS files can themselves contain other EPS % files with their own %%BoundingBox comments. % % If we find a line % % %%BoundingBox: llx lly urx ury % % then we save the 4 values in \epsfllx, \epsflly, \epsfurx, \epsfury. % Then, if we have not previously parsed an (atend), we flag completion % and can stop reading the file. Otherwise, we must keep on reading % to end of file so that we find the values on the LAST %%BoundingBox. \long\def\epsfaux#1#2:#3\\% {% \def\testit{#2}% % save second character up to just before colon \ifx#1\epsfpercent % then first char is percent (quick test) \ifx\testit\epsfbblit % then (slow test) we have %%BoundingBox \epsfgrab #3 . . . \\% \ifx\epsfllx\epsfatend % then ignore %%BoundingBox: (atend) \global\epsfatendtrue \else % else found %%BoundingBox: llx lly urx ury \ifepsfatend % then keep parsing ALL %%BoundingBox lines \else % else stop after first one parsed \epsffileokfalse \fi \global\epsfbbfoundtrue \fi \fi \fi }% % % Here we grab the values and stuff them in the appropriate definitions. % \def\epsfempty{}% \def\epsfgrab #1 #2 #3 #4 #5\\{% \global\def\epsfllx{#1}\ifx\epsfllx\epsfempty \epsfgrab #2 #3 #4 #5 .\\\else \global\def\epsflly{#2}% \global\def\epsfurx{#3}\global\def\epsfury{#4}\fi }% % % We default the epsfsize macro. % \def\epsfsize#1#2{\epsfxsize}% % % Finally, another definition for compatibility with older macros. % \let\epsffile=\epsfbox \endinput texinfo-3.12/doc/userdoc.texi0000664000175000017500000013227706355015175013502 0ustar gg@c This file is meant to be included in any arbitrary piece of @c documentation that wishes to describe the info program. Some day @c info-stnd.texi should probably use this file instead of duplicating @c its contents. @c @c This file documents the use of the standalone GNU Info program, @c versions 2.7 and later. @ifclear InfoProgVer @set InfoProgVer 2.11 @end ifclear @synindex vr cp @synindex fn cp @synindex ky cp @heading What is Info? This text documents the use of the GNU Info program, version @value{InfoProgVer}. @dfn{Info} is a program which is used to view info files on an ASCII terminal. @dfn{info files} are the result of processing texinfo files with the program @code{makeinfo} or with the Emacs command @code{M-x texinfo-format-buffer}. Finally, @dfn{texinfo} is a documentation language which allows a printed manual and online documentation (an info file) to be produced from a single source file. @menu * Options:: Options you can pass on the command line. * Cursor Commands:: Commands which move the cursor within a node. * Scrolling Commands:: Commands for moving the node around in a window. * Node Commands:: Commands for selecting a new node. * Searching Commands:: Commands for searching an info file. * Xref Commands:: Commands for selecting cross references. * Window Commands:: Commands which manipulate multiple windows. * Printing Nodes:: How to print out the contents of a node. * Miscellaneous Commands:: A few commands that defy categories. * Variables:: How to change the default behaviour of Info. @ifset NOTSET * Info for Sys Admins:: How to setup Info. Using special options. @end ifset @ifset STANDALONE * GNU Info Global Index:: Global index containing keystrokes, command names, variable names, and general concepts. @end ifset @end menu @node Options @chapter Command Line Options @cindex command line options @cindex arguments, command line GNU Info accepts several options to control the initial node being viewed, and to specify which directories to search for info files. Here is a template showing an invocation of GNU Info from the shell: @example info [--@var{option-name} @var{option-value}] @var{menu-item}@dots{} @end example The following @var{option-names} are available when invoking Info from the shell: @table @code @cindex directory path @item --directory @var{directory-path} @itemx -d @var{directory-path} Adds @var{directory-path} to the list of directory paths searched when Info needs to find a file. You may issue @code{--directory} multiple times; once for each directory which contains info files. Alternatively, you may specify a value for the environment variable @code{INFOPATH}; if @code{--directory} is not given, the value of @code{INFOPATH} is used. The value of @code{INFOPATH} is a colon separated list of directory names. If you do not supply @code{INFOPATH} or @code{--directory-path} a default path is used. @item --file @var{filename} @itemx -f @var{filename} @cindex info file, selecting Specifies a particular info file to visit. Instead of visiting the file @code{dir}, Info will start with @code{(@var{filename})Top} as the first file and node. @item --node @var{nodename} @itemx -n @var{nodename} @cindex node, selecting Specifies a particular node to visit in the initial file loaded. This is especially useful in conjunction with @code{--file}@footnote{Of course, you can specify both the file and node in a @code{--node} command; but don't forget to escape the open and close parentheses from the shell as in: @code{info --node '(emacs)Buffers'}}. You may specify @code{--node} multiple times; for an interactive Info, each @var{nodename} is visited in its own window, for a non-interactive Info (such as when @code{--output} is given) each @var{nodename} is processed sequentially. @item --output @var{filename} @itemx -o @var{filename} @cindex file, outputting to @cindex outputting to a file Specify @var{filename} as the name of a file to output to. Each node that Info visits will be output to @var{filename} instead of interactively viewed. A value of @code{-} for @var{filename} specifies the standard output. @item --subnodes @cindex @code{--subnodes}, command line option This option only has meaning when given in conjunction with @code{--output}. It means to recursively output the nodes appearing in the menus of each node being output. Menu items which resolve to external info files are not output, and neither are menu items which are members of an index. Each node is only output once. @item --help @itemx -h Produces a relatively brief description of the available Info options. @item --version @cindex version information Prints the version information of Info and exits. @item @var{menu-item} @cindex menu, following Remaining arguments to Info are treated as the names of menu items. The first argument would be a menu item in the initial node visited, while the second argument would be a menu item in the first argument's node. You can easily move to the node of your choice by specifying the menu names which describe the path to that node. For example, @example info emacs buffers @end example first selects the menu item @samp{Emacs} in the node @samp{(dir)Top}, and then selects the menu item @samp{Buffers} in the node @samp{(emacs)Top}. @end table @node Cursor Commands @chapter Moving the Cursor @cindex cursor, moving Many people find that reading screens of text page by page is made easier when one is able to indicate particular pieces of text with some kind of pointing device. Since this is the case, GNU Info (both the Emacs and standalone versions) have several commands which allow you to move the cursor about the screen. The notation used in this manual to describe keystrokes is identical to the notation used within the Emacs manual, and the GNU Readline manual. @xref{Characters, , Character Conventions, emacs, the GNU Emacs Manual}, if you are unfamilar with the notation. The following table lists the basic cursor movement commands in Info. Each entry consists of the key sequence you should type to execute the cursor movement, the @code{M-x}@footnote{@code{M-x} is also a command; it invokes @code{execute-extended-command}. @xref{M-x, , Executing an extended command, emacs, the GNU Emacs Manual}, for more detailed information.} command name (displayed in parentheses), and a short description of what the command does. All of the cursor motion commands can take an @dfn{numeric} argument (@pxref{Miscellaneous Commands, @code{universal-argument}}), to find out how to supply them. With a numeric argument, the motion commands are simply executed that many times; for example, a numeric argument of 4 given to @code{next-line} causes the cursor to move down 4 lines. With a negative numeric argument, the motion is reversed; an argument of -4 given to the @code{next-line} command would cause the cursor to move @emph{up} 4 lines. @table @asis @item @code{C-n} (@code{next-line}) @kindex C-n @findex next-line Moves the cursor down to the next line. @item @code{C-p} (@code{prev-line}) @kindex C-p @findex prev-line Move the cursor up to the previous line. @item @code{C-a} (@code{beginning-of-line}) @kindex C-a, in Info windows @findex beginning-of-line Move the cursor to the start of the current line. @item @code{C-e} (@code{end-of-line}) @kindex C-e, in Info windows @findex end-of-line Moves the cursor to the end of the current line. @item @code{C-f} (@code{forward-char}) @kindex C-f, in Info windows @findex forward-char Move the cursor forward a character. @item @code{C-b} (@code{backward-char}) @kindex C-b, in Info windows @findex backward-char Move the cursor backward a character. @item @code{M-f} (@code{forward-word}) @kindex M-f, in Info windows @findex forward-word Moves the cursor forward a word. @item @code{M-b} (@code{backward-word}) @kindex M-b, in Info winows @findex backward-word Moves the cursor backward a word. @item @code{M-<} (@code{beginning-of-node}) @itemx @code{b} @kindex b, in Info winows @kindex M-< @findex beginning-of-node Moves the cursor to the start of the current node. @item @code{M->} (@code{end-of-node}) @kindex M-> @findex end-of-node Moves the cursor to the end of the current node. @item @code{M-r} (@code{move-to-window-line}) @kindex M-r @findex move-to-window-line Moves the cursor to a specific line of the window. Without a numeric argument, @code{M-r} moves the cursor to the start of the line in the center of the window. With a numeric argument of @var{n}, @code{M-r} moves the cursor to the start of the @var{n}th line in the window. @end table @node Scrolling Commands @chapter Moving Text Within a Window @cindex scrolling Sometimes you are looking at a screenful of text, and only part of the current paragraph you are reading is visible on the screen. The commands detailed in this section are used to shift which part of the current node is visible on the screen. @table @asis @item @code{SPC} (@code{scroll-forward}) @itemx @code{C-v} @kindex SPC, in Info windows @kindex C-v @findex scroll-forward Shift the text in this window up. That is, show more of the node which is currently below the bottom of the window. With a numeric argument, show that many more lines at the bottom of the window; a numeric argument of 4 would shift all of the text in the window up 4 lines (discarding the top 4 lines), and show you four new lines at the bottom of the window. Without a numeric argument, @key{SPC} takes the bottom two lines of the window and places them at the top of the window, redisplaying almost a completely new screenful of lines. @item @code{DEL} (@code{scroll-backward}) @itemx @code{M-v} @kindex DEL, in Info windows @kindex M-v @findex scroll-backward Shift the text in this window down. The inverse of @code{scroll-forward}. @end table @cindex scrolling through node structure The @code{scroll-forward} and @code{scroll-backward} commands can also move forward and backward through the node structure of the file. If you press @key{SPC} while viewing the end of a node, or @key{DEL} while viewing the beginning of a node, what happens is controlled by the variable @code{scroll-behaviour}. @xref{Variables, @code{scroll-behaviour}}, for more information. @table @asis @item @code{C-l} (@code{redraw-display}) @kindex C-l @findex redraw-display Redraw the display from scratch, or shift the line containing the cursor to a specified location. With no numeric argument, @samp{C-l} clears the screen, and then redraws its entire contents. Given a numeric argument of @var{n}, the line containing the cursor is shifted so that it is on the @var{n}th line of the window. @item @code{C-x w} (@code{toggle-wrap}) @kindex C-w @findex toggle-wrap Toggles the state of line wrapping in the current window. Normally, lines which are longer than the screen width @dfn{wrap}, i.e., they are continued on the next line. Lines which wrap have a @samp{\} appearing in the rightmost column of the screen. You can cause such lines to be terminated at the rightmost column by changing the state of line wrapping in the window with @code{C-x w}. When a line which needs more space than one screen width to display is displayed, a @samp{$} appears in the rightmost column of the screen, and the remainder of the line is invisible. @end table @node Node Commands @chapter Selecting a New Node @cindex nodes, selection of This section details the numerous Info commands which select a new node to view in the current window. The most basic node commands are @samp{n}, @samp{p}, @samp{u}, and @samp{l}. When you are viewing a node, the top line of the node contains some Info @dfn{pointers} which describe where the next, previous, and up nodes are. Info uses this line to move about the node structure of the file when you use the following commands: @table @asis @item @code{n} (@code{next-node}) @kindex n @findex next-node Selects the `Next' node. @item @code{p} (@code{prev-node}) @kindex p @findex prev-node Selects the `Prev' node. @item @code{u} (@code{up-node}) @kindex u @findex up-node Selects the `Up' node. @end table You can easily select a node that you have already viewed in this window by using the @samp{l} command -- this name stands for "last", and actually moves through the list of already visited nodes for this window. @samp{l} with a negative numeric argument moves forward through the history of nodes for this window, so you can quickly step between two adjacent (in viewing history) nodes. @table @asis @item @code{l} (@code{history-node}) @kindex l @findex history-node Selects the most recently selected node in this window. @end table Two additional commands make it easy to select the most commonly selected nodes; they are @samp{t} and @samp{d}. @table @asis @item @code{t} (@code{top-node}) @kindex t @findex top-node Selects the node @samp{Top} in the current info file. @item @code{d} (@code{dir-node}) @kindex d @findex dir-node Selects the directory node (i.e., the node @samp{(dir)}). @end table Here are some other commands which immediately result in the selection of a different node in the current window: @table @asis @item @code{<} (@code{first-node}) @kindex < @findex first-node Selects the first node which appears in this file. This node is most often @samp{Top}, but it doesn't have to be. @item @code{>} (@code{last-node}) @kindex > @findex last-node Selects the last node which appears in this file. @item @code{]} (@code{global-next-node}) @kindex ] @findex global-next-node Moves forward or down through node structure. If the node that you are currently viewing has a @samp{Next} pointer, that node is selected. Otherwise, if this node has a menu, the first menu item is selected. If there is no @samp{Next} and no menu, the same process is tried with the @samp{Up} node of this node. @item @code{[} (@code{global-prev-node}) @kindex [ @findex global-prev-node Moves backward or up through node structure. If the node that you are currently viewing has a @samp{Prev} pointer, that node is selected. Otherwise, if the node has an @samp{Up} pointer, that node is selected, and if it has a menu, the last item in the menu is selected. @end table You can get the same behaviour as @code{global-next-node} and @code{global-prev-node} while simply scrolling through the file with @key{SPC} and @key{DEL}; @xref{Variables, @code{scroll-behaviour}}, for more information. @table @asis @item @code{g} (@code{goto-node}) @kindex g @findex goto-node Reads the name of a node and selects it. No completion is done while reading the node name, since the desired node may reside in a separate file. The node must be typed exactly as it appears in the info file. A file name may be included as with any node specification, for example @example @code{g(emacs)Buffers} @end example finds the node @samp{Buffers} in the info file @file{emacs}. @item @code{C-x k} (@code{kill-node}) @kindex C-x k @findex kill-node Kills a node. The node name is prompted for in the echo area, with a default of the current node. @dfn{Killing} a node means that Info tries hard to forget about it, removing it from the list of history nodes kept for the window where that node is found. Another node is selected in the window which contained the killed node. @item @code{C-x C-f} (@code{view-file}) @kindex C-x C-f @findex view-file Reads the name of a file and selects the entire file. The command @example @code{C-x C-f @var{filename}} @end example is equivalent to typing @example @code{g(@var{filename})*} @end example @item @code{C-x C-b} (@code{list-visited-nodes}) @kindex C-x C-b @findex list-visited-nodes Makes a window containing a menu of all of the currently visited nodes. This window becomes the selected window, and you may use the standard Info commands within it. @item @code{C-x b} (@code{select-visited-node}) @kindex C-x b @findex select-visited-node Selects a node which has been previously visited in a visible window. This is similar to @samp{C-x C-b} followed by @samp{m}, but no window is created. @end table @node Searching Commands @chapter Searching an Info File @cindex searching GNU Info allows you to search for a sequence of characters throughout an entire info file, search through the indices of an info file, or find areas within an info file which discuss a particular topic. @table @asis @item @code{s} (@code{search}) @kindex s @findex search Reads a string in the echo area and searches for it. @item @code{C-s} (@code{isearch-forward}) @kindex C-s @findex isearch-forward Interactively searches forward through the info file for a string as you type it. @item @code{C-r} (@code{isearch-backward}) @kindex C-r @findex isearch-backward Interactively searches backward through the info file for a string as you type it. @item @code{i} (@code{index-search}) @kindex i @findex index-search Looks up a string in the indices for this info file, and selects a node where the found index entry points to. @item @code{,} (@code{next-index-match}) @kindex , @findex next-index-match Moves to the node containing the next matching index item from the last @samp{i} command. @end table The most basic searching command is @samp{s} (@code{search}). The @samp{s} command prompts you for a string in the echo area, and then searches the remainder of the info file for an ocurrence of that string. If the string is found, the node containing it is selected, and the cursor is left positioned at the start of the found string. Subsequent @samp{s} commands show you the default search string within @samp{[} and @samp{]}; pressing @key{RET} instead of typing a new string will use the default search string. @dfn{Incremental searching} is similar to basic searching, but the string is looked up while you are typing it, instead of waiting until the entire search string has been specified. @node Xref Commands @chapter Selecting Cross References We have already discussed the @samp{Next}, @samp{Prev}, and @samp{Up} pointers which appear at the top of a node. In addition to these pointers, a node may contain other pointers which refer you to a different node, perhaps in another info file. Such pointers are called @dfn{cross references}, or @dfn{xrefs} for short. @menu * Parts of an Xref:: What a cross reference is made of. * Selecting Xrefs:: Commands for selecting menu or note items. @end menu @node Parts of an Xref @section Parts of an Xref Cross references have two major parts: the first part is called the @dfn{label}; it is the name that you can use to refer to the cross reference, and the second is the @dfn{target}; it is the full name of the node that the cross reference points to. The target is separated from the label by a colon @samp{:}; first the label appears, and then the target. For example, in the sample menu cross reference below, the single colon separates the label from the target. @example * Foo Label: Foo Target. More information about Foo. @end example Note the @samp{.} which ends the name of the target. The @samp{.} is not part of the target; it serves only to let Info know where the target name ends. A shorthand way of specifying references allows two adjacent colons to stand for a target name which is the same as the label name: @example * Foo Commands:: Commands pertaining to Foo. @end example In the above example, the name of the target is the same as the name of the label, in this case @code{Foo Commands}. You will normally see two types of cross references while viewing nodes: @dfn{menu} references, and @dfn{note} references. Menu references appear within a node's menu; they begin with a @samp{*} at the beginning of a line, and continue with a label, a target, and a comment which describes what the contents of the node pointed to contains. Note references appear within the body of the node text; they begin with @code{*Note}, and continue with a label and a target. Like @samp{Next}, @samp{Prev} and @samp{Up} pointers, cross references can point to any valid node. They are used to refer you to a place where more detailed information can be found on a particular subject. Here is a cross reference which points to a node within the Texinfo documentation: @xref{xref, , Writing an Xref, texinfo, the Texinfo Manual}, for more information on creating your own texinfo cross references. @node Selecting Xrefs @section Selecting Xrefs The following table lists the Info commands which operate on menu items. @table @asis @item @code{1} (@code{menu-digit}) @itemx @code{2} @dots{} @code{9} @cindex 1 @dots{} 9, in Info windows @kindex 1 @dots{} 9, in Info windows @findex menu-digit Within an Info window, pressing a single digit, (such as @samp{1}), selects that menu item, and places its node in the current window. For convenience, there is one exception; pressing @samp{0} selects the @emph{last} item in the node's menu. @item @code{0} (@code{last-menu-item}) @kindex 0, in Info windows @findex last-menu-item Select the last item in the current node's menu. @item @code{m} (@code{menu-item}) @kindex m @findex menu-item Reads the name of a menu item in the echo area and selects its node. Completion is available while reading the menu label. @item @code{M-x find-menu} @findex find-menu Moves the cursor to the start of this node's menu. @end table This table lists the Info commands which operate on note cross references. @table @asis @item @code{f} (@code{xref-item}) @itemx @code{r} @kindex f @kindex r @findex xref-item Reads the name of a note cross reference in the echo area and selects its node. Completion is available while reading the cross reference label. @end table Finally, the next few commands operate on menu or note references alike: @table @asis @item @code{TAB} (@code{move-to-next-xref}) @kindex TAB, in Info windows @findex move-to-next-xref Moves the cursor to the start of the next nearest menu item or note reference in this node. You can then use @key{RET} (@code{select-reference-this-line} to select the menu or note reference. @item @code{M-TAB} (@code{move-to-prev-xref}) @kindex M-TAB, in Info windows @findex move-to-prev-xref Moves the cursor the start of the nearest previous menu item or note reference in this node. @item @code{RET} (@code{select-reference-this-line}) @kindex RET, in Info windows @findex select-reference-this-line Selects the menu item or note reference appearing on this line. @end table @node Window Commands @chapter Manipulating Multiple Windows @cindex windows, manipulating A @dfn{window} is a place to show the text of a node. Windows have a view area where the text of the node is displayed, and an associated @dfn{mode line}, which briefly describes the node being viewed. GNU Info supports multiple windows appearing in a single screen; each window is separated from the next by its modeline. At any time, there is only one @dfn{active} window, that is, the window in which the cursor appears. There are commands available for creating windows, changing the size of windows, selecting which window is active, and for deleting windows. @menu * The Mode Line:: What appears in the mode line? * Basic Windows:: Manipulating windows in Info. * The Echo Area:: Used for displaying errors and reading input. @end menu @node The Mode Line @section The Mode Line A @dfn{mode line} is a line of inverse video which appears at the bottom of an info window. It describes the contents of the window just above it; this information includes the name of the file and node appearing in that window, the number of screen lines it takes to display the node, and the percentage of text that is above the top of the window. It can also tell you if the indirect tags table for this info file needs to be updated, and whether or not the info file was compressed when stored on disk. Here is a sample mode line for a window containing an uncompressed file named @file{dir}, showing the node @samp{Top}. @example -----Info: (dir)Top, 40 lines --Top--------------------------------------- ^^ ^ ^^^ ^^ (file)Node #lines where @end example When a node comes from a file which is compressed on disk, this is indicated in the mode line with two small @samp{z}'s. In addition, if the info file containing the node has been split into subfiles, the name of the subfile containing the node appears in the modeline as well: @example --zz-Info: (emacs)Top, 291 lines --Top-- Subfile: emacs-1.Z--------------- @end example When Info makes a node internally, such that there is no corresponding info file on disk, the name of the node is surrounded by asterisks (@samp{*}). The name itself tells you what the contents of the window are; the sample mode line below shows an internally constructed node showing possible completions: @example -----Info: *Completions*, 7 lines --All----------------------------------- @end example @node Basic Windows @section Window Commands It can be convenient to view more than one node at a time. To allow this, Info can display more than one @dfn{window}. Each window has its own mode line (@pxref{The Mode Line}) and history of nodes viewed in that window (@pxref{Node Commands, , @code{history-node}}). @table @asis @item @code{C-x o} (@code{next-window}) @cindex windows, selecting @kindex C-x o @findex next-window Selects the next window on the screen. Note that the echo area can only be selected if it is already in use, and you have left it temporarily. Normally, @samp{C-x o} simply moves the cursor into the next window on the screen, or if you are already within the last window, into the first window on the screen. Given a numeric argument, @samp{C-x o} moves over that many windows. A negative argument causes @samp{C-x o} to select the previous window on the screen. @item @code{M-x prev-window} @findex prev-window Selects the previous window on the screen. This is identical to @samp{C-x o} with a negative argument. @item @code{C-x 2} (@code{split-window}) @cindex windows, creating @kindex C-x 2 @findex split-window Splits the current window into two windows, both showing the same node. Each window is one half the size of the original window, and the cursor remains in the original window. The variable @code{automatic-tiling} can cause all of the windows on the screen to be resized for you automatically, please @pxref{Variables, , automatic-tiling} for more information. @item @code{C-x 0} (@code{delete-window}) @cindex windows, deleting @kindex C-x 0 @findex delete-window Deletes the current window from the screen. If you have made too many windows and your screen appears cluttered, this is the way to get rid of some of them. @item @code{C-x 1} (@code{keep-one-window}) @kindex C-x 1 @findex keep-one-window Deletes all of the windows excepting the current one. @item @code{ESC C-v} (@code{scroll-other-window}) @kindex ESC C-v, in Info windows @findex scroll-other-window Scrolls the other window, in the same fashion that @samp{C-v} might scroll the current window. Given a negative argument, the "other" window is scrolled backward. @item @code{C-x ^} (@code{grow-window}) @kindex C-x ^ @findex grow-window Grows (or shrinks) the current window. Given a numeric argument, grows the current window that many lines; with a negative numeric argument, the window is shrunk instead. @item @code{C-x t} (@code{tile-windows}) @cindex tiling @kindex C-x t @findex tile-windows Divides the available screen space among all of the visible windows. Each window is given an equal portion of the screen in which to display its contents. The variable @code{automatic-tiling} can cause @code{tile-windows} to be called when a window is created or deleted. @xref{Variables, , @code{automatic-tiling}}. @end table @node The Echo Area @section The Echo Area @cindex echo area The @dfn{echo area} is a one line window which appears at the bottom of the screen. It is used to display informative or error messages, and to read lines of input from you when that is necessary. Almost all of the commands available in the echo area are identical to their Emacs counterparts, so please refer to that documentation for greater depth of discussion on the concepts of editing a line of text. The following table briefly lists the commands that are available while input is being read in the echo area: @table @asis @item @code{C-f} (@code{echo-area-forward}) @kindex C-f, in the echo area @findex echo-area-forward Moves forward a character. @item @code{C-b} (@code{echo-area-backward}) @kindex C-b, in the echo area @findex echo-area-backward Moves backward a character. @item @code{C-a} (@code{echo-area-beg-of-line}) @kindex C-a, in the echo area @findex echo-area-beg-of-line Moves to the start of the input line. @item @code{C-e} (@code{echo-area-end-of-line}) @kindex C-e, in the echo area @findex echo-area-end-of-line Moves to the end of the input line. @item @code{M-f} (@code{echo-area-forward-word}) @kindex M-f, in the echo area @findex echo-area-forward-word Moves forward a word. @item @code{M-b} (@code{echo-area-backward-word}) @kindex M-b, in the echo area @findex echo-area-backward-word Moves backward a word. @item @code{C-d} (@code{echo-area-delete}) @kindex C-d, in the echo area @findex echo-area-delete Deletes the character under the cursor. @item @code{DEL} (@code{echo-area-rubout}) @kindex DEL, in the echo area @findex echo-area-rubout Deletes the character behind the cursor. @item @code{C-g} (@code{echo-area-abort}) @kindex C-g, in the echo area @findex echo-area-abort Cancels or quits the current operation. If completion is being read, @samp{C-g} discards the text of the input line which does not match any completion. If the input line is empty, @samp{C-g} aborts the calling function. @item @code{RET} (@code{echo-area-newline}) @kindex RET, in the echo area @findex echo-area-newline Accepts (or forces completion of) the current input line. @item @code{C-q} (@code{echo-area-quoted-insert}) @kindex C-q, in the echo area @findex echo-area-quoted-insert Inserts the next character verbatim. This is how you can insert control characters into a search string, for example. @item @var{printing character} (@code{echo-area-insert}) @kindex printing characters, in the echo area @findex echo-area-insert Inserts the character. @item @code{M-TAB} (@code{echo-area-tab-insert}) @kindex M-TAB, in the echo area @findex echo-area-tab-insert Inserts a TAB character. @item @code{C-t} (@code{echo-area-transpose-chars}) @kindex C-t, in the echo area @findex echo-area-transpose-chars Transposes the characters at the cursor. @end table The next group of commands deal with @dfn{killing}, and @dfn{yanking} text. For an in depth discussion of killing and yanking, @pxref{Killing, , Killing and Deleting, emacs, the GNU Emacs Manual} @table @asis @item @code{M-d} (@code{echo-area-kill-word}) @kindex M-d, in the echo area @findex echo-area-kill-word Kills the word following the cursor. @item @code{M-DEL} (@code{echo-area-backward-kill-word}) @kindex M-DEL, in the echo area @findex echo-area-backward-kill-word Kills the word preceding the cursor. @item @code{C-k} (@code{echo-area-kill-line}) @kindex C-k, in the echo area @findex echo-area-kill-line Kills the text from the cursor to the end of the line. @item @code{C-x DEL} (@code{echo-area-backward-kill-line}) @kindex C-x DEL, in the echo area @findex echo-area-backward-kill-line Kills the text from the cursor to the beginning of the line. @item @code{C-y} (@code{echo-area-yank}) @kindex C-y, in the echo area @findex echo-area-yank Yanks back the contents of the last kill. @item @code{M-y} (@code{echo-area-yank-pop}) @kindex M-y, in the echo area @findex echo-area-yank-pop Yanks back a previous kill, removing the last yanked text first. @end table Sometimes when reading input in the echo area, the command that needed input will only accept one of a list of several choices. The choices represent the @dfn{possible completions}, and you must respond with one of them. Since there are a limited number of responses you can make, Info allows you to abbreviate what you type, only typing as much of the response as is necessary to uniquely identify it. In addition, you can request Info to fill in as much of the response as is possible; this is called @dfn{completion}. The following commands are available when completing in the echo area: @table @asis @item @code{TAB} (@code{echo-area-complete}) @itemx @code{SPC} @kindex TAB, in the echo area @kindex SPC, in the echo area @findex echo-area-complete Inserts as much of a completion as is possible. @item @code{?} (@code{echo-area-possible-completions}) @kindex ?, in the echo area @findex echo-area-possible-completions Displays a window containing a list of the possible completions of what you have typed so far. For example, if the available choices are: @example bar foliate food forget @end example and you have typed an @samp{f}, followed by @samp{?}, the possible completions would contain: @example foliate food forget @end example i.e., all of the choices which begin with @samp{f}. Pressing @key{SPC} or @key{TAB} would result in @samp{fo} appearing in the echo area, since all of the choices which begin with @samp{f} continue with @samp{o}. Now, typing @samp{l} followed by @samp{TAB} results in @samp{foliate} appearing in the echo area, since that is the only choice which begins with @samp{fol}. @item @code{ESC C-v} (@code{echo-area-scroll-completions-window}) @kindex ESC C-v, in the echo area @findex echo-area-scroll-completions-window Scrolls the completions window, if that is visible, or the "other" window if not. @end table @node Printing Nodes @chapter Printing Out Nodes @cindex printing You may wish to print out the contents of a node as a quick reference document for later use. Info provides you with a command for doing this. In general, we recommend that you use @TeX{} to format the document and print sections of it, by running @code{tex} on the texinfo source file. @table @asis @item @code{M-x print-node} @findex print-node @cindex INFO_PRINT_COMMAND, environment variable Pipes the contents of the current node through the command in the environment variable @code{INFO_PRINT_COMMAND}. If the variable doesn't exist, the node is simply piped to @code{lpr}. @end table @node Miscellaneous Commands @chapter Miscellaneous Commands GNU Info contains several commands which self-document GNU Info: @table @asis @item @code{M-x describe-command} @cindex functions, describing @cindex commands, describing @findex describe-command Reads the name of an Info command in the echo area and then displays a brief description of what that command does. @item @code{M-x describe-key} @cindex keys, describing @findex describe-key Reads a key sequence in the echo area, and then displays the name and documentation of the Info command that the key sequence invokes. @item @code{M-x describe-variable} Reads the name of a variable in the echo area and then displays a brief description of what the variable affects. @item @code{M-x where-is} @findex where-is Reads the name of an Info command in the echo area, and then displays a key sequence which can be typed in order to invoke that command. @item @code{C-h} (@code{get-help-window}) @itemx @code{?} @kindex C-h @kindex ?, in Info windows @findex get-help-window Creates (or moves into) the window displaying @code{*Help*}, and places a node containing a quick reference card into it. This window displays the most concise information about GNU Info available. @item @code{h} (@code{get-info-help-node}) @kindex h @findex get-info-help-node Tries hard to visit the node @code{(info)Help}. The info file @file{info.texi} distributed with GNU Info contains this node. Of course, the file must first be processed with @code{makeinfo}, and then placed into the location of your info directory. @end table Here are the commands for creating a numeric argument: @table @asis @item @code{C-u} (@code{universal-argument}) @cindex numeric arguments @kindex C-u @findex universal-argument Starts (or multiplies by 4) the current numeric argument. @samp{C-u} is a good way to give a small numeric argument to cursor movement or scrolling commands; @samp{C-u C-v} scrolls the screen 4 lines, while @samp{C-u C-u C-n} moves the cursor down 16 lines. @item @code{M-1} (@code{add-digit-to-numeric-arg}) @itemx @code{M-2} @dots{} @code{M-9} @kindex M-1 @dots{} M-9 @findex add-digit-to-numeric-arg Adds the digit value of the invoking key to the current numeric argument. Once Info is reading a numeric argument, you may just type the digits of the argument, without the Meta prefix. For example, you might give @samp{C-l} a numeric argument of 32 by typing: @example @kbd{C-u 3 2 C-l} @end example or @example @kbd{M-3 2 C-l} @end example @end table @samp{C-g} is used to abort the reading of a multi-character key sequence, to cancel lengthy operations (such as multi-file searches) and to cancel reading input in the echo area. @table @asis @item @code{C-g} (@code{abort-key}) @cindex cancelling typeahead @cindex cancelling the current operation @kindex C-g, in Info windows @findex abort-key Cancels current operation. @end table The @samp{q} command of Info simply quits running Info. @table @asis @item @code{q} (@code{quit}) @cindex quitting @kindex q @findex quit Exits GNU Info. @end table If the operating system tells GNU Info that the screen is 60 lines tall, and it is actually only 40 lines tall, here is a way to tell Info that the operating system is correct. @table @asis @item @code{M-x set-screen-height} @findex set-screen-height @cindex screen, changing the height of Reads a height value in the echo area and sets the height of the displayed screen to that value. @end table Finally, Info provides a convenient way to display footnotes which might be associated with the current node that you are viewing: @table @asis @item @code{ESC C-f} (@code{show-footnotes}) @kindex ESC C-f @findex show-footnotes @cindex footnotes, displaying Shows the footnotes (if any) associated with the current node in another window. You can have Info automatically display the footnotes associated with a node when the node is selected by setting the variable @code{automatic-footnotes}. @xref{Variables, , @code{automatic-footnotes}}. @end table @node Variables @chapter Manipulating Variables GNU Info contains several @dfn{variables} whose values are looked at by various Info commands. You can change the values of these variables, and thus change the behaviour of Info to more closely match your environment and info file reading manner. @table @asis @item @code{M-x set-variable} @cindex variables, setting @findex set-variable Reads the name of a variable, and the value for it, in the echo area and then sets the variable to that value. Completion is available when reading the variable name; often, completion is available when reading the value to give to the variable, but that depends on the variable itself. If a variable does @emph{not} supply multiple choices to complete over, it expects a numeric value. @item @code{M-x describe-variable} @cindex variables, describing @findex describe-variable Reads the name of a variable in the echo area and then displays a brief description of what the variable affects. @end table Here is a list of the variables that you can set in Info. @table @code @item automatic-footnotes @vindex automatic-footnotes When set to @code{On}, footnotes appear and disappear automatically. This variable is @code{On} by default. When a node is selected, a window containing the footnotes which appear in that node is created, and the footnotes are displayed within the new window. The window that Info creates to contain the footnotes is called @samp{*Footnotes*}. If a node is selected which contains no footnotes, and a @samp{*Footnotes*} window is on the screen, the @samp{*Footnotes*} window is deleted. Footnote windows created in this fashion are not automatically tiled so that they can use as little of the display as is possible. @item automatic-tiling @vindex automatic-tiling When set to @code{On}, creating or deleting a window resizes other windows. This variable is @code{Off} by default. Normally, typing @samp{C-x 2} divides the current window into two equal parts. When @code{automatic-tiling} is set to @code{On}, all of the windows are resized automatically, keeping an equal number of lines visible in each window. There are exceptions to the automatic tiling; specifically, the windows @samp{*Completions*} and @samp{*Footnotes*} are @emph{not} resized through automatic tiling; they remain their original size. @item visible-bell @vindex visible-bell When set to @code{On}, GNU Info attempts to flash the screen instead of ringing the bell. This variable is @code{Off} by default. Of course, Info can only flash the screen if the terminal allows it; in the case that the terminal does not allow it, the setting of this variable has no effect. However, you can make Info perform quietly by setting the @code{errors-ring-bell} variable to @code{Off}. @item errors-ring-bell @vindex errors-ring-bell When set to @code{On}, errors cause the bell to ring. The default setting of this variable is @code{On}. @item gc-compressed-files @vindex gc-compressed-files When set to @code{On}, Info garbage collects files which had to be uncompressed. The default value of this variable is @code{Off}. Whenever a node is visited in Info, the info file containing that node is read into core, and Info reads information about the tags and nodes contained in that file. Once the tags information is read by Info, it is never forgotten. However, the actual text of the nodes does not need to remain in core unless a particular info window needs it. For non-compressed files, the text of the nodes does not remain in core when it is no longer in use. But de-compressing a file can be a time consuming operation, and so Info tries hard not to do it twice. @code{gc-compressed-files} tells Info it is okay to garbage collect the text of the nodes of a file which was compressed on disk. @item show-index-match @vindex show-index-match When set to @code{On}, the portion of the matched search string is highlighted in the message which explains where the matched search string was found. The default value of this variable is @code{On}. When Info displays the location where an index match was found, (@pxref{Searching Commands, , @code{next-index-match}}), the portion of the string that you had typed is highlighted by displaying it in the inverse case from its surrounding characters. @item scroll-behaviour @vindex scroll-behaviour Controls what happens when forward scrolling is requested at the end of a node, or when backward scrolling is requested at the beginning of a node. The default value for this variable is @code{Continuous}. There are three possible values for this variable: @table @code @item Continuous Tries to get the first item in this node's menu, or failing that, the @samp{Next} node, or failing that, the @samp{Next} of the @samp{Up}. This behaviour is identical to using the @samp{]} (@code{global-next-node}) and @samp{[} (@code{global-prev-node}) commands. @item Next Only Only tries to get the @samp{Next} node. @item Page Only Simply gives up, changing nothing. If @code{scroll-behaviour} is @code{Page Only}, no scrolling command can change the node that is being viewed. @end table @item scroll-step @vindex scroll-step The number of lines to scroll when the cursor moves out of the window. Scrolling happens automatically if the cursor has moved out of the visible portion of the node text when it is time to display. Usually the scrolling is done so as to put the cursor on the center line of the current window. However, if the variable @code{scroll-step} has a nonzero value, Info attempts to scroll the node text by that many lines; if that is enough to bring the cursor back into the window, that is what is done. The default value of this variable is 0, thus placing the cursor (and the text it is attached to) in the center of the window. Setting this variable to 1 causes a kind of "smooth scrolling" which some people prefer. @item ISO-Latin @cindex ISO Latin characters @vindex ISO-Latin When set to @code{On}, Info accepts and displays ISO Latin characters. By default, Info assumes an ASCII character set. @code{ISO-Latin} tells Info that it is running in an environment where the European standard character set is in use, and allows you to input such characters to Info, as well as display them. @end table @c The following node and its children are currently unfinished. Please feel @c free to finish it! @ifset NOTSET @node Info for Sys Admins @chapter Info for System Administrators This text describes some common ways of setting up an Info heierarchy from scratch, and details the various options that are available when installing Info. This text is designed for the person who is installing GNU Info on the system; although users may find the information present in this section interesting, none of it is vital to understanding how to use GNU Info. @menu * Setting the INFOPATH:: Where are my Info files kept? * Editing the DIR node:: What goes in `DIR', and why? * Storing Info files:: Alternate formats allow flexibilty in setups. * Using `localdir':: Building DIR on the fly. * Example setups:: Some common ways to origanize Info files. @end menu @node Setting the INFOPATH @section Setting the INFOPATH Where are my Info files kept? @node Editing the DIR node @section Editing the DIR node What goes in `DIR', and why? @node Storing Info files @section Storing Info files Alternate formats allow flexibilty in setups. @node Using `localdir' @section Using `localdir' Building DIR on the fly. @node Example setups @section Example setups Some common ways to origanize Info files. @end ifset @ifset STANDALONE @node GNU Info Global Index @appendix Global Index @printindex cp @end ifset texinfo-3.12/doc/info.texi0000444000175000017500000011342506361255363012761 0ustar gg\input texinfo @c -*-texinfo-*- @comment %**start of header @setfilename info.info @settitle Info 1.0 @comment %**end of header @comment $Id: info.texi,v 1.4 1997/07/10 21:58:11 karl Exp $ @dircategory Texinfo documentation system @direntry * Info: (info). Documentation browsing system. @end direntry @ifinfo This file describes how to use Info, the on-line, menu-driven GNU documentation system. Copyright (C) 1989, 92, 96, 97 Free Software Foundation, Inc. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. @ignore Permission is granted to process this file through TeX and print the results, provided the printed document carries copying permission notice identical to this one except for the removal of this paragraph (this paragraph not being relevant to the printed manual). @end ignore Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation. @end ifinfo @titlepage @title Info @subtitle The online, menu-driven GNU documentation system @author Brian Fox @page @vskip 0pt plus 1filll Copyright @copyright{} 1989, 1992, 1993, 1996, 1997 Free Software Foundation, Inc. @sp 2 Published by the Free Software Foundation @* 59 Temple Place - Suite 330 @* Boston, MA 02111-1307, USA. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation. @end titlepage @ifinfo @node Top, Getting Started, , (dir) @top Info: An Introduction Info is a program for reading documentation, which you are using now. To learn how to use Info, type the command @kbd{h}. It brings you to a programmed instruction sequence. @c Need to make sure that `Info-help' goes to the right node, @c which is the first node of the first chapter. (It should.) @c (Info-find-node "info" @c (if (< (window-height) 23) @c "Help-Small-Screen" @c "Help"))) To learn advanced Info commands, type @kbd{n} twice. This brings you to @cite{Info for Experts}, skipping over the `Getting Started' chapter. @end ifinfo @menu * Getting Started:: Getting started using an Info reader. * Advanced Info:: Advanced commands within Info. * Create an Info File:: How to make your own Info file. * The Standalone Info Program: (info-stnd.info). @end menu @node Getting Started, Advanced Info, Top, Top @comment node-name, next, previous, up @chapter Getting Started This first part of the Info manual describes how to get around inside of Info. The second part of the manual describes various advanced Info commands, and how to write an Info as distinct from a Texinfo file. The third part is about how to generate Info files from Texinfo files. @iftex This manual is primarily designed for use on a computer, so that you can try Info commands while reading about them. Reading it on paper is less effective, since you must take it on faith that the commands described really do what the manual says. By all means go through this manual now that you have it; but please try going through the on-line version as well. There are two ways of looking at the online version of this manual: @enumerate @item Type @code{info} at your shell's command line. This approach uses a small stand-alone program designed just to read Info files. @item Type @code{emacs} at the command line; then type @kbd{C-h i} (Control @kbd{h}, followed by @kbd{i}). This approach uses the Info mode of the Emacs program, an editor with many other capabilities. @end enumerate In either case, then type @kbd{mInfo} (just the letters), followed by @key{RET}---the ``Return'' or ``Enter'' key. At this point, you should be ready to follow the instructions in this manual as you read them on the screen. @c FIXME! (pesch@cygnus.com, 14 dec 1992) @c Is it worth worrying about what-if the beginner goes to somebody @c else's Emacs session, which already has an Info running in the middle @c of something---in which case these simple instructions won't work? @end iftex @menu * Help-Small-Screen:: Starting Info on a Small Screen * Help:: How to use Info * Help-P:: Returning to the Previous node * Help-^L:: The Space, Rubout, B and ^L commands. * Help-M:: Menus * Help-Adv:: Some advanced Info commands * Help-Q:: Quitting Info @end menu @node Help-Small-Screen, Help, , Getting Started @comment node-name, next, previous, up @section Starting Info on a Small Screen @iftex (In Info, you only see this section if your terminal has a small number of lines; most readers pass by it without seeing it.) @end iftex Since your terminal has an unusually small number of lines on its screen, it is necessary to give you special advice at the beginning. If you see the text @samp{--All----} at near the bottom right corner of the screen, it means the entire text you are looking at fits on the screen. If you see @samp{--Top----} instead, it means that there is more text below that does not fit. To move forward through the text and see another screen full, press the Space bar, @key{SPC}. To move back up, press the key labeled @samp{Backspace} or @key{Delete}. @ifinfo Here are 40 lines of junk, so you can try Spaces and Deletes and see what they do. At the end are instructions of what you should do next. This is line 17 @* This is line 18 @* This is line 19 @* This is line 20 @* This is line 21 @* This is line 22 @* This is line 23 @* This is line 24 @* This is line 25 @* This is line 26 @* This is line 27 @* This is line 28 @* This is line 29 @* This is line 30 @* This is line 31 @* This is line 32 @* This is line 33 @* This is line 34 @* This is line 35 @* This is line 36 @* This is line 37 @* This is line 38 @* This is line 39 @* This is line 40 @* This is line 41 @* This is line 42 @* This is line 43 @* This is line 44 @* This is line 45 @* This is line 46 @* This is line 47 @* This is line 48 @* This is line 49 @* This is line 50 @* This is line 51 @* This is line 52 @* This is line 53 @* This is line 54 @* This is line 55 @* This is line 56 @* If you have managed to get here, go back to the beginning with Delete, and come back here again, then you understand Space and Delete. So now type an @kbd{n} ---just one character; don't type the quotes and don't type the Return key afterward--- to get to the normal start of the course. @end ifinfo @node Help, Help-P, Help-Small-Screen, Getting Started @comment node-name, next, previous, up @section How to use Info You are talking to the program Info, for reading documentation. Right now you are looking at one @dfn{Node} of Information. A node contains text describing a specific topic at a specific level of detail. This node's topic is ``how to use Info''. The top line of a node is its @dfn{header}. This node's header (look at it now) says that it is the node named @samp{Help} in the file @file{info}. It says that the @samp{Next} node after this one is the node called @samp{Help-P}. An advanced Info command lets you go to any node whose name you know. Besides a @samp{Next}, a node can have a @samp{Previous} or an @samp{Up}. This node has a @samp{Previous} but no @samp{Up}, as you can see. Now it is time to move on to the @samp{Next} node, named @samp{Help-P}. >> Type @samp{n} to move there. Type just one character; do not type the quotes and do not type a @key{RET} afterward. @samp{>>} in the margin means it is really time to try a command. @node Help-P, Help-^L, Help, Getting Started @comment node-name, next, previous, up @section Returning to the Previous node This node is called @samp{Help-P}. The @samp{Previous} node, as you see, is @samp{Help}, which is the one you just came from using the @kbd{n} command. Another @kbd{n} command now would take you to the next node, @samp{Help-^L}. >> But do not do that yet. First, try the @kbd{p} command, which takes you to the @samp{Previous} node. When you get there, you can do an @kbd{n} again to return here. This all probably seems insultingly simple so far, but @emph{do not} be led into skimming. Things will get more complicated soon. Also, do not try a new command until you are told it is time to. Otherwise, you may make Info skip past an important warning that was coming up. >> Now do an @kbd{n} to get to the node @samp{Help-^L} and learn more. @node Help-^L, Help-M, Help-P, Getting Started @comment node-name, next, previous, up @section The Space, Delete, B and ^L commands. This node's header tells you that you are now at node @samp{Help-^L}, and that @kbd{p} would get you back to @samp{Help-P}. The node's title is underlined; it says what the node is about (most nodes have titles). This is a big node and it does not all fit on your display screen. You can tell that there is more that is not visible because you can see the string @samp{--Top-----} rather than @samp{--All----} near the bottom right corner of the screen. The Space, Delete and @kbd{B} commands exist to allow you to ``move around'' in a node that does not all fit on the screen at once. Space moves forward, to show what was below the bottom of the screen. Delete moves backward, to show what was above the top of the screen (there is not anything above the top until you have typed some spaces). >> Now try typing a Space (afterward, type a Delete to return here). When you type the space, the two lines that were at the bottom of the screen appear at the top, followed by more lines. Delete takes the two lines from the top and moves them to the bottom, @emph{usually}, but if there are not a full screen's worth of lines above them they may not make it all the way to the bottom. If you type Space when there is no more to see, it rings the bell and otherwise does nothing. The same goes for Delete when the header of the node is visible. If your screen is ever garbaged, you can tell Info to print it out again by typing @kbd{C-l} (@kbd{Control-L}, that is---hold down ``Control'' and type an @key{L} or @kbd{l}). >> Type @kbd{C-l} now. To move back to the beginning of the node you are on, you can type a lot of Deletes. You can also type simply @kbd{b} for beginning. >> Try that now. (We have put in enough verbiage to push this past the first screenful, but screens are so big nowadays that perhaps it isn't enough. You may need to shrink your Emacs or Info window.) Then come back, with Spaces. If your screen is very tall, all of this node might fit at once. In that case, "b" won't do anything. Sorry; what can we do? You have just learned a considerable number of commands. If you want to use one but have trouble remembering which, you should type a @key{?} which prints out a brief list of commands. When you are finished looking at the list, make it go away by pressing @key{SPC} repeatedly. >> Type a @key{?} now. Press @key{SPC} to see consecutive screenfuls of >> the list until finished. From now on, you will encounter large nodes without warning, and will be expected to know how to use Space and Delete to move around in them without being told. Since not all terminals have the same size screen, it would be impossible to warn you anyway. >> Now type @kbd{n} to see the description of the @kbd{m} command. @node Help-M, Help-Adv, Help-^L, Getting Started @comment node-name, next, previous, up @section Menus Menus and the @kbd{m} command With only the @kbd{n} and @kbd{p} commands for moving between nodes, nodes are restricted to a linear sequence. Menus allow a branching structure. A menu is a list of other nodes you can move to. It is actually just part of the text of the node formatted specially so that Info can interpret it. The beginning of a menu is always identified by a line which starts with @samp{* Menu:}. A node contains a menu if and only if it has a line in it which starts that way. The only menu you can use at any moment is the one in the node you are in. To use a menu in any other node, you must move to that node first. After the start of the menu, each line that starts with a @samp{*} identifies one subtopic. The line usually contains a brief name for the subtopic (followed by a @samp{:}), the name of the node that talks about that subtopic, and optionally some further description of the subtopic. Lines in the menu that do not start with a @samp{*} have no special meaning---they are only for the human reader's benefit and do not define additional subtopics. Here is an example: @example * Foo: FOO's Node This tells about FOO @end example The subtopic name is Foo, and the node describing it is @samp{FOO's Node}. The rest of the line is just for the reader's Information. [[ But this line is not a real menu item, simply because there is no line above it which starts with @samp{* Menu:}.]] When you use a menu to go to another node (in a way that will be described soon), what you specify is the subtopic name, the first thing in the menu line. Info uses it to find the menu line, extracts the node name from it, and goes to that node. The reason that there is both a subtopic name and a node name is that the node name must be meaningful to the computer and may therefore have to be ugly looking. The subtopic name can be chosen just to be convenient for the user to specify. Often the node name is convenient for the user to specify and so both it and the subtopic name are the same. There is an abbreviation for this: @example * Foo:: This tells about FOO @end example @noindent This means that the subtopic name and node name are the same; they are both @samp{Foo}. >> Now use Spaces to find the menu in this node, then come back to the front with a @kbd{b} and some Spaces. As you see, a menu is actually visible in its node. If you cannot find a menu in a node by looking at it, then the node does not have a menu and the @kbd{m} command is not available. The command to go to one of the subnodes is @kbd{m}---but @emph{do not do it yet!} Before you use @kbd{m}, you must understand the difference between commands and arguments. So far, you have learned several commands that do not need arguments. When you type one, Info processes it and is instantly ready for another command. The @kbd{m} command is different: it is incomplete without the @dfn{name of the subtopic}. Once you have typed @kbd{m}, Info tries to read the subtopic name. Now look for the line containing many dashes near the bottom of the screen. There is one more line beneath that one, but usually it is blank. If it is empty, Info is ready for a command, such as @kbd{n} or @kbd{b} or Space or @kbd{m}. If that line contains text ending in a colon, it mean Info is trying to read the @dfn{argument} to a command. At such times, commands do not work, because Info tries to use them as the argument. You must either type the argument and finish the command you started, or type @kbd{Control-g} to cancel the command. When you have done one of those things, the line becomes blank again. The command to go to a subnode via a menu is @kbd{m}. After you type the @kbd{m}, the line at the bottom of the screen says @samp{Menu item: }. You must then type the name of the subtopic you want, and end it with a @key{RET}. You can abbreviate the subtopic name. If the abbreviation is not unique, the first matching subtopic is chosen. Some menus put the shortest possible abbreviation for each subtopic name in capital letters, so you can see how much you need to type. It does not matter whether you use upper case or lower case when you type the subtopic. You should not put any spaces at the end, or inside of the item name, except for one space where a space appears in the item in the menu. You can also use the @dfn{completion} feature to help enter the subtopic name. If you type the Tab key after entering part of a name, it will magically fill in more of the name---as much as follows uniquely from what you have entered. If you move the cursor to one of the menu subtopic lines, then you do not need to type the argument: you just type a Return, and it stands for the subtopic of the line you are on. Here is a menu to give you a chance to practice. * Menu: The menu starts here. This menu gives you three ways of going to one place, Help-FOO. * Foo: Help-FOO. A node you can visit for fun.@* * Bar: Help-FOO. Strange! two ways to get to the same place.@* * Help-FOO:: And yet another!@* >> Now type just an @kbd{m} and see what happens: Now you are ``inside'' an @kbd{m} command. Commands cannot be used now; the next thing you will type must be the name of a subtopic. You can change your mind about doing the @kbd{m} by typing Control-g. >> Try that now; notice the bottom line clear. >> Then type another @kbd{m}. >> Now type @samp{BAR} item name. Do not type Return yet. While you are typing the item name, you can use the Delete key to cancel one character at a time if you make a mistake. >> Type one to cancel the @samp{R}. You could type another @samp{R} to replace it. You do not have to, since @samp{BA} is a valid abbreviation. >> Now you are ready to go. Type a @key{RET}. After visiting Help-FOO, you should return here. >> Type @kbd{n} to see more commands. @c If a menu appears at the end of this node, remove it. @c It is an accident of the menu updating command. Here is another way to get to Help-FOO, a menu. You can ignore this if you want, or else try it (but then please come back to here). @menu * Help-FOO:: @end menu @node Help-FOO, , , Help-M @comment node-name, next, previous, up @subsection The @kbd{u} command Congratulations! This is the node @samp{Help-FOO}. Unlike the other nodes you have seen, this one has an @samp{Up}: @samp{Help-M}, the node you just came from via the @kbd{m} command. This is the usual convention---the nodes you reach from a menu have @samp{Up} nodes that lead back to the menu. Menus move Down in the tree, and @samp{Up} moves Up. @samp{Previous}, on the other hand, is usually used to ``stay on the same level but go backwards'' You can go back to the node @samp{Help-M} by typing the command @kbd{u} for ``Up''. That puts you at the @emph{front} of the node---to get back to where you were reading you have to type some @key{SPC}s. >> Now type @kbd{u} to move back up to @samp{Help-M}. @node Help-Adv, Help-Q, Help-M, Getting Started @comment node-name, next, previous, up @section Some advanced Info commands The course is almost over, so please stick with it to the end. If you have been moving around to different nodes and wish to retrace your steps, the @kbd{l} command (@kbd{l} for @dfn{last}) will do that, one node-step at a time. As you move from node to node, Info records the nodes where you have been in a special history list. The @kbd{l} command revisits nodes in the history list; each successive @kbd{l} command moves one step back through the history. If you have been following directions, ad @kbd{l} command now will get you back to @samp{Help-M}. Another @kbd{l} command would undo the @kbd{u} and get you back to @samp{Help-FOO}. Another @kbd{l} would undo the @kbd{m} and get you back to @samp{Help-M}. >> Try typing three @kbd{l}'s, pausing in between to see what each @kbd{l} does. Then follow directions again and you will end up back here. Note the difference between @kbd{l} and @kbd{p}: @kbd{l} moves to where @emph{you} last were, whereas @kbd{p} always moves to the node which the header says is the @samp{Previous} node (from this node, to @samp{Help-M}). The @samp{d} command gets you instantly to the Directory node. This node, which is the first one you saw when you entered Info, has a menu which leads (directly, or indirectly through other menus), to all the nodes that exist. >> Try doing a @samp{d}, then do an @kbd{l} to return here (yes, @emph{do} return). Sometimes, in Info documentation, you will see a cross reference. Cross references look like this: @xref{Help-Cross, Cross}. That is a real, live cross reference which is named @samp{Cross} and points at the node named @samp{Help-Cross}. If you wish to follow a cross reference, you must use the @samp{f} command. The @samp{f} must be followed by the cross reference name (in this case, @samp{Cross}). While you enter the name, you can use the Delete key to edit your input. If you change your mind about following any reference, you can use @kbd{Control-g} to cancel the command. Completion is available in the @samp{f} command; you can complete among all the cross reference names in the current node by typing a Tab. >> Type @samp{f}, followed by @samp{Cross}, and a @key{RET}. To get a list of all the cross references in the current node, you can type @kbd{?} after an @samp{f}. The @samp{f} continues to await a cross reference name even after printing the list, so if you don't actually want to follow a reference, you should type a @kbd{Control-g} to cancel the @samp{f}. >> Type "f?" to get a list of the cross references in this node. Then type a @kbd{Control-g} and see how the @samp{f} gives up. >> Now type @kbd{n} to see the last node of the course. @c If a menu appears at the end of this node, remove it. @c It is an accident of the menu updating command. @node Help-Cross, , , Help-Adv @comment node-name, next, previous, up @unnumberedsubsec The node reached by the cross reference in Info This is the node reached by the cross reference named @samp{Cross}. While this node is specifically intended to be reached by a cross reference, most cross references lead to nodes that ``belong'' someplace else far away in the structure of Info. So you cannot expect the footnote to have a @samp{Next}, @samp{Previous} or @samp{Up} pointing back to where you came from. In general, the @kbd{l} (el) command is the only way to get back there. >> Type @kbd{l} to return to the node where the cross reference was. @node Help-Q, , Help-Adv, Getting Started @comment node-name, next, previous, up @section Quitting Info To get out of Info, back to what you were doing before, type @kbd{q} for @dfn{Quit}. This is the end of the course on using Info. There are some other commands that are meant for experienced users; they are useful, and you can find them by looking in the directory node for documentation on Info. Finding them will be a good exercise in using Info in the usual manner. >> Type @samp{d} to go to the Info directory node; then type @samp{mInfo} and Return, to get to the node about Info and see what other help is available. @node Advanced Info, Create an Info File, Getting Started, Top @comment node-name, next, previous, up @chapter Info for Experts This chapter describes various advanced Info commands, and how to write an Info as distinct from a Texinfo file. (However, in most cases, writing a Texinfo file is better, since you can use it @emph{both} to generate an Info file and to make a printed manual. @xref{Top,, Overview of Texinfo, texinfo, Texinfo: The GNU Documentation Format}.) @menu * Expert:: Advanced Info commands: g, s, e, and 1 - 5. * Add:: Describes how to add new nodes to the hierarchy. Also tells what nodes look like. * Menus:: How to add to or create menus in Info nodes. * Cross-refs:: How to add cross-references to Info nodes. * Tags:: How to make tag tables for Info files. * Checking:: Checking an Info File * Emacs Info Variables:: Variables modifying the behavior of Emacs Info. @end menu @node Expert, Add, , Advanced Info @comment node-name, next, previous, up @section Advanced Info Commands @kbd{g}, @kbd{s}, @kbd{1}, -- @kbd{9}, and @kbd{e} If you know a node's name, you can go there by typing @kbd{g}, the name, and @key{RET}. Thus, @kbd{gTop@key{RET}} would go to the node called @samp{Top} in this file (its directory node). @kbd{gExpert@key{RET}} would come back here. Unlike @kbd{m}, @kbd{g} does not allow the use of abbreviations. To go to a node in another file, you can include the filename in the node name by putting it at the front, in parentheses. Thus, @kbd{g(dir)Top@key{RET}} would go to the Info Directory node, which is node @samp{Top} in the file @file{dir}. The node name @samp{*} specifies the whole file. So you can look at all of the current file by typing @kbd{g*@key{RET}} or all of any other file with @kbd{g(FILENAME)@key{RET}}. The @kbd{s} command allows you to search a whole file for a string. It switches to the next node if and when that is necessary. You type @kbd{s} followed by the string to search for, terminated by @key{RET}. To search for the same string again, just @kbd{s} followed by @key{RET} will do. The file's nodes are scanned in the order they are in in the file, which has no necessary relationship to the order that they may be in in the tree structure of menus and @samp{next} pointers. But normally the two orders are not very different. In any case, you can always do a @kbd{b} to find out what node you have reached, if the header is not visible (this can happen, because @kbd{s} puts your cursor at the occurrence of the string, not at the beginning of the node). If you grudge the system each character of type-in it requires, you might like to use the commands @kbd{1}, @kbd{2}, @kbd{3}, @kbd{4}, ... @kbd{9}. They are short for the @kbd{m} command together with an argument. @kbd{1} goes through the first item in the current node's menu; @kbd{2} goes through the second item, etc. If you display supports multiple fonts, and you are using Emacs' Info mode to read Info files, the @samp{*} for the fifth menu item is underlines, and so is the @samp{*} for the ninth item; these underlines make it easy to see at a glance which number to use for an item. On ordinary terminals, you won't have underlining. If you need to actually count items, it is better to use @kbd{m} instead, and specify the name. The Info command @kbd{e} changes from Info mode to an ordinary Emacs editing mode, so that you can edit the text of the current node. Type @kbd{C-c C-c} to switch back to Info. The @kbd{e} command is allowed only if the variable @code{Info-enable-edit} is non-@code{nil}. @node Add, Menus, Expert, Advanced Info @comment node-name, next, previous, up @section Adding a new node to Info To add a new topic to the list in the Info directory, you must: @enumerate @item Create some nodes, in some file, to document that topic. @item Put that topic in the menu in the directory. @xref{Menus, Menu}. @end enumerate Usually, the way to create the nodes is with Texinfo @pxref{Top,, Overview of Texinfo, texinfo, Texinfo: The GNU Documentation Format}); this has the advantage that you can also make a printed manual from them. However, if hyou want to edit an Info file, here is how. The new node can live in an existing documentation file, or in a new one. It must have a @key{^_} character before it (invisible to the user; this node has one but you cannot see it), and it ends with either a @key{^_}, a @key{^L}, or the end of file. Note: If you put in a @key{^L} to end a new node, be sure that there is a @key{^_} after it to start the next one, since @key{^L} cannot @emph{start} a node. Also, a nicer way to make a node boundary be a page boundary as well is to put a @key{^L} @emph{right after} the @key{^_}. The @key{^_} starting a node must be followed by a newline or a @key{^L} newline, after which comes the node's header line. The header line must give the node's name (by which Info finds it), and state the names of the @samp{Next}, @samp{Previous}, and @samp{Up} nodes (if there are any). As you can see, this node's @samp{Up} node is the node @samp{Top}, which points at all the documentation for Info. The @samp{Next} node is @samp{Menus}. The keywords @dfn{Node}, @dfn{Previous}, @dfn{Up}, and @dfn{Next}, may appear in any order, anywhere in the header line, but the recommended order is the one in this sentence. Each keyword must be followed by a colon, spaces and tabs, and then the appropriate name. The name may be terminated with a tab, a comma, or a newline. A space does not end it; node names may contain spaces. The case of letters in the names is insignificant. A node name has two forms. A node in the current file is named by what appears after the @samp{Node: } in that node's first line. For example, this node's name is @samp{Add}. A node in another file is named by @samp{(@var{filename})@var{node-within-file}}, as in @samp{(info)Add} for this node. If the file name starts with ``./'', then it is relative to the current directory; otherwise, it is relative starting from the standard Info file directory of your site. The name @samp{(@var{filename})Top} can be abbreviated to just @samp{(@var{filename})}. By convention, the name @samp{Top} is used for the ``highest'' node in any single file---the node whose @samp{Up} points out of the file. The Directory node is @file{(dir)}. The @samp{Top} node of a document file listed in the Directory should have an @samp{Up: (dir)} in it. The node name @kbd{*} is special: it refers to the entire file. Thus, @kbd{g*} shows you the whole current file. The use of the node @kbd{*} is to make it possible to make old-fashioned, unstructured files into nodes of the tree. The @samp{Node:} name, in which a node states its own name, must not contain a filename, since Info when searching for a node does not expect one to be there. The @samp{Next}, @samp{Previous} and @samp{Up} names may contain them. In this node, since the @samp{Up} node is in the same file, it was not necessary to use one. Note that the nodes in this file have a file name in the header line. The file names are ignored by Info, but they serve as comments to help identify the node for the user. @node Menus, Cross-refs, Add, Advanced Info @comment node-name, next, previous, up @section How to Create Menus Any node in the Info hierarchy may have a @dfn{menu}---a list of subnodes. The @kbd{m} command searches the current node's menu for the topic which it reads from the terminal. A menu begins with a line starting with @samp{* Menu:}. The rest of the line is a comment. After the starting line, every line that begins with a @samp{* } lists a single topic. The name of the topic--the argument that the user must give to the @kbd{m} command to select this topic---comes right after the star and space, and is followed by a colon, spaces and tabs, and the name of the node which discusses that topic. The node name, like node names following @samp{Next}, @samp{Previous} and @samp{Up}, may be terminated with a tab, comma, or newline; it may also be terminated with a period. If the node name and topic name are the same, then rather than giving the name twice, the abbreviation @samp{* NAME::} may be used (and should be used, whenever possible, as it reduces the visual clutter in the menu). It is considerate to choose the topic names so that they differ from each other very near the beginning---this allows the user to type short abbreviations. In a long menu, it is a good idea to capitalize the beginning of each item name which is the minimum acceptable abbreviation for it (a long menu is more than 5 or so entries). The nodes listed in a node's menu are called its ``subnodes'', and it is their ``superior''. They should each have an @samp{Up:} pointing at the superior. It is often useful to arrange all or most of the subnodes in a sequence of @samp{Next} and @samp{Previous} pointers so that someone who wants to see them all need not keep revisiting the Menu. The Info Directory is simply the menu of the node @samp{(dir)Top}---that is, node @samp{Top} in file @file{.../info/dir}. You can put new entries in that menu just like any other menu. The Info Directory is @emph{not} the same as the file directory called @file{info}. It happens that many of Info's files live on that file directory, but they do not have to; and files on that directory are not automatically listed in the Info Directory node. Also, although the Info node graph is claimed to be a ``hierarchy'', in fact it can be @emph{any} directed graph. Shared structures and pointer cycles are perfectly possible, and can be used if they are appropriate to the meaning to be expressed. There is no need for all the nodes in a file to form a connected structure. In fact, this file has two connected components. You are in one of them, which is under the node @samp{Top}; the other contains the node @samp{Help} which the @kbd{h} command goes to. In fact, since there is no garbage collector, nothing terrible happens if a substructure is not pointed to, but such a substructure is rather useless since nobody can ever find out that it exists. @node Cross-refs, Tags, Menus, Advanced Info @comment node-name, next, previous, up @section Creating Cross References A cross reference can be placed anywhere in the text, unlike a menu item which must go at the front of a line. A cross reference looks like a menu item except that it has @samp{*note} instead of @kbd{*}. It @emph{cannot} be terminated by a @samp{)}, because @samp{)}'s are so often part of node names. If you wish to enclose a cross reference in parentheses, terminate it with a period first. Here are two examples of cross references pointers: @example *Note details: commands. (See *note 3: Full Proof.) @end example They are just examples. The places they ``lead to'' do not really exist! @node Tags, Checking, Cross-refs, Advanced Info @comment node-name, next, previous, up @section Tag Tables for Info Files You can speed up the access to nodes of a large Info file by giving it a tag table. Unlike the tag table for a program, the tag table for an Info file lives inside the file itself and is used automatically whenever Info reads in the file. To make a tag table, go to a node in the file using Emacs Info mode and type @kbd{M-x Info-tagify}. Then you must use @kbd{C-x C-s} to save the file. Once the Info file has a tag table, you must make certain it is up to date. If, as a result of deletion of text, any node moves back more than a thousand characters in the file from the position recorded in the tag table, Info will no longer be able to find that node. To update the tag table, use the @code{Info-tagify} command again. An Info file tag table appears at the end of the file and looks like this: @example ^_ Tag Table: File: info, Node: Cross-refs^?21419 File: info, Node: Tags^?22145 ^_ End Tag Table @end example @noindent Note that it contains one line per node, and this line contains the beginning of the node's header (ending just after the node name), a Delete character, and the character position in the file of the beginning of the node. @node Checking, Emacs Info Variables, Tags, Advanced Info @comment node-name, next, previous, up @section Checking an Info File When creating an Info file, it is easy to forget the name of a node when you are making a pointer to it from another node. If you put in the wrong name for a node, this is not detected until someone tries to go through the pointer using Info. Verification of the Info file is an automatic process which checks all pointers to nodes and reports any pointers which are invalid. Every @samp{Next}, @samp{Previous}, and @samp{Up} is checked, as is every menu item and every cross reference. In addition, any @samp{Next} which does not have a @samp{Previous} pointing back is reported. Only pointers within the file are checked, because checking pointers to other files would be terribly slow. But those are usually few. To check an Info file, do @kbd{M-x Info-validate} while looking at any node of the file with Emacs Info mode. @node Emacs Info Variables, , Checking, Advanced Info @section Emacs Info-mode Variables The following variables may modify the behaviour of Info-mode in Emacs; you may wish to set one or several of these variables interactively, or in your @file{~/.emacs} init file. @xref{Examining, Examining and Setting Variables, Examining and Setting Variables, emacs, The GNU Emacs Manual}. @vtable @code @item Info-enable-edit Set to @code{nil}, disables the @samp{e} (@code{Info-edit}) command. A non-@code{nil} value enables it. @xref{Add, Edit}. @item Info-enable-active-nodes When set to a non-@code{nil} value, allows Info to execute Lisp code associated with nodes. The Lisp code is executed when the node is selected. @item Info-directory-list The list of directories to search for Info files. Each element is a string (directory name) or @code{nil} (try default directory). @item Info-directory The standard directory for Info documentation files. Only used when the function @code{Info-directory} is called. @end vtable @node Create an Info File, , Advanced Info, Top @comment node-name, next, previous, up @chapter Creating an Info File from a Makeinfo file @code{makeinfo} is a utility that converts a Texinfo file into an Info file; @code{texinfo-format-region} and @code{texinfo-format-buffer} are GNU Emacs functions that do the same. @xref{Create an Info File, , Creating an Info File, texinfo, the Texinfo Manual}, to learn how to create an Info file from a Texinfo file. @xref{Top,, Overview of Texinfo, texinfo, Texinfo: The GNU Documentation Format}, to learn how to write a Texinfo file. @bye texinfo-3.12/doc/Makefile.am0000444000175000017500000000361006475632060013160 0ustar gg## Makefile.am for texinfo/emacs. ## $Id: Makefile.am,v 1.12 1998/02/27 21:46:23 karl Exp $ ## Run automake in .. to produce Makefile.in from this. info_TEXINFOS = info-stnd.texi info.texi texinfo.txi # Use the programs built in our distribution. MAKEINFO = ../makeinfo/makeinfo INSTALL_INFO = ../util/install-info # Include our texinfo.tex, not Automake's. EXTRA_DIST = macro.texi userdoc.texi epsf.tex texinfo.tex # We try to discover this via configure just to give a better help message. TEXMF = @TEXMF@ install-data-local: @echo "WARNING: You must install texinfo.tex and epsf.tex manually," @echo "WARNING: perhaps in $(TEXMF)/tex/texinfo/" @echo "WARNING: and $(TEXMF)/tex/generic/dvips/ respectively." @echo "WARNING: See doc/README for some considerations." # Do not create info files for distribution. dist-info: # Do not try to build the info files in $(srcdir), # since we don't distribute them. .texi.info: $(MAKEINFO) -I$(srcdir) `echo $< | sed 's,.*/,,'` texinfo: $(srcdir)/texinfo.txi $(MAKEINFO) -I$(srcdir) texinfo.txi # Similarly, Do not try to install the info files from $(srcdir). install-info-am: $(INFO_DEPS) @$(NORMAL_INSTALL) $(mkinstalldirs) $(infodir) @for file in $(INFO_DEPS); do \ d=.; \ for ifile in `cd $$d && echo $$file $$file-[0-9] $$file-[0-9][0-9]`; do \ if test -f $$d/$$ifile; then \ echo " $(INSTALL_DATA) $$d/$$ifile $(infodir)/$$ifile"; \ $(INSTALL_DATA) $$d/$$ifile $(infodir)/$$ifile; \ else : ; fi; \ done; \ done @$(POST_INSTALL) @if $(SHELL) -c '$(INSTALL_INFO) --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \ for file in $(INFO_DEPS); do \ echo " $(INSTALL_INFO) --info-dir=$(infodir) $(infodir)/$$file";\ $(INSTALL_INFO) --info-dir=$(infodir) $(infodir)/$$file || :;\ done; \ else : ; fi # Remove the info files at make distclean. distclean-aminfo: rm -f texinfo texinfo-* info*.info* texinfo-3.12/doc/texinfo.tex0000444000175000017500000050604706477055046013343 0ustar gg% texinfo.tex -- TeX macros to handle Texinfo files. % $Id: texinfo.tex,v 2.227 1998/02/25 22:54:34 karl Exp $ % % Copyright (C) 1985, 86, 88, 90, 91, 92, 93, 94, 95, 96, 97, 98 % Free Software Foundation, Inc. % % This texinfo.tex file is free software; you can redistribute it and/or % modify it under the terms of the GNU General Public License as % published by the Free Software Foundation; either version 2, or (at % your option) any later version. % % This texinfo.tex file is distributed in the hope that it will be % useful, but WITHOUT ANY WARRANTY; without even the implied warranty % of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU % General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this texinfo.tex file; see the file COPYING. If not, write % to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, % Boston, MA 02111-1307, USA. % % In other words, you are welcome to use, share and improve this program. % You are forbidden to forbid anyone else to use, share and improve % what you give them. Help stamp out software-hoarding! % % Please try the latest version of texinfo.tex before submitting bug % reports; you can get the latest version from: % ftp://ftp.cs.umb.edu/pub/tex/texinfo.tex % /home/gd/gnu/doc/texinfo.tex on the GNU machines. % % Send bug reports to bug-texinfo@gnu.org. % Please include a precise test case in each bug report, % including a complete document with which we can reproduce the problem. % % Texinfo macros (with @macro) are *not* supported by texinfo.tex. You % have to run makeinfo -E to expand macros first; the texi2dvi script % does this. % Make it possible to create a .fmt file just by loading this file: % if the underlying format is not loaded, start by loading it now. % Added by gildea November 1993. \expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi % This automatically updates the version number based on RCS. \def\deftexinfoversion$#1: #2 ${\def\texinfoversion{#2}} \deftexinfoversion$Revision: 2.227 $ \message{Loading texinfo package [Version \texinfoversion]:} % If in a .fmt file, print the version number % and turn on active characters that we couldn't do earlier because % they might have appeared in the input file name. \everyjob{\message{[Texinfo version \texinfoversion]}\message{} \catcode`+=\active \catcode`\_=\active} % Save some parts of plain tex whose names we will redefine. \let\ptexb=\b \let\ptexbullet=\bullet \let\ptexc=\c \let\ptexcomma=\, \let\ptexdot=\. \let\ptexdots=\dots \let\ptexend=\end \let\ptexequiv=\equiv \let\ptexexclam=\! \let\ptexi=\i \let\ptexlbrace=\{ \let\ptexrbrace=\} \let\ptexstar=\* \let\ptext=\t % Be sure we're in horizontal mode when doing a tie, since we make space % equivalent to this in @example-like environments. Otherwise, a space % at the beginning of a line will start with \penalty -- and % since \penalty is valid in vertical mode, we'd end up putting the % penalty on the vertical list instead of in the new paragraph. {\catcode`@ = 11 % Avoid using \@M directly, because that causes trouble % if the definition is written into an index file. \global\let\tiepenalty = \@M \gdef\tie{\leavevmode\penalty\tiepenalty\ } } \message{Basics,} \chardef\other=12 % If this character appears in an error message or help string, it % starts a new line in the output. \newlinechar = `^^J % Set up fixed words for English. \ifx\putwordChapter\undefined{\gdef\putwordChapter{Chapter}}\fi% \def\putwordInfo{Info}% \ifx\putwordSee\undefined{\gdef\putwordSee{See}}\fi% \ifx\putwordsee\undefined{\gdef\putwordsee{see}}\fi% \ifx\putwordfile\undefined{\gdef\putwordfile{file}}\fi% \ifx\putwordpage\undefined{\gdef\putwordpage{page}}\fi% \ifx\putwordsection\undefined{\gdef\putwordsection{section}}\fi% \ifx\putwordSection\undefined{\gdef\putwordSection{Section}}\fi% \ifx\putwordTableofContents\undefined{\gdef\putwordTableofContents{Table of Contents}}\fi% \ifx\putwordShortContents\undefined{\gdef\putwordShortContents{Short Contents}}\fi% \ifx\putwordAppendix\undefined{\gdef\putwordAppendix{Appendix}}\fi% % Ignore a token. % \def\gobble#1{} \hyphenation{ap-pen-dix} \hyphenation{mini-buf-fer mini-buf-fers} \hyphenation{eshell} \hyphenation{white-space} % Margin to add to right of even pages, to left of odd pages. \newdimen \bindingoffset \newdimen \normaloffset \newdimen\pagewidth \newdimen\pageheight % Sometimes it is convenient to have everything in the transcript file % and nothing on the terminal. We don't just call \tracingall here, % since that produces some useless output on the terminal. % \def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}% \def\loggingall{\tracingcommands2 \tracingstats2 \tracingpages1 \tracingoutput1 \tracinglostchars1 \tracingmacros2 \tracingparagraphs1 \tracingrestores1 \showboxbreadth\maxdimen\showboxdepth\maxdimen }% % For @cropmarks command. % Do @cropmarks to get crop marks. % \newif\ifcropmarks \let\cropmarks = \cropmarkstrue % % Dimensions to add cropmarks at corners. % Added by P. A. MacKay, 12 Nov. 1986 % \newdimen\cornerlong \newdimen\cornerthick \newdimen\topandbottommargin \newdimen\outerhsize \newdimen\outervsize \cornerlong=1pc\cornerthick=.3pt % These set size of cropmarks \outerhsize=7in %\outervsize=9.5in % Alternative @smallbook page size is 9.25in \outervsize=9.25in \topandbottommargin=.75in % Main output routine. \chardef\PAGE = 255 \output = {\onepageout{\pagecontents\PAGE}} \newbox\headlinebox \newbox\footlinebox % \onepageout takes a vbox as an argument. Note that \pagecontents % does insertions, but you have to call it yourself. \def\onepageout#1{% \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi % \ifodd\pageno \advance\hoffset by \bindingoffset \else \advance\hoffset by -\bindingoffset\fi % % Do this outside of the \shipout so @code etc. will be expanded in % the headline as they should be, not taken literally (outputting ''code). \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}% \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}% % {% % Have to do this stuff outside the \shipout because we want it to % take effect in \write's, yet the group defined by the \vbox ends % before the \shipout runs. % \escapechar = `\\ % use backslash in output files. \indexdummies % don't expand commands in the output. \normalturnoffactive % \ in index entries must not stay \, e.g., if % the page break happens to be in the middle of an example. \shipout\vbox{% \ifcropmarks \vbox to \outervsize\bgroup \hsize = \outerhsize \line{\ewtop\hfil\ewtop}% \nointerlineskip \line{% \vbox{\moveleft\cornerthick\nstop}% \hfill \vbox{\moveright\cornerthick\nstop}% }% \vskip\topandbottommargin \line\bgroup \hfil % center the page within the outer (page) hsize. \ifodd\pageno\hskip\bindingoffset\fi \vbox\bgroup \fi % \unvbox\headlinebox \pagebody{#1}% \ifdim\ht\footlinebox > 0pt % Only leave this space if the footline is nonempty. % (We lessened \vsize for it in \oddfootingxxx.) % The \baselineskip=24pt in plain's \makefootline has no effect. \vskip 2\baselineskip \unvbox\footlinebox \fi % \ifcropmarks \egroup % end of \vbox\bgroup \hfil\egroup % end of (centering) \line\bgroup \vskip\topandbottommargin plus1fill minus1fill \boxmaxdepth = \cornerthick \line{% \vbox{\moveleft\cornerthick\nsbot}% \hfill \vbox{\moveright\cornerthick\nsbot}% }% \nointerlineskip \line{\ewbot\hfil\ewbot}% \egroup % \vbox from first cropmarks clause \fi }% end of \shipout\vbox }% end of group with \turnoffactive \advancepageno \ifnum\outputpenalty>-20000 \else\dosupereject\fi } \newinsert\margin \dimen\margin=\maxdimen \def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}} {\catcode`\@ =11 \gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi % marginal hacks, juha@viisa.uucp (Juha Takala) \ifvoid\margin\else % marginal info is present \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi \dimen@=\dp#1 \unvbox#1 \ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi \ifr@ggedbottom \kern-\dimen@ \vfil \fi} } % Here are the rules for the cropmarks. Note that they are % offset so that the space between them is truly \outerhsize or \outervsize % (P. A. MacKay, 12 November, 1986) % \def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong} \def\nstop{\vbox {\hrule height\cornerthick depth\cornerlong width\cornerthick}} \def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong} \def\nsbot{\vbox {\hrule height\cornerlong depth\cornerthick width\cornerthick}} % Parse an argument, then pass it to #1. The argument is the rest of % the input line (except we remove a trailing comment). #1 should be a % macro which expects an ordinary undelimited TeX argument. % \def\parsearg#1{% \let\next = #1% \begingroup \obeylines \futurelet\temp\parseargx } % If the next token is an obeyed space (from an @example environment or % the like), remove it and recurse. Otherwise, we're done. \def\parseargx{% % \obeyedspace is defined far below, after the definition of \sepspaces. \ifx\obeyedspace\temp \expandafter\parseargdiscardspace \else \expandafter\parseargline \fi } % Remove a single space (as the delimiter token to the macro call). {\obeyspaces % \gdef\parseargdiscardspace {\futurelet\temp\parseargx}} {\obeylines % \gdef\parseargline#1^^M{% \endgroup % End of the group started in \parsearg. % % First remove any @c comment, then any @comment. % Result of each macro is put in \toks0. \argremovec #1\c\relax % \expandafter\argremovecomment \the\toks0 \comment\relax % % % Call the caller's macro, saved as \next in \parsearg. \expandafter\next\expandafter{\the\toks0}% }% } % Since all \c{,omment} does is throw away the argument, we can let TeX % do that for us. The \relax here is matched by the \relax in the call % in \parseargline; it could be more or less anything, its purpose is % just to delimit the argument to the \c. \def\argremovec#1\c#2\relax{\toks0 = {#1}} \def\argremovecomment#1\comment#2\relax{\toks0 = {#1}} % \argremovec{,omment} might leave us with trailing spaces, though; e.g., % @end itemize @c foo % will have two active spaces as part of the argument with the % `itemize'. Here we remove all active spaces from #1, and assign the % result to \toks0. % % This loses if there are any *other* active characters besides spaces % in the argument -- _ ^ +, for example -- since they get expanded. % Fortunately, Texinfo does not define any such commands. (If it ever % does, the catcode of the characters in questionwill have to be changed % here.) But this means we cannot call \removeactivespaces as part of % \argremovec{,omment}, since @c uses \parsearg, and thus the argument % that \parsearg gets might well have any character at all in it. % \def\removeactivespaces#1{% \begingroup \ignoreactivespaces \edef\temp{#1}% \global\toks0 = \expandafter{\temp}% \endgroup } % Change the active space to expand to nothing. % \begingroup \obeyspaces \gdef\ignoreactivespaces{\obeyspaces\let =\empty} \endgroup \def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next} %% These are used to keep @begin/@end levels from running away %% Call \inENV within environments (after a \begingroup) \newif\ifENV \ENVfalse \def\inENV{\ifENV\relax\else\ENVtrue\fi} \def\ENVcheck{% \ifENV\errmessage{Still within an environment. Type Return to continue.} \endgroup\fi} % This is not perfect, but it should reduce lossage % @begin foo is the same as @foo, for now. \newhelp\EMsimple{Type to continue.} \outer\def\begin{\parsearg\beginxxx} \def\beginxxx #1{% \expandafter\ifx\csname #1\endcsname\relax {\errhelp=\EMsimple \errmessage{Undefined command @begin #1}}\else \csname #1\endcsname\fi} % @end foo executes the definition of \Efoo. % \def\end{\parsearg\endxxx} \def\endxxx #1{% \removeactivespaces{#1}% \edef\endthing{\the\toks0}% % \expandafter\ifx\csname E\endthing\endcsname\relax \expandafter\ifx\csname \endthing\endcsname\relax % There's no \foo, i.e., no ``environment'' foo. \errhelp = \EMsimple \errmessage{Undefined command `@end \endthing'}% \else \unmatchedenderror\endthing \fi \else % Everything's ok; the right environment has been started. \csname E\endthing\endcsname \fi } % There is an environment #1, but it hasn't been started. Give an error. % \def\unmatchedenderror#1{% \errhelp = \EMsimple \errmessage{This `@end #1' doesn't have a matching `@#1'}% } % Define the control sequence \E#1 to give an unmatched @end error. % \def\defineunmatchedend#1{% \expandafter\def\csname E#1\endcsname{\unmatchedenderror{#1}}% } % Single-spacing is done by various environments (specifically, in % \nonfillstart and \quotations). \newskip\singlespaceskip \singlespaceskip = 12.5pt \def\singlespace{% % Why was this kern here? It messes up equalizing space above and below % environments. --karl, 6may93 %{\advance \baselineskip by -\singlespaceskip %\kern \baselineskip}% \setleading \singlespaceskip } %% Simple single-character @ commands % @@ prints an @ % Kludge this until the fonts are right (grr). \def\@{{\tt \char '100}} % This is turned off because it was never documented % and you can use @w{...} around a quote to suppress ligatures. %% Define @` and @' to be the same as ` and ' %% but suppressing ligatures. %\def\`{{`}} %\def\'{{'}} % Used to generate quoted braces. \def\mylbrace {{\tt \char '173}} \def\myrbrace {{\tt \char '175}} \let\{=\mylbrace \let\}=\myrbrace \begingroup % Definitions to produce actual \{ & \} command in an index. \catcode`\{ = 12 \catcode`\} = 12 \catcode`\[ = 1 \catcode`\] = 2 \catcode`\@ = 0 \catcode`\\ = 12 @gdef@lbracecmd[\{]% @gdef@rbracecmd[\}]% @endgroup % Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent % Others are defined by plain TeX: @` @' @" @^ @~ @= @v @H. \let\, = \c \let\dotaccent = \. \def\ringaccent#1{{\accent23 #1}} \let\tieaccent = \t \let\ubaraccent = \b \let\udotaccent = \d % Other special characters: @questiondown @exclamdown % Plain TeX defines: @AA @AE @O @OE @L (and lowercase versions) @ss. \def\questiondown{?`} \def\exclamdown{!`} % Dotless i and dotless j, used for accents. \def\imacro{i} \def\jmacro{j} \def\dotless#1{% \def\temp{#1}% \ifx\temp\imacro \ptexi \else\ifx\temp\jmacro \j \else \errmessage{@dotless can be used only with i or j}% \fi\fi } % @: forces normal size whitespace following. \def\:{\spacefactor=1000 } % @* forces a line break. \def\*{\hfil\break\hbox{}\ignorespaces} % @. is an end-of-sentence period. \def\.{.\spacefactor=3000 } % @! is an end-of-sentence bang. \def\!{!\spacefactor=3000 } % @? is an end-of-sentence query. \def\?{?\spacefactor=3000 } % @w prevents a word break. Without the \leavevmode, @w at the % beginning of a paragraph, when TeX is still in vertical mode, would % produce a whole line of output instead of starting the paragraph. \def\w#1{\leavevmode\hbox{#1}} % @group ... @end group forces ... to be all on one page, by enclosing % it in a TeX vbox. We use \vtop instead of \vbox to construct the box % to keep its height that of a normal line. According to the rules for % \topskip (p.114 of the TeXbook), the glue inserted is % max (\topskip - \ht (first item), 0). If that height is large, % therefore, no glue is inserted, and the space between the headline and % the text is small, which looks bad. % \def\group{\begingroup \ifnum\catcode13=\active \else \errhelp = \groupinvalidhelp \errmessage{@group invalid in context where filling is enabled}% \fi % % The \vtop we start below produces a box with normal height and large % depth; thus, TeX puts \baselineskip glue before it, and (when the % next line of text is done) \lineskip glue after it. (See p.82 of % the TeXbook.) Thus, space below is not quite equal to space % above. But it's pretty close. \def\Egroup{% \egroup % End the \vtop. \endgroup % End the \group. }% % \vtop\bgroup % We have to put a strut on the last line in case the @group is in % the midst of an example, rather than completely enclosing it. % Otherwise, the interline space between the last line of the group % and the first line afterwards is too small. But we can't put the % strut in \Egroup, since there it would be on a line by itself. % Hence this just inserts a strut at the beginning of each line. \everypar = {\strut}% % % Since we have a strut on every line, we don't need any of TeX's % normal interline spacing. \offinterlineskip % % OK, but now we have to do something about blank % lines in the input in @example-like environments, which normally % just turn into \lisppar, which will insert no space now that we've % turned off the interline space. Simplest is to make them be an % empty paragraph. \ifx\par\lisppar \edef\par{\leavevmode \par}% % % Reset ^^M's definition to new definition of \par. \obeylines \fi % % Do @comment since we are called inside an environment such as % @example, where each end-of-line in the input causes an % end-of-line in the output. We don't want the end-of-line after % the `@group' to put extra space in the output. Since @group % should appear on a line by itself (according to the Texinfo % manual), we don't worry about eating any user text. \comment } % % TeX puts in an \escapechar (i.e., `@') at the beginning of the help % message, so this ends up printing `@group can only ...'. % \newhelp\groupinvalidhelp{% group can only be used in environments such as @example,^^J% where each line of input produces a line of output.} % @need space-in-mils % forces a page break if there is not space-in-mils remaining. \newdimen\mil \mil=0.001in \def\need{\parsearg\needx} % Old definition--didn't work. %\def\needx #1{\par % %% This method tries to make TeX break the page naturally %% if the depth of the box does not fit. %{\baselineskip=0pt% %\vtop to #1\mil{\vfil}\kern -#1\mil\penalty 10000 %\prevdepth=-1000pt %}} \def\needx#1{% % Go into vertical mode, so we don't make a big box in the middle of a % paragraph. \par % % Don't add any leading before our big empty box, but allow a page % break, since the best break might be right here. \allowbreak \nointerlineskip \vtop to #1\mil{\vfil}% % % TeX does not even consider page breaks if a penalty added to the % main vertical list is 10000 or more. But in order to see if the % empty box we just added fits on the page, we must make it consider % page breaks. On the other hand, we don't want to actually break the % page after the empty box. So we use a penalty of 9999. % % There is an extremely small chance that TeX will actually break the % page at this \penalty, if there are no other feasible breakpoints in % sight. (If the user is using lots of big @group commands, which % almost-but-not-quite fill up a page, TeX will have a hard time doing % good page breaking, for example.) However, I could not construct an % example where a page broke at this \penalty; if it happens in a real % document, then we can reconsider our strategy. \penalty9999 % % Back up by the size of the box, whether we did a page break or not. \kern -#1\mil % % Do not allow a page break right after this kern. \nobreak } % @br forces paragraph break \let\br = \par % @dots{} output an ellipsis using the current font. % We do .5em per period so that it has the same spacing in a typewriter % font as three actual period characters. % \def\dots{\hbox to 1.5em{% \hskip 0pt plus 0.25fil minus 0.25fil .\hss.\hss.% \hskip 0pt plus 0.5fil minus 0.5fil }} % @enddots{} is an end-of-sentence ellipsis. % \def\enddots{% \hbox to 2em{% \hskip 0pt plus 0.25fil minus 0.25fil .\hss.\hss.\hss.% \hskip 0pt plus 0.5fil minus 0.5fil }% \spacefactor=3000 } % @page forces the start of a new page \def\page{\par\vfill\supereject} % @exdent text.... % outputs text on separate line in roman font, starting at standard page margin % This records the amount of indent in the innermost environment. % That's how much \exdent should take out. \newskip\exdentamount % This defn is used inside fill environments such as @defun. \def\exdent{\parsearg\exdentyyy} \def\exdentyyy #1{{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}} % This defn is used inside nofill environments such as @example. \def\nofillexdent{\parsearg\nofillexdentyyy} \def\nofillexdentyyy #1{{\advance \leftskip by -\exdentamount \leftline{\hskip\leftskip{\rm#1}}}} % @inmargin{TEXT} puts TEXT in the margin next to the current paragraph. \def\inmargin#1{% \strut\vadjust{\nobreak\kern-\strutdepth \vtop to \strutdepth{\baselineskip\strutdepth\vss \llap{\rightskip=\inmarginspacing \vbox{\noindent #1}}\null}}} \newskip\inmarginspacing \inmarginspacing=1cm \def\strutdepth{\dp\strutbox} %\hbox{{\rm#1}}\hfil\break}} % @include file insert text of that file as input. % Allow normal characters that we make active in the argument (a file name). \def\include{\begingroup \catcode`\\=12 \catcode`~=12 \catcode`^=12 \catcode`_=12 \catcode`|=12 \catcode`<=12 \catcode`>=12 \catcode`+=12 \parsearg\includezzz} % Restore active chars for included file. \def\includezzz#1{\endgroup\begingroup % Read the included file in a group so nested @include's work. \def\thisfile{#1}% \input\thisfile \endgroup} \def\thisfile{} % @center line outputs that line, centered \def\center{\parsearg\centerzzz} \def\centerzzz #1{{\advance\hsize by -\leftskip \advance\hsize by -\rightskip \centerline{#1}}} % @sp n outputs n lines of vertical space \def\sp{\parsearg\spxxx} \def\spxxx #1{\vskip #1\baselineskip} % @comment ...line which is ignored... % @c is the same as @comment % @ignore ... @end ignore is another way to write a comment \def\comment{\catcode 64=\other \catcode 123=\other \catcode 125=\other% \parsearg \commentxxx} \def\commentxxx #1{\catcode 64=0 \catcode 123=1 \catcode 125=2 } \let\c=\comment % @paragraphindent is defined for the Info formatting commands only. \let\paragraphindent=\comment % Prevent errors for section commands. % Used in @ignore and in failing conditionals. \def\ignoresections{% \let\chapter=\relax \let\unnumbered=\relax \let\top=\relax \let\unnumberedsec=\relax \let\unnumberedsection=\relax \let\unnumberedsubsec=\relax \let\unnumberedsubsection=\relax \let\unnumberedsubsubsec=\relax \let\unnumberedsubsubsection=\relax \let\section=\relax \let\subsec=\relax \let\subsubsec=\relax \let\subsection=\relax \let\subsubsection=\relax \let\appendix=\relax \let\appendixsec=\relax \let\appendixsection=\relax \let\appendixsubsec=\relax \let\appendixsubsection=\relax \let\appendixsubsubsec=\relax \let\appendixsubsubsection=\relax \let\contents=\relax \let\smallbook=\relax \let\titlepage=\relax } % Used in nested conditionals, where we have to parse the Texinfo source % and so want to turn off most commands, in case they are used % incorrectly. % \def\ignoremorecommands{% \let\defcodeindex = \relax \let\defcv = \relax \let\deffn = \relax \let\deffnx = \relax \let\defindex = \relax \let\defivar = \relax \let\defmac = \relax \let\defmethod = \relax \let\defop = \relax \let\defopt = \relax \let\defspec = \relax \let\deftp = \relax \let\deftypefn = \relax \let\deftypefun = \relax \let\deftypevar = \relax \let\deftypevr = \relax \let\defun = \relax \let\defvar = \relax \let\defvr = \relax \let\ref = \relax \let\xref = \relax \let\printindex = \relax \let\pxref = \relax \let\settitle = \relax \let\setchapternewpage = \relax \let\setchapterstyle = \relax \let\everyheading = \relax \let\evenheading = \relax \let\oddheading = \relax \let\everyfooting = \relax \let\evenfooting = \relax \let\oddfooting = \relax \let\headings = \relax \let\include = \relax \let\lowersections = \relax \let\down = \relax \let\raisesections = \relax \let\up = \relax \let\set = \relax \let\clear = \relax \let\item = \relax } % Ignore @ignore ... @end ignore. % \def\ignore{\doignore{ignore}} % Ignore @ifinfo, @ifhtml, @ifnottex, @html, @menu, and @direntry text. % \def\ifinfo{\doignore{ifinfo}} \def\ifhtml{\doignore{ifhtml}} \def\ifnottex{\doignore{ifnottex}} \def\html{\doignore{html}} \def\menu{\doignore{menu}} \def\direntry{\doignore{direntry}} % Also ignore @macro ... @end macro. The user must run texi2dvi, % which runs makeinfo to do macro expansion. Ignore @unmacro, too. \def\macro{\doignore{macro}} \let\unmacro = \comment % @dircategory CATEGORY -- specify a category of the dir file % which this file should belong to. Ignore this in TeX. \let\dircategory = \comment % Ignore text until a line `@end #1'. % \def\doignore#1{\begingroup % Don't complain about control sequences we have declared \outer. \ignoresections % % Define a command to swallow text until we reach `@end #1'. \long\def\doignoretext##1\end #1{\enddoignore}% % % Make sure that spaces turn into tokens that match what \doignoretext wants. \catcode32 = 10 % % Ignore braces, too, so mismatched braces don't cause trouble. \catcode`\{ = 9 \catcode`\} = 9 % % And now expand that command. \doignoretext } % What we do to finish off ignored text. % \def\enddoignore{\endgroup\ignorespaces}% \newif\ifwarnedobs\warnedobsfalse \def\obstexwarn{% \ifwarnedobs\relax\else % We need to warn folks that they may have trouble with TeX 3.0. % This uses \immediate\write16 rather than \message to get newlines. \immediate\write16{} \immediate\write16{***WARNING*** for users of Unix TeX 3.0!} \immediate\write16{This manual trips a bug in TeX version 3.0 (tex hangs).} \immediate\write16{If you are running another version of TeX, relax.} \immediate\write16{If you are running Unix TeX 3.0, kill this TeX process.} \immediate\write16{ Then upgrade your TeX installation if you can.} \immediate\write16{ (See ftp://ftp.gnu.ai.mit.edu/pub/gnu/TeX.README.)} \immediate\write16{If you are stuck with version 3.0, run the} \immediate\write16{ script ``tex3patch'' from the Texinfo distribution} \immediate\write16{ to use a workaround.} \immediate\write16{} \global\warnedobstrue \fi } % **In TeX 3.0, setting text in \nullfont hangs tex. For a % workaround (which requires the file ``dummy.tfm'' to be installed), % uncomment the following line: %%%%%\font\nullfont=dummy\let\obstexwarn=\relax % Ignore text, except that we keep track of conditional commands for % purposes of nesting, up to an `@end #1' command. % \def\nestedignore#1{% \obstexwarn % We must actually expand the ignored text to look for the @end % command, so that nested ignore constructs work. Thus, we put the % text into a \vbox and then do nothing with the result. To minimize % the change of memory overflow, we follow the approach outlined on % page 401 of the TeXbook: make the current font be a dummy font. % \setbox0 = \vbox\bgroup % Don't complain about control sequences we have declared \outer. \ignoresections % % Define `@end #1' to end the box, which will in turn undefine the % @end command again. \expandafter\def\csname E#1\endcsname{\egroup\ignorespaces}% % % We are going to be parsing Texinfo commands. Most cause no % trouble when they are used incorrectly, but some commands do % complicated argument parsing or otherwise get confused, so we % undefine them. % % We can't do anything about stray @-signs, unfortunately; % they'll produce `undefined control sequence' errors. \ignoremorecommands % % Set the current font to be \nullfont, a TeX primitive, and define % all the font commands to also use \nullfont. We don't use % dummy.tfm, as suggested in the TeXbook, because not all sites % might have that installed. Therefore, math mode will still % produce output, but that should be an extremely small amount of % stuff compared to the main input. % \nullfont \let\tenrm = \nullfont \let\tenit = \nullfont \let\tensl = \nullfont \let\tenbf = \nullfont \let\tentt = \nullfont \let\smallcaps = \nullfont \let\tensf = \nullfont % Similarly for index fonts (mostly for their use in % smallexample) \let\indrm = \nullfont \let\indit = \nullfont \let\indsl = \nullfont \let\indbf = \nullfont \let\indtt = \nullfont \let\indsc = \nullfont \let\indsf = \nullfont % % Don't complain when characters are missing from the fonts. \tracinglostchars = 0 % % Don't bother to do space factor calculations. \frenchspacing % % Don't report underfull hboxes. \hbadness = 10000 % % Do minimal line-breaking. \pretolerance = 10000 % % Do not execute instructions in @tex \def\tex{\doignore{tex}}% } % @set VAR sets the variable VAR to an empty value. % @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE. % % Since we want to separate VAR from REST-OF-LINE (which might be % empty), we can't just use \parsearg; we have to insert a space of our % own to delimit the rest of the line, and then take it out again if we % didn't need it. Make sure the catcode of space is correct to avoid % losing inside @example, for instance. % \def\set{\begingroup\catcode` =10 \catcode`\-=12 \catcode`\_=12 % Allow - and _ in VAR. \parsearg\setxxx} \def\setxxx#1{\setyyy#1 \endsetyyy} \def\setyyy#1 #2\endsetyyy{% \def\temp{#2}% \ifx\temp\empty \global\expandafter\let\csname SET#1\endcsname = \empty \else \setzzz{#1}#2\endsetzzz % Remove the trailing space \setxxx inserted. \fi \endgroup } % Can't use \xdef to pre-expand #2 and save some time, since \temp or % \next or other control sequences that we've defined might get us into % an infinite loop. Consider `@set foo @cite{bar}'. \def\setzzz#1#2 \endsetzzz{\expandafter\gdef\csname SET#1\endcsname{#2}} % @clear VAR clears (i.e., unsets) the variable VAR. % \def\clear{\parsearg\clearxxx} \def\clearxxx#1{\global\expandafter\let\csname SET#1\endcsname=\relax} % @value{foo} gets the text saved in variable foo. % \def\value{\begingroup \catcode`\-=12 \catcode`\_=12 % Allow - and _ in VAR. \valuexxx} \def\valuexxx#1{% \expandafter\ifx\csname SET#1\endcsname\relax {\{No value for ``#1''\}}% \else \csname SET#1\endcsname \fi \endgroup} % @ifset VAR ... @end ifset reads the `...' iff VAR has been defined % with @set. % \def\ifset{\parsearg\ifsetxxx} \def\ifsetxxx #1{% \expandafter\ifx\csname SET#1\endcsname\relax \expandafter\ifsetfail \else \expandafter\ifsetsucceed \fi } \def\ifsetsucceed{\conditionalsucceed{ifset}} \def\ifsetfail{\nestedignore{ifset}} \defineunmatchedend{ifset} % @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been % defined with @set, or has been undefined with @clear. % \def\ifclear{\parsearg\ifclearxxx} \def\ifclearxxx #1{% \expandafter\ifx\csname SET#1\endcsname\relax \expandafter\ifclearsucceed \else \expandafter\ifclearfail \fi } \def\ifclearsucceed{\conditionalsucceed{ifclear}} \def\ifclearfail{\nestedignore{ifclear}} \defineunmatchedend{ifclear} % @iftex, @ifnothtml, @ifnotinfo always succeed; we read the text % following, through the first @end iftex (etc.). Make `@end iftex' % (etc.) valid only after an @iftex. % \def\iftex{\conditionalsucceed{iftex}} \def\ifnothtml{\conditionalsucceed{ifnothtml}} \def\ifnotinfo{\conditionalsucceed{ifnotinfo}} \defineunmatchedend{iftex} \defineunmatchedend{ifnothtml} \defineunmatchedend{ifnotinfo} % We can't just want to start a group at @iftex (for example) and end it % at @end iftex, since then @set commands inside the conditional have no % effect (they'd get reverted at the end of the group). So we must % define \Eiftex to redefine itself to be its previous value. (We can't % just define it to fail again with an ``unmatched end'' error, since % the @ifset might be nested.) % \def\conditionalsucceed#1{% \edef\temp{% % Remember the current value of \E#1. \let\nece{prevE#1} = \nece{E#1}% % % At the `@end #1', redefine \E#1 to be its previous value. \def\nece{E#1}{\let\nece{E#1} = \nece{prevE#1}}% }% \temp } % We need to expand lots of \csname's, but we don't want to expand the % control sequences after we've constructed them. % \def\nece#1{\expandafter\noexpand\csname#1\endcsname} % @asis just yields its argument. Used with @table, for example. % \def\asis#1{#1} % @math means output in math mode. % We don't use $'s directly in the definition of \math because control % sequences like \math are expanded when the toc file is written. Then, % we read the toc file back, the $'s will be normal characters (as they % should be, according to the definition of Texinfo). So we must use a % control sequence to switch into and out of math mode. % % This isn't quite enough for @math to work properly in indices, but it % seems unlikely it will ever be needed there. % \let\implicitmath = $ \def\math#1{\implicitmath #1\implicitmath} % @bullet and @minus need the same treatment as @math, just above. \def\bullet{\implicitmath\ptexbullet\implicitmath} \def\minus{\implicitmath-\implicitmath} \def\node{\ENVcheck\parsearg\nodezzz} \def\nodezzz#1{\nodexxx [#1,]} \def\nodexxx[#1,#2]{\gdef\lastnode{#1}} \let\nwnode=\node \let\lastnode=\relax \def\donoderef{\ifx\lastnode\relax\else \expandafter\expandafter\expandafter\setref{\lastnode}\fi \global\let\lastnode=\relax} \def\unnumbnoderef{\ifx\lastnode\relax\else \expandafter\expandafter\expandafter\unnumbsetref{\lastnode}\fi \global\let\lastnode=\relax} \def\appendixnoderef{\ifx\lastnode\relax\else \expandafter\expandafter\expandafter\appendixsetref{\lastnode}\fi \global\let\lastnode=\relax} % @refill is a no-op. \let\refill=\relax % @setfilename is done at the beginning of every texinfo file. % So open here the files we need to have open while reading the input. % This makes it possible to make a .fmt file for texinfo. \def\setfilename{% \readauxfile \opencontents \openindices \fixbackslash % Turn off hack to swallow `\input texinfo'. \global\let\setfilename=\comment % Ignore extra @setfilename cmds. % % If texinfo.cnf is present on the system, read it. % Useful for site-wide @afourpaper, etc. % Just to be on the safe side, close the input stream before the \input. \openin 1 texinfo.cnf \ifeof1 \let\temp=\relax \else \def\temp{\input texinfo.cnf }\fi \closein1 \temp % \comment % Ignore the actual filename. } % @bye. \outer\def\bye{\pagealignmacro\tracingstats=1\ptexend} % \def\macro#1{\begingroup\ignoresections\catcode`\#=6\def\macrotemp{#1}\parsearg\macroxxx} % \def\macroxxx#1#2 \end macro{% % \expandafter\gdef\macrotemp#1{#2}% % \endgroup} %\def\linemacro#1{\begingroup\ignoresections\catcode`\#=6\def\macrotemp{#1}\parsearg\linemacroxxx} %\def\linemacroxxx#1#2 \end linemacro{% %\let\parsearg=\relax %\edef\macrotempx{\csname M\butfirst\expandafter\string\macrotemp\endcsname}% %\expandafter\xdef\macrotemp{\parsearg\macrotempx}% %\expandafter\gdef\macrotempx#1{#2}% %\endgroup} %\def\butfirst#1{} \message{fonts,} % Font-change commands. % Texinfo supports the sans serif font style, which plain TeX does not. % So we set up a \sf analogous to plain's \rm, etc. \newfam\sffam \def\sf{\fam=\sffam \tensf} \let\li = \sf % Sometimes we call it \li, not \sf. % We don't need math for this one. \def\ttsl{\tenttsl} % Use Computer Modern fonts at \magstephalf (11pt). \newcount\mainmagstep \mainmagstep=\magstephalf % Set the font macro #1 to the font named #2, adding on the % specified font prefix (normally `cm'). % #3 is the font's design size, #4 is a scale factor \def\setfont#1#2#3#4{\font#1=\fontprefix#2#3 scaled #4} % Use cm as the default font prefix. % To specify the font prefix, you must define \fontprefix % before you read in texinfo.tex. \ifx\fontprefix\undefined \def\fontprefix{cm} \fi % Support font families that don't use the same naming scheme as CM. \def\rmshape{r} \def\rmbshape{bx} %where the normal face is bold \def\bfshape{b} \def\bxshape{bx} \def\ttshape{tt} \def\ttbshape{tt} \def\ttslshape{sltt} \def\itshape{ti} \def\itbshape{bxti} \def\slshape{sl} \def\slbshape{bxsl} \def\sfshape{ss} \def\sfbshape{ss} \def\scshape{csc} \def\scbshape{csc} \ifx\bigger\relax \let\mainmagstep=\magstep1 \setfont\textrm\rmshape{12}{1000} \setfont\texttt\ttshape{12}{1000} \else \setfont\textrm\rmshape{10}{\mainmagstep} \setfont\texttt\ttshape{10}{\mainmagstep} \fi % Instead of cmb10, you many want to use cmbx10. % cmbx10 is a prettier font on its own, but cmb10 % looks better when embedded in a line with cmr10. \setfont\textbf\bfshape{10}{\mainmagstep} \setfont\textit\itshape{10}{\mainmagstep} \setfont\textsl\slshape{10}{\mainmagstep} \setfont\textsf\sfshape{10}{\mainmagstep} \setfont\textsc\scshape{10}{\mainmagstep} \setfont\textttsl\ttslshape{10}{\mainmagstep} \font\texti=cmmi10 scaled \mainmagstep \font\textsy=cmsy10 scaled \mainmagstep % A few fonts for @defun, etc. \setfont\defbf\bxshape{10}{\magstep1} %was 1314 \setfont\deftt\ttshape{10}{\magstep1} \def\df{\let\tentt=\deftt \let\tenbf = \defbf \bf} % Fonts for indices and small examples (9pt). % We actually use the slanted font rather than the italic, % because texinfo normally uses the slanted fonts for that. % Do not make many font distinctions in general in the index, since they % aren't very useful. \setfont\ninett\ttshape{9}{1000} \setfont\indrm\rmshape{9}{1000} \setfont\indit\slshape{9}{1000} \let\indsl=\indit \let\indtt=\ninett \let\indttsl=\ninett \let\indsf=\indrm \let\indbf=\indrm \setfont\indsc\scshape{10}{900} \font\indi=cmmi9 \font\indsy=cmsy9 % Fonts for title page: \setfont\titlerm\rmbshape{12}{\magstep3} \setfont\titleit\itbshape{10}{\magstep4} \setfont\titlesl\slbshape{10}{\magstep4} \setfont\titlett\ttbshape{12}{\magstep3} \setfont\titlettsl\ttslshape{10}{\magstep4} \setfont\titlesf\sfbshape{17}{\magstep1} \let\titlebf=\titlerm \setfont\titlesc\scbshape{10}{\magstep4} \font\titlei=cmmi12 scaled \magstep3 \font\titlesy=cmsy10 scaled \magstep4 \def\authorrm{\secrm} % Chapter (and unnumbered) fonts (17.28pt). \setfont\chaprm\rmbshape{12}{\magstep2} \setfont\chapit\itbshape{10}{\magstep3} \setfont\chapsl\slbshape{10}{\magstep3} \setfont\chaptt\ttbshape{12}{\magstep2} \setfont\chapttsl\ttslshape{10}{\magstep3} \setfont\chapsf\sfbshape{17}{1000} \let\chapbf=\chaprm \setfont\chapsc\scbshape{10}{\magstep3} \font\chapi=cmmi12 scaled \magstep2 \font\chapsy=cmsy10 scaled \magstep3 % Section fonts (14.4pt). \setfont\secrm\rmbshape{12}{\magstep1} \setfont\secit\itbshape{10}{\magstep2} \setfont\secsl\slbshape{10}{\magstep2} \setfont\sectt\ttbshape{12}{\magstep1} \setfont\secttsl\ttslshape{10}{\magstep2} \setfont\secsf\sfbshape{12}{\magstep1} \let\secbf\secrm \setfont\secsc\scbshape{10}{\magstep2} \font\seci=cmmi12 scaled \magstep1 \font\secsy=cmsy10 scaled \magstep2 % \setfont\ssecrm\bxshape{10}{\magstep1} % This size an font looked bad. % \setfont\ssecit\itshape{10}{\magstep1} % The letters were too crowded. % \setfont\ssecsl\slshape{10}{\magstep1} % \setfont\ssectt\ttshape{10}{\magstep1} % \setfont\ssecsf\sfshape{10}{\magstep1} %\setfont\ssecrm\bfshape{10}{1315} % Note the use of cmb rather than cmbx. %\setfont\ssecit\itshape{10}{1315} % Also, the size is a little larger than %\setfont\ssecsl\slshape{10}{1315} % being scaled magstep1. %\setfont\ssectt\ttshape{10}{1315} %\setfont\ssecsf\sfshape{10}{1315} %\let\ssecbf=\ssecrm % Subsection fonts (13.15pt). \setfont\ssecrm\rmbshape{12}{\magstephalf} \setfont\ssecit\itbshape{10}{1315} \setfont\ssecsl\slbshape{10}{1315} \setfont\ssectt\ttbshape{12}{\magstephalf} \setfont\ssecttsl\ttslshape{10}{1315} \setfont\ssecsf\sfbshape{12}{\magstephalf} \let\ssecbf\ssecrm \setfont\ssecsc\scbshape{10}{\magstep1} \font\sseci=cmmi12 scaled \magstephalf \font\ssecsy=cmsy10 scaled 1315 % The smallcaps and symbol fonts should actually be scaled \magstep1.5, % but that is not a standard magnification. % In order for the font changes to affect most math symbols and letters, % we have to define the \textfont of the standard families. Since % texinfo doesn't allow for producing subscripts and superscripts, we % don't bother to reset \scriptfont and \scriptscriptfont (which would % also require loading a lot more fonts). % \def\resetmathfonts{% \textfont0 = \tenrm \textfont1 = \teni \textfont2 = \tensy \textfont\itfam = \tenit \textfont\slfam = \tensl \textfont\bffam = \tenbf \textfont\ttfam = \tentt \textfont\sffam = \tensf } % The font-changing commands redefine the meanings of \tenSTYLE, instead % of just \STYLE. We do this so that font changes will continue to work % in math mode, where it is the current \fam that is relevant in most % cases, not the current font. Plain TeX does \def\bf{\fam=\bffam % \tenbf}, for example. By redefining \tenbf, we obviate the need to % redefine \bf itself. \def\textfonts{% \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy \let\tenttsl=\textttsl \resetmathfonts} \def\titlefonts{% \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy \let\tenttsl=\titlettsl \resetmathfonts \setleading{25pt}} \def\titlefont#1{{\titlefonts\rm #1}} \def\chapfonts{% \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy \let\tenttsl=\chapttsl \resetmathfonts \setleading{19pt}} \def\secfonts{% \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy \let\tenttsl=\secttsl \resetmathfonts \setleading{16pt}} \def\subsecfonts{% \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy \let\tenttsl=\ssecttsl \resetmathfonts \setleading{15pt}} \let\subsubsecfonts = \subsecfonts % Maybe make sssec fonts scaled magstephalf? \def\indexfonts{% \let\tenrm=\indrm \let\tenit=\indit \let\tensl=\indsl \let\tenbf=\indbf \let\tentt=\indtt \let\smallcaps=\indsc \let\tensf=\indsf \let\teni=\indi \let\tensy=\indsy \let\tenttsl=\indttsl \resetmathfonts \setleading{12pt}} % Set up the default fonts, so we can use them for creating boxes. % \textfonts % Define these so they can be easily changed for other fonts. \def\angleleft{$\langle$} \def\angleright{$\rangle$} % Count depth in font-changes, for error checks \newcount\fontdepth \fontdepth=0 % Fonts for short table of contents. \setfont\shortcontrm\rmshape{12}{1000} \setfont\shortcontbf\bxshape{12}{1000} \setfont\shortcontsl\slshape{12}{1000} %% Add scribe-like font environments, plus @l for inline lisp (usually sans %% serif) and @ii for TeX italic % \smartitalic{ARG} outputs arg in italics, followed by an italic correction % unless the following character is such as not to need one. \def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else\/\fi\fi\fi} \def\smartitalic#1{{\sl #1}\futurelet\next\smartitalicx} \let\i=\smartitalic \let\var=\smartitalic \let\dfn=\smartitalic \let\emph=\smartitalic \let\cite=\smartitalic \def\b#1{{\bf #1}} \let\strong=\b % We can't just use \exhyphenpenalty, because that only has effect at % the end of a paragraph. Restore normal hyphenation at the end of the % group within which \nohyphenation is presumably called. % \def\nohyphenation{\hyphenchar\font = -1 \aftergroup\restorehyphenation} \def\restorehyphenation{\hyphenchar\font = `- } \def\t#1{% {\tt \rawbackslash \frenchspacing #1}% \null } \let\ttfont=\t \def\samp#1{`\tclose{#1}'\null} \setfont\smallrm\rmshape{8}{1000} \font\smallsy=cmsy9 \def\key#1{{\smallrm\textfont2=\smallsy \leavevmode\hbox{% \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{% \vbox{\hrule\kern-0.4pt \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}% \kern-0.4pt\hrule}% \kern-.06em\raise0.4pt\hbox{\angleright}}}} % The old definition, with no lozenge: %\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null} \def\ctrl #1{{\tt \rawbackslash \hat}#1} \let\file=\samp % @code is a modification of @t, % which makes spaces the same size as normal in the surrounding text. \def\tclose#1{% {% % Change normal interword space to be same as for the current font. \spaceskip = \fontdimen2\font % % Switch to typewriter. \tt % % But `\ ' produces the large typewriter interword space. \def\ {{\spaceskip = 0pt{} }}% % % Turn off hyphenation. \nohyphenation % \rawbackslash \frenchspacing #1% }% \null } % We *must* turn on hyphenation at `-' and `_' in \code. % Otherwise, it is too hard to avoid overfull hboxes % in the Emacs manual, the Library manual, etc. % Unfortunately, TeX uses one parameter (\hyphenchar) to control % both hyphenation at - and hyphenation within words. % We must therefore turn them both off (\tclose does that) % and arrange explicitly to hyphenate at a dash. % -- rms. { \catcode`\-=\active \catcode`\_=\active \catcode`\|=\active \global\def\code{\begingroup \catcode`\-=\active \let-\codedash \catcode`\_=\active \let_\codeunder \codex} % The following is used by \doprintindex to insure that long function names % wrap around. It is necessary for - and _ to be active before the index is % read from the file, as \entry parses the arguments long before \code is % ever called. -- mycroft % _ is always active; and it shouldn't be \let = to an _ that is a % subscript character anyway. Then, @cindex @samp{_} (for example) % fails. --karl \global\def\indexbreaks{% \catcode`\-=\active \let-\realdash } } \def\realdash{-} \def\codedash{-\discretionary{}{}{}} \def\codeunder{\ifusingtt{\normalunderscore\discretionary{}{}{}}{\_}} \def\codex #1{\tclose{#1}\endgroup} %\let\exp=\tclose %Was temporary % @kbd is like @code, except that if the argument is just one @key command, % then @kbd has no effect. % @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always), % `example' (@kbd uses ttsl only inside of @example and friends), % or `code' (@kbd uses normal tty font always). \def\kbdinputstyle{\parsearg\kbdinputstylexxx} \def\kbdinputstylexxx#1{% \def\arg{#1}% \ifx\arg\worddistinct \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}% \else\ifx\arg\wordexample \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}% \else\ifx\arg\wordcode \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}% \fi\fi\fi } \def\worddistinct{distinct} \def\wordexample{example} \def\wordcode{code} % Default is kbdinputdistinct. (Too much of a hassle to call the macro, % the catcodes are wrong for parsearg to work.) \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl} \def\xkey{\key} \def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}% \ifx\one\xkey\ifx\threex\three \key{#2}% \else{\tclose{\kbdfont\look}}\fi \else{\tclose{\kbdfont\look}}\fi} % @url. Quotes do not seem necessary, so use \code. \let\url=\code % @uref (abbreviation for `urlref') takes an optional second argument % specifying the text to display. First (mandatory) arg is the url. % Perhaps eventually put in a hypertex \special here. % \def\uref#1{\urefxxx #1,,\finish} \def\urefxxx#1,#2,#3\finish{% \setbox0 = \hbox{\ignorespaces #2}% \ifdim\wd0 > 0pt \unhbox0\ (\code{#1})% \else \code{#1}% \fi } % rms does not like the angle brackets --karl, 17may97. % So now @email is just like @uref. %\def\email#1{\angleleft{\tt #1}\angleright} \let\email=\uref % Check if we are currently using a typewriter font. Since all the % Computer Modern typewriter fonts have zero interword stretch (and % shrink), and it is reasonable to expect all typewriter fonts to have % this property, we can check that font parameter. % \def\ifmonospace{\ifdim\fontdimen3\font=0pt } % Typeset a dimension, e.g., `in' or `pt'. The only reason for the % argument is to make the input look right: @dmn{pt} instead of % @dmn{}pt. % \def\dmn#1{\thinspace #1} \def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??\par} % @l was never documented to mean ``switch to the Lisp font'', % and it is not used as such in any manual I can find. We need it for % Polish suppressed-l. --karl, 22sep96. %\def\l#1{{\li #1}\null} \def\r#1{{\rm #1}} % roman font % Use of \lowercase was suggested. \def\sc#1{{\smallcaps#1}} % smallcaps font \def\ii#1{{\it #1}} % italic font % @pounds{} is a sterling sign. \def\pounds{{\it\$}} \message{page headings,} \newskip\titlepagetopglue \titlepagetopglue = 1.5in \newskip\titlepagebottomglue \titlepagebottomglue = 2pc % First the title page. Must do @settitle before @titlepage. \newif\ifseenauthor \newif\iffinishedtitlepage \def\shorttitlepage{\parsearg\shorttitlepagezzz} \def\shorttitlepagezzz #1{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}% \endgroup\page\hbox{}\page} \def\titlepage{\begingroup \parindent=0pt \textfonts \let\subtitlerm=\tenrm % I deinstalled the following change because \cmr12 is undefined. % This change was not in the ChangeLog anyway. --rms. % \let\subtitlerm=\cmr12 \def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}% % \def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines}% % % Leave some space at the very top of the page. \vglue\titlepagetopglue % % Now you can print the title using @title. \def\title{\parsearg\titlezzz}% \def\titlezzz##1{\leftline{\titlefonts\rm ##1} % print a rule at the page bottom also. \finishedtitlepagefalse \vskip4pt \hrule height 4pt width \hsize \vskip4pt}% % No rule at page bottom unless we print one at the top with @title. \finishedtitlepagetrue % % Now you can put text using @subtitle. \def\subtitle{\parsearg\subtitlezzz}% \def\subtitlezzz##1{{\subtitlefont \rightline{##1}}}% % % @author should come last, but may come many times. \def\author{\parsearg\authorzzz}% \def\authorzzz##1{\ifseenauthor\else\vskip 0pt plus 1filll\seenauthortrue\fi {\authorfont \leftline{##1}}}% % % Most title ``pages'' are actually two pages long, with space % at the top of the second. We don't want the ragged left on the second. \let\oldpage = \page \def\page{% \iffinishedtitlepage\else \finishtitlepage \fi \oldpage \let\page = \oldpage \hbox{}}% % \def\page{\oldpage \hbox{}} } \def\Etitlepage{% \iffinishedtitlepage\else \finishtitlepage \fi % It is important to do the page break before ending the group, % because the headline and footline are only empty inside the group. % If we use the new definition of \page, we always get a blank page % after the title page, which we certainly don't want. \oldpage \endgroup \HEADINGSon } \def\finishtitlepage{% \vskip4pt \hrule height 2pt width \hsize \vskip\titlepagebottomglue \finishedtitlepagetrue } %%% Set up page headings and footings. \let\thispage=\folio \newtoks \evenheadline % Token sequence for heading line of even pages \newtoks \oddheadline % Token sequence for heading line of odd pages \newtoks \evenfootline % Token sequence for footing line of even pages \newtoks \oddfootline % Token sequence for footing line of odd pages % Now make Tex use those variables \headline={{\textfonts\rm \ifodd\pageno \the\oddheadline \else \the\evenheadline \fi}} \footline={{\textfonts\rm \ifodd\pageno \the\oddfootline \else \the\evenfootline \fi}\HEADINGShook} \let\HEADINGShook=\relax % Commands to set those variables. % For example, this is what @headings on does % @evenheading @thistitle|@thispage|@thischapter % @oddheading @thischapter|@thispage|@thistitle % @evenfooting @thisfile|| % @oddfooting ||@thisfile \def\evenheading{\parsearg\evenheadingxxx} \def\oddheading{\parsearg\oddheadingxxx} \def\everyheading{\parsearg\everyheadingxxx} \def\evenfooting{\parsearg\evenfootingxxx} \def\oddfooting{\parsearg\oddfootingxxx} \def\everyfooting{\parsearg\everyfootingxxx} {\catcode`\@=0 % \gdef\evenheadingxxx #1{\evenheadingyyy #1@|@|@|@|\finish} \gdef\evenheadingyyy #1@|#2@|#3@|#4\finish{% \global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} \gdef\oddheadingxxx #1{\oddheadingyyy #1@|@|@|@|\finish} \gdef\oddheadingyyy #1@|#2@|#3@|#4\finish{% \global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} \gdef\everyheadingxxx#1{\oddheadingxxx{#1}\evenheadingxxx{#1}}% \gdef\evenfootingxxx #1{\evenfootingyyy #1@|@|@|@|\finish} \gdef\evenfootingyyy #1@|#2@|#3@|#4\finish{% \global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} \gdef\oddfootingxxx #1{\oddfootingyyy #1@|@|@|@|\finish} \gdef\oddfootingyyy #1@|#2@|#3@|#4\finish{% \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}% % % Leave some space for the footline. Hopefully ok to assume % @evenfooting will not be used by itself. \global\advance\pageheight by -\baselineskip \global\advance\vsize by -\baselineskip } \gdef\everyfootingxxx#1{\oddfootingxxx{#1}\evenfootingxxx{#1}} % }% unbind the catcode of @. % @headings double turns headings on for double-sided printing. % @headings single turns headings on for single-sided printing. % @headings off turns them off. % @headings on same as @headings double, retained for compatibility. % @headings after turns on double-sided headings after this page. % @headings doubleafter turns on double-sided headings after this page. % @headings singleafter turns on single-sided headings after this page. % By default, they are off at the start of a document, % and turned `on' after @end titlepage. \def\headings #1 {\csname HEADINGS#1\endcsname} \def\HEADINGSoff{ \global\evenheadline={\hfil} \global\evenfootline={\hfil} \global\oddheadline={\hfil} \global\oddfootline={\hfil}} \HEADINGSoff % When we turn headings on, set the page number to 1. % For double-sided printing, put current file name in lower left corner, % chapter name on inside top of right hand pages, document % title on inside top of left hand pages, and page numbers on outside top % edge of all pages. \def\HEADINGSdouble{ \global\pageno=1 \global\evenfootline={\hfil} \global\oddfootline={\hfil} \global\evenheadline={\line{\folio\hfil\thistitle}} \global\oddheadline={\line{\thischapter\hfil\folio}} \global\let\contentsalignmacro = \chapoddpage } \let\contentsalignmacro = \chappager % For single-sided printing, chapter title goes across top left of page, % page number on top right. \def\HEADINGSsingle{ \global\pageno=1 \global\evenfootline={\hfil} \global\oddfootline={\hfil} \global\evenheadline={\line{\thischapter\hfil\folio}} \global\oddheadline={\line{\thischapter\hfil\folio}} \global\let\contentsalignmacro = \chappager } \def\HEADINGSon{\HEADINGSdouble} \def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex} \let\HEADINGSdoubleafter=\HEADINGSafter \def\HEADINGSdoublex{% \global\evenfootline={\hfil} \global\oddfootline={\hfil} \global\evenheadline={\line{\folio\hfil\thistitle}} \global\oddheadline={\line{\thischapter\hfil\folio}} \global\let\contentsalignmacro = \chapoddpage } \def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex} \def\HEADINGSsinglex{% \global\evenfootline={\hfil} \global\oddfootline={\hfil} \global\evenheadline={\line{\thischapter\hfil\folio}} \global\oddheadline={\line{\thischapter\hfil\folio}} \global\let\contentsalignmacro = \chappager } % Subroutines used in generating headings % Produces Day Month Year style of output. \def\today{\number\day\space \ifcase\month\or January\or February\or March\or April\or May\or June\or July\or August\or September\or October\or November\or December\fi \space\number\year} % Use this if you want the Month Day, Year style of output. %\def\today{\ifcase\month\or %January\or February\or March\or April\or May\or June\or %July\or August\or September\or October\or November\or December\fi %\space\number\day, \number\year} % @settitle line... specifies the title of the document, for headings % It generates no output of its own \def\thistitle{No Title} \def\settitle{\parsearg\settitlezzz} \def\settitlezzz #1{\gdef\thistitle{#1}} \message{tables,} % @tabs -- simple alignment % These don't work. For one thing, \+ is defined as outer. % So these macros cannot even be defined. %\def\tabs{\parsearg\tabszzz} %\def\tabszzz #1{\settabs\+#1\cr} %\def\tabline{\parsearg\tablinezzz} %\def\tablinezzz #1{\+#1\cr} %\def\&{&} % Tables -- @table, @ftable, @vtable, @item(x), @kitem(x), @xitem(x). % default indentation of table text \newdimen\tableindent \tableindent=.8in % default indentation of @itemize and @enumerate text \newdimen\itemindent \itemindent=.3in % margin between end of table item and start of table text. \newdimen\itemmargin \itemmargin=.1in % used internally for \itemindent minus \itemmargin \newdimen\itemmax % Note @table, @vtable, and @vtable define @item, @itemx, etc., with % these defs. % They also define \itemindex % to index the item name in whatever manner is desired (perhaps none). \newif\ifitemxneedsnegativevskip \def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi} \def\internalBitem{\smallbreak \parsearg\itemzzz} \def\internalBitemx{\itemxpar \parsearg\itemzzz} \def\internalBxitem "#1"{\def\xitemsubtopix{#1} \smallbreak \parsearg\xitemzzz} \def\internalBxitemx "#1"{\def\xitemsubtopix{#1} \itemxpar \parsearg\xitemzzz} \def\internalBkitem{\smallbreak \parsearg\kitemzzz} \def\internalBkitemx{\itemxpar \parsearg\kitemzzz} \def\kitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \lastfunction}}% \itemzzz {#1}} \def\xitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \xitemsubtopic}}% \itemzzz {#1}} \def\itemzzz #1{\begingroup % \advance\hsize by -\rightskip \advance\hsize by -\tableindent \setbox0=\hbox{\itemfont{#1}}% \itemindex{#1}% \nobreak % This prevents a break before @itemx. % % Be sure we are not still in the middle of a paragraph. %{\parskip = 0in %\par %}% % % If the item text does not fit in the space we have, put it on a line % by itself, and do not allow a page break either before or after that % line. We do not start a paragraph here because then if the next % command is, e.g., @kindex, the whatsit would get put into the % horizontal list on a line by itself, resulting in extra blank space. \ifdim \wd0>\itemmax % % Make this a paragraph so we get the \parskip glue and wrapping, % but leave it ragged-right. \begingroup \advance\leftskip by-\tableindent \advance\hsize by\tableindent \advance\rightskip by0pt plus1fil \leavevmode\unhbox0\par \endgroup % % We're going to be starting a paragraph, but we don't want the % \parskip glue -- logically it's part of the @item we just started. \nobreak \vskip-\parskip % % Stop a page break at the \parskip glue coming up. Unfortunately % we can't prevent a possible page break at the following % \baselineskip glue. \nobreak \endgroup \itemxneedsnegativevskipfalse \else % The item text fits into the space. Start a paragraph, so that the % following text (if any) will end up on the same line. Since that % text will be indented by \tableindent, we make the item text be in % a zero-width box. \noindent \rlap{\hskip -\tableindent\box0}\ignorespaces% \endgroup% \itemxneedsnegativevskiptrue% \fi } \def\item{\errmessage{@item while not in a table}} \def\itemx{\errmessage{@itemx while not in a table}} \def\kitem{\errmessage{@kitem while not in a table}} \def\kitemx{\errmessage{@kitemx while not in a table}} \def\xitem{\errmessage{@xitem while not in a table}} \def\xitemx{\errmessage{@xitemx while not in a table}} %% Contains a kludge to get @end[description] to work \def\description{\tablez{\dontindex}{1}{}{}{}{}} \def\table{\begingroup\inENV\obeylines\obeyspaces\tablex} {\obeylines\obeyspaces% \gdef\tablex #1^^M{% \tabley\dontindex#1 \endtabley}} \def\ftable{\begingroup\inENV\obeylines\obeyspaces\ftablex} {\obeylines\obeyspaces% \gdef\ftablex #1^^M{% \tabley\fnitemindex#1 \endtabley \def\Eftable{\endgraf\afterenvbreak\endgroup}% \let\Etable=\relax}} \def\vtable{\begingroup\inENV\obeylines\obeyspaces\vtablex} {\obeylines\obeyspaces% \gdef\vtablex #1^^M{% \tabley\vritemindex#1 \endtabley \def\Evtable{\endgraf\afterenvbreak\endgroup}% \let\Etable=\relax}} \def\dontindex #1{} \def\fnitemindex #1{\doind {fn}{\code{#1}}}% \def\vritemindex #1{\doind {vr}{\code{#1}}}% {\obeyspaces % \gdef\tabley#1#2 #3 #4 #5 #6 #7\endtabley{\endgroup% \tablez{#1}{#2}{#3}{#4}{#5}{#6}}} \def\tablez #1#2#3#4#5#6{% \aboveenvbreak % \begingroup % \def\Edescription{\Etable}% Necessary kludge. \let\itemindex=#1% \ifnum 0#3>0 \advance \leftskip by #3\mil \fi % \ifnum 0#4>0 \tableindent=#4\mil \fi % \ifnum 0#5>0 \advance \rightskip by #5\mil \fi % \def\itemfont{#2}% \itemmax=\tableindent % \advance \itemmax by -\itemmargin % \advance \leftskip by \tableindent % \exdentamount=\tableindent \parindent = 0pt \parskip = \smallskipamount \ifdim \parskip=0pt \parskip=2pt \fi% \def\Etable{\endgraf\afterenvbreak\endgroup}% \let\item = \internalBitem % \let\itemx = \internalBitemx % \let\kitem = \internalBkitem % \let\kitemx = \internalBkitemx % \let\xitem = \internalBxitem % \let\xitemx = \internalBxitemx % } % This is the counter used by @enumerate, which is really @itemize \newcount \itemno \def\itemize{\parsearg\itemizezzz} \def\itemizezzz #1{% \begingroup % ended by the @end itemsize \itemizey {#1}{\Eitemize} } \def\itemizey #1#2{% \aboveenvbreak % \itemmax=\itemindent % \advance \itemmax by -\itemmargin % \advance \leftskip by \itemindent % \exdentamount=\itemindent \parindent = 0pt % \parskip = \smallskipamount % \ifdim \parskip=0pt \parskip=2pt \fi% \def#2{\endgraf\afterenvbreak\endgroup}% \def\itemcontents{#1}% \let\item=\itemizeitem} % Set sfcode to normal for the chars that usually have another value. % These are `.?!:;,' \def\frenchspacing{\sfcode46=1000 \sfcode63=1000 \sfcode33=1000 \sfcode58=1000 \sfcode59=1000 \sfcode44=1000 } % \splitoff TOKENS\endmark defines \first to be the first token in % TOKENS, and \rest to be the remainder. % \def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}% % Allow an optional argument of an uppercase letter, lowercase letter, % or number, to specify the first label in the enumerated list. No % argument is the same as `1'. % \def\enumerate{\parsearg\enumeratezzz} \def\enumeratezzz #1{\enumeratey #1 \endenumeratey} \def\enumeratey #1 #2\endenumeratey{% \begingroup % ended by the @end enumerate % % If we were given no argument, pretend we were given `1'. \def\thearg{#1}% \ifx\thearg\empty \def\thearg{1}\fi % % Detect if the argument is a single token. If so, it might be a % letter. Otherwise, the only valid thing it can be is a number. % (We will always have one token, because of the test we just made. % This is a good thing, since \splitoff doesn't work given nothing at % all -- the first parameter is undelimited.) \expandafter\splitoff\thearg\endmark \ifx\rest\empty % Only one token in the argument. It could still be anything. % A ``lowercase letter'' is one whose \lccode is nonzero. % An ``uppercase letter'' is one whose \lccode is both nonzero, and % not equal to itself. % Otherwise, we assume it's a number. % % We need the \relax at the end of the \ifnum lines to stop TeX from % continuing to look for a . % \ifnum\lccode\expandafter`\thearg=0\relax \numericenumerate % a number (we hope) \else % It's a letter. \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax \lowercaseenumerate % lowercase letter \else \uppercaseenumerate % uppercase letter \fi \fi \else % Multiple tokens in the argument. We hope it's a number. \numericenumerate \fi } % An @enumerate whose labels are integers. The starting integer is % given in \thearg. % \def\numericenumerate{% \itemno = \thearg \startenumeration{\the\itemno}% } % The starting (lowercase) letter is in \thearg. \def\lowercaseenumerate{% \itemno = \expandafter`\thearg \startenumeration{% % Be sure we're not beyond the end of the alphabet. \ifnum\itemno=0 \errmessage{No more lowercase letters in @enumerate; get a bigger alphabet}% \fi \char\lccode\itemno }% } % The starting (uppercase) letter is in \thearg. \def\uppercaseenumerate{% \itemno = \expandafter`\thearg \startenumeration{% % Be sure we're not beyond the end of the alphabet. \ifnum\itemno=0 \errmessage{No more uppercase letters in @enumerate; get a bigger alphabet} \fi \char\uccode\itemno }% } % Call itemizey, adding a period to the first argument and supplying the % common last two arguments. Also subtract one from the initial value in % \itemno, since @item increments \itemno. % \def\startenumeration#1{% \advance\itemno by -1 \itemizey{#1.}\Eenumerate\flushcr } % @alphaenumerate and @capsenumerate are abbreviations for giving an arg % to @enumerate. % \def\alphaenumerate{\enumerate{a}} \def\capsenumerate{\enumerate{A}} \def\Ealphaenumerate{\Eenumerate} \def\Ecapsenumerate{\Eenumerate} % Definition of @item while inside @itemize. \def\itemizeitem{% \advance\itemno by 1 {\let\par=\endgraf \smallbreak}% \ifhmode \errmessage{In hmode at itemizeitem}\fi {\parskip=0in \hskip 0pt \hbox to 0pt{\hss \itemcontents\hskip \itemmargin}% \vadjust{\penalty 1200}}% \flushcr} % @multitable macros % Amy Hendrickson, 8/18/94, 3/6/96 % % @multitable ... @end multitable will make as many columns as desired. % Contents of each column will wrap at width given in preamble. Width % can be specified either with sample text given in a template line, % or in percent of \hsize, the current width of text on page. % Table can continue over pages but will only break between lines. % To make preamble: % % Either define widths of columns in terms of percent of \hsize: % @multitable @columnfractions .25 .3 .45 % @item ... % % Numbers following @columnfractions are the percent of the total % current hsize to be used for each column. You may use as many % columns as desired. % Or use a template: % @multitable {Column 1 template} {Column 2 template} {Column 3 template} % @item ... % using the widest term desired in each column. % % For those who want to use more than one line's worth of words in % the preamble, break the line within one argument and it % will parse correctly, i.e., % % @multitable {Column 1 template} {Column 2 template} {Column 3 % template} % Not: % @multitable {Column 1 template} {Column 2 template} % {Column 3 template} % Each new table line starts with @item, each subsequent new column % starts with @tab. Empty columns may be produced by supplying @tab's % with nothing between them for as many times as empty columns are needed, % ie, @tab@tab@tab will produce two empty columns. % @item, @tab, @multitable or @end multitable do not need to be on their % own lines, but it will not hurt if they are. % Sample multitable: % @multitable {Column 1 template} {Column 2 template} {Column 3 template} % @item first col stuff @tab second col stuff @tab third col % @item % first col stuff % @tab % second col stuff % @tab % third col % @item first col stuff @tab second col stuff % @tab Many paragraphs of text may be used in any column. % % They will wrap at the width determined by the template. % @item@tab@tab This will be in third column. % @end multitable % Default dimensions may be reset by user. % @multitableparskip is vertical space between paragraphs in table. % @multitableparindent is paragraph indent in table. % @multitablecolmargin is horizontal space to be left between columns. % @multitablelinespace is space to leave between table items, baseline % to baseline. % 0pt means it depends on current normal line spacing. % \newskip\multitableparskip \newskip\multitableparindent \newdimen\multitablecolspace \newskip\multitablelinespace \multitableparskip=0pt \multitableparindent=6pt \multitablecolspace=12pt \multitablelinespace=0pt % Macros used to set up halign preamble: % \let\endsetuptable\relax \def\xendsetuptable{\endsetuptable} \let\columnfractions\relax \def\xcolumnfractions{\columnfractions} \newif\ifsetpercent % 2/1/96, to allow fractions to be given with more than one digit. \def\pickupwholefraction#1 {\global\advance\colcount by1 % \expandafter\xdef\csname col\the\colcount\endcsname{.#1\hsize}% \setuptable} \newcount\colcount \def\setuptable#1{\def\firstarg{#1}% \ifx\firstarg\xendsetuptable\let\go\relax% \else \ifx\firstarg\xcolumnfractions\global\setpercenttrue% \else \ifsetpercent \let\go\pickupwholefraction % In this case arg of setuptable % is the decimal point before the % number given in percent of hsize. % We don't need this so we don't use it. \else \global\advance\colcount by1 \setbox0=\hbox{#1 }% Add a normal word space as a separator; % typically that is always in the input, anyway. \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}% \fi% \fi% \ifx\go\pickupwholefraction\else\let\go\setuptable\fi% \fi\go} % multitable syntax \def\tab{&\hskip1sp\relax} % 2/2/96 % tiny skip here makes sure this column space is % maintained, even if it is never used. % @multitable ... @end multitable definitions: \def\multitable{\parsearg\dotable} \def\dotable#1{\bgroup \vskip\parskip \let\item\crcr \tolerance=9500 \hbadness=9500 \setmultitablespacing \parskip=\multitableparskip \parindent=\multitableparindent \overfullrule=0pt \global\colcount=0 \def\Emultitable{\global\setpercentfalse\cr\egroup\egroup}% % % To parse everything between @multitable and @item: \setuptable#1 \endsetuptable % % \everycr will reset column counter, \colcount, at the end of % each line. Every column entry will cause \colcount to advance by one. % The table preamble % looks at the current \colcount to find the correct column width. \everycr{\noalign{% % % \filbreak%% keeps underfull box messages off when table breaks over pages. % Maybe so, but it also creates really weird page breaks when the table % breaks over pages. Wouldn't \vfil be better? Wait until the problem % manifests itself, so it can be fixed for real --karl. \global\colcount=0\relax}}% % % This preamble sets up a generic column definition, which will % be used as many times as user calls for columns. % \vtop will set a single line and will also let text wrap and % continue for many paragraphs if desired. \halign\bgroup&\global\advance\colcount by 1\relax \multistrut\vtop{\hsize=\expandafter\csname col\the\colcount\endcsname % % In order to keep entries from bumping into each other % we will add a \leftskip of \multitablecolspace to all columns after % the first one. % % If a template has been used, we will add \multitablecolspace % to the width of each template entry. % % If the user has set preamble in terms of percent of \hsize we will % use that dimension as the width of the column, and the \leftskip % will keep entries from bumping into each other. Table will start at % left margin and final column will justify at right margin. % % Make sure we don't inherit \rightskip from the outer environment. \rightskip=0pt \ifnum\colcount=1 % The first column will be indented with the surrounding text. \advance\hsize by\leftskip \else \ifsetpercent \else % If user has not set preamble in terms of percent of \hsize % we will advance \hsize by \multitablecolspace. \advance\hsize by \multitablecolspace \fi % In either case we will make \leftskip=\multitablecolspace: \leftskip=\multitablecolspace \fi % Ignoring space at the beginning and end avoids an occasional spurious % blank line, when TeX decides to break the line at the space before the % box from the multistrut, so the strut ends up on a line by itself. % For example: % @multitable @columnfractions .11 .89 % @item @code{#} % @tab Legal holiday which is valid in major parts of the whole country. % Is automatically provided with highlighting sequences respectively marking % characters. \noindent\ignorespaces##\unskip\multistrut}\cr } \def\setmultitablespacing{% test to see if user has set \multitablelinespace. % If so, do nothing. If not, give it an appropriate dimension based on % current baselineskip. \ifdim\multitablelinespace=0pt %% strut to put in table in case some entry doesn't have descenders, %% to keep lines equally spaced \let\multistrut = \strut %% Test to see if parskip is larger than space between lines of %% table. If not, do nothing. %% If so, set to same dimension as multitablelinespace. \else \gdef\multistrut{\vrule height\multitablelinespace depth\dp0 width0pt\relax} \fi \ifdim\multitableparskip>\multitablelinespace \global\multitableparskip=\multitablelinespace \global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller %% than skip between lines in the table. \fi% \ifdim\multitableparskip=0pt \global\multitableparskip=\multitablelinespace \global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller %% than skip between lines in the table. \fi} \message{indexing,} % Index generation facilities % Define \newwrite to be identical to plain tex's \newwrite % except not \outer, so it can be used within \newindex. {\catcode`\@=11 \gdef\newwrite{\alloc@7\write\chardef\sixt@@n}} % \newindex {foo} defines an index named foo. % It automatically defines \fooindex such that % \fooindex ...rest of line... puts an entry in the index foo. % It also defines \fooindfile to be the number of the output channel for % the file that accumulates this index. The file's extension is foo. % The name of an index should be no more than 2 characters long % for the sake of vms. \def\newindex #1{ \expandafter\newwrite \csname#1indfile\endcsname% Define number for output file \openout \csname#1indfile\endcsname \jobname.#1 % Open the file \expandafter\xdef\csname#1index\endcsname{% % Define \xxxindex \noexpand\doindex {#1}} } % @defindex foo == \newindex{foo} \def\defindex{\parsearg\newindex} % Define @defcodeindex, like @defindex except put all entries in @code. \def\newcodeindex #1{ \expandafter\newwrite \csname#1indfile\endcsname% Define number for output file \openout \csname#1indfile\endcsname \jobname.#1 % Open the file \expandafter\xdef\csname#1index\endcsname{% % Define \xxxindex \noexpand\docodeindex {#1}} } \def\defcodeindex{\parsearg\newcodeindex} % @synindex foo bar makes index foo feed into index bar. % Do this instead of @defindex foo if you don't want it as a separate index. \def\synindex #1 #2 {% \expandafter\let\expandafter\synindexfoo\expandafter=\csname#2indfile\endcsname \expandafter\let\csname#1indfile\endcsname=\synindexfoo \expandafter\xdef\csname#1index\endcsname{% % Define \xxxindex \noexpand\doindex {#2}}% } % @syncodeindex foo bar similar, but put all entries made for index foo % inside @code. \def\syncodeindex #1 #2 {% \expandafter\let\expandafter\synindexfoo\expandafter=\csname#2indfile\endcsname \expandafter\let\csname#1indfile\endcsname=\synindexfoo \expandafter\xdef\csname#1index\endcsname{% % Define \xxxindex \noexpand\docodeindex {#2}}% } % Define \doindex, the driver for all \fooindex macros. % Argument #1 is generated by the calling \fooindex macro, % and it is "foo", the name of the index. % \doindex just uses \parsearg; it calls \doind for the actual work. % This is because \doind is more useful to call from other macros. % There is also \dosubind {index}{topic}{subtopic} % which makes an entry in a two-level index such as the operation index. \def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer} \def\singleindexer #1{\doind{\indexname}{#1}} % like the previous two, but they put @code around the argument. \def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer} \def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}} \def\indexdummies{% % Take care of the plain tex accent commands. \def\"{\realbackslash "}% \def\`{\realbackslash `}% \def\'{\realbackslash '}% \def\^{\realbackslash ^}% \def\~{\realbackslash ~}% \def\={\realbackslash =}% \def\b{\realbackslash b}% \def\c{\realbackslash c}% \def\d{\realbackslash d}% \def\u{\realbackslash u}% \def\v{\realbackslash v}% \def\H{\realbackslash H}% % Take care of the plain tex special European modified letters. \def\oe{\realbackslash oe}% \def\ae{\realbackslash ae}% \def\aa{\realbackslash aa}% \def\OE{\realbackslash OE}% \def\AE{\realbackslash AE}% \def\AA{\realbackslash AA}% \def\o{\realbackslash o}% \def\O{\realbackslash O}% \def\l{\realbackslash l}% \def\L{\realbackslash L}% \def\ss{\realbackslash ss}% % Take care of texinfo commands likely to appear in an index entry. % (Must be a way to avoid doing expansion at all, and thus not have to % laboriously list every single command here.) \def\@{@}% will be @@ when we switch to @ as escape char. %\let\{ = \lbracecmd %\let\} = \rbracecmd \def\_{{\realbackslash _}}% \def\w{\realbackslash w }% \def\bf{\realbackslash bf }% %\def\rm{\realbackslash rm }% \def\sl{\realbackslash sl }% \def\sf{\realbackslash sf}% \def\tt{\realbackslash tt}% \def\gtr{\realbackslash gtr}% \def\less{\realbackslash less}% \def\hat{\realbackslash hat}% %\def\char{\realbackslash char}% \def\TeX{\realbackslash TeX}% \def\dots{\realbackslash dots }% \def\result{\realbackslash result}% \def\equiv{\realbackslash equiv}% \def\expansion{\realbackslash expansion}% \def\print{\realbackslash print}% \def\error{\realbackslash error}% \def\point{\realbackslash point}% \def\copyright{\realbackslash copyright}% \def\tclose##1{\realbackslash tclose {##1}}% \def\code##1{\realbackslash code {##1}}% \def\dotless##1{\realbackslash dotless {##1}}% \def\samp##1{\realbackslash samp {##1}}% \def\,##1{\realbackslash ,{##1}}% \def\t##1{\realbackslash t {##1}}% \def\r##1{\realbackslash r {##1}}% \def\i##1{\realbackslash i {##1}}% \def\b##1{\realbackslash b {##1}}% \def\sc##1{\realbackslash sc {##1}}% \def\cite##1{\realbackslash cite {##1}}% \def\key##1{\realbackslash key {##1}}% \def\file##1{\realbackslash file {##1}}% \def\var##1{\realbackslash var {##1}}% \def\kbd##1{\realbackslash kbd {##1}}% \def\dfn##1{\realbackslash dfn {##1}}% \def\emph##1{\realbackslash emph {##1}}% \def\value##1{\realbackslash value {##1}}% \unsepspaces } % If an index command is used in an @example environment, any spaces % therein should become regular spaces in the raw index file, not the % expansion of \tie (\\leavevmode \penalty \@M \ ). {\obeyspaces \gdef\unsepspaces{\obeyspaces\let =\space}} % \indexnofonts no-ops all font-change commands. % This is used when outputting the strings to sort the index by. \def\indexdummyfont#1{#1} \def\indexdummytex{TeX} \def\indexdummydots{...} \def\indexnofonts{% % Just ignore accents. \let\,=\indexdummyfont \let\"=\indexdummyfont \let\`=\indexdummyfont \let\'=\indexdummyfont \let\^=\indexdummyfont \let\~=\indexdummyfont \let\==\indexdummyfont \let\b=\indexdummyfont \let\c=\indexdummyfont \let\d=\indexdummyfont \let\u=\indexdummyfont \let\v=\indexdummyfont \let\H=\indexdummyfont \let\dotless=\indexdummyfont % Take care of the plain tex special European modified letters. \def\oe{oe}% \def\ae{ae}% \def\aa{aa}% \def\OE{OE}% \def\AE{AE}% \def\AA{AA}% \def\o{o}% \def\O{O}% \def\l{l}% \def\L{L}% \def\ss{ss}% \let\w=\indexdummyfont \let\t=\indexdummyfont \let\r=\indexdummyfont \let\i=\indexdummyfont \let\b=\indexdummyfont \let\emph=\indexdummyfont \let\strong=\indexdummyfont \let\cite=\indexdummyfont \let\sc=\indexdummyfont %Don't no-op \tt, since it isn't a user-level command % and is used in the definitions of the active chars like <, >, |... %\let\tt=\indexdummyfont \let\tclose=\indexdummyfont \let\code=\indexdummyfont \let\file=\indexdummyfont \let\samp=\indexdummyfont \let\kbd=\indexdummyfont \let\key=\indexdummyfont \let\var=\indexdummyfont \let\TeX=\indexdummytex \let\dots=\indexdummydots \def\@{@}% } % To define \realbackslash, we must make \ not be an escape. % We must first make another character (@) an escape % so we do not become unable to do a definition. {\catcode`\@=0 \catcode`\\=\other @gdef@realbackslash{\}} \let\indexbackslash=0 %overridden during \printindex. \let\SETmarginindex=\relax %initialize! % workhorse for all \fooindexes % #1 is name of index, #2 is stuff to put there \def\doind #1#2{% % Put the index entry in the margin if desired. \ifx\SETmarginindex\relax\else \insert\margin{\hbox{\vrule height8pt depth3pt width0pt #2}}% \fi {% \count255=\lastpenalty {% \indexdummies % Must do this here, since \bf, etc expand at this stage \escapechar=`\\ {% \let\folio=0% We will expand all macros now EXCEPT \folio. \def\rawbackslashxx{\indexbackslash}% \indexbackslash isn't defined now % so it will be output as is; and it will print as backslash. % % First process the index-string with all font commands turned off % to get the string to sort by. {\indexnofonts \xdef\indexsorttmp{#2}}% % % Now produce the complete index entry, with both the sort key and the % original text, including any font commands. \toks0 = {#2}% \edef\temp{% \write\csname#1indfile\endcsname{% \realbackslash entry{\indexsorttmp}{\folio}{\the\toks0}}% }% \temp }% }% \penalty\count255 }% } \def\dosubind #1#2#3{% {\count10=\lastpenalty % {\indexdummies % Must do this here, since \bf, etc expand at this stage \escapechar=`\\% {\let\folio=0% \def\rawbackslashxx{\indexbackslash}% % % Now process the index-string once, with all font commands turned off, % to get the string to sort the index by. {\indexnofonts \xdef\temp1{#2 #3}% }% % Now produce the complete index entry. We process the index-string again, % this time with font commands expanded, to get what to print in the index. \edef\temp{% \write \csname#1indfile\endcsname{% \realbackslash entry {\temp1}{\folio}{#2}{#3}}}% \temp }% }\penalty\count10}} % The index entry written in the file actually looks like % \entry {sortstring}{page}{topic} % or % \entry {sortstring}{page}{topic}{subtopic} % The texindex program reads in these files and writes files % containing these kinds of lines: % \initial {c} % before the first topic whose initial is c % \entry {topic}{pagelist} % for a topic that is used without subtopics % \primary {topic} % for the beginning of a topic that is used with subtopics % \secondary {subtopic}{pagelist} % for each subtopic. % Define the user-accessible indexing commands % @findex, @vindex, @kindex, @cindex. \def\findex {\fnindex} \def\kindex {\kyindex} \def\cindex {\cpindex} \def\vindex {\vrindex} \def\tindex {\tpindex} \def\pindex {\pgindex} \def\cindexsub {\begingroup\obeylines\cindexsub} {\obeylines % \gdef\cindexsub "#1" #2^^M{\endgroup % \dosubind{cp}{#2}{#1}}} % Define the macros used in formatting output of the sorted index material. % @printindex causes a particular index (the ??s file) to get printed. % It does not print any chapter heading (usually an @unnumbered). % \def\printindex{\parsearg\doprintindex} \def\doprintindex#1{\begingroup \dobreak \chapheadingskip{10000}% % \indexfonts \rm \tolerance = 9500 \indexbreaks % % See if the index file exists and is nonempty. % Change catcode of @ here so that if the index file contains % \initial {@} % as its first line, TeX doesn't complain about mismatched braces % (because it thinks @} is a control sequence). \catcode`\@ = 11 \openin 1 \jobname.#1s \ifeof 1 % \enddoublecolumns gets confused if there is no text in the index, % and it loses the chapter title and the aux file entries for the % index. The easiest way to prevent this problem is to make sure % there is some text. (Index is nonexistent) \else % % If the index file exists but is empty, then \openin leaves \ifeof % false. We have to make TeX try to read something from the file, so % it can discover if there is anything in it. \read 1 to \temp \ifeof 1 (Index is empty) \else % Index files are almost Texinfo source, but we use \ as the escape % character. It would be better to use @, but that's too big a change % to make right now. \def\indexbackslash{\rawbackslashxx}% \catcode`\\ = 0 \escapechar = `\\ \begindoublecolumns \input \jobname.#1s \enddoublecolumns \fi \fi \closein 1 \endgroup} % These macros are used by the sorted index file itself. % Change them to control the appearance of the index. % Same as \bigskipamount except no shrink. % \balancecolumns gets confused if there is any shrink. \newskip\initialskipamount \initialskipamount 12pt plus4pt \def\initial #1{% {\let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt \ifdim\lastskip<\initialskipamount \removelastskip \penalty-200 \vskip \initialskipamount\fi \line{\secbf#1\hfill}\kern 2pt\penalty10000}} % This typesets a paragraph consisting of #1, dot leaders, and then #2 % flush to the right margin. It is used for index and table of contents % entries. The paragraph is indented by \leftskip. % \def\entry #1#2{\begingroup % % Start a new paragraph if necessary, so our assignments below can't % affect previous text. \par % % Do not fill out the last line with white space. \parfillskip = 0in % % No extra space above this paragraph. \parskip = 0in % % Do not prefer a separate line ending with a hyphen to fewer lines. \finalhyphendemerits = 0 % % \hangindent is only relevant when the entry text and page number % don't both fit on one line. In that case, bob suggests starting the % dots pretty far over on the line. Unfortunately, a large % indentation looks wrong when the entry text itself is broken across % lines. So we use a small indentation and put up with long leaders. % % \hangafter is reset to 1 (which is the value we want) at the start % of each paragraph, so we need not do anything with that. \hangindent=2em % % When the entry text needs to be broken, just fill out the first line % with blank space. \rightskip = 0pt plus1fil % % Start a ``paragraph'' for the index entry so the line breaking % parameters we've set above will have an effect. \noindent % % Insert the text of the index entry. TeX will do line-breaking on it. #1% % The following is kludged to not output a line of dots in the index if % there are no page numbers. The next person who breaks this will be % cursed by a Unix daemon. \def\tempa{{\rm }}% \def\tempb{#2}% \edef\tempc{\tempa}% \edef\tempd{\tempb}% \ifx\tempc\tempd\ \else% % % If we must, put the page number on a line of its own, and fill out % this line with blank space. (The \hfil is overwhelmed with the % fill leaders glue in \indexdotfill if the page number does fit.) \hfil\penalty50 \null\nobreak\indexdotfill % Have leaders before the page number. % % The `\ ' here is removed by the implicit \unskip that TeX does as % part of (the primitive) \par. Without it, a spurious underfull % \hbox ensues. \ #2% The page number ends the paragraph. \fi% \par \endgroup} % Like \dotfill except takes at least 1 em. \def\indexdotfill{\cleaders \hbox{$\mathsurround=0pt \mkern1.5mu ${\it .}$ \mkern1.5mu$}\hskip 1em plus 1fill} \def\primary #1{\line{#1\hfil}} \newskip\secondaryindent \secondaryindent=0.5cm \def\secondary #1#2{ {\parfillskip=0in \parskip=0in \hangindent =1in \hangafter=1 \noindent\hskip\secondaryindent\hbox{#1}\indexdotfill #2\par }} % Define two-column mode, which we use to typeset indexes. % Adapted from the TeXbook, page 416, which is to say, % the manmac.tex format used to print the TeXbook itself. \catcode`\@=11 \newbox\partialpage \newdimen\doublecolumnhsize \def\begindoublecolumns{\begingroup % ended by \enddoublecolumns % Grab any single-column material above us. \output = {\global\setbox\partialpage = \vbox{% % % Here is a possibility not foreseen in manmac: if we accumulate a % whole lot of material, we might end up calling this \output % routine twice in a row (see the doublecol-lose test, which is % essentially a couple of indexes with @setchapternewpage off). In % that case, we must prevent the second \partialpage from % simply overwriting the first, causing us to lose the page. % This will preserve it until a real output routine can ship it % out. Generally, \partialpage will be empty when this runs and % this will be a no-op. \unvbox\partialpage % % Unvbox the main output page. \unvbox255 \kern-\topskip \kern\baselineskip }}% \eject % % Use the double-column output routine for subsequent pages. \output = {\doublecolumnout}% % % Change the page size parameters. We could do this once outside this % routine, in each of @smallbook, @afourpaper, and the default 8.5x11 % format, but then we repeat the same computation. Repeating a couple % of assignments once per index is clearly meaningless for the % execution time, so we may as well do it in one place. % % First we halve the line length, less a little for the gutter between % the columns. We compute the gutter based on the line length, so it % changes automatically with the paper format. The magic constant % below is chosen so that the gutter has the same value (well, +-<1pt) % as it did when we hard-coded it. % % We put the result in a separate register, \doublecolumhsize, so we % can restore it in \pagesofar, after \hsize itself has (potentially) % been clobbered. % \doublecolumnhsize = \hsize \advance\doublecolumnhsize by -.04154\hsize \divide\doublecolumnhsize by 2 \hsize = \doublecolumnhsize % % Double the \vsize as well. (We don't need a separate register here, % since nobody clobbers \vsize.) \vsize = 2\vsize } \def\doublecolumnout{% \splittopskip=\topskip \splitmaxdepth=\maxdepth % Get the available space for the double columns -- the normal % (undoubled) page height minus any material left over from the % previous page. \dimen@=\pageheight \advance\dimen@ by-\ht\partialpage % box0 will be the left-hand column, box2 the right. \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@ \onepageout\pagesofar \unvbox255 \penalty\outputpenalty } \def\pagesofar{% % Re-output the contents of the output page -- any previous material, % followed by the two boxes we just split. \unvbox\partialpage \hsize = \doublecolumnhsize \wd0=\hsize \wd2=\hsize \hbox to\pagewidth{\box0\hfil\box2}% } \def\enddoublecolumns{% \output = {\balancecolumns}\eject % split what we have \endgroup % started in \begindoublecolumns % % Back to normal single-column typesetting, but take account of the % fact that we just accumulated some stuff on the output page. \pagegoal = \vsize } \def\balancecolumns{% % Called at the end of the double column material. \setbox0 = \vbox{\unvbox255}% \dimen@ = \ht0 \advance\dimen@ by \topskip \advance\dimen@ by-\baselineskip \divide\dimen@ by 2 \splittopskip = \topskip % Loop until we get a decent breakpoint. {\vbadness=10000 \loop \global\setbox3=\copy0 \global\setbox1=\vsplit3 to\dimen@ \ifdim\ht3>\dimen@ \global\advance\dimen@ by1pt \repeat}% \setbox0=\vbox to\dimen@{\unvbox1}% \setbox2=\vbox to\dimen@{\unvbox3}% \pagesofar } \catcode`\@ = \other \message{sectioning,} % Define chapters, sections, etc. \newcount\chapno \newcount\secno \secno=0 \newcount\subsecno \subsecno=0 \newcount\subsubsecno \subsubsecno=0 % This counter is funny since it counts through charcodes of letters A, B, ... \newcount\appendixno \appendixno = `\@ \def\appendixletter{\char\the\appendixno} \newwrite\contentsfile % This is called from \setfilename. \def\opencontents{\openout\contentsfile = \jobname.toc } % Each @chapter defines this as the name of the chapter. % page headings and footings can use it. @section does likewise \def\thischapter{} \def\thissection{} \def\seccheck#1{\ifnum \pageno<0 \errmessage{@#1 not allowed after generating table of contents}% \fi} \def\chapternofonts{% \let\rawbackslash=\relax \let\frenchspacing=\relax \def\result{\realbackslash result}% \def\equiv{\realbackslash equiv}% \def\expansion{\realbackslash expansion}% \def\print{\realbackslash print}% \def\TeX{\realbackslash TeX}% \def\dots{\realbackslash dots}% \def\result{\realbackslash result}% \def\equiv{\realbackslash equiv}% \def\expansion{\realbackslash expansion}% \def\print{\realbackslash print}% \def\error{\realbackslash error}% \def\point{\realbackslash point}% \def\copyright{\realbackslash copyright}% \def\tt{\realbackslash tt}% \def\bf{\realbackslash bf}% \def\w{\realbackslash w}% \def\less{\realbackslash less}% \def\gtr{\realbackslash gtr}% \def\hat{\realbackslash hat}% \def\char{\realbackslash char}% \def\tclose##1{\realbackslash tclose{##1}}% \def\code##1{\realbackslash code{##1}}% \def\samp##1{\realbackslash samp{##1}}% \def\r##1{\realbackslash r{##1}}% \def\b##1{\realbackslash b{##1}}% \def\key##1{\realbackslash key{##1}}% \def\file##1{\realbackslash file{##1}}% \def\kbd##1{\realbackslash kbd{##1}}% % These are redefined because @smartitalic wouldn't work inside xdef. \def\i##1{\realbackslash i{##1}}% \def\cite##1{\realbackslash cite{##1}}% \def\var##1{\realbackslash var{##1}}% \def\emph##1{\realbackslash emph{##1}}% \def\dfn##1{\realbackslash dfn{##1}}% } \newcount\absseclevel % used to calculate proper heading level \newcount\secbase\secbase=0 % @raise/lowersections modify this count % @raisesections: treat @section as chapter, @subsection as section, etc. \def\raisesections{\global\advance\secbase by -1} \let\up=\raisesections % original BFox name % @lowersections: treat @chapter as section, @section as subsection, etc. \def\lowersections{\global\advance\secbase by 1} \let\down=\lowersections % original BFox name % Choose a numbered-heading macro % #1 is heading level if unmodified by @raisesections or @lowersections % #2 is text for heading \def\numhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 \ifcase\absseclevel \chapterzzz{#2} \or \seczzz{#2} \or \numberedsubseczzz{#2} \or \numberedsubsubseczzz{#2} \else \ifnum \absseclevel<0 \chapterzzz{#2} \else \numberedsubsubseczzz{#2} \fi \fi } % like \numhead, but chooses appendix heading levels \def\apphead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 \ifcase\absseclevel \appendixzzz{#2} \or \appendixsectionzzz{#2} \or \appendixsubseczzz{#2} \or \appendixsubsubseczzz{#2} \else \ifnum \absseclevel<0 \appendixzzz{#2} \else \appendixsubsubseczzz{#2} \fi \fi } % like \numhead, but chooses numberless heading levels \def\unnmhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1 \ifcase\absseclevel \unnumberedzzz{#2} \or \unnumberedseczzz{#2} \or \unnumberedsubseczzz{#2} \or \unnumberedsubsubseczzz{#2} \else \ifnum \absseclevel<0 \unnumberedzzz{#2} \else \unnumberedsubsubseczzz{#2} \fi \fi } \def\thischaptername{No Chapter Title} \outer\def\chapter{\parsearg\chapteryyy} \def\chapteryyy #1{\numhead0{#1}} % normally numhead0 calls chapterzzz \def\chapterzzz #1{\seccheck{chapter}% \secno=0 \subsecno=0 \subsubsecno=0 \global\advance \chapno by 1 \message{\putwordChapter \the\chapno}% \chapmacro {#1}{\the\chapno}% \gdef\thissection{#1}% \gdef\thischaptername{#1}% % We don't substitute the actual chapter name into \thischapter % because we don't want its macros evaluated now. \xdef\thischapter{\putwordChapter{} \the\chapno: \noexpand\thischaptername}% {\chapternofonts% \toks0 = {#1}% \edef\temp{{\realbackslash chapentry{\the\toks0}{\the\chapno}{\noexpand\folio}}}% \escapechar=`\\% \write \contentsfile \temp % \donoderef % \global\let\section = \numberedsec \global\let\subsection = \numberedsubsec \global\let\subsubsection = \numberedsubsubsec }} \outer\def\appendix{\parsearg\appendixyyy} \def\appendixyyy #1{\apphead0{#1}} % normally apphead0 calls appendixzzz \def\appendixzzz #1{\seccheck{appendix}% \secno=0 \subsecno=0 \subsubsecno=0 \global\advance \appendixno by 1 \message{Appendix \appendixletter}% \chapmacro {#1}{\putwordAppendix{} \appendixletter}% \gdef\thissection{#1}% \gdef\thischaptername{#1}% \xdef\thischapter{\putwordAppendix{} \appendixletter: \noexpand\thischaptername}% {\chapternofonts% \toks0 = {#1}% \edef\temp{{\realbackslash chapentry{\the\toks0}% {\putwordAppendix{} \appendixletter}{\noexpand\folio}}}% \escapechar=`\\% \write \contentsfile \temp % \appendixnoderef % \global\let\section = \appendixsec \global\let\subsection = \appendixsubsec \global\let\subsubsection = \appendixsubsubsec }} % @centerchap is like @unnumbered, but the heading is centered. \outer\def\centerchap{\parsearg\centerchapyyy} \def\centerchapyyy #1{{\let\unnumbchapmacro=\centerchapmacro \unnumberedyyy{#1}}} \outer\def\top{\parsearg\unnumberedyyy} \outer\def\unnumbered{\parsearg\unnumberedyyy} \def\unnumberedyyy #1{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz \def\unnumberedzzz #1{\seccheck{unnumbered}% \secno=0 \subsecno=0 \subsubsecno=0 % % This used to be simply \message{#1}, but TeX fully expands the % argument to \message. Therefore, if #1 contained @-commands, TeX % expanded them. For example, in `@unnumbered The @cite{Book}', TeX % expanded @cite (which turns out to cause errors because \cite is meant % to be executed, not expanded). % % Anyway, we don't want the fully-expanded definition of @cite to appear % as a result of the \message, we just want `@cite' itself. We use % \the to achieve this: TeX expands \the only once, % simply yielding the contents of the . \toks0 = {#1}\message{(\the\toks0)}% % \unnumbchapmacro {#1}% \gdef\thischapter{#1}\gdef\thissection{#1}% {\chapternofonts% \toks0 = {#1}% \edef\temp{{\realbackslash unnumbchapentry{\the\toks0}{\noexpand\folio}}}% \escapechar=`\\% \write \contentsfile \temp % \unnumbnoderef % \global\let\section = \unnumberedsec \global\let\subsection = \unnumberedsubsec \global\let\subsubsection = \unnumberedsubsubsec }} \outer\def\numberedsec{\parsearg\secyyy} \def\secyyy #1{\numhead1{#1}} % normally calls seczzz \def\seczzz #1{\seccheck{section}% \subsecno=0 \subsubsecno=0 \global\advance \secno by 1 % \gdef\thissection{#1}\secheading {#1}{\the\chapno}{\the\secno}% {\chapternofonts% \toks0 = {#1}% \edef\temp{{\realbackslash secentry % {\the\toks0}{\the\chapno}{\the\secno}{\noexpand\folio}}}% \escapechar=`\\% \write \contentsfile \temp % \donoderef % \penalty 10000 % }} \outer\def\appendixsection{\parsearg\appendixsecyyy} \outer\def\appendixsec{\parsearg\appendixsecyyy} \def\appendixsecyyy #1{\apphead1{#1}} % normally calls appendixsectionzzz \def\appendixsectionzzz #1{\seccheck{appendixsection}% \subsecno=0 \subsubsecno=0 \global\advance \secno by 1 % \gdef\thissection{#1}\secheading {#1}{\appendixletter}{\the\secno}% {\chapternofonts% \toks0 = {#1}% \edef\temp{{\realbackslash secentry % {\the\toks0}{\appendixletter}{\the\secno}{\noexpand\folio}}}% \escapechar=`\\% \write \contentsfile \temp % \appendixnoderef % \penalty 10000 % }} \outer\def\unnumberedsec{\parsearg\unnumberedsecyyy} \def\unnumberedsecyyy #1{\unnmhead1{#1}} % normally calls unnumberedseczzz \def\unnumberedseczzz #1{\seccheck{unnumberedsec}% \plainsecheading {#1}\gdef\thissection{#1}% {\chapternofonts% \toks0 = {#1}% \edef\temp{{\realbackslash unnumbsecentry{\the\toks0}{\noexpand\folio}}}% \escapechar=`\\% \write \contentsfile \temp % \unnumbnoderef % \penalty 10000 % }} \outer\def\numberedsubsec{\parsearg\numberedsubsecyyy} \def\numberedsubsecyyy #1{\numhead2{#1}} % normally calls numberedsubseczzz \def\numberedsubseczzz #1{\seccheck{subsection}% \gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 % \subsecheading {#1}{\the\chapno}{\the\secno}{\the\subsecno}% {\chapternofonts% \toks0 = {#1}% \edef\temp{{\realbackslash subsecentry % {\the\toks0}{\the\chapno}{\the\secno}{\the\subsecno}{\noexpand\folio}}}% \escapechar=`\\% \write \contentsfile \temp % \donoderef % \penalty 10000 % }} \outer\def\appendixsubsec{\parsearg\appendixsubsecyyy} \def\appendixsubsecyyy #1{\apphead2{#1}} % normally calls appendixsubseczzz \def\appendixsubseczzz #1{\seccheck{appendixsubsec}% \gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 % \subsecheading {#1}{\appendixletter}{\the\secno}{\the\subsecno}% {\chapternofonts% \toks0 = {#1}% \edef\temp{{\realbackslash subsecentry % {\the\toks0}{\appendixletter}{\the\secno}{\the\subsecno}{\noexpand\folio}}}% \escapechar=`\\% \write \contentsfile \temp % \appendixnoderef % \penalty 10000 % }} \outer\def\unnumberedsubsec{\parsearg\unnumberedsubsecyyy} \def\unnumberedsubsecyyy #1{\unnmhead2{#1}} %normally calls unnumberedsubseczzz \def\unnumberedsubseczzz #1{\seccheck{unnumberedsubsec}% \plainsubsecheading {#1}\gdef\thissection{#1}% {\chapternofonts% \toks0 = {#1}% \edef\temp{{\realbackslash unnumbsubsecentry{\the\toks0}{\noexpand\folio}}}% \escapechar=`\\% \write \contentsfile \temp % \unnumbnoderef % \penalty 10000 % }} \outer\def\numberedsubsubsec{\parsearg\numberedsubsubsecyyy} \def\numberedsubsubsecyyy #1{\numhead3{#1}} % normally numberedsubsubseczzz \def\numberedsubsubseczzz #1{\seccheck{subsubsection}% \gdef\thissection{#1}\global\advance \subsubsecno by 1 % \subsubsecheading {#1} {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}% {\chapternofonts% \toks0 = {#1}% \edef\temp{{\realbackslash subsubsecentry{\the\toks0} {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno} {\noexpand\folio}}}% \escapechar=`\\% \write \contentsfile \temp % \donoderef % \penalty 10000 % }} \outer\def\appendixsubsubsec{\parsearg\appendixsubsubsecyyy} \def\appendixsubsubsecyyy #1{\apphead3{#1}} % normally appendixsubsubseczzz \def\appendixsubsubseczzz #1{\seccheck{appendixsubsubsec}% \gdef\thissection{#1}\global\advance \subsubsecno by 1 % \subsubsecheading {#1} {\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}% {\chapternofonts% \toks0 = {#1}% \edef\temp{{\realbackslash subsubsecentry{\the\toks0}% {\appendixletter} {\the\secno}{\the\subsecno}{\the\subsubsecno}{\noexpand\folio}}}% \escapechar=`\\% \write \contentsfile \temp % \appendixnoderef % \penalty 10000 % }} \outer\def\unnumberedsubsubsec{\parsearg\unnumberedsubsubsecyyy} \def\unnumberedsubsubsecyyy #1{\unnmhead3{#1}} %normally unnumberedsubsubseczzz \def\unnumberedsubsubseczzz #1{\seccheck{unnumberedsubsubsec}% \plainsubsubsecheading {#1}\gdef\thissection{#1}% {\chapternofonts% \toks0 = {#1}% \edef\temp{{\realbackslash unnumbsubsubsecentry{\the\toks0}{\noexpand\folio}}}% \escapechar=`\\% \write \contentsfile \temp % \unnumbnoderef % \penalty 10000 % }} % These are variants which are not "outer", so they can appear in @ifinfo. % Actually, they should now be obsolete; ordinary section commands should work. \def\infotop{\parsearg\unnumberedzzz} \def\infounnumbered{\parsearg\unnumberedzzz} \def\infounnumberedsec{\parsearg\unnumberedseczzz} \def\infounnumberedsubsec{\parsearg\unnumberedsubseczzz} \def\infounnumberedsubsubsec{\parsearg\unnumberedsubsubseczzz} \def\infoappendix{\parsearg\appendixzzz} \def\infoappendixsec{\parsearg\appendixseczzz} \def\infoappendixsubsec{\parsearg\appendixsubseczzz} \def\infoappendixsubsubsec{\parsearg\appendixsubsubseczzz} \def\infochapter{\parsearg\chapterzzz} \def\infosection{\parsearg\sectionzzz} \def\infosubsection{\parsearg\subsectionzzz} \def\infosubsubsection{\parsearg\subsubsectionzzz} % These macros control what the section commands do, according % to what kind of chapter we are in (ordinary, appendix, or unnumbered). % Define them by default for a numbered chapter. \global\let\section = \numberedsec \global\let\subsection = \numberedsubsec \global\let\subsubsection = \numberedsubsubsec % Define @majorheading, @heading and @subheading % NOTE on use of \vbox for chapter headings, section headings, and % such: % 1) We use \vbox rather than the earlier \line to permit % overlong headings to fold. % 2) \hyphenpenalty is set to 10000 because hyphenation in a % heading is obnoxious; this forbids it. % 3) Likewise, headings look best if no \parindent is used, and % if justification is not attempted. Hence \raggedright. \def\majorheading{\parsearg\majorheadingzzz} \def\majorheadingzzz #1{% {\advance\chapheadingskip by 10pt \chapbreak }% {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 \parindent=0pt\raggedright \rm #1\hfill}}\bigskip \par\penalty 200} \def\chapheading{\parsearg\chapheadingzzz} \def\chapheadingzzz #1{\chapbreak % {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 \parindent=0pt\raggedright \rm #1\hfill}}\bigskip \par\penalty 200} % @heading, @subheading, @subsubheading. \def\heading{\parsearg\plainsecheading} \def\subheading{\parsearg\plainsubsecheading} \def\subsubheading{\parsearg\plainsubsubsecheading} % These macros generate a chapter, section, etc. heading only % (including whitespace, linebreaking, etc. around it), % given all the information in convenient, parsed form. %%% Args are the skip and penalty (usually negative) \def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi} \def\setchapterstyle #1 {\csname CHAPF#1\endcsname} %%% Define plain chapter starts, and page on/off switching for it % Parameter controlling skip before chapter headings (if needed) \newskip\chapheadingskip \def\chapbreak{\dobreak \chapheadingskip {-4000}} \def\chappager{\par\vfill\supereject} \def\chapoddpage{\chappager \ifodd\pageno \else \hbox to 0pt{} \chappager\fi} \def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname} \def\CHAPPAGoff{ \global\let\contentsalignmacro = \chappager \global\let\pchapsepmacro=\chapbreak \global\let\pagealignmacro=\chappager} \def\CHAPPAGon{ \global\let\contentsalignmacro = \chappager \global\let\pchapsepmacro=\chappager \global\let\pagealignmacro=\chappager \global\def\HEADINGSon{\HEADINGSsingle}} \def\CHAPPAGodd{ \global\let\contentsalignmacro = \chapoddpage \global\let\pchapsepmacro=\chapoddpage \global\let\pagealignmacro=\chapoddpage \global\def\HEADINGSon{\HEADINGSdouble}} \CHAPPAGon \def\CHAPFplain{ \global\let\chapmacro=\chfplain \global\let\unnumbchapmacro=\unnchfplain \global\let\centerchapmacro=\centerchfplain} % Plain chapter opening. % #1 is the text, #2 the chapter number or empty if unnumbered. \def\chfplain#1#2{% \pchapsepmacro {% \chapfonts \rm \def\chapnum{#2}% \setbox0 = \hbox{#2\ifx\chapnum\empty\else\enspace\fi}% \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright \hangindent = \wd0 \centerparametersmaybe \unhbox0 #1\par}% }% \nobreak\bigskip % no page break after a chapter title \nobreak } % Plain opening for unnumbered. \def\unnchfplain#1{\chfplain{#1}{}} % @centerchap -- centered and unnumbered. \let\centerparametersmaybe = \relax \def\centerchfplain#1{{% \def\centerparametersmaybe{% \advance\rightskip by 3\rightskip \leftskip = \rightskip \parfillskip = 0pt }% \chfplain{#1}{}% }} \CHAPFplain % The default \def\unnchfopen #1{% \chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 \parindent=0pt\raggedright \rm #1\hfill}}\bigskip \par\penalty 10000 % } \def\chfopen #1#2{\chapoddpage {\chapfonts \vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}% \par\penalty 5000 % } \def\centerchfopen #1{% \chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 \parindent=0pt \hfill {\rm #1}\hfill}}\bigskip \par\penalty 10000 % } \def\CHAPFopen{ \global\let\chapmacro=\chfopen \global\let\unnumbchapmacro=\unnchfopen \global\let\centerchapmacro=\centerchfopen} % Section titles. \newskip\secheadingskip \def\secheadingbreak{\dobreak \secheadingskip {-1000}} \def\secheading#1#2#3{\sectionheading{sec}{#2.#3}{#1}} \def\plainsecheading#1{\sectionheading{sec}{}{#1}} % Subsection titles. \newskip \subsecheadingskip \def\subsecheadingbreak{\dobreak \subsecheadingskip {-500}} \def\subsecheading#1#2#3#4{\sectionheading{subsec}{#2.#3.#4}{#1}} \def\plainsubsecheading#1{\sectionheading{subsec}{}{#1}} % Subsubsection titles. \let\subsubsecheadingskip = \subsecheadingskip \let\subsubsecheadingbreak = \subsecheadingbreak \def\subsubsecheading#1#2#3#4#5{\sectionheading{subsubsec}{#2.#3.#4.#5}{#1}} \def\plainsubsubsecheading#1{\sectionheading{subsubsec}{}{#1}} % Print any size section title. % % #1 is the section type (sec/subsec/subsubsec), #2 is the section % number (maybe empty), #3 the text. \def\sectionheading#1#2#3{% {% \expandafter\advance\csname #1headingskip\endcsname by \parskip \csname #1headingbreak\endcsname }% {% % Switch to the right set of fonts. \csname #1fonts\endcsname \rm % % Only insert the separating space if we have a section number. \def\secnum{#2}% \setbox0 = \hbox{#2\ifx\secnum\empty\else\enspace\fi}% % \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright \hangindent = \wd0 % zero if no section number \unhbox0 #3}% }% \ifdim\parskip<10pt \nobreak\kern10pt\nobreak\kern-\parskip\fi \nobreak } \message{toc printing,} % Finish up the main text and prepare to read what we've written % to \contentsfile. \newskip\contentsrightmargin \contentsrightmargin=1in \def\startcontents#1{% % If @setchapternewpage on, and @headings double, the contents should % start on an odd page, unlike chapters. Thus, we maintain % \contentsalignmacro in parallel with \pagealignmacro. % From: Torbjorn Granlund \contentsalignmacro \immediate\closeout \contentsfile \ifnum \pageno>0 \pageno = -1 % Request roman numbered pages. \fi % Don't need to put `Contents' or `Short Contents' in the headline. % It is abundantly clear what they are. \unnumbchapmacro{#1}\def\thischapter{}% \begingroup % Set up to handle contents files properly. \catcode`\\=0 \catcode`\{=1 \catcode`\}=2 \catcode`\@=11 % We can't do this, because then an actual ^ in a section % title fails, e.g., @chapter ^ -- exponentiation. --karl, 9jul97. %\catcode`\^=7 % to see ^^e4 as \"a etc. juha@piuha.ydi.vtt.fi \raggedbottom % Worry more about breakpoints than the bottom. \advance\hsize by -\contentsrightmargin % Don't use the full line length. } % Normal (long) toc. \outer\def\contents{% \startcontents{\putwordTableofContents}% \input \jobname.toc \endgroup \vfill \eject } % And just the chapters. \outer\def\summarycontents{% \startcontents{\putwordShortContents}% % \let\chapentry = \shortchapentry \let\unnumbchapentry = \shortunnumberedentry % We want a true roman here for the page numbers. \secfonts \let\rm=\shortcontrm \let\bf=\shortcontbf \let\sl=\shortcontsl \rm \hyphenpenalty = 10000 \advance\baselineskip by 1pt % Open it up a little. \def\secentry ##1##2##3##4{} \def\unnumbsecentry ##1##2{} \def\subsecentry ##1##2##3##4##5{} \def\unnumbsubsecentry ##1##2{} \def\subsubsecentry ##1##2##3##4##5##6{} \def\unnumbsubsubsecentry ##1##2{} \input \jobname.toc \endgroup \vfill \eject } \let\shortcontents = \summarycontents % These macros generate individual entries in the table of contents. % The first argument is the chapter or section name. % The last argument is the page number. % The arguments in between are the chapter number, section number, ... % Chapter-level things, for both the long and short contents. \def\chapentry#1#2#3{\dochapentry{#2\labelspace#1}{#3}} % See comments in \dochapentry re vbox and related settings \def\shortchapentry#1#2#3{% \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno{#3}}% } % Typeset the label for a chapter or appendix for the short contents. % The arg is, e.g. `Appendix A' for an appendix, or `3' for a chapter. % We could simplify the code here by writing out an \appendixentry % command in the toc file for appendices, instead of using \chapentry % for both, but it doesn't seem worth it. \setbox0 = \hbox{\shortcontrm \putwordAppendix } \newdimen\shortappendixwidth \shortappendixwidth = \wd0 \def\shortchaplabel#1{% % We typeset #1 in a box of constant width, regardless of the text of % #1, so the chapter titles will come out aligned. \setbox0 = \hbox{#1}% \dimen0 = \ifdim\wd0 > \shortappendixwidth \shortappendixwidth \else 0pt \fi % % This space should be plenty, since a single number is .5em, and the % widest letter (M) is 1em, at least in the Computer Modern fonts. % (This space doesn't include the extra space that gets added after % the label; that gets put in by \shortchapentry above.) \advance\dimen0 by 1.1em \hbox to \dimen0{#1\hfil}% } \def\unnumbchapentry#1#2{\dochapentry{#1}{#2}} \def\shortunnumberedentry#1#2{\tocentry{#1}{\doshortpageno{#2}}} % Sections. \def\secentry#1#2#3#4{\dosecentry{#2.#3\labelspace#1}{#4}} \def\unnumbsecentry#1#2{\dosecentry{#1}{#2}} % Subsections. \def\subsecentry#1#2#3#4#5{\dosubsecentry{#2.#3.#4\labelspace#1}{#5}} \def\unnumbsubsecentry#1#2{\dosubsecentry{#1}{#2}} % And subsubsections. \def\subsubsecentry#1#2#3#4#5#6{% \dosubsubsecentry{#2.#3.#4.#5\labelspace#1}{#6}} \def\unnumbsubsubsecentry#1#2{\dosubsubsecentry{#1}{#2}} % This parameter controls the indentation of the various levels. \newdimen\tocindent \tocindent = 3pc % Now for the actual typesetting. In all these, #1 is the text and #2 is the % page number. % % If the toc has to be broken over pages, we want it to be at chapters % if at all possible; hence the \penalty. \def\dochapentry#1#2{% \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip \begingroup \chapentryfonts \tocentry{#1}{\dopageno{#2}}% \endgroup \nobreak\vskip .25\baselineskip plus.1\baselineskip } \def\dosecentry#1#2{\begingroup \secentryfonts \leftskip=\tocindent \tocentry{#1}{\dopageno{#2}}% \endgroup} \def\dosubsecentry#1#2{\begingroup \subsecentryfonts \leftskip=2\tocindent \tocentry{#1}{\dopageno{#2}}% \endgroup} \def\dosubsubsecentry#1#2{\begingroup \subsubsecentryfonts \leftskip=3\tocindent \tocentry{#1}{\dopageno{#2}}% \endgroup} % Final typesetting of a toc entry; we use the same \entry macro as for % the index entries, but we want to suppress hyphenation here. (We % can't do that in the \entry macro, since index entries might consist % of hyphenated-identifiers-that-do-not-fit-on-a-line-and-nothing-else.) \def\tocentry#1#2{\begingroup \vskip 0pt plus1pt % allow a little stretch for the sake of nice page breaks % Do not use \turnoffactive in these arguments. Since the toc is % typeset in cmr, so characters such as _ would come out wrong; we % have to do the usual translation tricks. \entry{#1}{#2}% \endgroup} % Space between chapter (or whatever) number and the title. \def\labelspace{\hskip1em \relax} \def\dopageno#1{{\rm #1}} \def\doshortpageno#1{{\rm #1}} \def\chapentryfonts{\secfonts \rm} \def\secentryfonts{\textfonts} \let\subsecentryfonts = \textfonts \let\subsubsecentryfonts = \textfonts \message{environments,} % Since these characters are used in examples, it should be an even number of % \tt widths. Each \tt character is 1en, so two makes it 1em. % Furthermore, these definitions must come after we define our fonts. \newbox\dblarrowbox \newbox\longdblarrowbox \newbox\pushcharbox \newbox\bullbox \newbox\equivbox \newbox\errorbox %{\tentt %\global\setbox\dblarrowbox = \hbox to 1em{\hfil$\Rightarrow$\hfil} %\global\setbox\longdblarrowbox = \hbox to 1em{\hfil$\mapsto$\hfil} %\global\setbox\pushcharbox = \hbox to 1em{\hfil$\dashv$\hfil} %\global\setbox\equivbox = \hbox to 1em{\hfil$\ptexequiv$\hfil} % Adapted from the manmac format (p.420 of TeXbook) %\global\setbox\bullbox = \hbox to 1em{\kern.15em\vrule height .75ex width .85ex % depth .1ex\hfil} %} % @point{}, @result{}, @expansion{}, @print{}, @equiv{}. \def\point{$\star$} \def\result{\leavevmode\raise.15ex\hbox to 1em{\hfil$\Rightarrow$\hfil}} \def\expansion{\leavevmode\raise.1ex\hbox to 1em{\hfil$\mapsto$\hfil}} \def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}} \def\equiv{\leavevmode\lower.1ex\hbox to 1em{\hfil$\ptexequiv$\hfil}} % Adapted from the TeXbook's \boxit. {\tentt \global\dimen0 = 3em}% Width of the box. \dimen2 = .55pt % Thickness of rules % The text. (`r' is open on the right, `e' somewhat less so on the left.) \setbox0 = \hbox{\kern-.75pt \tensf error\kern-1.5pt} \global\setbox\errorbox=\hbox to \dimen0{\hfil \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right. \advance\hsize by -2\dimen2 % Rules. \vbox{ \hrule height\dimen2 \hbox{\vrule width\dimen2 \kern3pt % Space to left of text. \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below. \kern3pt\vrule width\dimen2}% Space to right. \hrule height\dimen2} \hfil} % The @error{} command. \def\error{\leavevmode\lower.7ex\copy\errorbox} % @tex ... @end tex escapes into raw Tex temporarily. % One exception: @ is still an escape character, so that @end tex works. % But \@ or @@ will get a plain tex @ character. \def\tex{\begingroup \catcode `\\=0 \catcode `\{=1 \catcode `\}=2 \catcode `\$=3 \catcode `\&=4 \catcode `\#=6 \catcode `\^=7 \catcode `\_=8 \catcode `\~=13 \let~=\tie \catcode `\%=14 \catcode 43=12 % plus \catcode`\"=12 \catcode`\==12 \catcode`\|=12 \catcode`\<=12 \catcode`\>=12 \escapechar=`\\ % \let\b=\ptexb \let\bullet=\ptexbullet \let\c=\ptexc \let\,=\ptexcomma \let\.=\ptexdot \let\dots=\ptexdots \let\equiv=\ptexequiv \let\!=\ptexexclam \let\i=\ptexi \let\{=\ptexlbrace \let\}=\ptexrbrace \let\*=\ptexstar \let\t=\ptext % \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}% \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}% \def\@{@}% \let\Etex=\endgroup} % Define @lisp ... @endlisp. % @lisp does a \begingroup so it can rebind things, % including the definition of @endlisp (which normally is erroneous). % Amount to narrow the margins by for @lisp. \newskip\lispnarrowing \lispnarrowing=0.4in % This is the definition that ^^M gets inside @lisp, @example, and other % such environments. \null is better than a space, since it doesn't % have any width. \def\lisppar{\null\endgraf} % Make each space character in the input produce a normal interword % space in the output. Don't allow a line break at this space, as this % is used only in environments like @example, where each line of input % should produce a line of output anyway. % {\obeyspaces % \gdef\sepspaces{\obeyspaces\let =\tie}} % Define \obeyedspace to be our active space, whatever it is. This is % for use in \parsearg. {\sepspaces% \global\let\obeyedspace= } % This space is always present above and below environments. \newskip\envskipamount \envskipamount = 0pt % Make spacing and below environment symmetrical. We use \parskip here % to help in doing that, since in @example-like environments \parskip % is reset to zero; thus the \afterenvbreak inserts no space -- but the % start of the next paragraph will insert \parskip % \def\aboveenvbreak{{\advance\envskipamount by \parskip \endgraf \ifdim\lastskip<\envskipamount \removelastskip \penalty-50 \vskip\envskipamount \fi}} \let\afterenvbreak = \aboveenvbreak % \nonarrowing is a flag. If "set", @lisp etc don't narrow margins. \let\nonarrowing=\relax %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \cartouche: draw rectangle w/rounded corners around argument \font\circle=lcircle10 \newdimen\circthick \newdimen\cartouter\newdimen\cartinner \newskip\normbskip\newskip\normpskip\newskip\normlskip \circthick=\fontdimen8\circle % \def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth \def\ctr{{\hskip 6pt\circle\char'010}} \def\cbl{{\circle\char'012\hskip -6pt}} \def\cbr{{\hskip 6pt\circle\char'011}} \def\carttop{\hbox to \cartouter{\hskip\lskip \ctl\leaders\hrule height\circthick\hfil\ctr \hskip\rskip}} \def\cartbot{\hbox to \cartouter{\hskip\lskip \cbl\leaders\hrule height\circthick\hfil\cbr \hskip\rskip}} % \newskip\lskip\newskip\rskip \long\def\cartouche{% \begingroup \lskip=\leftskip \rskip=\rightskip \leftskip=0pt\rightskip=0pt %we want these *outside*. \cartinner=\hsize \advance\cartinner by-\lskip \advance\cartinner by-\rskip \cartouter=\hsize \advance\cartouter by 18pt % allow for 3pt kerns on either % side, and for 6pt waste from % each corner char \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip % Flag to tell @lisp, etc., not to narrow margin. \let\nonarrowing=\comment \vbox\bgroup \baselineskip=0pt\parskip=0pt\lineskip=0pt \carttop \hbox\bgroup \hskip\lskip \vrule\kern3pt \vbox\bgroup \hsize=\cartinner \kern3pt \begingroup \baselineskip=\normbskip \lineskip=\normlskip \parskip=\normpskip \vskip -\parskip \def\Ecartouche{% \endgroup \kern3pt \egroup \kern3pt\vrule \hskip\rskip \egroup \cartbot \egroup \endgroup }} % This macro is called at the beginning of all the @example variants, % inside a group. \def\nonfillstart{% \aboveenvbreak \inENV % This group ends at the end of the body \hfuzz = 12pt % Don't be fussy \sepspaces % Make spaces be word-separators rather than space tokens. \singlespace \let\par = \lisppar % don't ignore blank lines \obeylines % each line of input is a line of output \parskip = 0pt \parindent = 0pt \emergencystretch = 0pt % don't try to avoid overfull boxes % @cartouche defines \nonarrowing to inhibit narrowing % at next level down. \ifx\nonarrowing\relax \advance \leftskip by \lispnarrowing \exdentamount=\lispnarrowing \let\exdent=\nofillexdent \let\nonarrowing=\relax \fi } % To ending an @example-like environment, we first end the paragraph % (via \afterenvbreak's vertical glue), and then the group. That way we % keep the zero \parskip that the environments set -- \parskip glue % will be inserted at the beginning of the next paragraph in the % document, after the environment. % \def\nonfillfinish{\afterenvbreak\endgroup}% \def\lisp{\begingroup \nonfillstart \let\Elisp = \nonfillfinish \tt % Make @kbd do something special, if requested. \let\kbdfont\kbdexamplefont \rawbackslash % have \ input char produce \ char from current font \gobble } % Define the \E... control sequence only if we are inside the % environment, so the error checking in \end will work. % % We must call \lisp last in the definition, since it reads the % return following the @example (or whatever) command. % \def\example{\begingroup \def\Eexample{\nonfillfinish\endgroup}\lisp} \def\smallexample{\begingroup \def\Esmallexample{\nonfillfinish\endgroup}\lisp} \def\smalllisp{\begingroup \def\Esmalllisp{\nonfillfinish\endgroup}\lisp} % @smallexample and @smalllisp. This is not used unless the @smallbook % command is given. Originally contributed by Pavel@xerox. % \def\smalllispx{\begingroup \nonfillstart \let\Esmalllisp = \nonfillfinish \let\Esmallexample = \nonfillfinish % % Smaller fonts for small examples. \indexfonts \tt \rawbackslash % make \ output the \ character from the current font (tt) \gobble } % This is @display; same as @lisp except use roman font. % \def\display{\begingroup \nonfillstart \let\Edisplay = \nonfillfinish \gobble } % This is @format; same as @display except don't narrow margins. % \def\format{\begingroup \let\nonarrowing = t \nonfillstart \let\Eformat = \nonfillfinish \gobble } % @flushleft (same as @format) and @flushright. % \def\flushleft{\begingroup \let\nonarrowing = t \nonfillstart \let\Eflushleft = \nonfillfinish \gobble } \def\flushright{\begingroup \let\nonarrowing = t \nonfillstart \let\Eflushright = \nonfillfinish \advance\leftskip by 0pt plus 1fill \gobble} % @quotation does normal linebreaking (hence we can't use \nonfillstart) % and narrows the margins. % \def\quotation{% \begingroup\inENV %This group ends at the end of the @quotation body {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip \singlespace \parindent=0pt % We have retained a nonzero parskip for the environment, since we're % doing normal filling. So to avoid extra space below the environment... \def\Equotation{\parskip = 0pt \nonfillfinish}% % % @cartouche defines \nonarrowing to inhibit narrowing at next level down. \ifx\nonarrowing\relax \advance\leftskip by \lispnarrowing \advance\rightskip by \lispnarrowing \exdentamount = \lispnarrowing \let\nonarrowing = \relax \fi } \message{defuns,} % Define formatter for defuns % First, allow user to change definition object font (\df) internally \def\setdeffont #1 {\csname DEF#1\endcsname} \newskip\defbodyindent \defbodyindent=.4in \newskip\defargsindent \defargsindent=50pt \newskip\deftypemargin \deftypemargin=12pt \newskip\deflastargmargin \deflastargmargin=18pt \newcount\parencount % define \functionparens, which makes ( and ) and & do special things. % \functionparens affects the group it is contained in. \def\activeparens{% \catcode`\(=\active \catcode`\)=\active \catcode`\&=\active \catcode`\[=\active \catcode`\]=\active} % Make control sequences which act like normal parenthesis chars. \let\lparen = ( \let\rparen = ) {\activeparens % Now, smart parens don't turn on until &foo (see \amprm) % Be sure that we always have a definition for `(', etc. For example, % if the fn name has parens in it, \boldbrax will not be in effect yet, % so TeX would otherwise complain about undefined control sequence. \global\let(=\lparen \global\let)=\rparen \global\let[=\lbrack \global\let]=\rbrack \gdef\functionparens{\boldbrax\let&=\amprm\parencount=0 } \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb} % This is used to turn on special parens % but make & act ordinary (given that it's active). \gdef\boldbraxnoamp{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb\let&=\ampnr} % Definitions of (, ) and & used in args for functions. % This is the definition of ( outside of all parentheses. \gdef\oprm#1 {{\rm\char`\(}#1 \bf \let(=\opnested \global\advance\parencount by 1 } % % This is the definition of ( when already inside a level of parens. \gdef\opnested{\char`\(\global\advance\parencount by 1 } % \gdef\clrm{% Print a paren in roman if it is taking us back to depth of 0. % also in that case restore the outer-level definition of (. \ifnum \parencount=1 {\rm \char `\)}\sl \let(=\oprm \else \char `\) \fi \global\advance \parencount by -1 } % If we encounter &foo, then turn on ()-hacking afterwards \gdef\amprm#1 {{\rm\}\let(=\oprm \let)=\clrm\ } % \gdef\normalparens{\boldbrax\let&=\ampnr} } % End of definition inside \activeparens %% These parens (in \boldbrax) actually are a little bolder than the %% contained text. This is especially needed for [ and ] \def\opnr{{\sf\char`\(}\global\advance\parencount by 1 } \def\clnr{{\sf\char`\)}\global\advance\parencount by -1 } \def\ampnr{\&} \def\lbrb{{\bf\char`\[}} \def\rbrb{{\bf\char`\]}} % First, defname, which formats the header line itself. % #1 should be the function name. % #2 should be the type of definition, such as "Function". \def\defname #1#2{% % Get the values of \leftskip and \rightskip as they were % outside the @def... \dimen2=\leftskip \advance\dimen2 by -\defbodyindent \dimen3=\rightskip \advance\dimen3 by -\defbodyindent \noindent % \setbox0=\hbox{\hskip \deflastargmargin{\rm #2}\hskip \deftypemargin}% \dimen0=\hsize \advance \dimen0 by -\wd0 % compute size for first line \dimen1=\hsize \advance \dimen1 by -\defargsindent %size for continuations \parshape 2 0in \dimen0 \defargsindent \dimen1 % % Now output arg 2 ("Function" or some such) % ending at \deftypemargin from the right margin, % but stuck inside a box of width 0 so it does not interfere with linebreaking {% Adjust \hsize to exclude the ambient margins, % so that \rightline will obey them. \advance \hsize by -\dimen2 \advance \hsize by -\dimen3 \rlap{\rightline{{\rm #2}\hskip \deftypemargin}}}% % Make all lines underfull and no complaints: \tolerance=10000 \hbadness=10000 \advance\leftskip by -\defbodyindent \exdentamount=\defbodyindent {\df #1}\enskip % Generate function name } % Actually process the body of a definition % #1 should be the terminating control sequence, such as \Edefun. % #2 should be the "another name" control sequence, such as \defunx. % #3 should be the control sequence that actually processes the header, % such as \defunheader. \def\defparsebody #1#2#3{\begingroup\inENV% Environment for definitionbody \medbreak % % Define the end token that this defining construct specifies % so that it will exit this group. \def#1{\endgraf\endgroup\medbreak}% \def#2{\begingroup\obeylines\activeparens\spacesplit#3}% \parindent=0in \advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent \exdentamount=\defbodyindent \begingroup % \catcode 61=\active % 61 is `=' \obeylines\activeparens\spacesplit#3} \def\defmethparsebody #1#2#3#4 {\begingroup\inENV % \medbreak % % Define the end token that this defining construct specifies % so that it will exit this group. \def#1{\endgraf\endgroup\medbreak}% \def#2##1 {\begingroup\obeylines\activeparens\spacesplit{#3{##1}}}% \parindent=0in \advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent \exdentamount=\defbodyindent \begingroup\obeylines\activeparens\spacesplit{#3{#4}}} \def\defopparsebody #1#2#3#4#5 {\begingroup\inENV % \medbreak % % Define the end token that this defining construct specifies % so that it will exit this group. \def#1{\endgraf\endgroup\medbreak}% \def#2##1 ##2 {\def#4{##1}% \begingroup\obeylines\activeparens\spacesplit{#3{##2}}}% \parindent=0in \advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent \exdentamount=\defbodyindent \begingroup\obeylines\activeparens\spacesplit{#3{#5}}} % These parsing functions are similar to the preceding ones % except that they do not make parens into active characters. % These are used for "variables" since they have no arguments. \def\defvarparsebody #1#2#3{\begingroup\inENV% Environment for definitionbody \medbreak % % Define the end token that this defining construct specifies % so that it will exit this group. \def#1{\endgraf\endgroup\medbreak}% \def#2{\begingroup\obeylines\spacesplit#3}% \parindent=0in \advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent \exdentamount=\defbodyindent \begingroup % \catcode 61=\active % \obeylines\spacesplit#3} % This is used for \def{tp,vr}parsebody. It could probably be used for % some of the others, too, with some judicious conditionals. % \def\parsebodycommon#1#2#3{% \begingroup\inENV % \medbreak % % Define the end token that this defining construct specifies % so that it will exit this group. \def#1{\endgraf\endgroup\medbreak}% \def#2##1 {\begingroup\obeylines\spacesplit{#3{##1}}}% \parindent=0in \advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent \exdentamount=\defbodyindent \begingroup\obeylines } \def\defvrparsebody#1#2#3#4 {% \parsebodycommon{#1}{#2}{#3}% \spacesplit{#3{#4}}% } % This loses on `@deftp {Data Type} {struct termios}' -- it thinks the % type is just `struct', because we lose the braces in `{struct % termios}' when \spacesplit reads its undelimited argument. Sigh. % \let\deftpparsebody=\defvrparsebody % % So, to get around this, we put \empty in with the type name. That % way, TeX won't find exactly `{...}' as an undelimited argument, and % won't strip off the braces. % \def\deftpparsebody #1#2#3#4 {% \parsebodycommon{#1}{#2}{#3}% \spacesplit{\parsetpheaderline{#3{#4}}}\empty } % Fine, but then we have to eventually remove the \empty *and* the % braces (if any). That's what this does. % \def\removeemptybraces\empty#1\relax{#1} % After \spacesplit has done its work, this is called -- #1 is the final % thing to call, #2 the type name (which starts with \empty), and #3 % (which might be empty) the arguments. % \def\parsetpheaderline#1#2#3{% #1{\removeemptybraces#2\relax}{#3}% }% \def\defopvarparsebody #1#2#3#4#5 {\begingroup\inENV % \medbreak % % Define the end token that this defining construct specifies % so that it will exit this group. \def#1{\endgraf\endgroup\medbreak}% \def#2##1 ##2 {\def#4{##1}% \begingroup\obeylines\spacesplit{#3{##2}}}% \parindent=0in \advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent \exdentamount=\defbodyindent \begingroup\obeylines\spacesplit{#3{#5}}} % Split up #2 at the first space token. % call #1 with two arguments: % the first is all of #2 before the space token, % the second is all of #2 after that space token. % If #2 contains no space token, all of it is passed as the first arg % and the second is passed as empty. {\obeylines \gdef\spacesplit#1#2^^M{\endgroup\spacesplitfoo{#1}#2 \relax\spacesplitfoo}% \long\gdef\spacesplitfoo#1#2 #3#4\spacesplitfoo{% \ifx\relax #3% #1{#2}{}\else #1{#2}{#3#4}\fi}} % So much for the things common to all kinds of definitions. % Define @defun. % First, define the processing that is wanted for arguments of \defun % Use this to expand the args and terminate the paragraph they make up \def\defunargs #1{\functionparens \sl % Expand, preventing hyphenation at `-' chars. % Note that groups don't affect changes in \hyphenchar. \hyphenchar\tensl=0 #1% \hyphenchar\tensl=45 \ifnum\parencount=0 \else \errmessage{Unbalanced parentheses in @def}\fi% \interlinepenalty=10000 \advance\rightskip by 0pt plus 1fil \endgraf\penalty 10000\vskip -\parskip\penalty 10000% } \def\deftypefunargs #1{% % Expand, preventing hyphenation at `-' chars. % Note that groups don't affect changes in \hyphenchar. % Use \boldbraxnoamp, not \functionparens, so that & is not special. \boldbraxnoamp \tclose{#1}% avoid \code because of side effects on active chars \interlinepenalty=10000 \advance\rightskip by 0pt plus 1fil \endgraf\penalty 10000\vskip -\parskip\penalty 10000% } % Do complete processing of one @defun or @defunx line already parsed. % @deffn Command forward-char nchars \def\deffn{\defmethparsebody\Edeffn\deffnx\deffnheader} \def\deffnheader #1#2#3{\doind {fn}{\code{#2}}% \begingroup\defname {#2}{#1}\defunargs{#3}\endgroup % \catcode 61=\other % Turn off change made in \defparsebody } % @defun == @deffn Function \def\defun{\defparsebody\Edefun\defunx\defunheader} \def\defunheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index \begingroup\defname {#1}{Function}% \defunargs {#2}\endgroup % \catcode 61=\other % Turn off change made in \defparsebody } % @deftypefun int foobar (int @var{foo}, float @var{bar}) \def\deftypefun{\defparsebody\Edeftypefun\deftypefunx\deftypefunheader} % #1 is the data type. #2 is the name and args. \def\deftypefunheader #1#2{\deftypefunheaderx{#1}#2 \relax} % #1 is the data type, #2 the name, #3 the args. \def\deftypefunheaderx #1#2 #3\relax{% \doind {fn}{\code{#2}}% Make entry in function index \begingroup\defname {\defheaderxcond#1\relax$$$#2}{Function}% \deftypefunargs {#3}\endgroup % \catcode 61=\other % Turn off change made in \defparsebody } % @deftypefn {Library Function} int foobar (int @var{foo}, float @var{bar}) \def\deftypefn{\defmethparsebody\Edeftypefn\deftypefnx\deftypefnheader} % \defheaderxcond#1\relax$$$ % puts #1 in @code, followed by a space, but does nothing if #1 is null. \def\defheaderxcond#1#2$$${\ifx#1\relax\else\code{#1#2} \fi} % #1 is the classification. #2 is the data type. #3 is the name and args. \def\deftypefnheader #1#2#3{\deftypefnheaderx{#1}{#2}#3 \relax} % #1 is the classification, #2 the data type, #3 the name, #4 the args. \def\deftypefnheaderx #1#2#3 #4\relax{% \doind {fn}{\code{#3}}% Make entry in function index \begingroup \normalparens % notably, turn off `&' magic, which prevents % at least some C++ text from working \defname {\defheaderxcond#2\relax$$$#3}{#1}% \deftypefunargs {#4}\endgroup % \catcode 61=\other % Turn off change made in \defparsebody } % @defmac == @deffn Macro \def\defmac{\defparsebody\Edefmac\defmacx\defmacheader} \def\defmacheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index \begingroup\defname {#1}{Macro}% \defunargs {#2}\endgroup % \catcode 61=\other % Turn off change made in \defparsebody } % @defspec == @deffn Special Form \def\defspec{\defparsebody\Edefspec\defspecx\defspecheader} \def\defspecheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index \begingroup\defname {#1}{Special Form}% \defunargs {#2}\endgroup % \catcode 61=\other % Turn off change made in \defparsebody } % This definition is run if you use @defunx % anywhere other than immediately after a @defun or @defunx. \def\deffnx #1 {\errmessage{@deffnx in invalid context}} \def\defunx #1 {\errmessage{@defunx in invalid context}} \def\defmacx #1 {\errmessage{@defmacx in invalid context}} \def\defspecx #1 {\errmessage{@defspecx in invalid context}} \def\deftypefnx #1 {\errmessage{@deftypefnx in invalid context}} \def\deftypemethodx #1 {\errmessage{@deftypemethodx in invalid context}} \def\deftypeunx #1 {\errmessage{@deftypeunx in invalid context}} % @defmethod, and so on % @defop {Funny Method} foo-class frobnicate argument \def\defop #1 {\def\defoptype{#1}% \defopparsebody\Edefop\defopx\defopheader\defoptype} \def\defopheader #1#2#3{% \dosubind {fn}{\code{#2}}{on #1}% Make entry in function index \begingroup\defname {#2}{\defoptype{} on #1}% \defunargs {#3}\endgroup % } % @deftypemethod foo-class return-type foo-method args % \def\deftypemethod{% \defmethparsebody\Edeftypemethod\deftypemethodx\deftypemethodheader} % % #1 is the class name, #2 the data type, #3 the method name, #4 the args. \def\deftypemethodheader#1#2#3#4{% \deftypefnheaderx{Method on #1}{#2}#3 #4\relax } % @defmethod == @defop Method \def\defmethod{\defmethparsebody\Edefmethod\defmethodx\defmethodheader} \def\defmethodheader #1#2#3{% \dosubind {fn}{\code{#2}}{on #1}% entry in function index \begingroup\defname {#2}{Method on #1}% \defunargs {#3}\endgroup % } % @defcv {Class Option} foo-class foo-flag \def\defcv #1 {\def\defcvtype{#1}% \defopvarparsebody\Edefcv\defcvx\defcvarheader\defcvtype} \def\defcvarheader #1#2#3{% \dosubind {vr}{\code{#2}}{of #1}% Make entry in var index \begingroup\defname {#2}{\defcvtype{} of #1}% \defvarargs {#3}\endgroup % } % @defivar == @defcv {Instance Variable} \def\defivar{\defvrparsebody\Edefivar\defivarx\defivarheader} \def\defivarheader #1#2#3{% \dosubind {vr}{\code{#2}}{of #1}% Make entry in var index \begingroup\defname {#2}{Instance Variable of #1}% \defvarargs {#3}\endgroup % } % These definitions are run if you use @defmethodx, etc., % anywhere other than immediately after a @defmethod, etc. \def\defopx #1 {\errmessage{@defopx in invalid context}} \def\defmethodx #1 {\errmessage{@defmethodx in invalid context}} \def\defcvx #1 {\errmessage{@defcvx in invalid context}} \def\defivarx #1 {\errmessage{@defivarx in invalid context}} % Now @defvar % First, define the processing that is wanted for arguments of @defvar. % This is actually simple: just print them in roman. % This must expand the args and terminate the paragraph they make up \def\defvarargs #1{\normalparens #1% \interlinepenalty=10000 \endgraf\penalty 10000\vskip -\parskip\penalty 10000} % @defvr Counter foo-count \def\defvr{\defvrparsebody\Edefvr\defvrx\defvrheader} \def\defvrheader #1#2#3{\doind {vr}{\code{#2}}% \begingroup\defname {#2}{#1}\defvarargs{#3}\endgroup} % @defvar == @defvr Variable \def\defvar{\defvarparsebody\Edefvar\defvarx\defvarheader} \def\defvarheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index \begingroup\defname {#1}{Variable}% \defvarargs {#2}\endgroup % } % @defopt == @defvr {User Option} \def\defopt{\defvarparsebody\Edefopt\defoptx\defoptheader} \def\defoptheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index \begingroup\defname {#1}{User Option}% \defvarargs {#2}\endgroup % } % @deftypevar int foobar \def\deftypevar{\defvarparsebody\Edeftypevar\deftypevarx\deftypevarheader} % #1 is the data type. #2 is the name, perhaps followed by text that % is actually part of the data type, which should not be put into the index. \def\deftypevarheader #1#2{% \dovarind#2 \relax% Make entry in variables index \begingroup\defname {\defheaderxcond#1\relax$$$#2}{Variable}% \interlinepenalty=10000 \endgraf\penalty 10000\vskip -\parskip\penalty 10000 \endgroup} \def\dovarind#1 #2\relax{\doind{vr}{\code{#1}}} % @deftypevr {Global Flag} int enable \def\deftypevr{\defvrparsebody\Edeftypevr\deftypevrx\deftypevrheader} \def\deftypevrheader #1#2#3{\dovarind#3 \relax% \begingroup\defname {\defheaderxcond#2\relax$$$#3}{#1} \interlinepenalty=10000 \endgraf\penalty 10000\vskip -\parskip\penalty 10000 \endgroup} % This definition is run if you use @defvarx % anywhere other than immediately after a @defvar or @defvarx. \def\defvrx #1 {\errmessage{@defvrx in invalid context}} \def\defvarx #1 {\errmessage{@defvarx in invalid context}} \def\defoptx #1 {\errmessage{@defoptx in invalid context}} \def\deftypevarx #1 {\errmessage{@deftypevarx in invalid context}} \def\deftypevrx #1 {\errmessage{@deftypevrx in invalid context}} % Now define @deftp % Args are printed in bold, a slight difference from @defvar. \def\deftpargs #1{\bf \defvarargs{#1}} % @deftp Class window height width ... \def\deftp{\deftpparsebody\Edeftp\deftpx\deftpheader} \def\deftpheader #1#2#3{\doind {tp}{\code{#2}}% \begingroup\defname {#2}{#1}\deftpargs{#3}\endgroup} % This definition is run if you use @deftpx, etc % anywhere other than immediately after a @deftp, etc. \def\deftpx #1 {\errmessage{@deftpx in invalid context}} \message{cross reference,} % Define cross-reference macros \newwrite \auxfile \newif\ifhavexrefs % True if xref values are known. \newif\ifwarnedxrefs % True if we warned once that they aren't known. % @inforef is simple. \def\inforef #1{\inforefzzz #1,,,,**} \def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}}, node \samp{\ignorespaces#1{}}} % \setref{foo} defines a cross-reference point named foo. \def\setref#1{% \dosetq{#1-title}{Ytitle}% \dosetq{#1-pg}{Ypagenumber}% \dosetq{#1-snt}{Ysectionnumberandtype}} \def\unnumbsetref#1{% \dosetq{#1-title}{Ytitle}% \dosetq{#1-pg}{Ypagenumber}% \dosetq{#1-snt}{Ynothing}} \def\appendixsetref#1{% \dosetq{#1-title}{Ytitle}% \dosetq{#1-pg}{Ypagenumber}% \dosetq{#1-snt}{Yappendixletterandtype}} % \xref, \pxref, and \ref generate cross-references to specified points. % For \xrefX, #1 is the node name, #2 the name of the Info % cross-reference, #3 the printed node name, #4 the name of the Info % file, #5 the name of the printed manual. All but the node name can be % omitted. % \def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]} \def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]} \def\ref#1{\xrefX[#1,,,,,,,]} \def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup \def\printedmanual{\ignorespaces #5}% \def\printednodename{\ignorespaces #3}% \setbox1=\hbox{\printedmanual}% \setbox0=\hbox{\printednodename}% \ifdim \wd0 = 0pt % No printed node name was explicitly given. \expandafter\ifx\csname SETxref-automatic-section-title\endcsname\relax % Use the node name inside the square brackets. \def\printednodename{\ignorespaces #1}% \else % Use the actual chapter/section title appear inside % the square brackets. Use the real section title if we have it. \ifdim \wd1>0pt% % It is in another manual, so we don't have it. \def\printednodename{\ignorespaces #1}% \else \ifhavexrefs % We know the real title if we have the xref values. \def\printednodename{\refx{#1-title}{}}% \else % Otherwise just copy the Info node name. \def\printednodename{\ignorespaces #1}% \fi% \fi \fi \fi % % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not % insert empty discretionaries after hyphens, which means that it will % not find a line break at a hyphen in a node names. Since some manuals % are best written with fairly long node names, containing hyphens, this % is a loss. Therefore, we give the text of the node name again, so it % is as if TeX is seeing it for the first time. \ifdim \wd1 > 0pt \putwordsection{} ``\printednodename'' in \cite{\printedmanual}% \else % _ (for example) has to be the character _ for the purposes of the % control sequence corresponding to the node, but it has to expand % into the usual \leavevmode...\vrule stuff for purposes of % printing. So we \turnoffactive for the \refx-snt, back on for the % printing, back off for the \refx-pg. {\turnoffactive \refx{#1-snt}{}}% \space [\printednodename],\space \turnoffactive \putwordpage\tie\refx{#1-pg}{}% \fi \endgroup} % \dosetq is the interface for calls from other macros % Use \turnoffactive so that punctuation chars such as underscore % work in node names. \def\dosetq #1#2{{\let\folio=0 \turnoffactive \edef\next{\write\auxfile{\internalsetq {#1}{#2}}}% \next}} % \internalsetq {foo}{page} expands into % CHARACTERS 'xrdef {foo}{...expansion of \Ypage...} % When the aux file is read, ' is the escape character \def\internalsetq #1#2{'xrdef {#1}{\csname #2\endcsname}} % Things to be expanded by \internalsetq \def\Ypagenumber{\folio} \def\Ytitle{\thissection} \def\Ynothing{} \def\Ysectionnumberandtype{% \ifnum\secno=0 \putwordChapter\xreftie\the\chapno % \else \ifnum \subsecno=0 \putwordSection\xreftie\the\chapno.\the\secno % \else \ifnum \subsubsecno=0 % \putwordSection\xreftie\the\chapno.\the\secno.\the\subsecno % \else % \putwordSection\xreftie\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno % \fi \fi \fi } \def\Yappendixletterandtype{% \ifnum\secno=0 \putwordAppendix\xreftie'char\the\appendixno{}% \else \ifnum \subsecno=0 \putwordSection\xreftie'char\the\appendixno.\the\secno % \else \ifnum \subsubsecno=0 % \putwordSection\xreftie'char\the\appendixno.\the\secno.\the\subsecno % \else % \putwordSection\xreftie'char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno % \fi \fi \fi } \gdef\xreftie{'tie} % Use TeX 3.0's \inputlineno to get the line number, for better error % messages, but if we're using an old version of TeX, don't do anything. % \ifx\inputlineno\thisisundefined \let\linenumber = \empty % Non-3.0. \else \def\linenumber{\the\inputlineno:\space} \fi % Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME. % If its value is nonempty, SUFFIX is output afterward. \def\refx#1#2{% \expandafter\ifx\csname X#1\endcsname\relax % If not defined, say something at least. \angleleft un\-de\-fined\angleright \ifhavexrefs \message{\linenumber Undefined cross reference `#1'.}% \else \ifwarnedxrefs\else \global\warnedxrefstrue \message{Cross reference values unknown; you must run TeX again.}% \fi \fi \else % It's defined, so just use it. \csname X#1\endcsname \fi #2% Output the suffix in any case. } % This is the macro invoked by entries in the aux file. % \def\xrdef#1{\begingroup % Reenable \ as an escape while reading the second argument. \catcode`\\ = 0 \afterassignment\endgroup \expandafter\gdef\csname X#1\endcsname } % Read the last existing aux file, if any. No error if none exists. \def\readauxfile{\begingroup \catcode`\^^@=\other \catcode`\^^A=\other \catcode`\^^B=\other \catcode`\^^C=\other \catcode`\^^D=\other \catcode`\^^E=\other \catcode`\^^F=\other \catcode`\^^G=\other \catcode`\^^H=\other \catcode`\^^K=\other \catcode`\^^L=\other \catcode`\^^N=\other \catcode`\^^P=\other \catcode`\^^Q=\other \catcode`\^^R=\other \catcode`\^^S=\other \catcode`\^^T=\other \catcode`\^^U=\other \catcode`\^^V=\other \catcode`\^^W=\other \catcode`\^^X=\other \catcode`\^^Z=\other \catcode`\^^[=\other \catcode`\^^\=\other \catcode`\^^]=\other \catcode`\^^^=\other \catcode`\^^_=\other \catcode`\@=\other \catcode`\^=\other % It was suggested to define this as 7, which would allow ^^e4 etc. % in xref tags, i.e., node names. But since ^^e4 notation isn't % supported in the main text, it doesn't seem desirable. Furthermore, % that is not enough: for node names that actually contain a ^ % character, we would end up writing a line like this: 'xrdef {'hat % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first % argument, and \hat is not an expandable control sequence. It could % all be worked out, but why? Either we support ^^ or we don't. % % The other change necessary for this was to define \auxhat: % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter % and then to call \auxhat in \setq. % \catcode`\~=\other \catcode`\[=\other \catcode`\]=\other \catcode`\"=\other \catcode`\_=\other \catcode`\|=\other \catcode`\<=\other \catcode`\>=\other \catcode`\$=\other \catcode`\#=\other \catcode`\&=\other % `\+ does not work, so use 43. \catcode43=\other % Make the characters 128-255 be printing characters {% \count 1=128 \def\loop{% \catcode\count 1=\other \advance\count 1 by 1 \ifnum \count 1<256 \loop \fi }% }% % The aux file uses ' as the escape (for now). % Turn off \ as an escape so we do not lose on % entries which were dumped with control sequences in their names. % For example, 'xrdef {$\leq $-fun}{page ...} made by @defun ^^ % Reference to such entries still does not work the way one would wish, % but at least they do not bomb out when the aux file is read in. \catcode`\{=1 \catcode`\}=2 \catcode`\%=\other \catcode`\'=0 \catcode`\\=\other % \openin 1 \jobname.aux \ifeof 1 \else \closein 1 \input \jobname.aux \global\havexrefstrue \global\warnedobstrue \fi % Open the new aux file. TeX will close it automatically at exit. \openout\auxfile=\jobname.aux \endgroup} % Footnotes. \newcount \footnoteno % The trailing space in the following definition for supereject is % vital for proper filling; pages come out unaligned when you do a % pagealignmacro call if that space before the closing brace is % removed. (Generally, numeric constants should always be followed by a % space to prevent strange expansion errors.) \def\supereject{\par\penalty -20000\footnoteno =0 } % @footnotestyle is meaningful for info output only. \let\footnotestyle=\comment \let\ptexfootnote=\footnote {\catcode `\@=11 % % Auto-number footnotes. Otherwise like plain. \gdef\footnote{% \global\advance\footnoteno by \@ne \edef\thisfootno{$^{\the\footnoteno}$}% % % In case the footnote comes at the end of a sentence, preserve the % extra spacing after we do the footnote number. \let\@sf\empty \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\/\fi % % Remove inadvertent blank space before typesetting the footnote number. \unskip \thisfootno\@sf \footnotezzz }% % Don't bother with the trickery in plain.tex to not require the % footnote text as a parameter. Our footnotes don't need to be so general. % % Oh yes, they do; otherwise, @ifset and anything else that uses % \parseargline fail inside footnotes because the tokens are fixed when % the footnote is read. --karl, 16nov96. % \long\gdef\footnotezzz{\insert\footins\bgroup % We want to typeset this text as a normal paragraph, even if the % footnote reference occurs in (for example) a display environment. % So reset some parameters. \interlinepenalty\interfootnotelinepenalty \splittopskip\ht\strutbox % top baseline for broken footnotes \splitmaxdepth\dp\strutbox \floatingpenalty\@MM \leftskip\z@skip \rightskip\z@skip \spaceskip\z@skip \xspaceskip\z@skip \parindent\defaultparindent % % Hang the footnote text off the number. \hang \textindent{\thisfootno}% % % Don't crash into the line above the footnote text. Since this % expands into a box, it must come within the paragraph, lest it % provide a place where TeX can split the footnote. \footstrut \futurelet\next\fo@t } \def\fo@t{\ifcat\bgroup\noexpand\next \let\next\f@@t \else\let\next\f@t\fi \next} \def\f@@t{\bgroup\aftergroup\@foot\let\next} \def\f@t#1{#1\@foot} \def\@foot{\strut\egroup} }%end \catcode `\@=11 % Set the baselineskip to #1, and the lineskip and strut size % correspondingly. There is no deep meaning behind these magic numbers % used as factors; they just match (closely enough) what Knuth defined. % \def\lineskipfactor{.08333} \def\strutheightpercent{.70833} \def\strutdepthpercent {.29167} % \def\setleading#1{% \normalbaselineskip = #1\relax \normallineskip = \lineskipfactor\normalbaselineskip \normalbaselines \setbox\strutbox =\hbox{% \vrule width0pt height\strutheightpercent\baselineskip depth \strutdepthpercent \baselineskip }% } % @| inserts a changebar to the left of the current line. It should % surround any changed text. This approach does *not* work if the % change spans more than two lines of output. To handle that, we would % have adopt a much more difficult approach (putting marks into the main % vertical list for the beginning and end of each change). % \def\|{% % \vadjust can only be used in horizontal mode. \leavevmode % % Append this vertical mode material after the current line in the output. \vadjust{% % We want to insert a rule with the height and depth of the current % leading; that is exactly what \strutbox is supposed to record. \vskip-\baselineskip % % \vadjust-items are inserted at the left edge of the type. So % the \llap here moves out into the left-hand margin. \llap{% % % For a thicker or thinner bar, change the `1pt'. \vrule height\baselineskip width1pt % % This is the space between the bar and the text. \hskip 12pt }% }% } % For a final copy, take out the rectangles % that mark overfull boxes (in case you have decided % that the text looks ok even though it passes the margin). % \def\finalout{\overfullrule=0pt} % @image. We use the macros from epsf.tex to support this. % If epsf.tex is not installed and @image is used, we complain. % % Check for and read epsf.tex up front. If we read it only at @image % time, we might be inside a group, and then its definitions would get % undone and the next image would fail. \openin 1 = epsf.tex \ifeof 1 \else \closein 1 \def\epsfannounce{\toks0 = }% do not bother showing banner \input epsf.tex \fi % \newif\ifwarnednoepsf \newhelp\noepsfhelp{epsf.tex must be installed for images to work. It is also included in the Texinfo distribution, or you can get it from ftp://ftp.tug.org/tex/epsf.tex.} % % Only complain once about lack of epsf.tex. \def\image#1{% \ifx\epsfbox\undefined \ifwarnednoepsf \else \errhelp = \noepsfhelp \errmessage{epsf.tex not found, images will be ignored}% \global\warnednoepsftrue \fi \else \imagexxx #1,,,\finish \fi } % % Arguments to @image: % #1 is (mandatory) image filename; we tack on .eps extension. % #2 is (optional) width, #3 is (optional) height. % #4 is just the usual extra ignored arg for parsing this stuff. \def\imagexxx#1,#2,#3,#4\finish{% % \epsfbox itself resets \epsf?size at each figure. \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi \setbox0 = \hbox{\ignorespaces #3}\ifdim\wd0 > 0pt \epsfysize=#3\relax \fi \epsfbox{#1.eps}% } % End of control word definitions. \message{and turning on texinfo input format.} \def\openindices{% \newindex{cp}% \newcodeindex{fn}% \newcodeindex{vr}% \newcodeindex{tp}% \newcodeindex{ky}% \newcodeindex{pg}% } % Set some numeric style parameters, for 8.5 x 11 format. \hsize = 6in \hoffset = .25in \newdimen\defaultparindent \defaultparindent = 15pt \parindent = \defaultparindent \parskip 3pt plus 2pt minus 1pt \setleading{13.2pt} \advance\topskip by 1.2cm \chapheadingskip = 15pt plus 4pt minus 2pt \secheadingskip = 12pt plus 3pt minus 2pt \subsecheadingskip = 9pt plus 2pt minus 2pt % Prevent underfull vbox error messages. \vbadness=10000 % Following George Bush, just get rid of widows and orphans. \widowpenalty=10000 \clubpenalty=10000 % Use TeX 3.0's \emergencystretch to help line breaking, but if we're % using an old version of TeX, don't do anything. We want the amount of % stretch added to depend on the line length, hence the dependence on % \hsize. This makes it come to about 9pt for the 8.5x11 format. % \ifx\emergencystretch\thisisundefined % Allow us to assign to \emergencystretch anyway. \def\emergencystretch{\dimen0}% \else \emergencystretch = \hsize \divide\emergencystretch by 45 \fi % Use @smallbook to reset parameters for 7x9.5 format (or else 7x9.25) \def\smallbook{ \global\chapheadingskip = 15pt plus 4pt minus 2pt \global\secheadingskip = 12pt plus 3pt minus 2pt \global\subsecheadingskip = 9pt plus 2pt minus 2pt % \global\lispnarrowing = 0.3in \setleading{12pt} \advance\topskip by -1cm \global\parskip 2pt plus 1pt \global\hsize = 5in \global\vsize=7.5in \global\tolerance=700 \global\hfuzz=1pt \global\contentsrightmargin=0pt \global\deftypemargin=0pt \global\defbodyindent=.5cm % \global\pagewidth=\hsize \global\pageheight=\vsize % \global\let\smalllisp=\smalllispx \global\let\smallexample=\smalllispx \global\def\Esmallexample{\Esmalllisp} } % Use @afourpaper to print on European A4 paper. \def\afourpaper{ \global\tolerance=700 \global\hfuzz=1pt \setleading{12pt} \global\parskip 15pt plus 1pt \global\vsize= 53\baselineskip \advance\vsize by \topskip %\global\hsize= 5.85in % A4 wide 10pt \global\hsize= 6.5in \global\outerhsize=\hsize \global\advance\outerhsize by 0.5in \global\outervsize=\vsize \global\advance\outervsize by 0.6in \global\pagewidth=\hsize \global\pageheight=\vsize } \bindingoffset=0pt \normaloffset=\hoffset \pagewidth=\hsize \pageheight=\vsize % Allow control of the text dimensions. Parameters in order: textheight; % textwidth; voffset; hoffset; binding offset; topskip. % All require a dimension; % header is additional; added length extends the bottom of the page. \def\changepagesizes#1#2#3#4#5#6{ \global\vsize= #1 \global\topskip= #6 \advance\vsize by \topskip \global\voffset= #3 \global\hsize= #2 \global\outerhsize=\hsize \global\advance\outerhsize by 0.5in \global\outervsize=\vsize \global\advance\outervsize by 0.6in \global\pagewidth=\hsize \global\pageheight=\vsize \global\normaloffset= #4 \global\bindingoffset= #5} % A specific text layout, 24x15cm overall, intended for A4 paper. Top margin % 29mm, hence bottom margin 28mm, nominal side margin 3cm. \def\afourlatex {\global\tolerance=700 \global\hfuzz=1pt \setleading{12pt} \global\parskip 15pt plus 1pt \advance\baselineskip by 1.6pt \changepagesizes{237mm}{150mm}{3.6mm}{3.6mm}{3mm}{7mm} } % Use @afourwide to print on European A4 paper in wide format. \def\afourwide{\afourpaper \changepagesizes{9.5in}{6.5in}{\hoffset}{\normaloffset}{\bindingoffset}{7mm}} % Define macros to output various characters with catcode for normal text. \catcode`\"=\other \catcode`\~=\other \catcode`\^=\other \catcode`\_=\other \catcode`\|=\other \catcode`\<=\other \catcode`\>=\other \catcode`\+=\other \def\normaldoublequote{"} \def\normaltilde{~} \def\normalcaret{^} \def\normalunderscore{_} \def\normalverticalbar{|} \def\normalless{<} \def\normalgreater{>} \def\normalplus{+} % This macro is used to make a character print one way in ttfont % where it can probably just be output, and another way in other fonts, % where something hairier probably needs to be done. % % #1 is what to print if we are indeed using \tt; #2 is what to print % otherwise. Since all the Computer Modern typewriter fonts have zero % interword stretch (and shrink), and it is reasonable to expect all % typewriter fonts to have this, we can check that font parameter. % \def\ifusingtt#1#2{\ifdim \fontdimen3\the\font=0pt #1\else #2\fi} % Turn off all special characters except @ % (and those which the user can use as if they were ordinary). % Most of these we simply print from the \tt font, but for some, we can % use math or other variants that look better in normal text. \catcode`\"=\active \def\activedoublequote{{\tt \char '042}} \let"=\activedoublequote \catcode`\~=\active \def~{{\tt \char '176}} \chardef\hat=`\^ \catcode`\^=\active \def^{{\tt \hat}} \catcode`\_=\active \def_{\ifusingtt\normalunderscore\_} % Subroutine for the previous macro. \def\_{\leavevmode \kern.06em \vbox{\hrule width.3em height.1ex}} \catcode`\|=\active \def|{{\tt \char '174}} \chardef \less=`\< \catcode`\<=\active \def<{{\tt \less}} \chardef \gtr=`\> \catcode`\>=\active \def>{{\tt \gtr}} \catcode`\+=\active \def+{{\tt \char 43}} %\catcode 27=\active %\def^^[{$\diamondsuit$} % Set up an active definition for =, but don't enable it most of the time. {\catcode`\==\active \global\def={{\tt \char 61}}} \catcode`+=\active \catcode`\_=\active % If a .fmt file is being used, characters that might appear in a file % name cannot be active until we have parsed the command line. % So turn them off again, and have \everyjob (or @setfilename) turn them on. % \otherifyactive is called near the end of this file. \def\otherifyactive{\catcode`+=\other \catcode`\_=\other} \catcode`\@=0 % \rawbackslashxx output one backslash character in current font \global\chardef\rawbackslashxx=`\\ %{\catcode`\\=\other %@gdef@rawbackslashxx{\}} % \rawbackslash redefines \ as input to do \rawbackslashxx. {\catcode`\\=\active @gdef@rawbackslash{@let\=@rawbackslashxx }} % \normalbackslash outputs one backslash in fixed width font. \def\normalbackslash{{\tt\rawbackslashxx}} % Say @foo, not \foo, in error messages. \escapechar=`\@ % \catcode 17=0 % Define control-q \catcode`\\=\active % Used sometimes to turn off (effectively) the active characters % even after parsing them. @def@turnoffactive{@let"=@normaldoublequote @let\=@realbackslash @let~=@normaltilde @let^=@normalcaret @let_=@normalunderscore @let|=@normalverticalbar @let<=@normalless @let>=@normalgreater @let+=@normalplus} @def@normalturnoffactive{@let"=@normaldoublequote @let\=@normalbackslash @let~=@normaltilde @let^=@normalcaret @let_=@normalunderscore @let|=@normalverticalbar @let<=@normalless @let>=@normalgreater @let+=@normalplus} % Make _ and + \other characters, temporarily. % This is canceled by @fixbackslash. @otherifyactive % If a .fmt file is being used, we don't want the `\input texinfo' to show up. % That is what \eatinput is for; after that, the `\' should revert to printing % a backslash. % @gdef@eatinput input texinfo{@fixbackslash} @global@let\ = @eatinput % On the other hand, perhaps the file did not have a `\input texinfo'. Then % the first `\{ in the file would cause an error. This macro tries to fix % that, assuming it is called before the first `\' could plausibly occur. % Also back turn on active characters that might appear in the input % file name, in case not using a pre-dumped format. % @gdef@fixbackslash{@ifx\@eatinput @let\ = @normalbackslash @fi @catcode`+=@active @catcode`@_=@active} %% These look ok in all fonts, so just make them not special. The @rm below %% makes sure that the current font starts out as the newly loaded cmr10 @catcode`@$=@other @catcode`@%=@other @catcode`@&=@other @catcode`@#=@other @textfonts @rm @c Local variables: @c page-delimiter: "^\\\\message" @c End: texinfo-3.12/doc/info-stnd.texi0000444000175000017500000014211506360011352013710 0ustar gg\input texinfo @c -*-texinfo-*- @comment %**start of header @setfilename info-stnd.info @settitle GNU Info @set InfoProgVer 2.11 @paragraphindent none @footnotestyle end @synindex vr cp @synindex fn cp @synindex ky cp @comment %**end of header @comment $Id: info-stnd.texi,v 1.3 1997/07/06 21:49:30 karl Exp $ @dircategory Texinfo documentation system @direntry * info program: (info-stnd). Standalone Info-reading program. @end direntry @ifinfo This file documents GNU Info, a program for viewing the on-line formatted versions of Texinfo files. This documentation is different from the documentation for the Info reader that is part of GNU Emacs. If you do not know how to use Info, but have a working Info reader, you should read that documentation first. Copyright @copyright{} 1992, 93, 96, 97 Free Software Foundation, Inc. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. @ignore Permission is granted to process this file through TeX and print the results, provided the printed document carries a copying permission notice identical to this one except for the removal of this paragraph (this paragraph not being relevant to the printed manual). @end ignore Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided also that the sections entitled ``Copying'' and ``GNU General Public License'' are included exactly as in the original, and provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation. @end ifinfo @titlepage @title GNU Info User's Guide @subtitle For GNU Info version @value{InfoProgVer} @author Brian J. Fox (bfox@@ai.mit.edu) @page @vskip 0pt plus 1filll Copyright @copyright{} 1992, 1993, 1997 Free Software Foundation Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided also that the sections entitled ``Copying'' and ``GNU General Public License'' are included exactly as in the original, and provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation. @end titlepage @ifinfo @node Top, What is Info, , (dir) @top The GNU Info Program This file documents GNU Info, a program for viewing the on-line formatted versions of Texinfo files, version @value{InfoProgVer}. This documentation is different from the documentation for the Info reader that is part of GNU Emacs. @end ifinfo @menu * What is Info:: * Options:: Options you can pass on the command line. * Cursor Commands:: Commands which move the cursor within a node. * Scrolling Commands:: Commands for moving the node around in a window. * Node Commands:: Commands for selecting a new node. * Searching Commands:: Commands for searching an Info file. * Xref Commands:: Commands for selecting cross references. * Window Commands:: Commands which manipulate multiple windows. * Printing Nodes:: How to print out the contents of a node. * Miscellaneous Commands:: A few commands that defy categories. * Variables:: How to change the default behavior of Info. * GNU Info Global Index:: Global index containing keystrokes, command names, variable names, and general concepts. @end menu @node What is Info, Options, Top, Top @chapter What is Info? @iftex This file documents GNU Info, a program for viewing the on-line formatted versions of Texinfo files, version @value{InfoProgVer}. @end iftex @dfn{Info} is a program which is used to view Info files on an ASCII terminal. @dfn{Info files} are the result of processing Texinfo files with the program @code{makeinfo} or with one of the Emacs commands, such as @code{M-x texinfo-format-buffer}. Texinfo itself is a documentation system that uses a single source file to produce both on-line information and printed output. You can typeset and print the files that you read in Info.@refill @node Options, Cursor Commands, What is Info, Top @chapter Command Line Options @cindex command line options @cindex arguments, command line GNU Info accepts several options to control the initial node being viewed, and to specify which directories to search for Info files. Here is a template showing an invocation of GNU Info from the shell: @example info [--@var{option-name} @var{option-value}] @var{menu-item}@dots{} @end example The following @var{option-names} are available when invoking Info from the shell: @table @code @cindex directory path @item --directory @var{directory-path} @itemx -d @var{directory-path} Add @var{directory-path} to the list of directory paths searched when Info needs to find a file. You may issue @code{--directory} multiple times; once for each directory which contains Info files. Alternatively, you may specify a value for the environment variable @code{INFOPATH}; if @code{--directory} is not given, the value of @code{INFOPATH} is used. The value of @code{INFOPATH} is a colon separated list of directory names. If you do not supply @code{INFOPATH} or @code{--directory-path}, Info uses a default path. @item --file @var{filename} @itemx -f @var{filename} @cindex Info file, selecting Specify a particular Info file to visit. By default, Info visits the file @code{dir}; if you use this option, Info will start with @code{(@var{filename})Top} as the first file and node. @item --index-search @var{string} @cindex index search, selecting @cindex online help, using Info as Go to the index entry @var{string} in the Info file specified with @samp{--file}. If no such entry, print @samp{no entries found} and exit with nonzero status. This can used from another program as a way to provide online help. @item --node @var{nodename} @itemx -n @var{nodename} @cindex node, selecting Specify a particular node to visit in the initial file that Info loads. This is especially useful in conjunction with @code{--file}@footnote{Of course, you can specify both the file and node in a @code{--node} command; but don't forget to escape the open and close parentheses from the shell as in: @code{info --node "(emacs)Buffers"}}. You may specify @code{--node} multiple times; for an interactive Info, each @var{nodename} is visited in its own window, for a non-interactive Info (such as when @code{--output} is given) each @var{nodename} is processed sequentially. @item --output @var{filename} @itemx -o @var{filename} @cindex file, outputting to @cindex outputting to a file Specify @var{filename} as the name of a file to which to direct output. Each node that Info visits will be output to @var{filename} instead of interactively viewed. A value of @code{-} for @var{filename} specifies the standard output. @item --subnodes @cindex @code{--subnodes}, command line option This option only has meaning when given in conjunction with @code{--output}. It means to recursively output the nodes appearing in the menus of each node being output. Menu items which resolve to external Info files are not output, and neither are menu items which are members of an index. Each node is only output once. @item --help @itemx -h Produces a relatively brief description of the available Info options. @item --version @cindex version information Prints the version information of Info and exits. @item @var{menu-item} @cindex menu, following Info treats its remaining arguments as the names of menu items. The first argument is a menu item in the initial node visited, while the second argument is a menu item in the first argument's node. You can easily move to the node of your choice by specifying the menu names which describe the path to that node. For example, @example info emacs buffers @end example @noindent first selects the menu item @samp{Emacs} in the node @samp{(dir)Top}, and then selects the menu item @samp{Buffers} in the node @samp{(emacs)Top}. @end table @node Cursor Commands, Scrolling Commands, Options, Top @chapter Moving the Cursor @cindex cursor, moving Many people find that reading screens of text page by page is made easier when one is able to indicate particular pieces of text with some kind of pointing device. Since this is the case, GNU Info (both the Emacs and standalone versions) have several commands which allow you to move the cursor about the screen. The notation used in this manual to describe keystrokes is identical to the notation used within the Emacs manual, and the GNU Readline manual. @xref{Characters, , Character Conventions, emacs, the GNU Emacs Manual}, if you are unfamiliar with the notation. The following table lists the basic cursor movement commands in Info. Each entry consists of the key sequence you should type to execute the cursor movement, the @code{M-x}@footnote{@code{M-x} is also a command; it invokes @code{execute-extended-command}. @xref{M-x, , Executing an extended command, emacs, the GNU Emacs Manual}, for more detailed information.} command name (displayed in parentheses), and a short description of what the command does. All of the cursor motion commands can take an @dfn{numeric} argument (@pxref{Miscellaneous Commands, @code{universal-argument}}), to find out how to supply them. With a numeric argument, the motion commands are simply executed that many times; for example, a numeric argument of 4 given to @code{next-line} causes the cursor to move down 4 lines. With a negative numeric argument, the motion is reversed; an argument of -4 given to the @code{next-line} command would cause the cursor to move @emph{up} 4 lines. @table @asis @item @code{C-n} (@code{next-line}) @kindex C-n @findex next-line Move the cursor down to the next line. @item @code{C-p} (@code{prev-line}) @kindex C-p @findex prev-line Move the cursor up to the previous line. @item @code{C-a} (@code{beginning-of-line}) @kindex C-a, in Info windows @findex beginning-of-line Move the cursor to the start of the current line. @item @code{C-e} (@code{end-of-line}) @kindex C-e, in Info windows @findex end-of-line Move the cursor to the end of the current line. @item @code{C-f} (@code{forward-char}) @kindex C-f, in Info windows @findex forward-char Move the cursor forward a character. @item @code{C-b} (@code{backward-char}) @kindex C-b, in Info windows @findex backward-char Move the cursor backward a character. @item @code{M-f} (@code{forward-word}) @kindex M-f, in Info windows @findex forward-word Move the cursor forward a word. @item @code{M-b} (@code{backward-word}) @kindex M-b, in Info windows @findex backward-word Move the cursor backward a word. @item @code{M-<} (@code{beginning-of-node}) @itemx @code{b} @kindex b, in Info windows @kindex M-< @findex beginning-of-node Move the cursor to the start of the current node. @item @code{M->} (@code{end-of-node}) @kindex M-> @findex end-of-node Move the cursor to the end of the current node. @item @code{M-r} (@code{move-to-window-line}) @kindex M-r @findex move-to-window-line Move the cursor to a specific line of the window. Without a numeric argument, @code{M-r} moves the cursor to the start of the line in the center of the window. With a numeric argument of @var{n}, @code{M-r} moves the cursor to the start of the @var{n}th line in the window. @end table @node Scrolling Commands, Node Commands, Cursor Commands, Top @chapter Moving Text Within a Window @cindex scrolling Sometimes you are looking at a screenful of text, and only part of the current paragraph you are reading is visible on the screen. The commands detailed in this section are used to shift which part of the current node is visible on the screen. @table @asis @item @code{SPC} (@code{scroll-forward}) @itemx @code{C-v} @kindex SPC, in Info windows @kindex C-v @findex scroll-forward Shift the text in this window up. That is, show more of the node which is currently below the bottom of the window. With a numeric argument, show that many more lines at the bottom of the window; a numeric argument of 4 would shift all of the text in the window up 4 lines (discarding the top 4 lines), and show you four new lines at the bottom of the window. Without a numeric argument, @key{SPC} takes the bottom two lines of the window and places them at the top of the window, redisplaying almost a completely new screenful of lines. @item @code{DEL} (@code{scroll-backward}) @itemx @code{M-v} @kindex DEL, in Info windows @kindex M-v @findex scroll-backward Shift the text in this window down. The inverse of @code{scroll-forward}. @end table @cindex scrolling through node structure The @code{scroll-forward} and @code{scroll-backward} commands can also move forward and backward through the node structure of the file. If you press @key{SPC} while viewing the end of a node, or @key{DEL} while viewing the beginning of a node, what happens is controlled by the variable @code{scroll-behavior}. @xref{Variables, @code{scroll-behavior}}, for more information. @table @asis @item @code{C-l} (@code{redraw-display}) @kindex C-l @findex redraw-display Redraw the display from scratch, or shift the line containing the cursor to a specified location. With no numeric argument, @samp{C-l} clears the screen, and then redraws its entire contents. Given a numeric argument of @var{n}, the line containing the cursor is shifted so that it is on the @var{n}th line of the window. @item @code{C-x w} (@code{toggle-wrap}) @kindex C-w @findex toggle-wrap Toggles the state of line wrapping in the current window. Normally, lines which are longer than the screen width @dfn{wrap}, i.e., they are continued on the next line. Lines which wrap have a @samp{\} appearing in the rightmost column of the screen. You can cause such lines to be terminated at the rightmost column by changing the state of line wrapping in the window with @code{C-x w}. When a line which needs more space than one screen width to display is displayed, a @samp{$} appears in the rightmost column of the screen, and the remainder of the line is invisible. @end table @node Node Commands, Searching Commands, Scrolling Commands, Top @chapter Selecting a New Node @cindex nodes, selection of This section details the numerous Info commands which select a new node to view in the current window. The most basic node commands are @samp{n}, @samp{p}, @samp{u}, and @samp{l}. When you are viewing a node, the top line of the node contains some Info @dfn{pointers} which describe where the next, previous, and up nodes are. Info uses this line to move about the node structure of the file when you use the following commands: @table @asis @item @code{n} (@code{next-node}) @kindex n @findex next-node Select the `Next' node. @item @code{p} (@code{prev-node}) @kindex p @findex prev-node Select the `Prev' node. @item @code{u} (@code{up-node}) @kindex u @findex up-node Select the `Up' node. @end table You can easily select a node that you have already viewed in this window by using the @samp{l} command -- this name stands for "last", and actually moves through the list of already visited nodes for this window. @samp{l} with a negative numeric argument moves forward through the history of nodes for this window, so you can quickly step between two adjacent (in viewing history) nodes. @table @asis @item @code{l} (@code{history-node}) @kindex l @findex history-node Select the most recently selected node in this window. @end table Two additional commands make it easy to select the most commonly selected nodes; they are @samp{t} and @samp{d}. @table @asis @item @code{t} (@code{top-node}) @kindex t @findex top-node Select the node @samp{Top} in the current Info file. @item @code{d} (@code{dir-node}) @kindex d @findex dir-node Select the directory node (i.e., the node @samp{(dir)}). @end table Here are some other commands which immediately result in the selection of a different node in the current window: @table @asis @item @code{<} (@code{first-node}) @kindex < @findex first-node Selects the first node which appears in this file. This node is most often @samp{Top}, but it does not have to be. @item @code{>} (@code{last-node}) @kindex > @findex last-node Select the last node which appears in this file. @item @code{]} (@code{global-next-node}) @kindex ] @findex global-next-node Move forward or down through node structure. If the node that you are currently viewing has a @samp{Next} pointer, that node is selected. Otherwise, if this node has a menu, the first menu item is selected. If there is no @samp{Next} and no menu, the same process is tried with the @samp{Up} node of this node. @item @code{[} (@code{global-prev-node}) @kindex [ @findex global-prev-node Move backward or up through node structure. If the node that you are currently viewing has a @samp{Prev} pointer, that node is selected. Otherwise, if the node has an @samp{Up} pointer, that node is selected, and if it has a menu, the last item in the menu is selected. @end table You can get the same behavior as @code{global-next-node} and @code{global-prev-node} while simply scrolling through the file with @key{SPC} and @key{DEL}; @xref{Variables, @code{scroll-behavior}}, for more information. @table @asis @item @code{g} (@code{goto-node}) @kindex g @findex goto-node Read the name of a node and select it. No completion is done while reading the node name, since the desired node may reside in a separate file. The node must be typed exactly as it appears in the Info file. A file name may be included as with any node specification, for example @example @code{g(emacs)Buffers} @end example finds the node @samp{Buffers} in the Info file @file{emacs}. @item @code{C-x k} (@code{kill-node}) @kindex C-x k @findex kill-node Kill a node. The node name is prompted for in the echo area, with a default of the current node. @dfn{Killing} a node means that Info tries hard to forget about it, removing it from the list of history nodes kept for the window where that node is found. Another node is selected in the window which contained the killed node. @item @code{C-x C-f} (@code{view-file}) @kindex C-x C-f @findex view-file Read the name of a file and selects the entire file. The command @example @code{C-x C-f @var{filename}} @end example is equivalent to typing @example @code{g(@var{filename})*} @end example @item @code{C-x C-b} (@code{list-visited-nodes}) @kindex C-x C-b @findex list-visited-nodes Make a window containing a menu of all of the currently visited nodes. This window becomes the selected window, and you may use the standard Info commands within it. @item @code{C-x b} (@code{select-visited-node}) @kindex C-x b @findex select-visited-node Select a node which has been previously visited in a visible window. This is similar to @samp{C-x C-b} followed by @samp{m}, but no window is created. @end table @node Searching Commands, Xref Commands, Node Commands, Top @chapter Searching an Info File @cindex searching GNU Info allows you to search for a sequence of characters throughout an entire Info file, search through the indices of an Info file, or find areas within an Info file which discuss a particular topic. @table @asis @item @code{s} (@code{search}) @kindex s @findex search Read a string in the echo area and search for it. @item @code{C-s} (@code{isearch-forward}) @kindex C-s @findex isearch-forward Interactively search forward through the Info file for a string as you type it. @item @code{C-r} (@code{isearch-backward}) @kindex C-r @findex isearch-backward Interactively search backward through the Info file for a string as you type it. @item @code{i} (@code{index-search}) @kindex i @findex index-search Look up a string in the indices for this Info file, and select a node where the found index entry points to. @item @code{,} (@code{next-index-match}) @kindex , @findex next-index-match Move to the node containing the next matching index item from the last @samp{i} command. @end table The most basic searching command is @samp{s} (@code{search}). The @samp{s} command prompts you for a string in the echo area, and then searches the remainder of the Info file for an occurrence of that string. If the string is found, the node containing it is selected, and the cursor is left positioned at the start of the found string. Subsequent @samp{s} commands show you the default search string within @samp{[} and @samp{]}; pressing @key{RET} instead of typing a new string will use the default search string. @dfn{Incremental searching} is similar to basic searching, but the string is looked up while you are typing it, instead of waiting until the entire search string has been specified. @node Xref Commands, Window Commands, Searching Commands, Top @chapter Selecting Cross References We have already discussed the @samp{Next}, @samp{Prev}, and @samp{Up} pointers which appear at the top of a node. In addition to these pointers, a node may contain other pointers which refer you to a different node, perhaps in another Info file. Such pointers are called @dfn{cross references}, or @dfn{xrefs} for short. @menu * Parts of an Xref:: What a cross reference is made of. * Selecting Xrefs:: Commands for selecting menu or note items. @end menu @node Parts of an Xref, Selecting Xrefs, , Xref Commands @section Parts of an Xref Cross references have two major parts: the first part is called the @dfn{label}; it is the name that you can use to refer to the cross reference, and the second is the @dfn{target}; it is the full name of the node that the cross reference points to. The target is separated from the label by a colon @samp{:}; first the label appears, and then the target. For example, in the sample menu cross reference below, the single colon separates the label from the target. @example * Foo Label: Foo Target. More information about Foo. @end example Note the @samp{.} which ends the name of the target. The @samp{.} is not part of the target; it serves only to let Info know where the target name ends. A shorthand way of specifying references allows two adjacent colons to stand for a target name which is the same as the label name: @example * Foo Commands:: Commands pertaining to Foo. @end example In the above example, the name of the target is the same as the name of the label, in this case @code{Foo Commands}. You will normally see two types of cross reference while viewing nodes: @dfn{menu} references, and @dfn{note} references. Menu references appear within a node's menu; they begin with a @samp{*} at the beginning of a line, and continue with a label, a target, and a comment which describes what the contents of the node pointed to contains. Note references appear within the body of the node text; they begin with @code{*Note}, and continue with a label and a target. Like @samp{Next}, @samp{Prev}, and @samp{Up} pointers, cross references can point to any valid node. They are used to refer you to a place where more detailed information can be found on a particular subject. Here is a cross reference which points to a node within the Texinfo documentation: @xref{xref, , Writing an Xref, texinfo, the Texinfo Manual}, for more information on creating your own texinfo cross references. @node Selecting Xrefs, , Parts of an Xref, Xref Commands @section Selecting Xrefs The following table lists the Info commands which operate on menu items. @table @asis @item @code{1} (@code{menu-digit}) @itemx @code{2} @dots{} @code{9} @cindex 1 @dots{} 9, in Info windows @kindex 1 @dots{} 9, in Info windows @findex menu-digit Within an Info window, pressing a single digit, (such as @samp{1}), selects that menu item, and places its node in the current window. For convenience, there is one exception; pressing @samp{0} selects the @emph{last} item in the node's menu. @item @code{0} (@code{last-menu-item}) @kindex 0, in Info windows @findex last-menu-item Select the last item in the current node's menu. @item @code{m} (@code{menu-item}) @kindex m @findex menu-item Reads the name of a menu item in the echo area and selects its node. Completion is available while reading the menu label. @item @code{M-x find-menu} @findex find-menu Move the cursor to the start of this node's menu. @end table This table lists the Info commands which operate on note cross references. @table @asis @item @code{f} (@code{xref-item}) @itemx @code{r} @kindex f @kindex r @findex xref-item Reads the name of a note cross reference in the echo area and selects its node. Completion is available while reading the cross reference label. @end table Finally, the next few commands operate on menu or note references alike: @table @asis @item @code{TAB} (@code{move-to-next-xref}) @kindex TAB, in Info windows @findex move-to-next-xref Move the cursor to the start of the next nearest menu item or note reference in this node. You can then use @key{RET} (@code{select-reference-this-line}) to select the menu or note reference. @item @code{M-TAB} (@code{move-to-prev-xref}) @kindex M-TAB, in Info windows @findex move-to-prev-xref Move the cursor the start of the nearest previous menu item or note reference in this node. @item @code{RET} (@code{select-reference-this-line}) @kindex RET, in Info windows @findex select-reference-this-line Select the menu item or note reference appearing on this line. @end table @node Window Commands, Printing Nodes, Xref Commands, Top @chapter Manipulating Multiple Windows @cindex windows, manipulating A @dfn{window} is a place to show the text of a node. Windows have a view area where the text of the node is displayed, and an associated @dfn{mode line}, which briefly describes the node being viewed. GNU Info supports multiple windows appearing in a single screen; each window is separated from the next by its modeline. At any time, there is only one @dfn{active} window, that is, the window in which the cursor appears. There are commands available for creating windows, changing the size of windows, selecting which window is active, and for deleting windows. @menu * The Mode Line:: What appears in the mode line? * Basic Windows:: Manipulating windows in Info. * The Echo Area:: Used for displaying errors and reading input. @end menu @node The Mode Line, Basic Windows, , Window Commands @section The Mode Line A @dfn{mode line} is a line of inverse video which appears at the bottom of an Info window. It describes the contents of the window just above it; this information includes the name of the file and node appearing in that window, the number of screen lines it takes to display the node, and the percentage of text that is above the top of the window. It can also tell you if the indirect tags table for this Info file needs to be updated, and whether or not the Info file was compressed when stored on disk. Here is a sample mode line for a window containing an uncompressed file named @file{dir}, showing the node @samp{Top}. @example @group -----Info: (dir)Top, 40 lines --Top--------------------------------------- ^^ ^ ^^^ ^^ (file)Node #lines where @end group @end example When a node comes from a file which is compressed on disk, this is indicated in the mode line with two small @samp{z}'s. In addition, if the Info file containing the node has been split into subfiles, the name of the subfile containing the node appears in the modeline as well: @example --zz-Info: (emacs)Top, 291 lines --Top-- Subfile: emacs-1.Z--------------- @end example When Info makes a node internally, such that there is no corresponding info file on disk, the name of the node is surrounded by asterisks (@samp{*}). The name itself tells you what the contents of the window are; the sample mode line below shows an internally constructed node showing possible completions: @example -----Info: *Completions*, 7 lines --All----------------------------------- @end example @node Basic Windows, The Echo Area, The Mode Line, Window Commands @section Window Commands It can be convenient to view more than one node at a time. To allow this, Info can display more than one @dfn{window}. Each window has its own mode line (@pxref{The Mode Line}) and history of nodes viewed in that window (@pxref{Node Commands, , @code{history-node}}). @table @asis @item @code{C-x o} (@code{next-window}) @cindex windows, selecting @kindex C-x o @findex next-window Select the next window on the screen. Note that the echo area can only be selected if it is already in use, and you have left it temporarily. Normally, @samp{C-x o} simply moves the cursor into the next window on the screen, or if you are already within the last window, into the first window on the screen. Given a numeric argument, @samp{C-x o} moves over that many windows. A negative argument causes @samp{C-x o} to select the previous window on the screen. @item @code{M-x prev-window} @findex prev-window Select the previous window on the screen. This is identical to @samp{C-x o} with a negative argument. @item @code{C-x 2} (@code{split-window}) @cindex windows, creating @kindex C-x 2 @findex split-window Split the current window into two windows, both showing the same node. Each window is one half the size of the original window, and the cursor remains in the original window. The variable @code{automatic-tiling} can cause all of the windows on the screen to be resized for you automatically, please @pxref{Variables, , automatic-tiling} for more information. @item @code{C-x 0} (@code{delete-window}) @cindex windows, deleting @kindex C-x 0 @findex delete-window Delete the current window from the screen. If you have made too many windows and your screen appears cluttered, this is the way to get rid of some of them. @item @code{C-x 1} (@code{keep-one-window}) @kindex C-x 1 @findex keep-one-window Delete all of the windows excepting the current one. @item @code{ESC C-v} (@code{scroll-other-window}) @kindex ESC C-v, in Info windows @findex scroll-other-window Scroll the other window, in the same fashion that @samp{C-v} might scroll the current window. Given a negative argument, scroll the "other" window backward. @item @code{C-x ^} (@code{grow-window}) @kindex C-x ^ @findex grow-window Grow (or shrink) the current window. Given a numeric argument, grow the current window that many lines; with a negative numeric argument, shrink the window instead. @item @code{C-x t} (@code{tile-windows}) @cindex tiling @kindex C-x t @findex tile-windows Divide the available screen space among all of the visible windows. Each window is given an equal portion of the screen in which to display its contents. The variable @code{automatic-tiling} can cause @code{tile-windows} to be called when a window is created or deleted. @xref{Variables, , @code{automatic-tiling}}. @end table @node The Echo Area, , Basic Windows, Window Commands @section The Echo Area @cindex echo area The @dfn{echo area} is a one line window which appears at the bottom of the screen. It is used to display informative or error messages, and to read lines of input from you when that is necessary. Almost all of the commands available in the echo area are identical to their Emacs counterparts, so please refer to that documentation for greater depth of discussion on the concepts of editing a line of text. The following table briefly lists the commands that are available while input is being read in the echo area: @table @asis @item @code{C-f} (@code{echo-area-forward}) @kindex C-f, in the echo area @findex echo-area-forward Move forward a character. @item @code{C-b} (@code{echo-area-backward}) @kindex C-b, in the echo area @findex echo-area-backward Move backward a character. @item @code{C-a} (@code{echo-area-beg-of-line}) @kindex C-a, in the echo area @findex echo-area-beg-of-line Move to the start of the input line. @item @code{C-e} (@code{echo-area-end-of-line}) @kindex C-e, in the echo area @findex echo-area-end-of-line Move to the end of the input line. @item @code{M-f} (@code{echo-area-forward-word}) @kindex M-f, in the echo area @findex echo-area-forward-word Move forward a word. @item @code{M-b} (@code{echo-area-backward-word}) @kindex M-b, in the echo area @findex echo-area-backward-word Move backward a word. @item @code{C-d} (@code{echo-area-delete}) @kindex C-d, in the echo area @findex echo-area-delete Delete the character under the cursor. @item @code{DEL} (@code{echo-area-rubout}) @kindex DEL, in the echo area @findex echo-area-rubout Delete the character behind the cursor. @item @code{C-g} (@code{echo-area-abort}) @kindex C-g, in the echo area @findex echo-area-abort Cancel or quit the current operation. If completion is being read, @samp{C-g} discards the text of the input line which does not match any completion. If the input line is empty, @samp{C-g} aborts the calling function. @item @code{RET} (@code{echo-area-newline}) @kindex RET, in the echo area @findex echo-area-newline Accept (or forces completion of) the current input line. @item @code{C-q} (@code{echo-area-quoted-insert}) @kindex C-q, in the echo area @findex echo-area-quoted-insert Insert the next character verbatim. This is how you can insert control characters into a search string, for example. @item @var{printing character} (@code{echo-area-insert}) @kindex printing characters, in the echo area @findex echo-area-insert Insert the character. @item @code{M-TAB} (@code{echo-area-tab-insert}) @kindex M-TAB, in the echo area @findex echo-area-tab-insert Insert a TAB character. @item @code{C-t} (@code{echo-area-transpose-chars}) @kindex C-t, in the echo area @findex echo-area-transpose-chars Transpose the characters at the cursor. @end table The next group of commands deal with @dfn{killing}, and @dfn{yanking} text. For an in depth discussion of killing and yanking, @pxref{Killing, , Killing and Deleting, emacs, the GNU Emacs Manual} @table @asis @item @code{M-d} (@code{echo-area-kill-word}) @kindex M-d, in the echo area @findex echo-area-kill-word Kill the word following the cursor. @item @code{M-DEL} (@code{echo-area-backward-kill-word}) @kindex M-DEL, in the echo area @findex echo-area-backward-kill-word Kill the word preceding the cursor. @item @code{C-k} (@code{echo-area-kill-line}) @kindex C-k, in the echo area @findex echo-area-kill-line Kill the text from the cursor to the end of the line. @item @code{C-x DEL} (@code{echo-area-backward-kill-line}) @kindex C-x DEL, in the echo area @findex echo-area-backward-kill-line Kill the text from the cursor to the beginning of the line. @item @code{C-y} (@code{echo-area-yank}) @kindex C-y, in the echo area @findex echo-area-yank Yank back the contents of the last kill. @item @code{M-y} (@code{echo-area-yank-pop}) @kindex M-y, in the echo area @findex echo-area-yank-pop Yank back a previous kill, removing the last yanked text first. @end table Sometimes when reading input in the echo area, the command that needed input will only accept one of a list of several choices. The choices represent the @dfn{possible completions}, and you must respond with one of them. Since there are a limited number of responses you can make, Info allows you to abbreviate what you type, only typing as much of the response as is necessary to uniquely identify it. In addition, you can request Info to fill in as much of the response as is possible; this is called @dfn{completion}. The following commands are available when completing in the echo area: @table @asis @item @code{TAB} (@code{echo-area-complete}) @itemx @code{SPC} @kindex TAB, in the echo area @kindex SPC, in the echo area @findex echo-area-complete Insert as much of a completion as is possible. @item @code{?} (@code{echo-area-possible-completions}) @kindex ?, in the echo area @findex echo-area-possible-completions Display a window containing a list of the possible completions of what you have typed so far. For example, if the available choices are: @example @group bar foliate food forget @end group @end example @noindent and you have typed an @samp{f}, followed by @samp{?}, the possible completions would contain: @example @group foliate food forget @end group @end example @noindent i.e., all of the choices which begin with @samp{f}. Pressing @key{SPC} or @key{TAB} would result in @samp{fo} appearing in the echo area, since all of the choices which begin with @samp{f} continue with @samp{o}. Now, typing @samp{l} followed by @samp{TAB} results in @samp{foliate} appearing in the echo area, since that is the only choice which begins with @samp{fol}. @item @code{ESC C-v} (@code{echo-area-scroll-completions-window}) @kindex ESC C-v, in the echo area @findex echo-area-scroll-completions-window Scroll the completions window, if that is visible, or the "other" window if not. @end table @node Printing Nodes, Miscellaneous Commands, Window Commands, Top @chapter Printing Out Nodes @cindex printing You may wish to print out the contents of a node as a quick reference document for later use. Info provides you with a command for doing this. In general, we recommend that you use @TeX{} to format the document and print sections of it, by running @code{tex} on the Texinfo source file. @table @asis @item @code{M-x print-node} @findex print-node @cindex INFO_PRINT_COMMAND, environment variable Pipe the contents of the current node through the command in the environment variable @code{INFO_PRINT_COMMAND}. If the variable does not exist, the node is simply piped to @code{lpr}. @end table @node Miscellaneous Commands, Variables, Printing Nodes, Top @chapter Miscellaneous Commands GNU Info contains several commands which self-document GNU Info: @table @asis @item @code{M-x describe-command} @cindex functions, describing @cindex commands, describing @findex describe-command Read the name of an Info command in the echo area and then display a brief description of what that command does. @item @code{M-x describe-key} @cindex keys, describing @findex describe-key Read a key sequence in the echo area, and then display the name and documentation of the Info command that the key sequence invokes. @item @code{M-x describe-variable} Read the name of a variable in the echo area and then display a brief description of what the variable affects. @item @code{M-x where-is} @findex where-is Read the name of an Info command in the echo area, and then display a key sequence which can be typed in order to invoke that command. @item @code{C-h} (@code{get-help-window}) @itemx @code{?} @kindex C-h @kindex ?, in Info windows @findex get-help-window Create (or Move into) the window displaying @code{*Help*}, and place a node containing a quick reference card into it. This window displays the most concise information about GNU Info available. @item @code{h} (@code{get-info-help-node}) @kindex h @findex get-info-help-node Try hard to visit the node @code{(info)Help}. The Info file @file{info.texi} distributed with GNU Info contains this node. Of course, the file must first be processed with @code{makeinfo}, and then placed into the location of your Info directory. @end table Here are the commands for creating a numeric argument: @table @asis @item @code{C-u} (@code{universal-argument}) @cindex numeric arguments @kindex C-u @findex universal-argument Start (or multiply by 4) the current numeric argument. @samp{C-u} is a good way to give a small numeric argument to cursor movement or scrolling commands; @samp{C-u C-v} scrolls the screen 4 lines, while @samp{C-u C-u C-n} moves the cursor down 16 lines. @item @code{M-1} (@code{add-digit-to-numeric-arg}) @itemx @code{M-2} @dots{} @code{M-9} @kindex M-1 @dots{} M-9 @findex add-digit-to-numeric-arg Add the digit value of the invoking key to the current numeric argument. Once Info is reading a numeric argument, you may just type the digits of the argument, without the Meta prefix. For example, you might give @samp{C-l} a numeric argument of 32 by typing: @example @kbd{C-u 3 2 C-l} @end example @noindent or @example @kbd{M-3 2 C-l} @end example @end table @samp{C-g} is used to abort the reading of a multi-character key sequence, to cancel lengthy operations (such as multi-file searches) and to cancel reading input in the echo area. @table @asis @item @code{C-g} (@code{abort-key}) @cindex cancelling typeahead @cindex cancelling the current operation @kindex C-g, in Info windows @findex abort-key Cancel current operation. @end table The @samp{q} command of Info simply quits running Info. @table @asis @item @code{q} (@code{quit}) @cindex quitting @kindex q @findex quit Exit GNU Info. @end table If the operating system tells GNU Info that the screen is 60 lines tall, and it is actually only 40 lines tall, here is a way to tell Info that the operating system is correct. @table @asis @item @code{M-x set-screen-height} @findex set-screen-height @cindex screen, changing the height of Read a height value in the echo area and set the height of the displayed screen to that value. @end table Finally, Info provides a convenient way to display footnotes which might be associated with the current node that you are viewing: @table @asis @item @code{ESC C-f} (@code{show-footnotes}) @kindex ESC C-f @findex show-footnotes @cindex footnotes, displaying Show the footnotes (if any) associated with the current node in another window. You can have Info automatically display the footnotes associated with a node when the node is selected by setting the variable @code{automatic-footnotes}. @xref{Variables, , @code{automatic-footnotes}}. @end table @node Variables, GNU Info Global Index, Miscellaneous Commands, Top @chapter Manipulating Variables GNU Info contains several @dfn{variables} whose values are looked at by various Info commands. You can change the values of these variables, and thus change the behavior of Info to more closely match your environment and Info file reading manner. @table @asis @item @code{M-x set-variable} @cindex variables, setting @findex set-variable Read the name of a variable, and the value for it, in the echo area and then set the variable to that value. Completion is available when reading the variable name; often, completion is available when reading the value to give to the variable, but that depends on the variable itself. If a variable does @emph{not} supply multiple choices to complete over, it expects a numeric value. @item @code{M-x describe-variable} @cindex variables, describing @findex describe-variable Read the name of a variable in the echo area and then display a brief description of what the variable affects. @end table Here is a list of the variables that you can set in Info. @table @code @item automatic-footnotes @vindex automatic-footnotes When set to @code{On}, footnotes appear and disappear automatically. This variable is @code{On} by default. When a node is selected, a window containing the footnotes which appear in that node is created, and the footnotes are displayed within the new window. The window that Info creates to contain the footnotes is called @samp{*Footnotes*}. If a node is selected which contains no footnotes, and a @samp{*Footnotes*} window is on the screen, the @samp{*Footnotes*} window is deleted. Footnote windows created in this fashion are not automatically tiled so that they can use as little of the display as is possible. @item automatic-tiling @vindex automatic-tiling When set to @code{On}, creating or deleting a window resizes other windows. This variable is @code{Off} by default. Normally, typing @samp{C-x 2} divides the current window into two equal parts. When @code{automatic-tiling} is set to @code{On}, all of the windows are resized automatically, keeping an equal number of lines visible in each window. There are exceptions to the automatic tiling; specifically, the windows @samp{*Completions*} and @samp{*Footnotes*} are @emph{not} resized through automatic tiling; they remain their original size. @item visible-bell @vindex visible-bell When set to @code{On}, GNU Info attempts to flash the screen instead of ringing the bell. This variable is @code{Off} by default. Of course, Info can only flash the screen if the terminal allows it; in the case that the terminal does not allow it, the setting of this variable has no effect. However, you can make Info perform quietly by setting the @code{errors-ring-bell} variable to @code{Off}. @item errors-ring-bell @vindex errors-ring-bell When set to @code{On}, errors cause the bell to ring. The default setting of this variable is @code{On}. @item gc-compressed-files @vindex gc-compressed-files When set to @code{On}, Info garbage collects files which had to be uncompressed. The default value of this variable is @code{Off}. Whenever a node is visited in Info, the Info file containing that node is read into core, and Info reads information about the tags and nodes contained in that file. Once the tags information is read by Info, it is never forgotten. However, the actual text of the nodes does not need to remain in core unless a particular Info window needs it. For non-compressed files, the text of the nodes does not remain in core when it is no longer in use. But de-compressing a file can be a time consuming operation, and so Info tries hard not to do it twice. @code{gc-compressed-files} tells Info it is okay to garbage collect the text of the nodes of a file which was compressed on disk. @item show-index-match @vindex show-index-match When set to @code{On}, the portion of the matched search string is highlighted in the message which explains where the matched search string was found. The default value of this variable is @code{On}. When Info displays the location where an index match was found, (@pxref{Searching Commands, , @code{next-index-match}}), the portion of the string that you had typed is highlighted by displaying it in the inverse case from its surrounding characters. @item scroll-behavior @vindex scroll-behavior Control what happens when forward scrolling is requested at the end of a node, or when backward scrolling is requested at the beginning of a node. The default value for this variable is @code{Continuous}. There are three possible values for this variable: @table @code @item Continuous Try to get the first item in this node's menu, or failing that, the @samp{Next} node, or failing that, the @samp{Next} of the @samp{Up}. This behavior is identical to using the @samp{]} (@code{global-next-node}) and @samp{[} (@code{global-prev-node}) commands. @item Next Only Only try to get the @samp{Next} node. @item Page Only Simply give up, changing nothing. If @code{scroll-behavior} is @code{Page Only}, no scrolling command can change the node that is being viewed. @end table @item scroll-step @vindex scroll-step The number of lines to scroll when the cursor moves out of the window. Scrolling happens automatically if the cursor has moved out of the visible portion of the node text when it is time to display. Usually the scrolling is done so as to put the cursor on the center line of the current window. However, if the variable @code{scroll-step} has a nonzero value, Info attempts to scroll the node text by that many lines; if that is enough to bring the cursor back into the window, that is what is done. The default value of this variable is 0, thus placing the cursor (and the text it is attached to) in the center of the window. Setting this variable to 1 causes a kind of "smooth scrolling" which some people prefer. @item ISO-Latin @cindex ISO Latin characters @vindex ISO-Latin When set to @code{On}, Info accepts and displays ISO Latin characters. By default, Info assumes an ASCII character set. @code{ISO-Latin} tells Info that it is running in an environment where the European standard character set is in use, and allows you to input such characters to Info, as well as display them. @end table @c the following is incomplete @ignore @c node Info for Sys Admins @c chapter Info for System Administrators This text describes some common ways of setting up an Info hierarchy from scratch, and details the various options that are available when installing Info. This text is designed for the person who is installing GNU Info on the system; although users may find the information present in this section interesting, none of it is vital to understanding how to use GNU Info. @menu * Setting the INFOPATH:: Where are my Info files kept? * Editing the DIR node:: What goes in `DIR', and why? * Storing Info files:: Alternate formats allow flexibility in setups. * Using `localdir':: Building DIR on the fly. * Example setups:: Some common ways to organize Info files. @end menu @c node Setting the INFOPATH @c section Setting the INFOPATH Where are my Info files kept? @c node Editing the DIR node @c section Editing the DIR node What goes in `DIR', and why? @c node Storing Info files @c section Storing Info files Alternate formats allow flexibility in setups. @c node Using `localdir' @c section Using `localdir' Building DIR on the fly. @c node Example setups @c section Example setups Some common ways to organize Info files. @end ignore @node GNU Info Global Index, , Variables, Top @appendix Global Index @printindex cp @contents @bye texinfo-3.12/doc/texinfo.txi0000444000175000017500000222404406475627144013345 0ustar gg\input texinfo.tex @c -*-texinfo-*- @c $Id: texinfo.txi,v 1.50 1998/02/27 21:21:34 karl Exp $ @c %**start of header @c All text is ignored before the setfilename. @setfilename texinfo @settitle Texinfo @value{edition} @c Edition number is now the same as the Texinfo distribution version number. @set edition 3.12 @set update-month February 1998 @set update-date 27 @value{update-month} @c Define a new index for options. @defcodeindex op @c Put everything except function (command, in this case) names in one @c index (arbitrarily chosen to be the concept index). @syncodeindex op cp @syncodeindex vr cp @syncodeindex pg cp @footnotestyle separate @paragraphindent 2 @finalout @comment %**end of header @c Before release, run C-u C-c C-u C-a (texinfo-all-menus-update with a @c prefix arg). This updates the node pointers, which texinfmt.el needs. @dircategory Texinfo documentation system @direntry * Texinfo: (texinfo). The GNU documentation format. * install-info: (texinfo)Invoking install-info. Updating info/dir entries. * texi2dvi: (texinfo)Format with texi2dvi. Printing Texinfo documentation. * texindex: (texinfo)Format with tex/texindex. Sorting Texinfo index files. * makeinfo: (texinfo)makeinfo Preferred. Translate Texinfo source. @end direntry @c Set smallbook if printing in smallbook format so the example of the @c smallbook font is actually written using smallbook; in bigbook, a kludge @c is used for TeX output. Do this through the -t option to texi2dvi, @c so this same source can be used for other paper sizes as well. @c smallbook @c set smallbook @c @@clear smallbook @c Currently undocumented command, 5 December 1993: @c nwnode (Same as node, but no warnings; for `makeinfo'.) @ifinfo This file documents Texinfo, a documentation system that can produce both on-line information and a printed manual from a single source file. Copyright (C) 1988, 90, 91, 92, 93, 95, 96, 97, 98 Free Software Foundation, Inc. This edition is for Texinfo version @value{edition}. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. @ignore Permission is granted to process this file through TeX and print the results, provided the printed document carries copying permission notice identical to this one except for the removal of this paragraph (this paragraph not being relevant to the printed manual). @end ignore Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation. @end ifinfo @setchapternewpage odd @shorttitlepage Texinfo @titlepage @c use the new format for titles @title Texinfo @subtitle The GNU Documentation Format @subtitle for Texinfo version @value{edition} @subtitle @value{update-month} @author Robert J.@: Chassell @author Richard M.@: Stallman @c Include the Distribution inside the titlepage so @c that headings are turned off. @page @vskip 0pt plus 1filll Copyright @copyright{} 1988, 90, 91, 92, 93, 95, 96, 97, 98 Free Software Foundation, Inc. Published by the Free Software Foundation @* 59 Temple Place Suite 330 @* Boston, MA 02111-1307 @* USA @* ISBN 1-882114-65-5 @c ISBN 1-882114-63-9 is for edition 2.20 of 28 February 1995 @c ISBN 1-882114-64-7 is for edition 2.24 of November 1996. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation. @sp 2 Cover art by Etienne Suvasa. @end titlepage @ifinfo @node Top, Copying, (dir), (dir) @top Texinfo Texinfo is a documentation system that uses a single source file to produce both on-line information and printed output.@refill The first part of this master menu lists the major nodes in this Info document, including the @@-command and concept indices. The rest of the menu lists all the lower level nodes in the document.@refill This is Edition @value{edition} of the Texinfo documentation, @w{@value{update-date}}. @end ifinfo @c Here is a spare copy of the chapter menu entry descriptions, @c in case they are accidently deleted @ignore Your rights. Texinfo in brief. How to use Texinfo mode. What is at the beginning of a Texinfo file? What is at the end of a Texinfo file? How to create chapters, sections, subsections, appendices, and other parts. How to provide structure for a document. How to write nodes. How to write menus. How to write cross references. How to mark words and phrases as code, keyboard input, meta-syntactic variables, and the like. How to write quotations, examples, etc. How to write lists and tables. How to create indices. How to insert @@-signs, braces, etc. How to indicate results of evaluation, expansion of macros, errors, etc. How to force and prevent line and page breaks. How to describe functions and the like in a uniform manner. How to write footnotes. How to specify text for either @TeX{} or Info. How to print hardcopy. How to create an Info file. How to install an Info file A list of all the Texinfo @@-commands. Hints on how to write a Texinfo document. A sample Texinfo file to look at. Tell readers they have the right to copy and distribute. How to incorporate other Texinfo files. How to write page headings and footings. How to find formatting mistakes. All about paragraph refilling. A description of @@-Command syntax. Texinfo second edition features. A menu containing commands and variables. A menu covering many topics. @end ignore @menu * Copying:: Your rights. * Overview:: Texinfo in brief. * Texinfo Mode:: How to use Texinfo mode. * Beginning a File:: What is at the beginning of a Texinfo file? * Ending a File:: What is at the end of a Texinfo file? * Structuring:: How to create chapters, sections, subsections, appendices, and other parts. * Nodes:: How to write nodes. * Menus:: How to write menus. * Cross References:: How to write cross references. * Marking Text:: How to mark words and phrases as code, keyboard input, meta-syntactic variables, and the like. * Quotations and Examples:: How to write quotations, examples, etc. * Lists and Tables:: How to write lists and tables. * Indices:: How to create indices. * Insertions:: How to insert @@-signs, braces, etc. * Breaks:: How to force and prevent line and page breaks. * Definition Commands:: How to describe functions and the like in a uniform manner. * Footnotes:: How to write footnotes. * Conditionals:: How to specify text for either @TeX{} or Info. * Macros:: Defining new Texinfo commands. * Format/Print Hardcopy:: How to convert a Texinfo file to a file for printing and how to print that file. * Create an Info File:: Convert a Texinfo file into an Info file. * Install an Info File:: Make an Info file accessible to users. * Command List:: All the Texinfo @@-commands. * Tips:: Hints on how to write a Texinfo document. * Sample Texinfo File:: A sample Texinfo file to look at. * Sample Permissions:: Tell readers they have the right to copy and distribute. * Include Files:: How to incorporate other Texinfo files. * Headings:: How to write page headings and footings. * Catching Mistakes:: How to find formatting mistakes. * Refilling Paragraphs:: All about paragraph refilling. * Command Syntax:: A description of @@-Command syntax. * Obtaining TeX:: How to Obtain @TeX{}. * Command and Variable Index:: A menu containing commands and variables. * Concept Index:: A menu covering many topics. @detailmenu --- The Detailed Node Listing --- Overview of Texinfo * Using Texinfo:: Create a conventional printed book or an Info file. * Info Files:: What is an Info file? * Printed Books:: Characteristics of a printed book or manual. * Formatting Commands:: @@-commands are used for formatting. * Conventions:: General rules for writing a Texinfo file. * Comments:: How to write comments and mark regions that the formatting commands will ignore. * Minimum:: What a Texinfo file must have. * Six Parts:: Usually, a Texinfo file has six parts. * Short Sample:: A short sample Texinfo file. * Acknowledgements:: Using Texinfo Mode * Texinfo Mode Overview:: How Texinfo mode can help you. * Emacs Editing:: Texinfo mode adds to GNU Emacs' general purpose editing features. * Inserting:: How to insert frequently used @@-commands. * Showing the Structure:: How to show the structure of a file. * Updating Nodes and Menus:: How to update or create new nodes and menus. * Info Formatting:: How to format for Info. * Printing:: How to format and print part or all of a file. * Texinfo Mode Summary:: Summary of all the Texinfo mode commands. Updating Nodes and Menus * Updating Commands:: Five major updating commands. * Updating Requirements:: How to structure a Texinfo file for using the updating command. * Other Updating Commands:: How to indent descriptions, insert missing nodes lines, and update nodes in sequence. Beginning a Texinfo File * Four Parts:: Four parts begin a Texinfo file. * Sample Beginning:: Here is a sample beginning for a Texinfo file. * Header:: The very beginning of a Texinfo file. * Info Summary and Permissions:: Summary and copying permissions for Info. * Titlepage & Copyright Page:: Creating the title and copyright pages. * The Top Node:: Creating the `Top' node and master menu. * Software Copying Permissions:: Ensure that you and others continue to have the right to use and share software. The Texinfo File Header * First Line:: The first line of a Texinfo file. * Start of Header:: Formatting a region requires this. * setfilename:: Tell Info the name of the Info file. * settitle:: Create a title for the printed work. * setchapternewpage:: Start chapters on right-hand pages. * paragraphindent:: An option to specify paragraph indentation. * End of Header:: Formatting a region requires this. The Title and Copyright Pages * titlepage:: Create a title for the printed document. * titlefont center sp:: The @code{@@titlefont}, @code{@@center}, and @code{@@sp} commands. * title subtitle author:: The @code{@@title}, @code{@@subtitle}, and @code{@@author} commands. * Copyright & Permissions:: How to write the copyright notice and include copying permissions. * end titlepage:: Turn on page headings after the title and copyright pages. * headings on off:: An option for turning headings on and off and double or single sided printing. The `Top' Node and Master Menu * Title of Top Node:: Sketch what the file is about. * Master Menu Parts:: A master menu has three or more parts. Ending a Texinfo File * Printing Indices & Menus:: How to print an index in hardcopy and generate index menus in Info. * Contents:: How to create a table of contents. * File End:: How to mark the end of a file. Chapter Structuring * Tree Structuring:: A manual is like an upside down tree @dots{} * Structuring Command Types:: How to divide a manual into parts. * makeinfo top:: The @code{@@top} command, part of the `Top' node. * chapter:: * unnumbered & appendix:: * majorheading & chapheading:: * section:: * unnumberedsec appendixsec heading:: * subsection:: * unnumberedsubsec appendixsubsec subheading:: * subsubsection:: Commands for the lowest level sections. * Raise/lower sections:: How to change commands' hierarchical level. Nodes * Two Paths:: Different commands to structure Info output and printed output. * Node Menu Illustration:: A diagram, and sample nodes and menus. * node:: How to write a node, in detail. * makeinfo Pointer Creation:: How to create node pointers with @code{makeinfo}. The @code{@@node} Command * Node Names:: How to choose node and pointer names. * Writing a Node:: How to write an @code{@@node} line. * Node Line Tips:: Keep names short. * Node Line Requirements:: Keep names unique, without @@-commands. * First Node:: How to write a `Top' node. * makeinfo top command:: How to use the @code{@@top} command. * Top Node Summary:: Write a brief description for readers. Menus * Menu Location:: Put a menu in a short node. * Writing a Menu:: What is a menu? * Menu Parts:: A menu entry has three parts. * Less Cluttered Menu Entry:: Two part menu entry. * Menu Example:: Two and three part menu entries. * Other Info Files:: How to refer to a different Info file. Cross References * References:: What cross references are for. * Cross Reference Commands:: A summary of the different commands. * Cross Reference Parts:: A cross reference has several parts. * xref:: Begin a reference with `See' @dots{} * Top Node Naming:: How to refer to the beginning of another file. * ref:: A reference for the last part of a sentence. * pxref:: How to write a parenthetical cross reference. * inforef:: How to refer to an Info-only file. * uref:: How to refer to a uniform resource locator. @code{@@xref} * Reference Syntax:: What a reference looks like and requires. * One Argument:: @code{@@xref} with one argument. * Two Arguments:: @code{@@xref} with two arguments. * Three Arguments:: @code{@@xref} with three arguments. * Four and Five Arguments:: @code{@@xref} with four and five arguments. Marking Words and Phrases * Indicating:: How to indicate definitions, files, etc. * Emphasis:: How to emphasize text. Indicating Definitions, Commands, etc. * Useful Highlighting:: Highlighting provides useful information. * code:: How to indicate code. * kbd:: How to show keyboard input. * key:: How to specify keys. * samp:: How to show a literal sequence of characters. * var:: How to indicate a metasyntactic variable. * file:: How to indicate the name of a file. * dfn:: How to specify a definition. * cite:: How to refer to a book that is not in Info. * url:: How to indicate a world wide web reference. * email:: How to indicate an electronic mail address. Emphasizing Text * emph & strong:: How to emphasize text in Texinfo. * Smallcaps:: How to use the small caps font. * Fonts:: Various font commands for printed output. * Customized Highlighting:: How to define highlighting commands. Quotations and Examples * Block Enclosing Commands:: Use different constructs for different purposes. * quotation:: How to write a quotation. * example:: How to write an example in a fixed-width font. * noindent:: How to prevent paragraph indentation. * Lisp Example:: How to illustrate Lisp code. * smallexample & smalllisp:: Forms for the @code{@@smallbook} option. * display:: How to write an example in the current font. * format:: How to write an example that does not narrow the margins. * exdent:: How to undo the indentation of a line. * flushleft & flushright:: How to push text flushleft or flushright. * cartouche:: How to draw cartouches around examples. Lists and Tables * Introducing Lists:: Texinfo formats lists for you. * itemize:: How to construct a simple list. * enumerate:: How to construct a numbered list. * Two-column Tables:: How to construct a two-column table. * Multi-column Tables:: How to construct generalized tables. Making a Two-column Table * table:: How to construct a two-column table. * ftable vtable:: Automatic indexing for two-column tables. * itemx:: How to put more entries in the first column. Multi-column Tables * Multitable Column Widths:: Defining multitable column widths. * Multitable Rows:: Defining multitable rows, with examples. Creating Indices * Index Entries:: Choose different words for index entries. * Predefined Indices:: Use different indices for different kinds of entry. * Indexing Commands:: How to make an index entry. * Combining Indices:: How to combine indices. * New Indices:: How to define your own indices. Combining Indices * syncodeindex:: How to merge two indices, using @code{@@code} font for the merged-from index. * synindex:: How to merge two indices, using the default font of the merged-to index. Special Insertions * Braces Atsigns:: How to insert braces, @samp{@@}. * Inserting Space:: How to insert the right amount of space within a sentence. * Inserting Accents:: How to insert accents and special characters. * Dots Bullets:: How to insert dots and bullets. * TeX and copyright:: How to insert the @TeX{} logo and the copyright symbol. * pounds:: How to insert the pounds currency symbol. * minus:: How to insert a minus sign. * math:: How to format a mathematical expression. * Glyphs:: How to indicate results of evaluation, expansion of macros, errors, etc. * Images:: How to include graphics. Inserting @@ and Braces * Inserting An Atsign:: How to insert @samp{@@}. * Inserting Braces:: How to insert @samp{@{} and @samp{@}}. Inserting Space * Not Ending a Sentence:: Sometimes a . doesn't end a sentence. * Ending a Sentence:: Sometimes it does. * Multiple Spaces:: Inserting multiple spaces. * dmn:: How to format a dimension. Inserting Ellipsis, Dots, and Bullets * dots:: How to insert dots @dots{} * bullet:: How to insert a bullet. Inserting @TeX{} and the Copyright Symbol * tex:: How to insert the @TeX{} logo. * copyright symbol:: How to use @code{@@copyright}@{@}. Glyphs for Examples * Glyphs Summary:: * result:: How to show the result of expression. * expansion:: How to indicate an expansion. * Print Glyph:: How to indicate printed output. * Error Glyph:: How to indicate an error message. * Equivalence:: How to indicate equivalence. * Point Glyph:: How to indicate the location of point. Glyphs Summary * result:: * expansion:: * Print Glyph:: * Error Glyph:: * Equivalence:: * Point Glyph:: Making and Preventing Breaks * Break Commands:: Cause and prevent splits. * Line Breaks:: How to force a single line to use two lines. * - and hyphenation:: How to tell TeX about hyphenation points. * w:: How to prevent unwanted line breaks. * sp:: How to insert blank lines. * page:: How to force the start of a new page. * group:: How to prevent unwanted page breaks. * need:: Another way to prevent unwanted page breaks. Definition Commands * Def Cmd Template:: How to structure a description using a definition command. * Optional Arguments:: How to handle optional and repeated arguments. * deffnx:: How to group two or more `first' lines. * Def Cmds in Detail:: All the definition commands. * Def Cmd Conventions:: Conventions for writing definitions. * Sample Function Definition:: The Definition Commands * Functions Commands:: Commands for functions and similar entities. * Variables Commands:: Commands for variables and similar entities. * Typed Functions:: Commands for functions in typed languages. * Typed Variables:: Commands for variables in typed languages. * Abstract Objects:: Commands for object-oriented programming. * Data Types:: The definition command for data types. Footnotes * Footnote Commands:: How to write a footnote in Texinfo. * Footnote Styles:: Controlling how footnotes appear in Info. Conditionally Visible Text * Conditional Commands:: Specifying text for HTML, Info, or @TeX{}. * Conditional Not Commands:: Specifying text for not HTML, Info, or @TeX{}. * Raw Formatter Commands:: Using raw @TeX{} or HTML commands. * set clear value:: Designating which text to format (for all output formats); and how to set a flag to a string that you can insert. @code{@@set}, @code{@@clear}, and @code{@@value} * ifset ifclear:: Format a region if a flag is set. * value:: Replace a flag with a string. * value Example:: An easy way to update edition information. Macros: Defining New Texinfo Commands * Defining Macros:: Both defining and undefining new commands. * Invoking Macros:: Using a macro, once you've defined it. Format and Print Hardcopy * Use TeX:: Use @TeX{} to format for hardcopy. * Format with tex/texindex:: How to format in a shell. * Format with texi2dvi:: A simpler way to use the shell. * Print with lpr:: How to print. * Within Emacs:: How to format and print from an Emacs shell. * Texinfo Mode Printing:: How to format and print in Texinfo mode. * Compile-Command:: How to print using Emacs's compile command. * Requirements Summary:: @TeX{} formatting requirements summary. * Preparing for TeX:: What you need to do to use @TeX{}. * Overfull hboxes:: What are and what to do with overfull hboxes. * smallbook:: How to print small format books and manuals. * A4 Paper:: How to print on European A4 paper. * Cropmarks and Magnification:: How to print marks to indicate the size of pages and how to print scaled up output. Creating an Info File * makeinfo advantages:: @code{makeinfo} provides better error checking. * Invoking makeinfo:: How to run @code{makeinfo} from a shell. * makeinfo options:: Specify fill-column and other options. * Pointer Validation:: How to check that pointers point somewhere. * makeinfo in Emacs:: How to run @code{makeinfo} from Emacs. * texinfo-format commands:: Two Info formatting commands written in Emacs Lisp are an alternative to @code{makeinfo}. * Batch Formatting:: How to format for Info in Emacs Batch mode. * Tag and Split Files:: How tagged and split files help Info to run better. Installing an Info File * Directory file:: The top level menu for all Info files. * New Info File:: Listing a new info file. * Other Info Directories:: How to specify Info files that are located in other directories. * Installing Dir Entries:: How to specify what menu entry to add to the Info directory. * Invoking install-info:: @code{install-info} options. Sample Permissions * Inserting Permissions:: How to put permissions in your document. * ifinfo Permissions:: Sample @samp{ifinfo} copying permissions. * Titlepage Permissions:: Sample Titlepage copying permissions. Include Files * Using Include Files:: How to use the @code{@@include} command. * texinfo-multiple-files-update:: How to create and update nodes and menus when using included files. * Include File Requirements:: What @code{texinfo-multiple-files-update} expects. * Sample Include File:: A sample outer file with included files within it; and a sample included file. * Include Files Evolution:: How use of the @code{@@include} command has changed over time. Page Headings * Headings Introduced:: Conventions for using page headings. * Heading Format:: Standard page heading formats. * Heading Choice:: How to specify the type of page heading. * Custom Headings:: How to create your own headings and footings. Formatting Mistakes * makeinfo Preferred:: @code{makeinfo} finds errors. * Debugging with Info:: How to catch errors with Info formatting. * Debugging with TeX:: How to catch errors with @TeX{} formatting. * Using texinfo-show-structure:: How to use @code{texinfo-show-structure}. * Using occur:: How to list all lines containing a pattern. * Running Info-Validate:: How to find badly referenced nodes. Finding Badly Referenced Nodes * Using Info-validate:: How to run @code{Info-validate}. * Unsplit:: How to create an unsplit file. * Tagifying:: How to tagify a file. * Splitting:: How to split a file manually. How to Obtain @TeX{} * New Texinfo Mode Commands:: The updating commands are especially useful. * New Commands:: Many newly described @@-commands. @end detailmenu @end menu @node Copying, Overview, Top, Top @comment node-name, next, previous, up @unnumbered Texinfo Copying Conditions @cindex Copying conditions @cindex Conditions for copying Texinfo The programs currently being distributed that relate to Texinfo include portions of GNU Emacs, plus other separate programs (including @code{makeinfo}, @code{info}, @code{texindex}, and @file{texinfo.tex}). These programs are @dfn{free}; this means that everyone is free to use them and free to redistribute them on a free basis. The Texinfo-related programs are not in the public domain; they are copyrighted and there are restrictions on their distribution, but these restrictions are designed to permit everything that a good cooperating citizen would want to do. What is not allowed is to try to prevent others from further sharing any version of these programs that they might get from you.@refill Specifically, we want to make sure that you have the right to give away copies of the programs that relate to Texinfo, that you receive source code or else can get it if you want it, that you can change these programs or use pieces of them in new free programs, and that you know you can do these things.@refill To make sure that everyone has such rights, we have to forbid you to deprive anyone else of these rights. For example, if you distribute copies of the Texinfo related programs, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must tell them their rights.@refill Also, for our own protection, we must make certain that everyone finds out that there is no warranty for the programs that relate to Texinfo. If these programs are modified by someone else and passed on, we want their recipients to know that what they have is not what we distributed, so that any problems introduced by others will not reflect on our reputation.@refill The precise conditions of the licenses for the programs currently being distributed that relate to Texinfo are found in the General Public Licenses that accompany them.@refill @node Overview, Texinfo Mode, Copying, Top @comment node-name, next, previous, up @chapter Overview of Texinfo @cindex Overview of Texinfo @cindex Texinfo overview @dfn{Texinfo}@footnote{Note that the first syllable of ``Texinfo'' is pronounced like ``speck'', not ``hex''. This odd pronunciation is derived from, but is not the same as, the pronunciation of @TeX{}. In the word @TeX{}, the @samp{X} is actually the Greek letter ``chi'' rather than the English letter ``ex''. Pronounce @TeX{} as if the @samp{X} were the last sound in the name `Bach'; but pronounce Texinfo as if the @samp{x} were a `k'. Spell ``Texinfo'' with a capital ``T'' and write the other letters in lower case.} is a documentation system that uses a single source file to produce both on-line information and printed output. This means that instead of writing two different documents, one for the on-line help or other on-line information and the other for a typeset manual or other printed work, you need write only one document. When the work is revised, you need revise only one document. (You can read the on-line information, known as an @dfn{Info file}, with an Info documentation-reading program.)@refill @menu * Using Texinfo:: Create a conventional printed book or an Info file. * Info Files:: What is an Info file? * Printed Books:: Characteristics of a printed book or manual. * Formatting Commands:: @@-commands are used for formatting. * Conventions:: General rules for writing a Texinfo file. * Comments:: How to write comments and mark regions that the formatting commands will ignore. * Minimum:: What a Texinfo file must have. * Six Parts:: Usually, a Texinfo file has six parts. * Short Sample:: A short sample Texinfo file. * Acknowledgements:: @end menu @node Using Texinfo, Info Files, Overview, Overview @ifinfo @heading Using Texinfo @end ifinfo Using Texinfo, you can create a printed document with the normal features of a book, including chapters, sections, cross references, and indices. From the same Texinfo source file, you can create a menu-driven, on-line Info file with nodes, menus, cross references, and indices. You can, if you wish, make the chapters and sections of the printed document correspond to the nodes of the on-line information; and you use the same cross references and indices for both the Info file and the printed work. @cite{The GNU Emacs Manual} is a good example of a Texinfo file, as is this manual.@refill To make a printed document, you process a Texinfo source file with the @TeX{} typesetting program. This creates a DVI file that you can typeset and print as a book or report. (Note that the Texinfo language is completely different from @TeX{}'s usual language, plain @TeX{}.) If you do not have @TeX{}, but do have @code{troff} or @code{nroff}, you can use the @code{texi2roff} program instead.@refill To make an Info file, you process a Texinfo source file with the @code{makeinfo} utility or Emacs's @code{texinfo-format-buffer} command; this creates an Info file that you can install on-line.@refill @TeX{} and @code{texi2roff} work with many types of printers; similarly, Info works with almost every type of computer terminal. This power makes Texinfo a general purpose system, but brings with it a constraint, which is that a Texinfo file may contain only the customary ``typewriter'' characters (letters, numbers, spaces, and punctuation marks) but no special graphics.@refill A Texinfo file is a plain @sc{ascii} file containing text and @dfn{@@-commands} (words preceded by an @samp{@@}) that tell the typesetting and formatting programs what to do. You may edit a Texinfo file with any text editor; but it is especially convenient to use GNU Emacs since that editor has a special mode, called Texinfo mode, that provides various Texinfo-related features. (@xref{Texinfo Mode}.)@refill Before writing a Texinfo source file, you should become familiar with the Info documentation reading program and learn about nodes, menus, cross references, and the rest. (@inforef{Top, info, info}, for more information.)@refill You can use Texinfo to create both on-line help and printed manuals; moreover, Texinfo is freely redistributable. For these reasons, Texinfo is the format in which documentation for GNU utilities and libraries is written.@refill @node Info Files, Printed Books, Using Texinfo, Overview @comment node-name, next, previous, up @section Info files @cindex Info files An Info file is a Texinfo file formatted so that the Info documentation reading program can operate on it. (@code{makeinfo} and @code{texinfo-format-buffer} are two commands that convert a Texinfo file into an Info file.)@refill Info files are divided into pieces called @dfn{nodes}, each of which contains the discussion of one topic. Each node has a name, and contains both text for the user to read and pointers to other nodes, which are identified by their names. The Info program displays one node at a time, and provides commands with which the user can move to other related nodes.@refill @ifinfo @inforef{Top, info, info}, for more information about using Info.@refill @end ifinfo Each node of an Info file may have any number of child nodes that describe subtopics of the node's topic. The names of child nodes are listed in a @dfn{menu} within the parent node; this allows you to use certain Info commands to move to one of the child nodes. Generally, an Info file is organized like a book. If a node is at the logical level of a chapter, its child nodes are at the level of sections; likewise, the child nodes of sections are at the level of subsections.@refill All the children of any one parent are linked together in a bidirectional chain of `Next' and `Previous' pointers. The `Next' pointer provides a link to the next section, and the `Previous' pointer provides a link to the previous section. This means that all the nodes that are at the level of sections within a chapter are linked together. Normally the order in this chain is the same as the order of the children in the parent's menu. Each child node records the parent node name as its `Up' pointer. The last child has no `Next' pointer, and the first child has the parent both as its `Previous' and as its `Up' pointer.@footnote{In some documents, the first child has no `Previous' pointer. Occasionally, the last child has the node name of the next following higher level node as its `Next' pointer.}@refill The book-like structuring of an Info file into nodes that correspond to chapters, sections, and the like is a matter of convention, not a requirement. The `Up', `Previous', and `Next' pointers of a node can point to any other nodes, and a menu can contain any other nodes. Thus, the node structure can be any directed graph. But it is usually more comprehensible to follow a structure that corresponds to the structure of chapters and sections in a printed book or report.@refill In addition to menus and to `Next', `Previous', and `Up' pointers, Info provides pointers of another kind, called references, that can be sprinkled throughout the text. This is usually the best way to represent links that do not fit a hierarchical structure.@refill Usually, you will design a document so that its nodes match the structure of chapters and sections in the printed output. But occasionally there are times when this is not right for the material being discussed. Therefore, Texinfo uses separate commands to specify the node structure for the Info file and the section structure for the printed output.@refill Generally, you enter an Info file through a node that by convention is named `Top'. This node normally contains just a brief summary of the file's purpose, and a large menu through which the rest of the file is reached. From this node, you can either traverse the file systematically by going from node to node, or you can go to a specific node listed in the main menu, or you can search the index menus and then go directly to the node that has the information you want. Alternatively, with the standalone Info program, you can specify specific menu items on the command line (@pxref{Top,,, info, Info}). If you want to read through an Info file in sequence, as if it were a printed manual, you can hit @key{SPC} repeatedly, or you get the whole file with the advanced Info command @kbd{g *}. (@inforef{Expert, Advanced Info commands, info}.)@refill @c !!! dir file may be located in one of many places: @c /usr/local/emacs/info mentioned in info.c DEFAULT_INFOPATH @c /usr/local/lib/emacs/info mentioned in info.c DEFAULT_INFOPATH @c /usr/gnu/info mentioned in info.c DEFAULT_INFOPATH @c /usr/local/info @c /usr/local/lib/info The @file{dir} file in the @file{info} directory serves as the departure point for the whole Info system. From it, you can reach the `Top' nodes of each of the documents in a complete Info system.@refill @node Printed Books, Formatting Commands, Info Files, Overview @comment node-name, next, previous, up @section Printed Books @cindex Printed book and manual characteristics @cindex Manual characteristics, printed @cindex Book characteristics, printed @cindex Texinfo printed book characteristics @cindex Characteristics, printed books or manuals @cindex Knuth, Donald A Texinfo file can be formatted and typeset as a printed book or manual. To do this, you need @TeX{}, a powerful, sophisticated typesetting program written by Donald Knuth.@footnote{You can also use the @code{texi2roff} program if you do not have @TeX{}; since Texinfo is designed for use with @TeX{}, @code{texi2roff} is not described here. @code{texi2roff} is not part of the standard GNU distribution.} A Texinfo-based book is similar to any other typeset, printed work: it can have a title page, copyright page, table of contents, and preface, as well as chapters, numbered or unnumbered sections and subsections, page headers, cross references, footnotes, and indices.@refill You can use Texinfo to write a book without ever having the intention of converting it into on-line information. You can use Texinfo for writing a printed novel, and even to write a printed memo, although this latter application is not recommended since electronic mail is so much easier.@refill @TeX{} is a general purpose typesetting program. Texinfo provides a file called @file{texinfo.tex} that contains information (definitions or @dfn{macros}) that @TeX{} uses when it typesets a Texinfo file. (@file{texinfo.tex} tells @TeX{} how to convert the Texinfo @@-commands to @TeX{} commands, which @TeX{} can then process to create the typeset document.) @file{texinfo.tex} contains the specifications for printing a document.@refill Most often, documents are printed on 8.5 inch by 11 inch pages (216@dmn{mm} by 280@dmn{mm}; this is the default size), but you can also print for 7 inch by 9.25 inch pages (178@dmn{mm} by 235@dmn{mm}; the @code{@@smallbook} size) or on European A4 size paper (@code{@@afourpaper}). (@xref{smallbook, , Printing ``Small'' Books}. Also, see @ref{A4 Paper, ,Printing on A4 Paper}.)@refill By changing the parameters in @file{texinfo.tex}, you can change the size of the printed document. In addition, you can change the style in which the printed document is formatted; for example, you can change the sizes and fonts used, the amount of indentation for each paragraph, the degree to which words are hyphenated, and the like. By changing the specifications, you can make a book look dignified, old and serious, or light-hearted, young and cheery.@refill @TeX{} is freely distributable. It is written in a superset of Pascal called WEB and can be compiled either in Pascal or (by using a conversion program that comes with the @TeX{} distribution) in C. (@xref{TeX Mode, ,@TeX{} Mode, emacs, The GNU Emacs Manual}, for information about @TeX{}.)@refill @TeX{} is very powerful and has a great many features. Because a Texinfo file must be able to present information both on a character-only terminal in Info form and in a typeset book, the formatting commands that Texinfo supports are necessarily limited.@refill @xref{Obtaining TeX, , How to Obtain @TeX{}}. @node Formatting Commands, Conventions, Printed Books, Overview @comment node-name, next, previous, up @section @@-commands @cindex @@-commands @cindex Formatting commands In a Texinfo file, the commands that tell @TeX{} how to typeset the printed manual and tell @code{makeinfo} and @code{texinfo-format-buffer} how to create an Info file are preceded by @samp{@@}; they are called @dfn{@@-commands}. For example, @code{@@node} is the command to indicate a node and @code{@@chapter} is the command to indicate the start of a chapter.@refill @quotation @strong{Please note:} All the @@-commands, with the exception of the @code{@@TeX@{@}} command, must be written entirely in lower case.@refill @end quotation The Texinfo @@-commands are a strictly limited set of constructs. The strict limits make it possible for Texinfo files to be understood both by @TeX{} and by the code that converts them into Info files. You can display Info files on any terminal that displays alphabetic and numeric characters. Similarly, you can print the output generated by @TeX{} on a wide variety of printers.@refill Depending on what they do or what arguments@footnote{The word @dfn{argument} comes from the way it is used in mathematics and does not refer to a disputation between two people; it refers to the information presented to the command. According to the @cite{Oxford English Dictionary}, the word derives from the Latin for @dfn{to make clear, prove}; thus it came to mean `the evidence offered as proof', which is to say, `the information offered', which led to its mathematical meaning. In its other thread of derivation, the word came to mean `to assert in a manner against which others may make counter assertions', which led to the meaning of `argument' as a disputation.} they take, you need to write @@-commands on lines of their own or as part of sentences:@refill @itemize @bullet @item Write a command such as @code{@@noindent} at the beginning of a line as the only text on the line. (@code{@@noindent} prevents the beginning of the next line from being indented as the beginning of a paragraph.)@refill @item Write a command such as @code{@@chapter} at the beginning of a line followed by the command's arguments, in this case the chapter title, on the rest of the line. (@code{@@chapter} creates chapter titles.)@refill @item Write a command such as @code{@@dots@{@}} wherever you wish but usually within a sentence. (@code{@@dots@{@}} creates dots @dots{})@refill @item Write a command such as @code{@@code@{@var{sample-code}@}} wherever you wish (but usually within a sentence) with its argument, @var{sample-code} in this example, between the braces. (@code{@@code} marks text as being code.)@refill @item Write a command such as @code{@@example} at the beginning of a line of its own; write the body-text on following lines; and write the matching @code{@@end} command, @code{@@end example} in this case, at the beginning of a line of its own after the body-text. (@code{@@example} @dots{} @code{@@end example} indents and typesets body-text as an example.)@refill @end itemize @noindent @cindex Braces, when to use As a general rule, a command requires braces if it mingles among other text; but it does not need braces if it starts a line of its own. The non-alphabetic commands, such as @code{@@:}, are exceptions to the rule; they do not need braces.@refill As you gain experience with Texinfo, you will rapidly learn how to write the different commands: the different ways to write commands make it easier to write and read Texinfo files than if all commands followed exactly the same syntax. (For details about @@-command syntax, see @ref{Command Syntax, , @@-Command Syntax}.)@refill @node Conventions, Comments, Formatting Commands, Overview @comment node-name, next, previous, up @section General Syntactic Conventions @cindex General syntactic conventions @cindex Syntactic conventions @cindex Conventions, syntactic All printable @sc{ascii} characters except @samp{@@}, @samp{@{} and @samp{@}} can appear in a Texinfo file and stand for themselves. @samp{@@} is the escape character which introduces commands. @samp{@{} and @samp{@}} should be used only to surround arguments to certain commands. To put one of these special characters into the document, put an @samp{@@} character in front of it, like this: @samp{@@@@}, @samp{@@@{}, and @samp{@@@}}.@refill @ifinfo It is customary in @TeX{} to use doubled single-quote characters to begin and end quotations: ` ` and ' ' (but without a space between the two single-quote characters). This convention should be followed in Texinfo files. @TeX{} converts doubled single-quote characters to left- and right-hand doubled quotation marks and Info converts doubled single-quote characters to @sc{ascii} double-quotes: ` ` and ' ' to " .@refill @end ifinfo @iftex It is customary in @TeX{} to use doubled single-quote characters to begin and end quotations: @w{@tt{ `` }} and @w{@tt{ '' }}. This convention should be followed in Texinfo files. @TeX{} converts doubled single-quote characters to left- and right-hand doubled quotation marks, ``like this'', and Info converts doubled single-quote characters to @sc{ascii} double-quotes: @w{@tt{ `` }} and @w{@tt{ '' }} to @w{@tt{ " }}.@refill @end iftex Use three hyphens in a row, @samp{---}, for a dash---like this. In @TeX{}, a single or double hyphen produces a printed dash that is shorter than the usual typeset dash. Info reduces three hyphens to two for display on the screen. To prevent a paragraph from being indented in the printed manual, put the command @code{@@noindent} on a line by itself before the paragraph.@refill If you mark off a region of the Texinfo file with the @code{@@iftex} and @w{@code{@@end iftex}} commands, that region will appear only in the printed copy; in that region, you can use certain commands borrowed from plain @TeX{} that you cannot use in Info. Likewise, if you mark off a region with the @code{@@ifinfo} and @code{@@end ifinfo} commands, that region will appear only in the Info file; in that region, you can use Info commands that you cannot use in @TeX{}. Similarly for @code{@@ifhtml @dots{} @@end ifhtml}, @code{@@ifnothtml @dots{} @@end ifnothtml}, @code{@@ifnotinfo @dots{} @@end ifnotinfo}, @code{@@ifnottex @dots{} @@end ifnottex}, @xref{Conditionals}. @cindex Tabs; don't use! @quotation @strong{Caution:} Do not use tabs in a Texinfo file! @TeX{} uses variable-width fonts, which means that it cannot predefine a tab to work in all circumstances. Consequently, @TeX{} treats tabs like single spaces, and that is not what they look like. Furthermore, @code{makeinfo} does nothing special with tabs, and thus a tab character in your input file may appear differently in the output. @noindent To avoid this problem, Texinfo mode causes GNU Emacs to insert multiple spaces when you press the @key{TAB} key.@refill @noindent Also, you can run @code{untabify} in Emacs to convert tabs in a region to multiple spaces.@refill @noindent Don't use tabs. @end quotation @node Comments, Minimum, Conventions, Overview @comment node-name, next, previous, up @section Comments You can write comments in a Texinfo file that will not appear in either the Info file or the printed manual by using the @code{@@comment} command (which may be abbreviated to @code{@@c}). Such comments are for the person who reads the Texinfo file. All the text on a line that follows either @code{@@comment} or @code{@@c} is a comment; the rest of the line does not appear in either the Info file or the printed manual. (Often, you can write the @code{@@comment} or @code{@@c} in the middle of a line, and only the text that follows after the @code{@@comment} or @code{@@c} command does not appear; but some commands, such as @code{@@settitle} and @code{@@setfilename}, work on a whole line. You cannot use @code{@@comment} or @code{@@c} in a line beginning with such a command.)@refill @cindex Comments @findex comment @findex c @r{(comment)} You can write long stretches of text that will not appear in either the Info file or the printed manual by using the @code{@@ignore} and @code{@@end ignore} commands. Write each of these commands on a line of its own, starting each command at the beginning of the line. Text between these two commands does not appear in the processed output. You can use @code{@@ignore} and @code{@@end ignore} for writing comments. Often, @code{@@ignore} and @code{@@end ignore} is used to enclose a part of the copying permissions that applies to the Texinfo source file of a document, but not to the Info or printed version of the document.@refill @cindex Ignored text @cindex Unprocessed text @findex ignore @c !!! Perhaps include this comment about ignore and ifset: @ignore Text enclosed by @code{@@ignore} or by failing @code{@@ifset} or @code{@@ifclear} conditions is ignored in the sense that it will not contribute to the formatted output. However, TeX and makeinfo must still parse the ignored text, in order to understand when to @emph{stop} ignoring text from the source file; that means that you will still get error messages if you have invalid Texinfo markup within ignored text. @end ignore @node Minimum, Six Parts, Comments, Overview @comment node-name, next, previous, up @section What a Texinfo File Must Have @cindex Minimal Texinfo file (requirements) @cindex Must have in Texinfo file @cindex Required in Texinfo file @cindex Texinfo file minimum By convention, the names of Texinfo files end with one of the extensions @file{.texinfo}, @file{.texi}, or @file{.tex}. The longer extension is preferred since it describes more clearly to a human reader the nature of the file. The shorter extensions are for operating systems that cannot handle long file names.@refill In order to be made into a printed manual and an Info file, a Texinfo file @strong{must} begin with lines like this:@refill @example @group \input texinfo @@setfilename @var{info-file-name} @@settitle @var{name-of-manual} @end group @end example @noindent The contents of the file follow this beginning, and then you @strong{must} end a Texinfo file with a line like this:@refill @example @@bye @end example @findex input @r{(@TeX{} command)} @noindent The @samp{\input texinfo} line tells @TeX{} to use the @file{texinfo.tex} file, which tells @TeX{} how to translate the Texinfo @@-commands into @TeX{} typesetting commands. (Note the use of the backslash, @samp{\}; this is correct for @TeX{}.) The @samp{@@setfilename} line provides a name for the Info file and tells @TeX{} to open auxiliary files. The @samp{@@settitle} line specifies a title for the page headers (or footers) of the printed manual.@refill The @code{@@bye} line at the end of the file on a line of its own tells the formatters that the file is ended and to stop formatting.@refill Usually, you will not use quite such a spare format, but will include mode setting and start-of-header and end-of-header lines at the beginning of a Texinfo file, like this:@refill @example @group \input texinfo @@c -*-texinfo-*- @@c %**start of header @@setfilename @var{info-file-name} @@settitle @var{name-of-manual} @@c %**end of header @end group @end example @noindent In the first line, @samp{-*-texinfo-*-} causes Emacs to switch into Texinfo mode when you edit the file. The @code{@@c} lines which surround the @samp{@@setfilename} and @samp{@@settitle} lines are optional, but you need them in order to run @TeX{} or Info on just part of the file. (@xref{Start of Header}, for more information.)@refill Furthermore, you will usually provide a Texinfo file with a title page, indices, and the like. But the minimum, which can be useful for short documents, is just the three lines at the beginning and the one line at the end.@refill @node Six Parts, Short Sample, Minimum, Overview @comment node-name, next, previous, up @section Six Parts of a Texinfo File Generally, a Texinfo file contains more than the minimal beginning and end---it usually contains six parts:@refill @table @r @item 1. Header The @dfn{Header} names the file, tells @TeX{} which definitions' file to use, and performs other ``housekeeping'' tasks.@refill @item 2. Summary Description and Copyright The @dfn{Summary Description and Copyright} segment describes the document and contains the copyright notice and copying permissions for the Info file. The segment must be enclosed between @code{@@ifinfo} and @code{@@end ifinfo} commands so that the formatters place it only in the Info file.@refill @item 3. Title and Copyright The @dfn{Title and Copyright} segment contains the title and copyright pages and copying permissions for the printed manual. The segment must be enclosed between @code{@@titlepage} and @code{@@end titlepage} commands. The title and copyright page appear only in the printed @w{manual}.@refill @item 4. `Top' Node and Master Menu The @dfn{Master Menu} contains a complete menu of all the nodes in the whole Info file. It appears only in the Info file, in the `Top' node.@refill @item 5. Body The @dfn{Body} of the document may be structured like a traditional book or encyclopedia or it may be free form.@refill @item 6. End The @dfn{End} contains commands for printing indices and generating the table of contents, and the @code{@@bye} command on a line of its own.@refill @end table @node Short Sample, Acknowledgements, Six Parts, Overview @comment node-name, next, previous, up @section A Short Sample Texinfo File @cindex Sample Texinfo file Here is a complete but very short Texinfo file, in six parts. The first three parts of the file, from @samp{\input texinfo} through to @samp{@@end titlepage}, look more intimidating than they are. Most of the material is standard boilerplate; when you write a manual, simply insert the names for your own manual in this segment. (@xref{Beginning a File}.)@refill @noindent In the following, the sample text is @emph{indented}; comments on it are not. The complete file, without any comments, is shown in @ref{Sample Texinfo File}. @subheading Part 1: Header @noindent The header does not appear in either the Info file or the printed output. It sets various parameters, including the name of the Info file and the title used in the header. @example @group \input texinfo @@c -*-texinfo-*- @@c %**start of header @@setfilename sample.info @@settitle Sample Document @@c %**end of header @@setchapternewpage odd @end group @end example @subheading Part 2: Summary Description and Copyright @noindent The summary description and copyright segment does not appear in the printed document. @example @group @@ifinfo This is a short example of a complete Texinfo file. Copyright @@copyright@{@} 1990 Free Software Foundation, Inc. @@end ifinfo @end group @end example @subheading Part 3: Titlepage and Copyright @noindent The titlepage segment does not appear in the Info file. @example @group @@titlepage @@sp 10 @@comment The title is printed in a large font. @@center @@titlefont@{Sample Title@} @end group @group @@c The following two commands start the copyright page. @@page @@vskip 0pt plus 1filll Copyright @@copyright@{@} 1990 Free Software Foundation, Inc. @@end titlepage @end group @end example @subheading Part 4: `Top' Node and Master Menu @noindent The `Top' node contains the master menu for the Info file. Since a printed manual uses a table of contents rather than a menu, the master menu appears only in the Info file. @example @group @@node Top, First Chapter, , (dir) @@comment node-name, next, previous, up @end group @end example @example @group @@menu * First Chapter:: The first chapter is the only chapter in this sample. * Concept Index:: This index has two entries. @@end menu @end group @end example @subheading Part 5: The Body of the Document @noindent The body segment contains all the text of the document, but not the indices or table of contents. This example illustrates a node and a chapter containing an enumerated list.@refill @example @group @@node First Chapter, Concept Index, Top, Top @@comment node-name, next, previous, up @@chapter First Chapter @@cindex Sample index entry @end group @group This is the contents of the first chapter. @@cindex Another sample index entry @end group @group Here is a numbered list. @@enumerate @@item This is the first item. @@item This is the second item. @@end enumerate @end group @group The @@code@{makeinfo@} and @@code@{texinfo-format-buffer@} commands transform a Texinfo file such as this into an Info file; and @@TeX@{@} typesets it for a printed manual. @end group @end example @subheading Part 6: The End of the Document @noindent The end segment contains commands both for generating an index in a node and unnumbered chapter of its own and for generating the table of contents; and it contains the @code{@@bye} command that marks the end of the document.@refill @example @group @@node Concept Index, , First Chapter, Top @@comment node-name, next, previous, up @@unnumbered Concept Index @end group @group @@printindex cp @@contents @@bye @end group @end example @subheading The Results Here is what the contents of the first chapter of the sample look like: @sp 1 @need 700 @quotation This is the contents of the first chapter. Here is a numbered list. @enumerate @item This is the first item. @item This is the second item. @end enumerate The @code{makeinfo} and @code{texinfo-format-buffer} commands transform a Texinfo file such as this into an Info file; and @TeX{} typesets it for a printed manual. @end quotation @node Acknowledgements, , Short Sample, Overview @comment node-name, next, previous, up @section Acknowledgements @cindex Stallman, Richard M. @cindex Chassell, Robert J. @cindex Berry, Karl Richard M.@: Stallman wrote Edition 1.0 of this manual. @w{Robert J.@: Chassell} revised and extended it, starting with Edition 1.1. Karl Berry made updates for the Texinfo 3.8 and subsequent releases, starting with Edition 2.22. @cindex Pinard, Fran@,{c}ois @cindex Zuhn, David D. @cindex Weisshaus, Melissa Our thanks go out to all who helped improve this work, particularly to Fran@,{c}ois Pinard and @w{David D.@: Zuhn}, who tirelessly recorded and reported mistakes and obscurities; our special thanks go to Melissa Weisshaus for her frequent and often tedious reviews of nearly similar editions. Our mistakes are our own. Please send suggestions and corrections to: @example @group @r{Internet address:} bug-texinfo@@gnu.org @end group @end example @noindent Please include the manual's edition number and update date in your messages. @node Texinfo Mode, Beginning a File, Overview, Top @comment node-name, next, previous, up @chapter Using Texinfo Mode @cindex Texinfo mode @cindex Mode, using Texinfo @cindex GNU Emacs @cindex Emacs You may edit a Texinfo file with any text editor you choose. A Texinfo file is no different from any other @sc{ascii} file. However, GNU Emacs comes with a special mode, called Texinfo mode, that provides Emacs commands and tools to help ease your work.@refill This chapter describes features of GNU Emacs' Texinfo mode but not any features of the Texinfo formatting language. If you are reading this manual straight through from the beginning, you may want to skim through this chapter briefly and come back to it after reading succeeding chapters which describe the Texinfo formatting language in detail.@refill @menu * Texinfo Mode Overview:: How Texinfo mode can help you. * Emacs Editing:: Texinfo mode adds to GNU Emacs' general purpose editing features. * Inserting:: How to insert frequently used @@-commands. * Showing the Structure:: How to show the structure of a file. * Updating Nodes and Menus:: How to update or create new nodes and menus. * Info Formatting:: How to format for Info. * Printing:: How to format and print part or all of a file. * Texinfo Mode Summary:: Summary of all the Texinfo mode commands. @end menu @node Texinfo Mode Overview, Emacs Editing, Texinfo Mode, Texinfo Mode @ifinfo @heading Texinfo Mode Overview @end ifinfo Texinfo mode provides special features for working with Texinfo files:@refill @itemize @bullet @item Insert frequently used @@-commands. @refill @item Automatically create @code{@@node} lines. @item Show the structure of a Texinfo source file.@refill @item Automatically create or update the `Next', `Previous', and `Up' pointers of a node. @item Automatically create or update menus.@refill @item Automatically create a master menu.@refill @item Format a part or all of a file for Info.@refill @item Typeset and print part or all of a file.@refill @end itemize Perhaps the two most helpful features are those for inserting frequently used @@-commands and for creating node pointers and menus.@refill @node Emacs Editing, Inserting, Texinfo Mode Overview, Texinfo Mode @section The Usual GNU Emacs Editing Commands In most cases, the usual Text mode commands work the same in Texinfo mode as they do in Text mode. Texinfo mode adds new editing commands and tools to GNU Emacs' general purpose editing features. The major difference concerns filling. In Texinfo mode, the paragraph separation variable and syntax table are redefined so that Texinfo commands that should be on lines of their own are not inadvertently included in paragraphs. Thus, the @kbd{M-q} (@code{fill-paragraph}) command will refill a paragraph but not mix an indexing command on a line adjacent to it into the paragraph.@refill In addition, Texinfo mode sets the @code{page-delimiter} variable to the value of @code{texinfo-chapter-level-regexp}; by default, this is a regular expression matching the commands for chapters and their equivalents, such as appendices. With this value for the page delimiter, you can jump from chapter title to chapter title with the @kbd{C-x ]} (@code{forward-page}) and @kbd{C-x [} (@code{backward-page}) commands and narrow to a chapter with the @kbd{C-x p} (@code{narrow-to-page}) command. (@xref{Pages, , ,emacs, The GNU Emacs Manual}, for details about the page commands.)@refill You may name a Texinfo file however you wish, but the convention is to end a Texinfo file name with one of the three extensions @file{.texinfo}, @file{.texi}, or @file{.tex}. A longer extension is preferred, since it is explicit, but a shorter extension may be necessary for operating systems that limit the length of file names. GNU Emacs automatically enters Texinfo mode when you visit a file with a @file{.texinfo} or @file{.texi} extension. Also, Emacs switches to Texinfo mode when you visit a file that has @samp{-*-texinfo-*-} in its first line. If ever you are in another mode and wish to switch to Texinfo mode, type @code{M-x texinfo-mode}.@refill Like all other Emacs features, you can customize or enhance Texinfo mode as you wish. In particular, the keybindings are very easy to change. The keybindings described here are the default or standard ones.@refill @node Inserting, Showing the Structure, Emacs Editing, Texinfo Mode @comment node-name, next, previous, up @section Inserting Frequently Used Commands @cindex Inserting frequently used commands @cindex Frequently used commands, inserting @cindex Commands, inserting them Texinfo mode provides commands to insert various frequently used @@-commands into the buffer. You can use these commands to save keystrokes.@refill The insert commands are invoked by typing @kbd{C-c} twice and then the first letter of the @@-command:@refill @table @kbd @item C-c C-c c @itemx M-x texinfo-insert-@@code @findex texinfo-insert-@@code Insert @code{@@code@{@}} and put the cursor between the braces.@refill @item C-c C-c d @itemx M-x texinfo-insert-@@dfn @findex texinfo-insert-@@dfn Insert @code{@@dfn@{@}} and put the cursor between the braces.@refill @item C-c C-c e @itemx M-x texinfo-insert-@@end @findex texinfo-insert-@@end Insert @code{@@end} and attempt to insert the correct following word, such as @samp{example} or @samp{table}. (This command does not handle nested lists correctly, but inserts the word appropriate to the immediately preceding list.)@refill @item C-c C-c i @itemx M-x texinfo-insert-@@item @findex texinfo-insert-@@item Insert @code{@@item} and put the cursor at the beginning of the next line.@refill @item C-c C-c k @itemx M-x texinfo-insert-@@kbd @findex texinfo-insert-@@kbd Insert @code{@@kbd@{@}} and put the cursor between the braces.@refill @item C-c C-c n @itemx M-x texinfo-insert-@@node @findex texinfo-insert-@@node Insert @code{@@node} and a comment line listing the sequence for the `Next', `Previous', and `Up' nodes. Leave point after the @code{@@node}.@refill @item C-c C-c o @itemx M-x texinfo-insert-@@noindent @findex texinfo-insert-@@noindent Insert @code{@@noindent} and put the cursor at the beginning of the next line.@refill @item C-c C-c s @itemx M-x texinfo-insert-@@samp @findex texinfo-insert-@@samp Insert @code{@@samp@{@}} and put the cursor between the braces.@refill @item C-c C-c t @itemx M-x texinfo-insert-@@table @findex texinfo-insert-@@table Insert @code{@@table} followed by a @key{SPC} and leave the cursor after the @key{SPC}.@refill @item C-c C-c v @itemx M-x texinfo-insert-@@var @findex texinfo-insert-@@var Insert @code{@@var@{@}} and put the cursor between the braces.@refill @item C-c C-c x @itemx M-x texinfo-insert-@@example @findex texinfo-insert-@@example Insert @code{@@example} and put the cursor at the beginning of the next line.@refill @c M-@{ was the binding for texinfo-insert-braces; @c in Emacs 19, backward-paragraph will take this binding. @item C-c C-c @{ @itemx M-x texinfo-insert-braces @findex texinfo-insert-braces Insert @code{@{@}} and put the cursor between the braces.@refill @item C-c C-c @} @itemx C-c C-c ] @itemx M-x up-list @findex up-list Move from between a pair of braces forward past the closing brace. Typing @kbd{C-c C-c ]} is easier than typing @kbd{C-c C-c @}}, which is, however, more mnemonic; hence the two keybindings. (Also, you can move out from between braces by typing @kbd{C-f}.)@refill @end table To put a command such as @w{@code{@@code@{@dots{}@}}} around an @emph{existing} word, position the cursor in front of the word and type @kbd{C-u 1 C-c C-c c}. This makes it easy to edit existing plain text. The value of the prefix argument tells Emacs how many words following point to include between braces---@samp{1} for one word, @samp{2} for two words, and so on. Use a negative argument to enclose the previous word or words. If you do not specify a prefix argument, Emacs inserts the @@-command string and positions the cursor between the braces. This feature works only for those @@-commands that operate on a word or words within one line, such as @code{@@kbd} and @code{@@var}.@refill This set of insert commands was created after analyzing the frequency with which different @@-commands are used in the @cite{GNU Emacs Manual} and the @cite{GDB Manual}. If you wish to add your own insert commands, you can bind a keyboard macro to a key, use abbreviations, or extend the code in @file{texinfo.el}.@refill @findex texinfo-start-menu-description @cindex Menu description, start @cindex Description for menu, start @kbd{C-c C-c C-d} (@code{texinfo-start-menu-description}) is an insert command that works differently from the other insert commands. It inserts a node's section or chapter title in the space for the description in a menu entry line. (A menu entry has three parts, the entry name, the node name, and the description. Only the node name is required, but a description helps explain what the node is about. @xref{Menu Parts, , The Parts of a Menu}.)@refill To use @code{texinfo-start-menu-description}, position point in a menu entry line and type @kbd{C-c C-c C-d}. The command looks for and copies the title that goes with the node name, and inserts the title as a description; it positions point at beginning of the inserted text so you can edit it. The function does not insert the title if the menu entry line already contains a description.@refill This command is only an aid to writing descriptions; it does not do the whole job. You must edit the inserted text since a title tends to use the same words as a node name but a useful description uses different words.@refill @node Showing the Structure, Updating Nodes and Menus, Inserting, Texinfo Mode @comment node-name, next, previous, up @section Showing the Section Structure of a File @cindex Showing the section structure of a file @cindex Section structure of a file, showing it @cindex Structure of a file, showing it @cindex Outline of file structure, showing it @cindex Contents-like outline of file structure @cindex File section structure, showing it @cindex Texinfo file section structure, showing it You can show the section structure of a Texinfo file by using the @kbd{C-c C-s} command (@code{texinfo-show-structure}). This command shows the section structure of a Texinfo file by listing the lines that begin with the @@-commands for @code{@@chapter}, @code{@@section}, and the like. It constructs what amounts to a table of contents. These lines are displayed in another buffer called the @samp{*Occur*} buffer. In that buffer, you can position the cursor over one of the lines and use the @kbd{C-c C-c} command (@code{occur-mode-goto-occurrence}), to jump to the corresponding spot in the Texinfo file.@refill @table @kbd @item C-c C-s @itemx M-x texinfo-show-structure @findex texinfo-show-structure Show the @code{@@chapter}, @code{@@section}, and such lines of a Texinfo file.@refill @item C-c C-c @itemx M-x occur-mode-goto-occurrence @findex occur-mode-goto-occurrence Go to the line in the Texinfo file corresponding to the line under the cursor in the @file{*Occur*} buffer.@refill @end table If you call @code{texinfo-show-structure} with a prefix argument by typing @w{@kbd{C-u C-c C-s}}, it will list not only those lines with the @@-commands for @code{@@chapter}, @code{@@section}, and the like, but also the @code{@@node} lines. (This is how the @code{texinfo-show-structure} command worked without an argument in the first version of Texinfo. It was changed because @code{@@node} lines clutter up the @samp{*Occur*} buffer and are usually not needed.) You can use @code{texinfo-show-structure} with a prefix argument to check whether the `Next', `Previous', and `Up' pointers of an @code{@@node} line are correct.@refill Often, when you are working on a manual, you will be interested only in the structure of the current chapter. In this case, you can mark off the region of the buffer that you are interested in by using the @kbd{C-x n n} (@code{narrow-to-region}) command and @code{texinfo-show-structure} will work on only that region. To see the whole buffer again, use @w{@kbd{C-x n w}} (@code{widen}). (@xref{Narrowing, , , emacs, The GNU Emacs Manual}, for more information about the narrowing commands.)@refill @vindex page-delimiter @cindex Page delimiter in Texinfo mode In addition to providing the @code{texinfo-show-structure} command, Texinfo mode sets the value of the page delimiter variable to match the chapter-level @@-commands. This enables you to use the @kbd{C-x ]} (@code{forward-page}) and @kbd{C-x [} (@code{backward-page}) commands to move forward and backward by chapter, and to use the @kbd{C-x p} (@code{narrow-to-page}) command to narrow to a chapter. @xref{Pages, , , emacs, The GNU Emacs Manual}, for more information about the page commands.@refill @node Updating Nodes and Menus, Info Formatting, Showing the Structure, Texinfo Mode @comment node-name, next, previous, up @section Updating Nodes and Menus @cindex Updating nodes and menus @cindex Create nodes, menus automatically @cindex Insert nodes, menus automatically @cindex Automatically insert nodes, menus Texinfo mode provides commands for automatically creating or updating menus and node pointers. The commands are called ``update'' commands because their most frequent use is for updating a Texinfo file after you have worked on it; but you can use them to insert the `Next', `Previous', and `Up' pointers into an @code{@@node} line that has none and to create menus in a file that has none.@refill If you do not use the updating commands, you need to write menus and node pointers by hand, which is a tedious task.@refill @menu * Updating Commands:: Five major updating commands. * Updating Requirements:: How to structure a Texinfo file for using the updating command. * Other Updating Commands:: How to indent descriptions, insert missing nodes lines, and update nodes in sequence. @end menu @node Updating Commands, Updating Requirements, Updating Nodes and Menus, Updating Nodes and Menus @ifinfo @subheading The Updating Commands @end ifinfo You can use the updating commands@refill @itemize @bullet @item to insert or update the `Next', `Previous', and `Up' pointers of a node,@refill @item to insert or update the menu for a section, and@refill @item to create a master menu for a Texinfo source file.@refill @end itemize You can also use the commands to update all the nodes and menus in a region or in a whole Texinfo file.@refill The updating commands work only with conventional Texinfo files, which are structured hierarchically like books. In such files, a structuring command line must follow closely after each @code{@@node} line, except for the `Top' @code{@@node} line. (A @dfn{structuring command line} is a line beginning with @code{@@chapter}, @code{@@section}, or other similar command.) You can write the structuring command line on the line that follows immediately after an @code{@@node} line or else on the line that follows after a single @code{@@comment} line or a single @code{@@ifinfo} line. You cannot interpose more than one line between the @code{@@node} line and the structuring command line; and you may interpose only an @code{@@comment} line or an @code{@@ifinfo} line. Commands which work on a whole buffer require that the `Top' node be followed by a node with an @code{@@chapter} or equivalent-level command. Note that the menu updating commands will not create a main or master menu for a Texinfo file that has only @code{@@chapter}-level nodes! The menu updating commands only create menus @emph{within} nodes for lower level nodes. To create a menu of chapters, you must provide a `Top' node.@refill The menu updating commands remove menu entries that refer to other Info files since they do not refer to nodes within the current buffer. This is a deficiency. Rather than use menu entries, you can use cross references to refer to other Info files. None of the updating commands affect cross references.@refill Texinfo mode has five updating commands that are used most often: two are for updating the node pointers or menu of a single node (or a region); two are for updating every node pointer and menu in a file; and one, the @code{texinfo-master-menu} command, is for creating a master menu for a complete file, and optionally, for updating every node and menu in the whole Texinfo file.@refill The @code{texinfo-master-menu} command is the primary command:@refill @table @kbd @item C-c C-u m @itemx M-x texinfo-master-menu @findex texinfo-master-menu Create or update a master menu that includes all the other menus (incorporating the descriptions from pre-existing menus, if any).@refill With an argument (prefix argument, @kbd{C-u,} if interactive), first create or update all the nodes and all the regular menus in the buffer before constructing the master menu. (@xref{The Top Node, , The Top Node and Master Menu}, for more about a master menu.)@refill For @code{texinfo-master-menu} to work, the Texinfo file must have a `Top' node and at least one subsequent node.@refill After extensively editing a Texinfo file, you can type the following: @example C-u M-x texinfo-master-menu @exdent or C-u C-c C-u m @end example @noindent This updates all the nodes and menus completely and all at once.@refill @end table The other major updating commands do smaller jobs and are designed for the person who updates nodes and menus as he or she writes a Texinfo file.@refill @need 1000 The commands are:@refill @table @kbd @item C-c C-u C-n @itemx M-x texinfo-update-node @findex texinfo-update-node Insert the `Next', `Previous', and `Up' pointers for the node that point is within (i.e., for the @code{@@node} line preceding point). If the @code{@@node} line has pre-existing `Next', `Previous', or `Up' pointers in it, the old pointers are removed and new ones inserted. With an argument (prefix argument, @kbd{C-u}, if interactive), this command updates all @code{@@node} lines in the region (which is the text between point and mark).@refill @item C-c C-u C-m @itemx M-x texinfo-make-menu @findex texinfo-make-menu Create or update the menu in the node that point is within. With an argument (@kbd{C-u} as prefix argument, if interactive), the command makes or updates menus for the nodes which are either within or a part of the region.@refill Whenever @code{texinfo-make-menu} updates an existing menu, the descriptions from that menu are incorporated into the new menu. This is done by copying descriptions from the existing menu to the entries in the new menu that have the same node names. If the node names are different, the descriptions are not copied to the new menu.@refill @item C-c C-u C-e @itemx M-x texinfo-every-node-update @findex texinfo-every-node-update Insert or update the `Next', `Previous', and `Up' pointers for every node in the buffer.@refill @item C-c C-u C-a @itemx M-x texinfo-all-menus-update @findex texinfo-all-menus-update Create or update all the menus in the buffer. With an argument (@kbd{C-u} as prefix argument, if interactive), first insert or update all the node pointers before working on the menus.@refill If a master menu exists, the @code{texinfo-all-menus-update} command updates it; but the command does not create a new master menu if none already exists. (Use the @code{texinfo-master-menu} command for that.)@refill When working on a document that does not merit a master menu, you can type the following: @example C-u C-c C-u C-a @exdent or C-u M-x texinfo-all-menus-update @end example @noindent This updates all the nodes and menus.@refill @end table The @code{texinfo-column-for-description} variable specifies the column to which menu descriptions are indented. By default, the value is 32 although it is often useful to reduce it to as low as 24. You can set the variable with the @kbd{M-x edit-options} command (@pxref{Edit Options, , Editing Variable Values, emacs, The GNU Emacs Manual}) or with the @kbd{M-x set-variable} command (@pxref{Examining, , Examining and Setting Variables, emacs, The GNU Emacs Manual}).@refill Also, the @code{texinfo-indent-menu-description} command may be used to indent existing menu descriptions to a specified column. Finally, if you wish, you can use the @code{texinfo-insert-node-lines} command to insert missing @code{@@node} lines into a file. (@xref{Other Updating Commands}, for more information.)@refill @node Updating Requirements, Other Updating Commands, Updating Commands, Updating Nodes and Menus @comment node-name, next, previous, up @subsection Updating Requirements @cindex Updating requirements @cindex Requirements for updating commands To use the updating commands, you must organize the Texinfo file hierarchically with chapters, sections, subsections, and the like. When you construct the hierarchy of the manual, do not `jump down' more than one level at a time: you can follow the `Top' node with a chapter, but not with a section; you can follow a chapter with a section, but not with a subsection. However, you may `jump up' any number of levels at one time---for example, from a subsection to a chapter.@refill Each @code{@@node} line, with the exception of the line for the `Top' node, must be followed by a line with a structuring command such as @code{@@chapter}, @code{@@section}, or @code{@@unnumberedsubsec}.@refill Each @code{@@node} line/structuring-command line combination must look either like this:@refill @example @group @@node Comments, Minimum, Conventions, Overview @@comment node-name, next, previous, up @@section Comments @end group @end example or like this (without the @code{@@comment} line): @example @group @@node Comments, Minimum, Conventions, Overview @@section Comments @end group @end example @noindent In this example, `Comments' is the name of both the node and the section. The next node is called `Minimum' and the previous node is called `Conventions'. The `Comments' section is within the `Overview' node, which is specified by the `Up' pointer. (Instead of an @code{@@comment} line, you can write an @code{@@ifinfo} line.)@refill If a file has a `Top' node, it must be called @samp{top} or @samp{Top} and be the first node in the file.@refill The menu updating commands create a menu of sections within a chapter, a menu of subsections within a section, and so on. This means that you must have a `Top' node if you want a menu of chapters.@refill Incidentally, the @code{makeinfo} command will create an Info file for a hierarchically organized Texinfo file that lacks `Next', `Previous' and `Up' pointers. Thus, if you can be sure that your Texinfo file will be formatted with @code{makeinfo}, you have no need for the `update node' commands. (@xref{Create an Info File, , Creating an Info File}, for more information about @code{makeinfo}.) However, both @code{makeinfo} and the @code{texinfo-format-@dots{}} commands require that you insert menus in the file.@refill @node Other Updating Commands, , Updating Requirements, Updating Nodes and Menus @comment node-name, next, previous, up @subsection Other Updating Commands In addition to the five major updating commands, Texinfo mode possesses several less frequently used updating commands:@refill @table @kbd @item M-x texinfo-insert-node-lines @findex texinfo-insert-node-lines Insert @code{@@node} lines before the @code{@@chapter}, @code{@@section}, and other sectioning commands wherever they are missing throughout a region in a Texinfo file.@refill With an argument (@kbd{C-u} as prefix argument, if interactive), the @code{texinfo-insert-node-lines} command not only inserts @code{@@node} lines but also inserts the chapter or section titles as the names of the corresponding nodes. In addition, it inserts the titles as node names in pre-existing @code{@@node} lines that lack names. Since node names should be more concise than section or chapter titles, you must manually edit node names so inserted.@refill For example, the following marks a whole buffer as a region and inserts @code{@@node} lines and titles throughout:@refill @example C-x h C-u M-x texinfo-insert-node-lines @end example (Note that this command inserts titles as node names in @code{@@node} lines; the @code{texinfo-start-menu-description} command (@pxref{Inserting, Inserting Frequently Used Commands}) inserts titles as descriptions in menu entries, a different action. However, in both cases, you need to edit the inserted text.)@refill @item M-x texinfo-multiple-files-update @findex texinfo-multiple-files-update @r{(in brief)} Update nodes and menus in a document built from several separate files. With @kbd{C-u} as a prefix argument, create and insert a master menu in the outer file. With a numeric prefix argument, such as @kbd{C-u 2}, first update all the menus and all the `Next', `Previous', and `Up' pointers of all the included files before creating and inserting a master menu in the outer file. The @code{texinfo-multiple-files-update} command is described in the appendix on @code{@@include} files. @ifinfo @xref{texinfo-multiple-files-update}.@refill @end ifinfo @iftex @xref{texinfo-multiple-files-update, , @code{texinfo-multiple-files-update}}.@refill @end iftex @item M-x texinfo-indent-menu-description @findex texinfo-indent-menu-description Indent every description in the menu following point to the specified column. You can use this command to give yourself more space for descriptions. With an argument (@kbd{C-u} as prefix argument, if interactive), the @code{texinfo-indent-menu-description} command indents every description in every menu in the region. However, this command does not indent the second and subsequent lines of a multi-line description.@refill @item M-x texinfo-sequential-node-update @findex texinfo-sequential-node-update Insert the names of the nodes immediately following and preceding the current node as the `Next' or `Previous' pointers regardless of those nodes' hierarchical level. This means that the `Next' node of a subsection may well be the next chapter. Sequentially ordered nodes are useful for novels and other documents that you read through sequentially. (However, in Info, the @kbd{g *} command lets you look through the file sequentially, so sequentially ordered nodes are not strictly necessary.) With an argument (prefix argument, if interactive), the @code{texinfo-sequential-node-update} command sequentially updates all the nodes in the region.@refill @end table @node Info Formatting, Printing, Updating Nodes and Menus, Texinfo Mode @comment node-name, next, previous, up @section Formatting for Info @cindex Formatting for Info @cindex Running an Info formatter @cindex Info formatting Texinfo mode provides several commands for formatting part or all of a Texinfo file for Info. Often, when you are writing a document, you want to format only part of a file---that is, a region.@refill You can use either the @code{texinfo-format-region} or the @code{makeinfo-region} command to format a region:@refill @table @kbd @findex texinfo-format-region @item C-c C-e C-r @itemx M-x texinfo-format-region @itemx C-c C-m C-r @itemx M-x makeinfo-region Format the current region for Info.@refill @end table You can use either the @code{texinfo-format-buffer} or the @code{makeinfo-buffer} command to format a whole buffer:@refill @table @kbd @findex texinfo-format-buffer @item C-c C-e C-b @itemx M-x texinfo-format-buffer @itemx C-c C-m C-b @itemx M-x makeinfo-buffer Format the current buffer for Info.@refill @end table @need 1000 For example, after writing a Texinfo file, you can type the following: @example C-u C-c C-u m @exdent or C-u M-x texinfo-master-menu @end example @noindent This updates all the nodes and menus. Then type the following to create an Info file: @example C-c C-m C-b @exdent or M-x makeinfo-buffer @end example For @TeX{} or the Info formatting commands to work, the file @emph{must} include a line that has @code{@@setfilename} in its header.@refill @xref{Create an Info File}, for details about Info formatting.@refill @node Printing, Texinfo Mode Summary, Info Formatting, Texinfo Mode @comment node-name, next, previous, up @section Formatting and Printing @cindex Formatting for printing @cindex Printing a region or buffer @cindex Region formatting and printing @cindex Buffer formatting and printing @cindex Part of file formatting and printing Typesetting and printing a Texinfo file is a multi-step process in which you first create a file for printing (called a DVI file), and then print the file. Optionally, you may also create indices. To do this, you must run the @code{texindex} command after first running the @code{tex} typesetting command; and then you must run the @code{tex} command again. Or else run the @code{texi2dvi} command which automatically creates indices as needed (@pxref{Format with texi2dvi}). Often, when you are writing a document, you want to typeset and print only part of a file to see what it will look like. You can use the @code{texinfo-tex-region} and related commands for this purpose. Use the @code{texinfo-tex-buffer} command to format all of a buffer.@refill @table @kbd @item C-c C-t C-b @itemx M-x texinfo-tex-buffer @findex texinfo-tex-buffer Run @code{texi2dvi} on the buffer. In addition to running @TeX{} on the buffer, this command automatically creates or updates indices as needed.@refill @item C-c C-t C-r @itemx M-x texinfo-tex-region @findex texinfo-tex-region Run @TeX{} on the region.@refill @item C-c C-t C-i @itemx M-x texinfo-texindex Run @code{texindex} to sort the indices of a Texinfo file formatted with @code{texinfo-tex-region}. The @code{texinfo-tex-region} command does not run @code{texindex} automatically; it only runs the @code{tex} typesetting command. You must run the @code{texinfo-tex-region} command a second time after sorting the raw index files with the @code{texindex} command. (Usually, you do not format an index when you format a region, only when you format a buffer. Now that the @code{texi2dvi} command exists, there is little or no need for this command.)@refill @item C-c C-t C-p @itemx M-x texinfo-tex-print @findex texinfo-tex-print Print the file (or the part of the file) previously formatted with @code{texinfo-tex-buffer} or @code{texinfo-tex-region}.@refill @end table For @code{texinfo-tex-region} or @code{texinfo-tex-buffer} to work, the file @emph{must} start with a @samp{\input texinfo} line and must include an @code{@@settitle} line. The file must end with @code{@@bye} on a line by itself. (When you use @code{texinfo-tex-region}, you must surround the @code{@@settitle} line with start-of-header and end-of-header lines.)@refill @xref{Format/Print Hardcopy}, for a description of the other @TeX{} related commands, such as @code{tex-show-print-queue}.@refill @node Texinfo Mode Summary, , Printing, Texinfo Mode @comment node-name, next, previous, up @section Texinfo Mode Summary In Texinfo mode, each set of commands has default keybindings that begin with the same keys. All the commands that are custom-created for Texinfo mode begin with @kbd{C-c}. The keys are somewhat mnemonic.@refill @subheading Insert Commands The insert commands are invoked by typing @kbd{C-c} twice and then the first letter of the @@-command to be inserted. (It might make more sense mnemonically to use @kbd{C-c C-i}, for `custom insert', but @kbd{C-c C-c} is quick to type.)@refill @example C-c C-c c @r{Insert} @samp{@@code}. C-c C-c d @r{Insert} @samp{@@dfn}. C-c C-c e @r{Insert} @samp{@@end}. C-c C-c i @r{Insert} @samp{@@item}. C-c C-c n @r{Insert} @samp{@@node}. C-c C-c s @r{Insert} @samp{@@samp}. C-c C-c v @r{Insert} @samp{@@var}. C-c C-c @{ @r{Insert braces.} C-c C-c ] C-c C-c @} @r{Move out of enclosing braces.} @group C-c C-c C-d @r{Insert a node's section title} @r{in the space for the description} @r{in a menu entry line.} @end group @end example @subheading Show Structure The @code{texinfo-show-structure} command is often used within a narrowed region.@refill @example C-c C-s @r{List all the headings.} @end example @subheading The Master Update Command The @code{texinfo-master-menu} command creates a master menu; and can be used to update every node and menu in a file as well.@refill @example @group C-c C-u m M-x texinfo-master-menu @r{Create or update a master menu.} @end group @group C-u C-c C-u m @r{With @kbd{C-u} as a prefix argument, first} @r{create or update all nodes and regular} @r{menus, and then create a master menu.} @end group @end example @subheading Update Pointers The update pointer commands are invoked by typing @kbd{C-c C-u} and then either @kbd{C-n} for @code{texinfo-update-node} or @kbd{C-e} for @code{texinfo-every-node-update}.@refill @example C-c C-u C-n @r{Update a node.} C-c C-u C-e @r{Update every node in the buffer.} @end example @subheading Update Menus Invoke the update menu commands by typing @kbd{C-c C-u} and then either @kbd{C-m} for @code{texinfo-make-menu} or @kbd{C-a} for @code{texinfo-all-menus-update}. To update both nodes and menus at the same time, precede @kbd{C-c C-u C-a} with @kbd{C-u}.@refill @example C-c C-u C-m @r{Make or update a menu.} @group C-c C-u C-a @r{Make or update all} @r{menus in a buffer.} @end group @group C-u C-c C-u C-a @r{With @kbd{C-u} as a prefix argument,} @r{first create or update all nodes and} @r{then create or update all menus.} @end group @end example @subheading Format for Info The Info formatting commands that are written in Emacs Lisp are invoked by typing @kbd{C-c C-e} and then either @kbd{C-r} for a region or @kbd{C-b} for the whole buffer.@refill The Info formatting commands that are written in C and based on the @code{makeinfo} program are invoked by typing @kbd{C-c C-m} and then either @kbd{C-r} for a region or @kbd{C-b} for the whole buffer.@refill @need 800 @noindent Use the @code{texinfo-format@dots{}} commands: @example @group C-c C-e C-r @r{Format the region.} C-c C-e C-b @r{Format the buffer.} @end group @end example @need 750 @noindent Use @code{makeinfo}: @example C-c C-m C-r @r{Format the region.} C-c C-m C-b @r{Format the buffer.} C-c C-m C-l @r{Recenter the @code{makeinfo} output buffer.} C-c C-m C-k @r{Kill the @code{makeinfo} formatting job.} @end example @subheading Typeset and Print The @TeX{} typesetting and printing commands are invoked by typing @kbd{C-c C-t} and then another control command: @kbd{C-r} for @code{texinfo-tex-region}, @kbd{C-b} for @code{texinfo-tex-buffer}, and so on.@refill @example C-c C-t C-r @r{Run @TeX{} on the region.} C-c C-t C-b @r{Run} @code{texi2dvi} @r{on the buffer.} C-c C-t C-i @r{Run} @code{texindex}. C-c C-t C-p @r{Print the DVI file.} C-c C-t C-q @r{Show the print queue.} C-c C-t C-d @r{Delete a job from the print queue.} C-c C-t C-k @r{Kill the current @TeX{} formatting job.} C-c C-t C-x @r{Quit a currently stopped @TeX{} formatting job.} C-c C-t C-l @r{Recenter the output buffer.} @end example @subheading Other Updating Commands The `other updating commands' do not have standard keybindings because they are rarely used. @example @group M-x texinfo-insert-node-lines @r{Insert missing @code{@@node} lines in region.} @r{With @kbd{C-u} as a prefix argument,} @r{use section titles as node names.} @end group @group M-x texinfo-multiple-files-update @r{Update a multi-file document.} @r{With @kbd{C-u 2} as a prefix argument,} @r{create or update all nodes and menus} @r{in all included files first.} @end group @group M-x texinfo-indent-menu-description @r{Indent descriptions.} @end group @group M-x texinfo-sequential-node-update @r{Insert node pointers in strict sequence.} @end group @end example @node Beginning a File, Ending a File, Texinfo Mode, Top @comment node-name, next, previous, up @chapter Beginning a Texinfo File @cindex Beginning a Texinfo file @cindex Texinfo file beginning @cindex File beginning Certain pieces of information must be provided at the beginning of a Texinfo file, such as the name of the file and the title of the document.@refill @menu * Four Parts:: Four parts begin a Texinfo file. * Sample Beginning:: Here is a sample beginning for a Texinfo file. * Header:: The very beginning of a Texinfo file. * Info Summary and Permissions:: Summary and copying permissions for Info. * Titlepage & Copyright Page:: Creating the title and copyright pages. * The Top Node:: Creating the `Top' node and master menu. * Software Copying Permissions:: Ensure that you and others continue to have the right to use and share software. @end menu @node Four Parts, Sample Beginning, Beginning a File, Beginning a File @ifinfo @heading Four Parts Begin a File @end ifinfo Generally, the beginning of a Texinfo file has four parts:@refill @enumerate @item The header, delimited by special comment lines, that includes the commands for naming the Texinfo file and telling @TeX{} what definitions file to use when processing the Texinfo file.@refill @item A short statement of what the file is about, with a copyright notice and copying permissions. This is enclosed in @code{@@ifinfo} and @code{@@end ifinfo} commands so that the formatters place it only in the Info file.@refill @item A title page and copyright page, with a copyright notice and copying permissions. This is enclosed between @code{@@titlepage} and @code{@@end titlepage} commands. The title and copyright page appear only in the printed @w{manual}.@refill @item The `Top' node that contains a menu for the whole Info file. The contents of this node appear only in the Info file.@refill @end enumerate Also, optionally, you may include the copying conditions for a program and a warranty disclaimer. The copying section will be followed by an introduction or else by the first chapter of the manual.@refill Since the copyright notice and copying permissions for the Texinfo document (in contrast to the copying permissions for a program) are in parts that appear only in the Info file or only in the printed manual, this information must be given twice.@refill @node Sample Beginning, Header, Four Parts, Beginning a File @comment node-name, next, previous, up @section Sample Texinfo File Beginning The following sample shows what is needed.@refill @example \input texinfo @@c -*-texinfo-*- @@c %**start of header @@setfilename @var{name-of-info-file} @@settitle @var{name-of-manual} @@setchapternewpage odd @@c %**end of header @@ifinfo This file documents @dots{} Copyright @var{year} @var{copyright-owner} @group Permission is granted to @dots{} @@end ifinfo @end group @group @@c This title page illustrates only one of the @@c two methods of forming a title page. @end group @group @@titlepage @@title @var{name-of-manual-when-printed} @@subtitle @var{subtitle-if-any} @@subtitle @var{second-subtitle} @@author @var{author} @end group @group @@c The following two commands @@c start the copyright page. @@page @@vskip 0pt plus 1filll Copyright @@copyright@{@} @var{year} @var{copyright-owner} @end group Published by @dots{} Permission is granted to @dots{} @@end titlepage @@node Top, Overview, , (dir) @@ifinfo This document describes @dots{} This document applies to version @dots{} of the program named @dots{} @@end ifinfo @group @@menu * Copying:: Your rights and freedoms. * First Chapter:: Getting started @dots{} * Second Chapter:: @dots{} @dots{} @dots{} @@end menu @end group @group @@node First Chapter, Second Chapter, top, top @@comment node-name, next, previous, up @@chapter First Chapter @@cindex Index entry for First Chapter @end group @end example @node Header, Info Summary and Permissions, Sample Beginning, Beginning a File @comment node-name, next, previous, up @section The Texinfo File Header @cindex Header for Texinfo files @cindex Texinfo file header Texinfo files start with at least three lines that provide Info and @TeX{} with necessary information. These are the @code{\input texinfo} line, the @code{@@settitle} line, and the @code{@@setfilename} line. If you want to run @TeX{} on just a part of the Texinfo File, you must write the @code{@@settitle} and @code{@@setfilename} lines between start-of-header and end-of-header lines.@refill Thus, the beginning of a Texinfo file looks like this: @example @group \input texinfo @@c -*-texinfo-*- @@setfilename sample.info @@settitle Sample Document @end group @end example @noindent or else like this: @example @group \input texinfo @@c -*-texinfo-*- @@c %**start of header @@setfilename sample.info @@settitle Sample Document @@c %**end of header @end group @end example @menu * First Line:: The first line of a Texinfo file. * Start of Header:: Formatting a region requires this. * setfilename:: Tell Info the name of the Info file. * settitle:: Create a title for the printed work. * setchapternewpage:: Start chapters on right-hand pages. * paragraphindent:: An option to specify paragraph indentation. * End of Header:: Formatting a region requires this. @end menu @node First Line, Start of Header, Header, Header @comment node-name, next, previous, up @subsection The First Line of a Texinfo File @cindex First line of a Texinfo file @cindex Beginning line of a Texinfo file @cindex Header of a Texinfo file Every Texinfo file that is to be the top-level input to @TeX{} must begin with a line that looks like this:@refill @example \input texinfo @@c -*-texinfo-*- @end example @noindent This line serves two functions: @enumerate @item When the file is processed by @TeX{}, the @samp{\input texinfo} command tells @TeX{} to load the macros needed for processing a Texinfo file. These are in a file called @file{texinfo.tex}, which is usually located in the @file{/usr/lib/tex/macros} directory. @TeX{} uses the backslash, @samp{\}, to mark the beginning of a command, just as Texinfo uses @samp{@@}. The @file{texinfo.tex} file causes the switch from @samp{\} to @samp{@@}; before the switch occurs, @TeX{} requires @samp{\}, which is why it appears at the beginning of the file.@refill @item When the file is edited in GNU Emacs, the @samp{-*-texinfo-*-} mode specification tells Emacs to use Texinfo mode.@refill @end enumerate @node Start of Header, setfilename, First Line, Header @comment node-name, next, previous, up @subsection Start of Header @cindex Start of header line Write a start-of-header line on the second line of a Texinfo file. Follow the start-of-header line with @code{@@setfilename} and @code{@@settitle} lines and, optionally, with other command lines, such as @code{@@smallbook} or @code{@@footnotestyle}; and then by an end-of-header line (@pxref{End of Header}).@refill With these lines, you can format part of a Texinfo file for Info or typeset part for printing.@refill A start-of-header line looks like this:@refill @example @@c %**start of header @end example The odd string of characters, @samp{%**}, is to ensure that no other comment is accidentally taken for a start-of-header line.@refill @node setfilename, settitle, Start of Header, Header @comment node-name, next, previous, up @subsection @code{@@setfilename} @cindex Info file requires @code{@@setfilename} @findex setfilename In order to serve as the primary input file for either @code{makeinfo} or @TeX{}, a Texinfo file must contain a line that looks like this: @example @@setfilename @var{info-file-name} @end example Write the @code{@@setfilename} command at the beginning of a line and follow it on the same line by the Info file name. Do not write anything else on the line; anything on the line after the command is considered part of the file name, including what would otherwise be a comment. The @code{@@setfilename} line specifies the name of the Info file to be generated. This name should be different from the name of the Texinfo file. There are two conventions for choosing the name: you can either remove the @samp{.texi} extension from the input file name, or replace it with the @samp{.info} extension. Some operating systems cannot handle long file names. You can run into a problem even when the file name you specify is itself short enough. This occurs because the Info formatters split a long Info file into short indirect subfiles, and name them by appending @samp{-1}, @samp{-2}, @dots{}, @samp{-10}, @samp{-11}, and so on, to the original file name. (@xref{Tag and Split Files, , Tag Files and Split Files}.) The subfile name @file{texinfo.info-10}, for example, is too long for some systems; so the Info file name for this document is @file{texinfo} rather than @file{texinfo.info}. @cindex Ignored before @code{@@setfilename} The Info formatting commands ignore everything written before the @code{@@setfilename} line, which is why the very first line of the file (the @code{\input} line) does not show up in the output. @pindex texinfo.cnf The @code{@@setfilename} line produces no output when you typeset a manual with @TeX{}, but it nevertheless is essential: it opens the index, cross-reference, and other auxiliary files used by Texinfo, and also reads @file{texinfo.cnf} if that file is present on your system (@pxref{Preparing for TeX,, Preparing to Use @TeX{}}). @node settitle, setchapternewpage, setfilename, Header @comment node-name, next, previous, up @subsection @code{@@settitle} @findex settitle In order to be made into a printed manual, a Texinfo file must contain a line that looks like this:@refill @example @@settitle @var{title} @end example Write the @code{@@settitle} command at the beginning of a line and follow it on the same line by the title. This tells @TeX{} the title to use in a header or footer. Do not write anything else on the line; anything on the line after the command is considered part of the title, including a comment.@refill Conventionally, when @TeX{} formats a Texinfo file for double-sided output, the title is printed in the left-hand (even-numbered) page headings and the current chapter title is printed in the right-hand (odd-numbered) page headings. (@TeX{} learns the title of each chapter from each @code{@@chapter} command.) Page footers are not printed.@refill Even if you are printing in a single-sided style, @TeX{} looks for an @code{@@settitle} command line, in case you include the manual title in the heading. @refill The @code{@@settitle} command should precede everything that generates actual output in @TeX{}.@refill Although the title in the @code{@@settitle} command is usually the same as the title on the title page, it does not affect the title as it appears on the title page. Thus, the two do not need not match exactly; and the title in the @code{@@settitle} command can be a shortened or expanded version of the title as it appears on the title page. (@xref{titlepage, , @code{@@titlepage}}.)@refill @TeX{} prints page headings only for that text that comes after the @code{@@end titlepage} command in the Texinfo file, or that comes after an @code{@@headings} command that turns on headings. (@xref{headings on off, , The @code{@@headings} Command}, for more information.)@refill You may, if you wish, create your own, customized headings and footings. @xref{Headings, , Page Headings}, for a detailed discussion of this process.@refill @node setchapternewpage, paragraphindent, settitle, Header @comment node-name, next, previous, up @subsection @code{@@setchapternewpage} @cindex Starting chapters @cindex Pages, starting odd @findex setchapternewpage In a book or a manual, text is usually printed on both sides of the paper, chapters start on right-hand pages, and right-hand pages have odd numbers. But in short reports, text often is printed only on one side of the paper. Also in short reports, chapters sometimes do not start on new pages, but are printed on the same page as the end of the preceding chapter, after a small amount of vertical whitespace.@refill You can use the @code{@@setchapternewpage} command with various arguments to specify how @TeX{} should start chapters and whether it should typeset pages for printing on one or both sides of the paper (single-sided or double-sided printing).@refill Write the @code{@@setchapternewpage} command at the beginning of a line followed by its argument.@refill For example, you would write the following to cause each chapter to start on a fresh odd-numbered page:@refill @example @@setchapternewpage odd @end example You can specify one of three alternatives with the @code{@@setchapternewpage} command:@refill @table @asis @ignore @item No @code{@@setchapternewpage} command If the Texinfo file does not contain an @code{@@setchapternewpage} command before the @code{@@titlepage} command, @TeX{} automatically begins chapters on new pages and prints headings in the standard format for single-sided printing. This is the conventional format for single-sided printing.@refill The result is exactly the same as when you write @code{@@setchapternewpage on}.@refill @end ignore @item @code{@@setchapternewpage off} Cause @TeX{} to typeset a new chapter on the same page as the last chapter, after skipping some vertical whitespace. Also, cause @TeX{} to format page headers for single-sided printing. (You can override the headers format with the @code{@@headings double} command; see @ref{headings on off, , The @code{@@headings} Command}.)@refill @item @code{@@setchapternewpage on} Cause @TeX{} to start new chapters on new pages and to typeset page headers for single-sided printing. This is the form most often used for short reports.@refill This alternative is the default.@refill @item @code{@@setchapternewpage odd} Cause @TeX{} to start new chapters on new, odd-numbered pages (right-handed pages) and to typeset for double-sided printing. This is the form most often used for books and manuals.@refill @end table @noindent Texinfo does not have an @code{@@setchapternewpage even} command.@refill @noindent (You can countermand or modify an @code{@@setchapternewpage} command with an @code{@@headings} command. @xref{headings on off, , The @code{@@headings} Command}.)@refill At the beginning of a manual or book, pages are not numbered---for example, the title and copyright pages of a book are not numbered. By convention, table of contents pages are numbered with roman numerals and not in sequence with the rest of the document.@refill Since an Info file does not have pages, the @code{@@setchapternewpage} command has no effect on it.@refill Usually, you do not write an @code{@@setchapternewpage} command for single-sided printing, but accept the default which is to typeset for single-sided printing and to start new chapters on new pages. Usually, you write an @code{@@setchapternewpage odd} command for double-sided printing.@refill @node paragraphindent, End of Header, setchapternewpage, Header @comment node-name, next, previous, up @subsection Paragraph Indenting @cindex Indenting paragraphs @cindex Paragraph indentation @findex paragraphindent The Info formatting commands may insert spaces at the beginning of the first line of each paragraph, thereby indenting that paragraph. You can use the @code{@@paragraphindent} command to specify the indentation. Write an @code{@@paragraphindent} command at the beginning of a line followed by either @samp{asis} or a number. The template is:@refill @example @@paragraphindent @var{indent} @end example The Info formatting commands indent according to the value of @var{indent}:@refill @itemize @bullet @item If the value of @var{indent} is @samp{asis}, the Info formatting commands do not change the existing indentation.@refill @item If the value of @var{indent} is zero, the Info formatting commands delete existing indentation.@refill @item If the value of @var{indent} is greater than zero, the Info formatting commands indent the paragraph by that number of spaces.@refill @end itemize The default value of @var{indent} is @samp{asis}.@refill Write the @code{@@paragraphindent} command before or shortly after the end-of-header line at the beginning of a Texinfo file. (If you write the command between the start-of-header and end-of-header lines, the region formatting commands indent paragraphs as specified.)@refill A peculiarity of the @code{texinfo-format-buffer} and @code{texinfo-format-region} commands is that they do not indent (nor fill) paragraphs that contain @code{@@w} or @code{@@*} commands. @xref{Refilling Paragraphs}, for a detailed description of what goes on.@refill @node End of Header, , paragraphindent, Header @comment node-name, next, previous, up @subsection End of Header @cindex End of header line Follow the header lines with an @w{end-of-header} line. An end-of-header line looks like this:@refill @example @@c %**end of header @end example If you include the @code{@@setchapternewpage} command between the start-of-header and end-of-header lines, @TeX{} will typeset a region as that command specifies. Similarly, if you include an @code{@@smallbook} command between the start-of-header and end-of-header lines, @TeX{} will typeset a region in the ``small'' book format.@refill @ifinfo The reason for the odd string of characters (@samp{%**}) is so that the @code{texinfo-tex-region} command does not accidentally find something that it should not when it is looking for the header.@refill The start-of-header line and the end-of-header line are Texinfo mode variables that you can change.@refill @end ifinfo @iftex @xref{Start of Header}. @end iftex @node Info Summary and Permissions, Titlepage & Copyright Page, Header, Beginning a File @comment node-name, next, previous, up @section Summary and Copying Permissions for Info The title page and the copyright page appear only in the printed copy of the manual; therefore, the same information must be inserted in a section that appears only in the Info file. This section usually contains a brief description of the contents of the Info file, a copyright notice, and copying permissions.@refill The copyright notice should read:@refill @example Copyright @var{year} @var{copyright-owner} @end example @noindent and be put on a line by itself.@refill Standard text for the copyright permissions is contained in an appendix to this manual; see @ref{ifinfo Permissions, , @samp{ifinfo} Copying Permissions}, for the complete text.@refill The permissions text appears in an Info file @emph{before} the first node. This mean that a reader does @emph{not} see this text when reading the file using Info, except when using the advanced Info command @kbd{g *}. @node Titlepage & Copyright Page, The Top Node, Info Summary and Permissions, Beginning a File @comment node-name, next, previous, up @section The Title and Copyright Pages A manual's name and author are usually printed on a title page. Sometimes copyright information is printed on the title page as well; more often, copyright information is printed on the back of the title page. The title and copyright pages appear in the printed manual, but not in the Info file. Because of this, it is possible to use several slightly obscure @TeX{} typesetting commands that cannot be used in an Info file. In addition, this part of the beginning of a Texinfo file contains the text of the copying permissions that will appear in the printed manual.@refill @xref{Titlepage Permissions, , Titlepage Copying Permissions}, for the standard text for the copyright permissions.@refill @menu * titlepage:: Create a title for the printed document. * titlefont center sp:: The @code{@@titlefont}, @code{@@center}, and @code{@@sp} commands. * title subtitle author:: The @code{@@title}, @code{@@subtitle}, and @code{@@author} commands. * Copyright & Permissions:: How to write the copyright notice and include copying permissions. * end titlepage:: Turn on page headings after the title and copyright pages. * headings on off:: An option for turning headings on and off and double or single sided printing. @end menu @node titlepage, titlefont center sp, Titlepage & Copyright Page, Titlepage & Copyright Page @comment node-name, next, previous, up @subsection @code{@@titlepage} @cindex Title page @findex titlepage Start the material for the title page and following copyright page with @code{@@titlepage} on a line by itself and end it with @code{@@end titlepage} on a line by itself.@refill The @code{@@end titlepage} command starts a new page and turns on page numbering. (@xref{Headings, , Page Headings}, for details about how to generate page headings.) All the material that you want to appear on unnumbered pages should be put between the @code{@@titlepage} and @code{@@end titlepage} commands. By using the @code{@@page} command you can force a page break within the region delineated by the @code{@@titlepage} and @code{@@end titlepage} commands and thereby create more than one unnumbered page. This is how the copyright page is produced. (The @code{@@titlepage} command might perhaps have been better named the @code{@@titleandadditionalpages} command, but that would have been rather long!)@refill @c !!! append refill to footnote when makeinfo can handle it. When you write a manual about a computer program, you should write the version of the program to which the manual applies on the title page. If the manual changes more frequently than the program or is independent of it, you should also include an edition number@footnote{We have found that it is helpful to refer to versions of manuals as `editions' and versions of programs as `versions'; otherwise, we find we are liable to confuse each other in conversation by referring to both the documentation and the software with the same words.} for the manual. This helps readers keep track of which manual is for which version of the program. (The `Top' node should also contain this information; see @ref{makeinfo top, , @code{@@top}}.)@refill Texinfo provides two main methods for creating a title page. One method uses the @code{@@titlefont}, @code{@@sp}, and @code{@@center} commands to generate a title page in which the words on the page are centered.@refill The second method uses the @code{@@title}, @code{@@subtitle}, and @code{@@author} commands to create a title page with black rules under the title and author lines and the subtitle text set flush to the right hand side of the page. With this method, you do not specify any of the actual formatting of the title page. You specify the text you want, and Texinfo does the formatting. You may use either method.@refill @findex shorttitlepage For extremely simple applications, Texinfo also provides a command @code{@@shorttitlepage} which takes a single argument as the title. The argument is typeset on a page by itself and followed by a blank page. @node titlefont center sp, title subtitle author, titlepage, Titlepage & Copyright Page @comment node-name, next, previous, up @subsection @code{@@titlefont}, @code{@@center}, and @code{@@sp} @findex titlefont @findex center @findex sp @r{(titlepage line spacing)} You can use the @code{@@titlefont}, @code{@@sp}, and @code{@@center} commands to create a title page for a printed document. (This is the first of the two methods for creating a title page in Texinfo.)@refill Use the @code{@@titlefont} command to select a large font suitable for the title itself.@refill @need 700 For example: @example @@titlefont@{Texinfo@} @end example Use the @code{@@center} command at the beginning of a line to center the remaining text on that line. Thus,@refill @example @@center @@titlefont@{Texinfo@} @end example @noindent centers the title, which in this example is ``Texinfo'' printed in the title font.@refill Use the @code{@@sp} command to insert vertical space. For example:@refill @example @@sp 2 @end example @noindent This inserts two blank lines on the printed page. (@xref{sp, , @code{@@sp}}, for more information about the @code{@@sp} command.)@refill A template for this method looks like this:@refill @example @group @@titlepage @@sp 10 @@center @@titlefont@{@var{name-of-manual-when-printed}@} @@sp 2 @@center @var{subtitle-if-any} @@sp 2 @@center @var{author} @dots{} @@end titlepage @end group @end example The spacing of the example fits an 8 1/2 by 11 inch manual.@refill @node title subtitle author, Copyright & Permissions, titlefont center sp, Titlepage & Copyright Page @comment node-name, next, previous, up @subsection @code{@@title}, @code{@@subtitle}, and @code{@@author} @findex title @findex subtitle @findex author You can use the @code{@@title}, @code{@@subtitle}, and @code{@@author} commands to create a title page in which the vertical and horizontal spacing is done for you automatically. This contrasts with the method described in the previous section, in which the @code{@@sp} command is needed to adjust vertical spacing.@refill Write the @code{@@title}, @code{@@subtitle}, or @code{@@author} commands at the beginning of a line followed by the title, subtitle, or author.@refill The @code{@@title} command produces a line in which the title is set flush to the left-hand side of the page in a larger than normal font. The title is underlined with a black rule.@refill The @code{@@subtitle} command sets subtitles in a normal-sized font flush to the right-hand side of the page.@refill The @code{@@author} command sets the names of the author or authors in a middle-sized font flush to the left-hand side of the page on a line near the bottom of the title page. The names are underlined with a black rule that is thinner than the rule that underlines the title. (The black rule only occurs if the @code{@@author} command line is followed by an @code{@@page} command line.)@refill There are two ways to use the @code{@@author} command: you can write the name or names on the remaining part of the line that starts with an @code{@@author} command:@refill @example @@author by Jane Smith and John Doe @end example @noindent or you can write the names one above each other by using two (or more) @code{@@author} commands:@refill @example @group @@author Jane Smith @@author John Doe @end group @end example @noindent (Only the bottom name is underlined with a black rule.)@refill @need 950 A template for this method looks like this:@refill @example @group @@titlepage @@title @var{name-of-manual-when-printed} @@subtitle @var{subtitle-if-any} @@subtitle @var{second-subtitle} @@author @var{author} @@page @dots{} @@end titlepage @end group @end example @ifinfo @noindent Contrast this form with the form of a title page written using the @code{@@sp}, @code{@@center}, and @code{@@titlefont} commands:@refill @example @@titlepage @@sp 10 @@center @@titlefont@{Name of Manual When Printed@} @@sp 2 @@center Subtitle, If Any @@sp 1 @@center Second subtitle @@sp 2 @@center Author @@page @dots{} @@end titlepage @end example @end ifinfo @node Copyright & Permissions, end titlepage, title subtitle author, Titlepage & Copyright Page @comment node-name, next, previous, up @subsection Copyright Page and Permissions @cindex Copyright page @cindex Printed permissions @cindex Permissions, printed By international treaty, the copyright notice for a book should be either on the title page or on the back of the title page. The copyright notice should include the year followed by the name of the organization or person who owns the copyright.@refill When the copyright notice is on the back of the title page, that page is customarily not numbered. Therefore, in Texinfo, the information on the copyright page should be within @code{@@titlepage} and @code{@@end titlepage} commands.@refill @findex vskip @findex filll @cindex Vertical whitespace (@samp{vskip}) Use the @code{@@page} command to cause a page break. To push the copyright notice and the other text on the copyright page towards the bottom of the page, you can write a somewhat mysterious line after the @code{@@page} command that reads like this:@refill @example @@vskip 0pt plus 1filll @end example @noindent This is a @TeX{} command that is not supported by the Info formatting commands. The @code{@@vskip} command inserts whitespace. The @samp{0pt plus 1filll} means to put in zero points of mandatory whitespace, and as much optional whitespace as needed to push the following text to the bottom of the page. Note the use of three @samp{l}s in the word @samp{filll}; this is the correct usage in @TeX{}.@refill @findex copyright In a printed manual, the @code{@@copyright@{@}} command generates a @samp{c} inside a circle. (In Info, it generates @samp{(C)}.) The copyright notice itself has the following legally defined sequence:@refill @example Copyright @copyright{} @var{year} @var{copyright-owner} @end example It is customary to put information on how to get a manual after the copyright notice, followed by the copying permissions for the manual.@refill Note that permissions must be given here as well as in the summary segment within @code{@@ifinfo} and @code{@@end ifinfo} that immediately follows the header since this text appears only in the printed manual and the @samp{ifinfo} text appears only in the Info file.@refill @xref{Sample Permissions}, for the standard text.@refill @node end titlepage, headings on off, Copyright & Permissions, Titlepage & Copyright Page @comment node-name, next, previous, up @subsection Heading Generation @findex end titlepage @cindex Headings, page, begin to appear @cindex Titlepage end starts headings @cindex End titlepage starts headings An @code{@@end titlepage} command on a line by itself not only marks the end of the title and copyright pages, but also causes @TeX{} to start generating page headings and page numbers. To repeat what is said elsewhere, Texinfo has two standard page heading formats, one for documents which are printed on one side of each sheet of paper (single-sided printing), and the other for documents which are printed on both sides of each sheet (double-sided printing). (@xref{setchapternewpage, ,@code{@@setchapternewpage}}.) You can specify these formats in different ways:@refill @itemize @bullet @item The conventional way is to write an @code{@@setchapternewpage} command before the title page commands, and then have the @code{@@end titlepage} command start generating page headings in the manner desired. (@xref{setchapternewpage, , @code{@@setchapternewpage}}.)@refill @item Alternatively, you can use the @code{@@headings} command to prevent page headings from being generated or to start them for either single or double-sided printing. (Write an @code{@@headings} command immediately after the @code{@@end titlepage} command. @xref{headings on off, , The @code{@@headings} Command}, for more information.)@refill @item Or, you may specify your own page heading and footing format. @xref{Headings, , Page Headings}, for detailed information about page headings and footings.@refill @end itemize Most documents are formatted with the standard single-sided or double-sided format, using @code{@@setchapternewpage odd} for double-sided printing and no @code{@@setchapternewpage} command for single-sided printing.@refill @node headings on off, , end titlepage, Titlepage & Copyright Page @comment node-name, next, previous, up @subsection The @code{@@headings} Command @findex headings The @code{@@headings} command is rarely used. It specifies what kind of page headings and footings to print on each page. Usually, this is controlled by the @code{@@setchapternewpage} command. You need the @code{@@headings} command only if the @code{@@setchapternewpage} command does not do what you want, or if you want to turn off pre-defined page headings prior to defining your own. Write an @code{@@headings} command immediately after the @code{@@end titlepage} command.@refill You can use @code{@@headings} as follows:@refill @table @code @item @@headings off Turn off printing of page headings.@refill @item @@headings single Turn on page headings appropriate for single-sided printing. @refill @item @@headings double Turn on page headings appropriate for double-sided printing. The two commands, @code{@@headings on} and @code{@@headings double}, are synonymous.@refill @item @@headings singleafter @itemx @@headings doubleafter Turn on @code{single} or @code{double} headings, respectively, after the current page is output. @item @@headings on Turn on page headings: @code{single} if @samp{@@setchapternewpage on}, @code{double} otherwise. @end table For example, suppose you write @code{@@setchapternewpage off} before the @code{@@titlepage} command to tell @TeX{} to start a new chapter on the same page as the end of the last chapter. This command also causes @TeX{} to typeset page headers for single-sided printing. To cause @TeX{} to typeset for double sided printing, write @code{@@headings double} after the @code{@@end titlepage} command. You can stop @TeX{} from generating any page headings at all by writing @code{@@headings off} on a line of its own immediately after the line containing the @code{@@end titlepage} command, like this:@refill @example @@end titlepage @@headings off @end example @noindent The @code{@@headings off} command overrides the @code{@@end titlepage} command, which would otherwise cause @TeX{} to print page headings.@refill You can also specify your own style of page heading and footing. @xref{Headings, , Page Headings}, for more information.@refill @node The Top Node, Software Copying Permissions, Titlepage & Copyright Page, Beginning a File @comment node-name, next, previous, up @section The `Top' Node and Master Menu @cindex @samp{@r{Top}} node @cindex Master menu @cindex Node, `Top' The `Top' node is the node from which you enter an Info file.@refill A `Top' node should contain a brief description of the Info file and an extensive, master menu for the whole Info file. This helps the reader understand what the Info file is about. Also, you should write the version number of the program to which the Info file applies; or, at least, the edition number.@refill The contents of the `Top' node should appear only in the Info file; none of it should appear in printed output, so enclose it between @code{@@ifinfo} and @code{@@end ifinfo} commands. (@TeX{} does not print either an @code{@@node} line or a menu; they appear only in Info; strictly speaking, you are not required to enclose these parts between @code{@@ifinfo} and @code{@@end ifinfo}, but it is simplest to do so. @xref{Conditionals, , Conditionally Visible Text}.)@refill @menu * Title of Top Node:: Sketch what the file is about. * Master Menu Parts:: A master menu has three or more parts. @end menu @node Title of Top Node, Master Menu Parts, The Top Node, The Top Node @ifinfo @subheading `Top' Node Title @end ifinfo Sometimes, you will want to place an @code{@@top} sectioning command line containing the title of the document immediately after the @code{@@node Top} line (@pxref{makeinfo top command, , The @code{@@top} Sectioning Command}, for more information).@refill For example, the beginning of the Top node of this manual contains an @code{@@top} sectioning command, a short description, and edition and version information. It looks like this:@refill @example @group @dots{} @@end titlepage @@ifinfo @@node Top, Copying, , (dir) @@top Texinfo Texinfo is a documentation system@dots{} @end group @group This is edition@dots{} @dots{} @@end ifinfo @end group @group @@menu * Copying:: Texinfo is freely redistributable. * Overview:: What is Texinfo? @dots{} @end group @@end menu @end example In a `Top' node, the `Previous', and `Up' nodes usually refer to the top level directory of the whole Info system, which is called @samp{(dir)}. The `Next' node refers to the first node that follows the main or master menu, which is usually the copying permissions, introduction, or first chapter.@refill @node Master Menu Parts, , Title of Top Node, The Top Node @subsection Parts of a Master Menu @cindex Master menu parts @cindex Parts of a master menu A @dfn{master menu} is a detailed main menu listing all the nodes in a file. A master menu is enclosed in @code{@@menu} and @code{@@end menu} commands and does not appear in the printed document.@refill Generally, a master menu is divided into parts.@refill @itemize @bullet @item The first part contains the major nodes in the Texinfo file: the nodes for the chapters, chapter-like sections, and the appendices.@refill @item The second part contains nodes for the indices.@refill @item The third and subsequent parts contain a listing of the other, lower level nodes, often ordered by chapter. This way, rather than go through an intermediary menu, an inquirer can go directly to a particular node when searching for specific information. These menu items are not required; add them if you think they are a convenience. If you do use them, put @code{@@detailmenu} before the first one, and @code{@@end detailmenu} after the last; otherwise, @code{makeinfo} will get confused. @end itemize Each section in the menu can be introduced by a descriptive line. So long as the line does not begin with an asterisk, it will not be treated as a menu entry. (@xref{Writing a Menu}, for more information.)@refill For example, the master menu for this manual looks like the following (but has many more entries):@refill @example @group @@menu * Copying:: Texinfo is freely redistributable. * Overview:: What is Texinfo? * Texinfo Mode:: Special features in GNU Emacs. @dots{} @dots{} @end group @group * Command and Variable Index:: An entry for each @@-command. * Concept Index:: An entry for each concept. @end group @group @@detailmenu --- The Detailed Node Listing --- Overview of Texinfo * Info Files:: What is an Info file? * Printed Manuals:: Characteristics of a printed manual. @dots{} @dots{} @end group @group Using Texinfo Mode * Info on a Region:: Formatting part of a file for Info. @dots{} @dots{} @@end detailmenu @@end menu @end group @end example @node Software Copying Permissions, , The Top Node, Beginning a File @comment node-name, next, previous, up @section Software Copying Permissions @cindex Software copying permissions @cindex Copying software @cindex Distribution @cindex License agreement If the Texinfo file has a section containing the ``General Public License'' and the distribution information and a warranty disclaimer for the software that is documented, this section usually follows the `Top' node. The General Public License is very important to Project GNU software. It ensures that you and others will continue to have a right to use and share the software.@refill The copying and distribution information and the disclaimer are followed by an introduction or else by the first chapter of the manual.@refill @cindex Introduction, as part of file Although an introduction is not a required part of a Texinfo file, it is very helpful. Ideally, it should state clearly and concisely what the file is about and who would be interested in reading it. In general, an introduction would follow the licensing and distribution information, although sometimes people put it earlier in the document. Usually, an introduction is put in an @code{@@unnumbered} section. (@xref{unnumbered & appendix, , The @code{@@unnumbered} and @code{@@appendix} Commands}.)@refill @node Ending a File, Structuring, Beginning a File, Top @comment node-name, next, previous, up @chapter Ending a Texinfo File @cindex Ending a Texinfo file @cindex Texinfo file ending @cindex File ending @findex bye The end of a Texinfo file should include the commands that create indices and generate detailed and summary tables of contents. And it must include the @code{@@bye} command that marks the last line processed by @TeX{}.@refill @need 700 For example: @example @@node Concept Index, , Variables Index, Top @@c node-name, next, previous, up @@unnumbered Concept Index @@printindex cp @@contents @@bye @end example @menu * Printing Indices & Menus:: How to print an index in hardcopy and generate index menus in Info. * Contents:: How to create a table of contents. * File End:: How to mark the end of a file. @end menu @node Printing Indices & Menus, Contents, Ending a File, Ending a File @comment node-name, next, previous, up @section Index Menus and Printing an Index @findex printindex @cindex Printing an index @cindex Indices, printing and menus @cindex Generating menus with indices @cindex Menus generated with indices To print an index means to include it as part of a manual or Info file. This does not happen automatically just because you use @code{@@cindex} or other index-entry generating commands in the Texinfo file; those just cause the raw data for the index to be accumulated. To generate an index, you must include the @code{@@printindex} command at the place in the document where you want the index to appear. Also, as part of the process of creating a printed manual, you must run a program called @code{texindex} (@pxref{Format/Print Hardcopy}) to sort the raw data to produce a sorted index file. The sorted index file is what is actually used to print the index.@refill Texinfo offers six different types of predefined index: the concept index, the function index, the variables index, the keystroke index, the program index, and the data type index (@pxref{Predefined Indices}). Each index type has a two-letter name: @samp{cp}, @samp{fn}, @samp{vr}, @samp{ky}, @samp{pg}, and @samp{tp}. You may merge indices, or put them into separate sections (@pxref{Combining Indices}); or you may define your own indices (@pxref{New Indices, , Defining New Indices}).@refill The @code{@@printindex} command takes a two-letter index name, reads the corresponding sorted index file and formats it appropriately into an index.@refill @ignore The two-letter index names are: @table @samp @item cp concept index @item fn function index @item vr variable index @item ky key index @item pg program index @item tp data type index @end table @end ignore The @code{@@printindex} command does not generate a chapter heading for the index. Consequently, you should precede the @code{@@printindex} command with a suitable section or chapter command (usually @code{@@unnumbered}) to supply the chapter heading and put the index into the table of contents. Precede the @code{@@unnumbered} command with an @code{@@node} line.@refill @need 1200 For example: @smallexample @group @@node Variable Index, Concept Index, Function Index, Top @@comment node-name, next, previous, up @@unnumbered Variable Index @@printindex vr @end group @group @@node Concept Index, , Variable Index, Top @@comment node-name, next, previous, up @@unnumbered Concept Index @@printindex cp @end group @group @@summarycontents @@contents @@bye @end group @end smallexample @noindent (Readers often prefer that the concept index come last in a book, since that makes it easiest to find.)@refill @ignore @c TeX can do sorting, just not conveniently enough to handle sorting @c Texinfo indexes. --karl, 5may97. In @TeX{}, the @code{@@printindex} command needs a sorted index file to work from. @TeX{} does not know how to do sorting; this is a deficiency. @TeX{} writes output files of raw index data; use the @code{texindex} program to convert these files to sorted index files. (@xref{Format/Print Hardcopy}, for more information.)@refill @end ignore @node Contents, File End, Printing Indices & Menus, Ending a File @comment node-name, next, previous, up @section Generating a Table of Contents @cindex Table of contents @cindex Contents, Table of @findex contents @findex summarycontents @findex shortcontents The @code{@@chapter}, @code{@@section}, and other structuring commands supply the information to make up a table of contents, but they do not cause an actual table to appear in the manual. To do this, you must use the @code{@@contents} and @code{@@summarycontents} commands:@refill @table @code @item @@contents Generate a table of contents in a printed manual, including all chapters, sections, subsections, etc., as well as appendices and unnumbered chapters. (Headings generated by the @code{@@heading} series of commands do not appear in the table of contents.) The @code{@@contents} command should be written on a line by itself.@refill @item @@shortcontents @itemx @@summarycontents (@code{@@summarycontents} is a synonym for @code{@@shortcontents}; the two commands are exactly the same.)@refill Generate a short or summary table of contents that lists only the chapters (and appendices and unnumbered chapters). Omit sections, subsections and subsubsections. Only a long manual needs a short table of contents in addition to the full table of contents.@refill Write the @code{@@shortcontents} command on a line by itself right @emph{before} the @code{@@contents} command.@refill @end table The table of contents commands automatically generate a chapter-like heading at the top of the first table of contents page. Write the table of contents commands at the very end of a Texinfo file, just before the @code{@@bye} command, following any index sections---anything in the Texinfo file after the table of contents commands will be omitted from the table of contents.@refill When you print a manual with a table of contents, the table of contents are printed last and numbered with roman numerals. You need to place those pages in their proper place, after the title page, yourself. (This is the only collating you need to do for a printed manual. The table of contents is printed last because it is generated after the rest of the manual is typeset.)@refill @need 700 Here is an example of where to write table of contents commands:@refill @example @group @var{indices}@dots{} @@shortcontents @@contents @@bye @end group @end example Since an Info file uses menus instead of tables of contents, the Info formatting commands ignore the @code{@@contents} and @code{@@shortcontents} commands.@refill @node File End, , Contents, Ending a File @comment node-name, next, previous, up @section @code{@@bye} File Ending @findex bye An @code{@@bye} command terminates @TeX{} or Info formatting. None of the formatting commands see any of the file following @code{@@bye}. The @code{@@bye} command should be on a line by itself.@refill If you wish, you may follow the @code{@@bye} line with notes. These notes will not be formatted and will not appear in either Info or a printed manual; it is as if text after @code{@@bye} were within @code{@@ignore} @dots{} @code{@@end ignore}. Also, you may follow the @code{@@bye} line with a local variables list. @xref{Compile-Command, , Using Local Variables and the Compile Command}, for more information.@refill @node Structuring, Nodes, Ending a File, Top @comment node-name, next, previous, up @chapter Chapter Structuring @cindex Chapter structuring @cindex Structuring of chapters The @dfn{chapter structuring} commands divide a document into a hierarchy of chapters, sections, subsections, and subsubsections. These commands generate large headings; they also provide information for the table of contents of a printed manual (@pxref{Contents, , Generating a Table of Contents}).@refill The chapter structuring commands do not create an Info node structure, so normally you should put an @code{@@node} command immediately before each chapter structuring command (@pxref{Nodes}). The only time you are likely to use the chapter structuring commands without using the node structuring commands is if you are writing a document that contains no cross references and will never be transformed into Info format.@refill It is unlikely that you will ever write a Texinfo file that is intended only as an Info file and not as a printable document. If you do, you might still use chapter structuring commands to create a heading at the top of each node---but you don't need to.@refill @menu * Tree Structuring:: A manual is like an upside down tree @dots{} * Structuring Command Types:: How to divide a manual into parts. * makeinfo top:: The @code{@@top} command, part of the `Top' node. * chapter:: * unnumbered & appendix:: * majorheading & chapheading:: * section:: * unnumberedsec appendixsec heading:: * subsection:: * unnumberedsubsec appendixsubsec subheading:: * subsubsection:: Commands for the lowest level sections. * Raise/lower sections:: How to change commands' hierarchical level. @end menu @node Tree Structuring, Structuring Command Types, Structuring, Structuring @comment node-name, next, previous, up @section Tree Structure of Sections @cindex Tree structuring A Texinfo file is usually structured like a book with chapters, sections, subsections, and the like. This structure can be visualized as a tree (or rather as an upside-down tree) with the root at the top and the levels corresponding to chapters, sections, subsection, and subsubsections.@refill Here is a diagram that shows a Texinfo file with three chapters, each of which has two sections.@refill @example @group Top | ------------------------------------- | | | Chapter 1 Chapter 2 Chapter 3 | | | -------- -------- -------- | | | | | | Section Section Section Section Section Section 1.1 1.2 2.1 2.2 3.1 3.2 @end group @end example In a Texinfo file that has this structure, the beginning of Chapter 2 looks like this:@refill @example @group @@node Chapter 2, Chapter 3, Chapter 1, top @@chapter Chapter 2 @end group @end example The chapter structuring commands are described in the sections that follow; the @code{@@node} and @code{@@menu} commands are described in following chapters. (@xref{Nodes}, and see @ref{Menus}.)@refill @node Structuring Command Types, makeinfo top, Tree Structuring, Structuring @comment node-name, next, previous, up @section Types of Structuring Commands The chapter structuring commands fall into four groups or series, each of which contains structuring commands corresponding to the hierarchical levels of chapters, sections, subsections, and subsubsections.@refill The four groups are the @code{@@chapter} series, the @code{@@unnumbered} series, the @code{@@appendix} series, and the @code{@@heading} series.@refill Each command produces titles that have a different appearance on the printed page or Info file; only some of the commands produce titles that are listed in the table of contents of a printed book or manual.@refill @itemize @bullet @item The @code{@@chapter} and @code{@@appendix} series of commands produce numbered or lettered entries both in the body of a printed work and in its table of contents.@refill @item The @code{@@unnumbered} series of commands produce unnumbered entries both in the body of a printed work and in its table of contents. The @code{@@top} command, which has a special use, is a member of this series (@pxref{makeinfo top, , @code{@@top}}).@refill @item The @code{@@heading} series of commands produce unnumbered headings that do not appear in a table of contents. The heading commands never start a new page.@refill @item The @code{@@majorheading} command produces results similar to using the @code{@@chapheading} command but generates a larger vertical whitespace before the heading.@refill @item When an @code{@@setchapternewpage} command says to do so, the @code{@@chapter}, @code{@@unnumbered}, and @code{@@appendix} commands start new pages in the printed manual; the @code{@@heading} commands do not.@refill @end itemize @need 1000 Here are the four groups of chapter structuring commands:@refill @c Slightly different formatting for regular sized books and smallbooks. @ifset smallbook @sp 1 @tex {\let\rm=\indrm \let\tt=\indtt \halign{\hskip\itemindent#\hfil& \hskip.5em#\hfil& \hskip.5em#\hfil& \hskip.5em#\hfil\cr & & & \rm No new pages\cr \rm Numbered& \rm Unnumbered& \rm Lettered and numbered& \rm Unnumbered\cr \rm In contents& \rm In contents& \rm In contents& \rm Not in contents\cr & & & \cr & \tt @@top& & \tt @@majorheading\cr \tt @@chapter& \tt @@unnumbered& \tt @@appendix& \tt @@chapheading\cr \tt @@section& \tt @@unnumberedsec& \tt @@appendixsec& \tt @@heading\cr \tt @@subsection&\tt @@unnumberedsubsec&\tt @@appendixsubsec& \tt @@subheading\cr \tt @@subsubsection& \tt @@unnumberedsubsubsec& \tt @@appendixsubsubsec& \tt @@subsubheading\cr}} @end tex @end ifset @ifclear smallbook @sp 1 @tex \vbox{ \halign{\hskip\itemindent\hskip.5em#\hfil& \hskip.5em#\hfil& \hskip.5em#\hfil& \hskip.5em #\hfil\cr & & & \cr & & & \rm No new pages\cr \rm Numbered& \rm Unnumbered& \rm Lettered and numbered& \rm Unnumbered\cr \rm In contents& \rm In contents& \rm In contents& \rm Not in contents\cr & & & \cr & \tt @@top& & \tt @@majorheading\cr \tt @@chapter& \tt @@unnumbered& \tt @@appendix& \tt @@chapheading\cr \tt @@section& \tt @@unnumberedsec& \tt @@appendixsec& \tt @@heading\cr \tt @@subsection&\tt @@unnumberedsubsec&\tt @@appendixsubsec& \tt @@subheading\cr \tt @@subsubsection& \tt @@unnumberedsubsubsec& \tt @@appendixsubsubsec& \tt @@subsubheading\cr}} @end tex @end ifclear @ifinfo @example @group @r{No new pages} @r{Numbered} @r{Unnumbered} @r{Lettered and numbered} @r{Unnumbered} @r{In contents} @r{In contents} @r{In contents} @r{Not in contents} @@top @@majorheading @@chapter @@unnumbered @@appendix @@chapheading @@section @@unnumberedsec @@appendixsec @@heading @@subsection @@unnumberedsubsec @@appendixsubsec @@subheading @@subsubsection @@unnumberedsubsubsec @@appendixsubsubsec @@subsubheading @end group @end example @end ifinfo @c Cannot line up columns properly inside of an example because of roman @c proportional fonts. @ignore @ifset smallbook @iftex @smallexample @group @r{No new pages} @r{Numbered} @r{Unnumbered} @r{Lettered and numbered} @r{Unnumbered} @r{In contents} @r{In contents} @r{In contents} @r{Not in contents} @@top @@majorheading @@chapter @@unnumbered @@appendix @@chapheading @@section @@unnumberedsec @@appendixsec @@heading @@subsection @@unnumberedsubsec @@appendixsubsec @@subheading @@subsubsection @@unnumberedsubsubsec @@appendixsubsubsec @@subsubheading @end group @end smallexample @end iftex @end ifset @ifclear smallbook @iftex @smallexample @group @r{No new pages} @r{Numbered} @r{Unnumbered} @r{Lettered and numbered} @r{Unnumbered} @r{In contents} @r{In contents} @r{In contents} @r{Not in contents} @@top @@majorheading @@chapter @@unnumbered @@appendix @@chapheading @@section @@unnumberedsec @@appendixsec @@heading @@subsection @@unnumberedsubsec @@appendixsubsec @@subheading @@subsubsection @@unnumberedsubsubsec @@appendixsubsubsec @@subsubheading @end group @end smallexample @end iftex @end ignore @node makeinfo top, chapter, Structuring Command Types, Structuring @comment node-name, next, previous, up @section @code{@@top} The @code{@@top} command is a special sectioning command that you use only after an @samp{@@node Top} line at the beginning of a Texinfo file. The @code{@@top} command tells the @code{makeinfo} formatter which node is the `Top' node. It has the same typesetting effect as @code{@@unnumbered} (@pxref{unnumbered & appendix, , @code{@@unnumbered}, @code{@@appendix}}). For detailed information, see @ref{makeinfo top command, , The @code{@@top} Command}.@refill @node chapter, unnumbered & appendix, makeinfo top, Structuring @comment node-name, next, previous, up @section @code{@@chapter} @findex chapter @code{@@chapter} identifies a chapter in the document. Write the command at the beginning of a line and follow it on the same line by the title of the chapter.@refill For example, this chapter in this manual is entitled ``Chapter Structuring''; the @code{@@chapter} line looks like this:@refill @example @@chapter Chapter Structuring @end example In @TeX{}, the @code{@@chapter} command creates a chapter in the document, specifying the chapter title. The chapter is numbered automatically.@refill In Info, the @code{@@chapter} command causes the title to appear on a line by itself, with a line of asterisks inserted underneath. Thus, in Info, the above example produces the following output:@refill @example Chapter Structuring ******************* @end example @findex centerchap Texinfo also provides a command @code{@@centerchap}, which is analogous to @code{@@unnumbered}, but centers its argument in the printed output. This kind of stylistic choice is not usually offered by Texinfo. @c but the Hacker's Dictionary wanted it ... @node unnumbered & appendix, majorheading & chapheading, chapter, Structuring @comment node-name, next, previous, up @section @code{@@unnumbered}, @code{@@appendix} @findex unnumbered @findex appendix Use the @code{@@unnumbered} command to create a chapter that appears in a printed manual without chapter numbers of any kind. Use the @code{@@appendix} command to create an appendix in a printed manual that is labelled by letter instead of by number.@refill For Info file output, the @code{@@unnumbered} and @code{@@appendix} commands are equivalent to @code{@@chapter}: the title is printed on a line by itself with a line of asterisks underneath. (@xref{chapter, , @code{@@chapter}}.)@refill To create an appendix or an unnumbered chapter, write an @code{@@appendix} or @code{@@unnumbered} command at the beginning of a line and follow it on the same line by the title, as you would if you were creating a chapter.@refill @node majorheading & chapheading, section, unnumbered & appendix, Structuring @section @code{@@majorheading}, @code{@@chapheading} @findex majorheading @findex chapheading The @code{@@majorheading} and @code{@@chapheading} commands put chapter-like headings in the body of a document.@refill However, neither command causes @TeX{} to produce a numbered heading or an entry in the table of contents; and neither command causes @TeX{} to start a new page in a printed manual.@refill In @TeX{}, an @code{@@majorheading} command generates a larger vertical whitespace before the heading than an @code{@@chapheading} command but is otherwise the same.@refill In Info, the @code{@@majorheading} and @code{@@chapheading} commands are equivalent to @code{@@chapter}: the title is printed on a line by itself with a line of asterisks underneath. (@xref{chapter, , @code{@@chapter}}.)@refill @node section, unnumberedsec appendixsec heading, majorheading & chapheading, Structuring @comment node-name, next, previous, up @section @code{@@section} @findex section In a printed manual, an @code{@@section} command identifies a numbered section within a chapter. The section title appears in the table of contents. In Info, an @code{@@section} command provides a title for a segment of text, underlined with @samp{=}.@refill This section is headed with an @code{@@section} command and looks like this in the Texinfo file:@refill @example @@section @@code@{@@@@section@} @end example To create a section, write the @code{@@section} command at the beginning of a line and follow it on the same line by the section title.@refill Thus, @example @@section This is a section @end example @noindent produces @example @group This is a section ================= @end group @end example @noindent in Info. @node unnumberedsec appendixsec heading, subsection, section, Structuring @comment node-name, next, previous, up @section @code{@@unnumberedsec}, @code{@@appendixsec}, @code{@@heading} @findex unnumberedsec @findex appendixsec @findex heading The @code{@@unnumberedsec}, @code{@@appendixsec}, and @code{@@heading} commands are, respectively, the unnumbered, appendix-like, and heading-like equivalents of the @code{@@section} command. (@xref{section, , @code{@@section}}.)@refill @table @code @item @@unnumberedsec The @code{@@unnumberedsec} command may be used within an unnumbered chapter or within a regular chapter or appendix to provide an unnumbered section.@refill @item @@appendixsec @itemx @@appendixsection @code{@@appendixsection} is a longer spelling of the @code{@@appendixsec} command; the two are synonymous.@refill @findex appendixsection Conventionally, the @code{@@appendixsec} or @code{@@appendixsection} command is used only within appendices.@refill @item @@heading You may use the @code{@@heading} command anywhere you wish for a section-style heading that will not appear in the table of contents.@refill @end table @node subsection, unnumberedsubsec appendixsubsec subheading, unnumberedsec appendixsec heading, Structuring @comment node-name, next, previous, up @section The @code{@@subsection} Command @findex subsection Subsections are to sections as sections are to chapters. (@xref{section, , @code{@@section}}.) In Info, subsection titles are underlined with @samp{-}. For example,@refill @example @@subsection This is a subsection @end example @noindent produces @example @group This is a subsection -------------------- @end group @end example In a printed manual, subsections are listed in the table of contents and are numbered three levels deep.@refill @node unnumberedsubsec appendixsubsec subheading, subsubsection, subsection, Structuring @comment node-name, next, previous, up @section The @code{@@subsection}-like Commands @cindex Subsection-like commands @findex unnumberedsubsec @findex appendixsubsec @findex subheading The @code{@@unnumberedsubsec}, @code{@@appendixsubsec}, and @code{@@subheading} commands are, respectively, the unnumbered, appendix-like, and heading-like equivalents of the @code{@@subsection} command. (@xref{subsection, , @code{@@subsection}}.)@refill In Info, the @code{@@subsection}-like commands generate a title underlined with hyphens. In a printed manual, an @code{@@subheading} command produces a heading like that of a subsection except that it is not numbered and does not appear in the table of contents. Similarly, an @code{@@unnumberedsubsec} command produces an unnumbered heading like that of a subsection and an @code{@@appendixsubsec} command produces a subsection-like heading labelled with a letter and numbers; both of these commands produce headings that appear in the table of contents.@refill @node subsubsection, Raise/lower sections, unnumberedsubsec appendixsubsec subheading, Structuring @comment node-name, next, previous, up @section The `subsub' Commands @cindex Subsub commands @findex subsubsection @findex unnumberedsubsubsec @findex appendixsubsubsec @findex subsubheading The fourth and lowest level sectioning commands in Texinfo are the `subsub' commands. They are:@refill @table @code @item @@subsubsection Subsubsections are to subsections as subsections are to sections. (@xref{subsection, , @code{@@subsection}}.) In a printed manual, subsubsection titles appear in the table of contents and are numbered four levels deep.@refill @item @@unnumberedsubsubsec Unnumbered subsubsection titles appear in the table of contents of a printed manual, but lack numbers. Otherwise, unnumbered subsubsections are the same as subsubsections. In Info, unnumbered subsubsections look exactly like ordinary subsubsections.@refill @item @@appendixsubsubsec Conventionally, appendix commands are used only for appendices and are lettered and numbered appropriately in a printed manual. They also appear in the table of contents. In Info, appendix subsubsections look exactly like ordinary subsubsections.@refill @item @@subsubheading The @code{@@subsubheading} command may be used anywhere that you need a small heading that will not appear in the table of contents. In Info, subsubheadings look exactly like ordinary subsubsection headings.@refill @end table In Info, `subsub' titles are underlined with periods. For example,@refill @example @@subsubsection This is a subsubsection @end example @noindent produces @example @group This is a subsubsection ....................... @end group @end example @node Raise/lower sections, , subsubsection, Structuring @comment node-name, next, previous, up @section @code{@@raisesections} and @code{@@lowersections} @findex raisesections @findex lowersections @cindex Raising and lowering sections @cindex Sections, raising and lowering The @code{@@raisesections} and @code{@@lowersections} commands raise and lower the hierarchical level of chapters, sections, subsections and the like. The @code{@@raisesections} command changes sections to chapters, subsections to sections, and so on. The @code{@@lowersections} command changes chapters to sections, sections to subsections, and so on. @cindex Include files, and section levels An @code{@@lowersections} command is useful if you wish to include text that is written as an outer or standalone Texinfo file in another Texinfo file as an inner, included file. If you write the command at the beginning of the file, all your @code{@@chapter} commands are formatted as if they were @code{@@section} commands, all your @code{@@section} command are formatted as if they were @code{@@subsection} commands, and so on. @need 1000 @code{@@raisesections} raises a command one level in the chapter structuring hierarchy:@refill @example @group @r{Change} @r{To} @@subsection @@section, @@section @@chapter, @@heading @@chapheading, @r{etc.} @end group @end example @need 1000 @code{@@lowersections} lowers a command one level in the chapter structuring hierarchy:@refill @example @group @r{Change} @r{To} @@chapter @@section, @@subsection @@subsubsection, @@heading @@subheading, @r{etc.} @end group @end example An @code{@@raisesections} or @code{@@lowersections} command changes only those structuring commands that follow the command in the Texinfo file. Write an @code{@@raisesections} or @code{@@lowersections} command on a line of its own. An @code{@@lowersections} command cancels an @code{@@raisesections} command, and vice versa. Typically, the commands are used like this: @example @@lowersections @@include somefile.texi @@raisesections @end example Without the @code{@@raisesections}, all the subsequent sections in your document will be lowered. Repeated use of the commands continue to raise or lower the hierarchical level a step at a time. An attempt to raise above `chapters' reproduces chapter commands; an attempt to lower below `subsubsections' reproduces subsubsection commands. @node Nodes, Menus, Structuring, Top @comment node-name, next, previous, up @chapter Nodes @dfn{Nodes} are the primary segments of a Texinfo file. They do not themselves impose a hierarchic or any other kind of structure on a file. Nodes contain @dfn{node pointers} that name other nodes, and can contain @dfn{menus} which are lists of nodes. In Info, the movement commands can carry you to a pointed-to node or to a node listed in a menu. Node pointers and menus provide structure for Info files just as chapters, sections, subsections, and the like, provide structure for printed books.@refill @menu * Two Paths:: Different commands to structure Info output and printed output. * Node Menu Illustration:: A diagram, and sample nodes and menus. * node:: How to write a node, in detail. * makeinfo Pointer Creation:: How to create node pointers with @code{makeinfo}. @end menu @node Two Paths, Node Menu Illustration, Nodes, Nodes @ifinfo @heading Two Paths @end ifinfo The node and menu commands and the chapter structuring commands are independent of each other: @itemize @bullet @item In Info, node and menu commands provide structure. The chapter structuring commands generate headings with different kinds of underlining---asterisks for chapters, hyphens for sections, and so on; they do nothing else.@refill @item In @TeX{}, the chapter structuring commands generate chapter and section numbers and tables of contents. The node and menu commands provide information for cross references; they do nothing else.@refill @end itemize You can use node pointers and menus to structure an Info file any way you want; and you can write a Texinfo file so that its Info output has a different structure than its printed output. However, most Texinfo files are written such that the structure for the Info output corresponds to the structure for the printed output. It is not convenient to do otherwise.@refill Generally, printed output is structured in a tree-like hierarchy in which the chapters are the major limbs from which the sections branch out. Similarly, node pointers and menus are organized to create a matching structure in the Info output.@refill @node Node Menu Illustration, node, Two Paths, Nodes @comment node-name, next, previous, up @section Node and Menu Illustration Here is a copy of the diagram shown earlier that illustrates a Texinfo file with three chapters, each of which contains two sections.@refill Note that the ``root'' is at the top of the diagram and the ``leaves'' are at the bottom. This is how such a diagram is drawn conventionally; it illustrates an upside-down tree. For this reason, the root node is called the `Top' node, and `Up' node pointers carry you closer to the root.@refill @example @group Top | ------------------------------------- | | | Chapter 1 Chapter 2 Chapter 3 | | | -------- -------- -------- | | | | | | Section Section Section Section Section Section 1.1 1.2 2.1 2.2 3.1 3.2 @end group @end example Write the beginning of the node for Chapter 2 like this:@refill @example @group @@node Chapter 2, Chapter 3, Chapter 1, top @@comment node-name, next, previous, up @end group @end example @noindent This @code{@@node} line says that the name of this node is ``Chapter 2'', the name of the `Next' node is ``Chapter 3'', the name of the `Previous' node is ``Chapter 1'', and the name of the `Up' node is ``Top''. @quotation @strong{Please Note:} `Next' refers to the next node at the same hierarchical level in the manual, not necessarily to the next node within the Texinfo file. In the Texinfo file, the subsequent node may be at a lower level---a section-level node may follow a chapter-level node, and a subsection-level node may follow a section-level node. `Next' and `Previous' refer to nodes at the @emph{same} hierarchical level. (The `Top' node contains the exception to this rule. Since the `Top' node is the only node at that level, `Next' refers to the first following node, which is almost always a chapter or chapter-level node.)@refill @end quotation To go to Sections 2.1 and 2.2 using Info, you need a menu inside Chapter 2. (@xref{Menus}.) You would write the menu just before the beginning of Section 2.1, like this:@refill @example @group @@menu * Sect. 2.1:: Description of this section. * Sect. 2.2:: @@end menu @end group @end example Write the node for Sect. 2.1 like this:@refill @example @group @@node Sect. 2.1, Sect. 2.2, Chapter 2, Chapter 2 @@comment node-name, next, previous, up @end group @end example In Info format, the `Next' and `Previous' pointers of a node usually lead to other nodes at the same level---from chapter to chapter or from section to section (sometimes, as shown, the `Previous' pointer points up); an `Up' pointer usually leads to a node at the level above (closer to the `Top' node); and a `Menu' leads to nodes at a level below (closer to `leaves'). (A cross reference can point to a node at any level; see @ref{Cross References}.)@refill Usually, an @code{@@node} command and a chapter structuring command are used in sequence, along with indexing commands. (You may follow the @code{@@node} line with a comment line that reminds you which pointer is which.)@refill Here is the beginning of the chapter in this manual called ``Ending a Texinfo File''. This shows an @code{@@node} line followed by a comment line, an @code{@@chapter} line, and then by indexing lines.@refill @example @group @@node Ending a File, Structuring, Beginning a File, Top @@comment node-name, next, previous, up @@chapter Ending a Texinfo File @@cindex Ending a Texinfo file @@cindex Texinfo file ending @@cindex File ending @end group @end example @node node, makeinfo Pointer Creation, Node Menu Illustration, Nodes @comment node-name, next, previous, up @section The @code{@@node} Command @cindex Node, defined A @dfn{node} is a segment of text that begins at an @code{@@node} command and continues until the next @code{@@node} command. The definition of node is different from that for chapter or section. A chapter may contain sections and a section may contain subsections; but a node cannot contain subnodes; the text of a node continues only until the next @code{@@node} command in the file. A node usually contains only one chapter structuring command, the one that follows the @code{@@node} line. On the other hand, in printed output nodes are used only for cross references, so a chapter or section may contain any number of nodes. Indeed, a chapter usually contains several nodes, one for each section, subsection, and subsubsection.@refill To create a node, write an @code{@@node} command at the beginning of a line, and follow it with four arguments, separated by commas, on the rest of the same line. These arguments are the name of the node, and the names of the `Next', `Previous', and `Up' pointers, in that order. You may insert spaces before each pointer if you wish; the spaces are ignored. You must write the name of the node, and the names of the `Next', `Previous', and `Up' pointers, all on the same line. Otherwise, the formatters fail. (@inforef{Top, info, info}, for more information about nodes in Info.)@refill Usually, you write one of the chapter-structuring command lines immediately after an @code{@@node} line---for example, an @code{@@section} or @code{@@subsection} line. (@xref{Structuring Command Types, , Types of Structuring Commands}.)@refill @quotation @strong{Please note:} The GNU Emacs Texinfo mode updating commands work only with Texinfo files in which @code{@@node} lines are followed by chapter structuring lines. @xref{Updating Requirements}.@refill @end quotation @TeX{} uses @code{@@node} lines to identify the names to use for cross references. For this reason, you must write @code{@@node} lines in a Texinfo file that you intend to format for printing, even if you do not intend to format it for Info. (Cross references, such as the one at the end of this sentence, are made with @code{@@xref} and its related commands; see @ref{Cross References}.)@refill @menu * Node Names:: How to choose node and pointer names. * Writing a Node:: How to write an @code{@@node} line. * Node Line Tips:: Keep names short. * Node Line Requirements:: Keep names unique, without @@-commands. * First Node:: How to write a `Top' node. * makeinfo top command:: How to use the @code{@@top} command. * Top Node Summary:: Write a brief description for readers. @end menu @node Node Names, Writing a Node, node, node @ifinfo @subheading Choosing Node and Pointer Names @end ifinfo The name of a node identifies the node. The pointers enable you to reach other nodes and consist of the names of those nodes.@refill Normally, a node's `Up' pointer contains the name of the node whose menu mentions that node. The node's `Next' pointer contains the name of the node that follows that node in that menu and its `Previous' pointer contains the name of the node that precedes it in that menu. When a node's `Previous' node is the same as its `Up' node, both node pointers name the same node.@refill Usually, the first node of a Texinfo file is the `Top' node, and its `Up' and `Previous' pointers point to the @file{dir} file, which contains the main menu for all of Info.@refill The `Top' node itself contains the main or master menu for the manual. Also, it is helpful to include a brief description of the manual in the `Top' node. @xref{First Node}, for information on how to write the first node of a Texinfo file.@refill @node Writing a Node, Node Line Tips, Node Names, node @comment node-name, next, previous, up @subsection How to Write an @code{@@node} Line @cindex Writing an @code{@@node} line @cindex @code{@@node} line writing @cindex Node line writing The easiest way to write an @code{@@node} line is to write @code{@@node} at the beginning of a line and then the name of the node, like this:@refill @example @@node @var{node-name} @end example If you are using GNU Emacs, you can use the update node commands provided by Texinfo mode to insert the names of the pointers; or you can leave the pointers out of the Texinfo file and let @code{makeinfo} insert node pointers into the Info file it creates. (@xref{Texinfo Mode}, and @ref{makeinfo Pointer Creation}.)@refill Alternatively, you can insert the `Next', `Previous', and `Up' pointers yourself. If you do this, you may find it helpful to use the Texinfo mode keyboard command @kbd{C-c C-c n}. This command inserts @samp{@@node} and a comment line listing the names of the pointers in their proper order. The comment line helps you keep track of which arguments are for which pointers. This comment line is especially useful if you are not familiar with Texinfo.@refill The template for a node line with `Next', `Previous', and `Up' pointers looks like this:@refill @example @@node @var{node-name}, @var{next}, @var{previous}, @var{up} @end example If you wish, you can ignore @code{@@node} lines altogether in your first draft and then use the @code{texinfo-insert-node-lines} command to create @code{@@node} lines for you. However, we do not recommend this practice. It is better to name the node itself at the same time that you write a segment so you can easily make cross references. A large number of cross references are an especially important feature of a good Info file.@refill After you have inserted an @code{@@node} line, you should immediately write an @@-command for the chapter or section and insert its name. Next (and this is important!), put in several index entries. Usually, you will find at least two and often as many as four or five ways of referring to the node in the index. Use them all. This will make it much easier for people to find the node.@refill @node Node Line Tips, Node Line Requirements, Writing a Node, node @comment node-name, next, previous, up @subsection @code{@@node} Line Tips Here are three suggestions: @itemize @bullet @item Try to pick node names that are informative but short.@refill In the Info file, the file name, node name, and pointer names are all inserted on one line, which may run into the right edge of the window. (This does not cause a problem with Info, but is ugly.)@refill @item Try to pick node names that differ from each other near the beginnings of their names. This way, it is easy to use automatic name completion in Info.@refill @item By convention, node names are capitalized just as they would be for section or chapter titles---initial and significant words are capitalized; others are not.@refill @end itemize @node Node Line Requirements, First Node, Node Line Tips, node @comment node-name, next, previous, up @subsection @code{@@node} Line Requirements @cindex Node line requirements Here are several requirements for @code{@@node} lines: @itemize @bullet @cindex Unique nodename requirement @cindex Nodename must be unique @item All the node names for a single Info file must be unique.@refill Duplicates confuse the Info movement commands. This means, for example, that if you end every chapter with a summary, you must name each summary node differently. You cannot just call each one ``Summary''. You may, however, duplicate the titles of chapters, sections, and the like. Thus you can end each chapter in a book with a section called ``Summary'', so long as the node names for those sections are all different.@refill @item A pointer name must be the name of a node.@refill The node to which a pointer points may come before or after the node containing the pointer.@refill @cindex @@-command in nodename @cindex Nodename, cannot contain @item You cannot use any of the Texinfo @@-commands in a node name; @w{@@-commands} confuse Info.@refill @need 750 Thus, the beginning of the section called @code{@@chapter} looks like this:@refill @smallexample @group @@node chapter, unnumbered & appendix, makeinfo top, Structuring @@comment node-name, next, previous, up @@section @@code@{@@@@chapter@} @@findex chapter @end group @end smallexample @cindex Comma in nodename @cindex Apostrophe in nodename @item You cannot use commas or apostrophes within a node name; these confuse @TeX{} or the Info formatters.@refill @need 700 For example, the following is a section title: @smallexample @@code@{@@@@unnumberedsec@}, @@code@{@@@@appendixsec@}, @@code@{@@@@heading@} @end smallexample @noindent The corresponding node name is: @smallexample unnumberedsec appendixsec heading @end smallexample @cindex Case in nodename @item Case is significant. @end itemize @node First Node, makeinfo top command, Node Line Requirements, node @comment node-name, next, previous, up @subsection The First Node @cindex Top node is first @cindex First node The first node of a Texinfo file is the @dfn{Top} node, except in an included file (@pxref{Include Files}). The Top node contains the main or master menu for the document, and a short summary of the document (@pxref{Top Node Summary}). @cindex Up node of Top node @cindex (dir) as Up node of Top node The Top node (which must be named @samp{top} or @samp{Top}) should have as its `Up' node the name of a node in another file, where there is a menu that leads to this file. Specify the file name in parentheses. If the file is to be installed directly in the Info directory file, use @samp{(dir)} as the parent of the Top node; this is short for @samp{(dir)top}, and specifies the Top node in the @file{dir} file, which contains the main menu for the Info system as a whole. For example, the @code{@@node Top} line of this manual looks like this: @example @@node Top, Copying, , (dir) @end example @noindent (You can use the Texinfo updating commands or the @code{makeinfo} utility to insert these pointers automatically.) @cindex Previous node of Top node Do not define the `Previous' node of the Top node to be @samp{(dir)}, as it causes confusing behavior for users: if you are in the Top node and hits @key{DEL} to go backwards, you wind up in the middle of the some other entry in the @file{dir} file, which has nothing to do with what you were reading. @xref{Install an Info File}, for more information about installing an Info file in the @file{info} directory. @node makeinfo top command, Top Node Summary, First Node, node @comment node-name, next, previous, up @subsection The @code{@@top} Sectioning Command @findex top @r{(@@-command)} A special sectioning command, @code{@@top}, has been created for use with the @code{@@node Top} line. The @code{@@top} sectioning command tells @code{makeinfo} that it marks the `Top' node in the file. It provides the information that @code{makeinfo} needs to insert node pointers automatically. Write the @code{@@top} command at the beginning of the line immediately following the @code{@@node Top} line. Write the title on the remaining part of the same line as the @code{@@top} command.@refill In Info, the @code{@@top} sectioning command causes the title to appear on a line by itself, with a line of asterisks inserted underneath.@refill In @TeX{} and @code{texinfo-format-buffer}, the @code{@@top} sectioning command is merely a synonym for @code{@@unnumbered}. Neither of these formatters require an @code{@@top} command, and do nothing special with it. You can use @code{@@chapter} or @code{@@unnumbered} after the @code{@@node Top} line when you use these formatters. Also, you can use @code{@@chapter} or @code{@@unnumbered} when you use the Texinfo updating commands to create or update pointers and menus.@refill @node Top Node Summary, , makeinfo top command, node @subsection The `Top' Node Summary @cindex @samp{@r{Top}} node summary You can help readers by writing a summary in the `Top' node, after the @code{@@top} line, before the main or master menu. The summary should briefly describe the document. In Info, this summary will appear just before the master menu. In a printed manual, this summary will appear on a page of its own.@refill If you do not want the summary to appear on a page of its own in a printed manual, you can enclose the whole of the `Top' node, including the @code{@@node Top} line and the @code{@@top} sectioning command line or other sectioning command line between @code{@@ifinfo} and @code{@@end ifinfo}. This prevents any of the text from appearing in the printed output. (@pxref{Conditionals, , Conditionally Visible Text}). You can repeat the brief description from the `Top' node within @code{@@iftex} @dots{} @code{@@end iftex} at the beginning of the first chapter, for those who read the printed manual. This saves paper and may look neater.@refill You should write the version number of the program to which the manual applies in the summary. This helps the reader keep track of which manual is for which version of the program. If the manual changes more frequently than the program or is independent of it, you should also include an edition number for the manual. (The title page should also contain this information: see @ref{titlepage, , @code{@@titlepage}}.)@refill @node makeinfo Pointer Creation, , node, Nodes @section Creating Pointers with @code{makeinfo} @cindex Creating pointers with @code{makeinfo} @cindex Pointer creation with @code{makeinfo} @cindex Automatic pointer creation with @code{makeinfo} The @code{makeinfo} program has a feature for automatically creating node pointers for a hierarchically organized file that lacks them.@refill When you take advantage of this feature, you do not need to write the `Next', `Previous', and `Up' pointers after the name of a node. However, you must write a sectioning command, such as @code{@@chapter} or @code{@@section}, on the line immediately following each truncated @code{@@node} line. You cannot write a comment line after a node line; the section line must follow it immediately.@refill In addition, you must follow the `Top' @code{@@node} line with a line beginning with @code{@@top} to mark the `Top' node in the file. @xref{makeinfo top, , @code{@@top}}. Finally, you must write the name of each node (except for the `Top' node) in a menu that is one or more hierarchical levels above the node's hierarchical level.@refill This node pointer insertion feature in @code{makeinfo} is an alternative to the menu and pointer creation and update commands in Texinfo mode. (@xref{Updating Nodes and Menus}.) It is especially helpful to people who do not use GNU Emacs for writing Texinfo documents.@refill @node Menus, Cross References, Nodes, Top @comment node-name, next, previous, up @chapter Menus @cindex Menus @findex menu @dfn{Menus} contain pointers to subordinate nodes.@footnote{Menus can carry you to any node, regardless of the hierarchical structure; even to nodes in a different Info file. However, the GNU Emacs Texinfo mode updating commands work only to create menus of subordinate nodes. Conventionally, cross references are used to refer to other nodes.} In Info, you use menus to go to such nodes. Menus have no effect in printed manuals and do not appear in them.@refill By convention, a menu is put at the end of a node since a reader who uses the menu may not see text that follows it.@refill @ifinfo A node that has a menu should @emph{not} contain much text. If you have a lot of text and a menu, move most of the text into a new subnode---all but a few lines.@refill @end ifinfo @iftex @emph{A node that has a menu should not contain much text.} If you have a lot of text and a menu, move most of the text into a new subnode---all but a few lines. Otherwise, a reader with a terminal that displays only a few lines may miss the menu and its associated text. As a practical matter, you should locate a menu within 20 lines of the beginning of the node.@refill @end iftex @menu * Menu Location:: Put a menu in a short node. * Writing a Menu:: What is a menu? * Menu Parts:: A menu entry has three parts. * Less Cluttered Menu Entry:: Two part menu entry. * Menu Example:: Two and three part menu entries. * Other Info Files:: How to refer to a different Info file. @end menu @node Menu Location, Writing a Menu, Menus, Menus @ifinfo @heading Menus Need Short Nodes @end ifinfo @cindex Menu location @cindex Location of menus @cindex Nodes for menus are short @cindex Short nodes for menus @ifinfo A reader can easily see a menu that is close to the beginning of the node. The node should be short. As a practical matter, you should locate a menu within 20 lines of the beginning of the node. Otherwise, a reader with a terminal that displays only a few lines may miss the menu and its associated text.@refill @end ifinfo The short text before a menu may look awkward in a printed manual. To avoid this, you can write a menu near the beginning of its node and follow the menu by an @code{@@node} line, and then an @code{@@heading} line located within @code{@@ifinfo} and @code{@@end ifinfo}. This way, the menu, @code{@@node} line, and title appear only in the Info file, not the printed document.@refill For example, the preceding two paragraphs follow an Info-only menu, @code{@@node} line, and heading, and look like this:@refill @example @group @@menu * Menu Location:: Put a menu in a short node. * Writing a Menu:: What is a menu? * Menu Parts:: A menu entry has three parts. * Less Cluttered Menu Entry:: Two part menu entry. * Menu Example:: Two and three part entries. * Other Info Files:: How to refer to a different Info file. @@end menu @@node Menu Location, Writing a Menu, , Menus @@ifinfo @@heading Menus Need Short Nodes @@end ifinfo @end group @end example The Texinfo file for this document contains more than a dozen examples of this procedure. One is at the beginning of this chapter; another is at the beginning of the ``Cross References'' chapter.@refill @node Writing a Menu, Menu Parts, Menu Location, Menus @section Writing a Menu @cindex Writing a menu @cindex Menu writing A menu consists of an @code{@@menu} command on a line by itself followed by menu entry lines or menu comment lines and then by an @code{@@end menu} command on a line by itself.@refill A menu looks like this:@refill @example @group @@menu Larger Units of Text * Files:: All about handling files. * Multiples: Buffers. Multiple buffers; editing several files at once. @@end menu @end group @end example In a menu, every line that begins with an @w{@samp{* }} is a @dfn{menu entry}. (Note the space after the asterisk.) A line that does not start with an @w{@samp{* }} may also appear in a menu. Such a line is not a menu entry but is a menu comment line that appears in the Info file. In the example above, the line @samp{Larger Units of Text} is a menu comment line; the two lines starting with @w{@samp{* }} are menu entries. @node Menu Parts, Less Cluttered Menu Entry, Writing a Menu, Menus @section The Parts of a Menu @cindex Parts of a menu @cindex Menu parts @cindex @code{@@menu} parts A menu entry has three parts, only the second of which is required: @enumerate @item The menu entry name (optional). @item The name of the node (required). @item A description of the item (optional). @end enumerate The template for a menu entry looks like this:@refill @example * @var{menu-entry-name}: @var{node-name}. @var{description} @end example Follow the menu entry name with a single colon and follow the node name with tab, comma, period, or newline.@refill In Info, a user selects a node with the @kbd{m} (@code{Info-menu}) command. The menu entry name is what the user types after the @kbd{m} command.@refill The third part of a menu entry is a descriptive phrase or sentence. Menu entry names and node names are often short; the description explains to the reader what the node is about. A useful description complements the node name rather than repeats it. The description, which is optional, can spread over two or more lines; if it does, some authors prefer to indent the second line while others prefer to align it with the first (and all others). It's up to you. @node Less Cluttered Menu Entry, Menu Example, Menu Parts, Menus @comment node-name, next, previous, up @section Less Cluttered Menu Entry @cindex Two part menu entry @cindex Double-colon menu entries @cindex Menu entries with two colons @cindex Less cluttered menu entry @cindex Uncluttered menu entry When the menu entry name and node name are the same, you can write the name immediately after the asterisk and space at the beginning of the line and follow the name with two colons.@refill @need 800 For example, write @example * Name:: @var{description} @end example @need 800 @noindent instead of @example * Name: Name. @var{description} @end example You should use the node name for the menu entry name whenever possible, since it reduces visual clutter in the menu.@refill @node Menu Example, Other Info Files, Less Cluttered Menu Entry, Menus @comment node-name, next, previous, up @section A Menu Example @cindex Menu example @cindex Example menu A menu looks like this in Texinfo:@refill @example @group @@menu * menu entry name: Node name. A short description. * Node name:: This form is preferred. @@end menu @end group @end example @need 800 @noindent This produces: @example @group * menu: * menu entry name: Node name. A short description. * Node name:: This form is preferred. @end group @end example @need 700 Here is an example as you might see it in a Texinfo file:@refill @example @group @@menu Larger Units of Text * Files:: All about handling files. * Multiples: Buffers. Multiple buffers; editing several files at once. @@end menu @end group @end example @need 800 @noindent This produces: @example @group * menu: Larger Units of Text * Files:: All about handling files. * Multiples: Buffers. Multiple buffers; editing several files at once. @end group @end example In this example, the menu has two entries. @samp{Files} is both a menu entry name and the name of the node referred to by that name. @samp{Multiples} is the menu entry name; it refers to the node named @samp{Buffers}. The line @samp{Larger Units of Text} is a comment; it appears in the menu, but is not an entry.@refill Since no file name is specified with either @samp{Files} or @samp{Buffers}, they must be the names of nodes in the same Info file (@pxref{Other Info Files, , Referring to Other Info Files}).@refill @node Other Info Files, , Menu Example, Menus @comment node-name, next, previous, up @section Referring to Other Info Files @cindex Referring to other Info files @cindex Nodes in other Info files @cindex Other Info files' nodes @cindex Going to other Info files' nodes @cindex Info; other files' nodes You can create a menu entry that enables a reader in Info to go to a node in another Info file by writing the file name in parentheses just before the node name. In this case, you should use the three-part menu entry format, which saves the reader from having to type the file name.@refill @need 800 The format looks like this:@refill @example @group @@menu * @var{first-entry-name}:(@var{filename})@var{nodename}. @var{description} * @var{second-entry-name}:(@var{filename})@var{second-node}. @var{description} @@end menu @end group @end example For example, to refer directly to the @samp{Outlining} and @samp{Rebinding} nodes in the @cite{Emacs Manual}, you would write a menu like this:@refill @example @group @@menu * Outlining: (emacs)Outline Mode. The major mode for editing outlines. * Rebinding: (emacs)Rebinding. How to redefine the meaning of a key. @@end menu @end group @end example If you do not list the node name, but only name the file, then Info presumes that you are referring to the `Top' node.@refill The @file{dir} file that contains the main menu for Info has menu entries that list only file names. These take you directly to the `Top' nodes of each Info document. (@xref{Install an Info File}.)@refill @need 700 For example: @example @group * Info: (info). Documentation browsing system. * Emacs: (emacs). The extensible, self-documenting text editor. @end group @end example @noindent (The @file{dir} top level directory for the Info system is an Info file, not a Texinfo file, but a menu entry looks the same in both types of file.)@refill Note that the GNU Emacs Texinfo mode menu updating commands only work with nodes within the current buffer, so you cannot use them to create menus that refer to other files. You must write such menus by hand.@refill @node Cross References, Marking Text, Menus, Top @comment node-name, next, previous, up @chapter Cross References @cindex Making cross references @cindex Cross references @cindex References @dfn{Cross references} are used to refer the reader to other parts of the same or different Texinfo files. In Texinfo, nodes are the places to which cross references can refer.@refill @menu * References:: What cross references are for. * Cross Reference Commands:: A summary of the different commands. * Cross Reference Parts:: A cross reference has several parts. * xref:: Begin a reference with `See' @dots{} * Top Node Naming:: How to refer to the beginning of another file. * ref:: A reference for the last part of a sentence. * pxref:: How to write a parenthetical cross reference. * inforef:: How to refer to an Info-only file. * uref:: How to refer to a uniform resource locator. @end menu @node References, Cross Reference Commands, Cross References, Cross References @ifinfo @heading What References Are For @end ifinfo Often, but not always, a printed document should be designed so that it can be read sequentially. People tire of flipping back and forth to find information that should be presented to them as they need it.@refill However, in any document, some information will be too detailed for the current context, or incidental to it; use cross references to provide access to such information. Also, an on-line help system or a reference manual is not like a novel; few read such documents in sequence from beginning to end. Instead, people look up what they need. For this reason, such creations should contain many cross references to help readers find other information that they may not have read.@refill In a printed manual, a cross reference results in a page reference, unless it is to another manual altogether, in which case the cross reference names that manual.@refill In Info, a cross reference results in an entry that you can follow using the Info @samp{f} command. (@inforef{Help-Adv, Some advanced Info commands, info}.)@refill The various cross reference commands use nodes to define cross reference locations. This is evident in Info, in which a cross reference takes you to the specified node. @TeX{} also uses nodes to define cross reference locations, but the action is less obvious. When @TeX{} generates a DVI file, it records nodes' page numbers and uses the page numbers in making references. Thus, if you are writing a manual that will only be printed, and will not be used on-line, you must nonetheless write @code{@@node} lines to name the places to which you make cross references.@refill @need 800 @node Cross Reference Commands, Cross Reference Parts, References, Cross References @comment node-name, next, previous, up @section Different Cross Reference Commands @cindex Different cross reference commands There are four different cross reference commands:@refill @table @code @item @@xref Used to start a sentence in the printed manual saying @w{`See @dots{}'} or an Info cross-reference saying @samp{*Note @var{name}: @var{node}.}. @item @@ref Used within or, more often, at the end of a sentence; same as @code{@@xref} for Info; produces just the reference in the printed manual without a preceding `See'.@refill @item @@pxref Used within parentheses to make a reference that suits both an Info file and a printed book. Starts with a lower case `see' within the printed manual. (@samp{p} is for `parenthesis'.)@refill @item @@inforef Used to make a reference to an Info file for which there is no printed manual.@refill @end table @noindent (The @code{@@cite} command is used to make references to books and manuals for which there is no corresponding Info file and, therefore, no node to which to point. @xref{cite, , @code{@@cite}}.)@refill @node Cross Reference Parts, xref, Cross Reference Commands, Cross References @comment node-name, next, previous, up @section Parts of a Cross Reference @cindex Cross reference parts @cindex Parts of a cross reference A cross reference command requires only one argument, which is the name of the node to which it refers. But a cross reference command may contain up to four additional arguments. By using these arguments, you can provide a cross reference name for Info, a topic description or section title for the printed output, the name of a different Info file, and the name of a different printed manual.@refill Here is a simple cross reference example:@refill @example @@xref@{Node name@}. @end example @noindent which produces @example *Note Node name::. @end example @noindent and @quotation See Section @var{nnn} [Node name], page @var{ppp}. @end quotation @need 700 Here is an example of a full five-part cross reference:@refill @example @group @@xref@{Node name, Cross Reference Name, Particular Topic, info-file-name, A Printed Manual@}, for details. @end group @end example @noindent which produces @example *Note Cross Reference Name: (info-file-name)Node name, for details. @end example @noindent in Info and @quotation See section ``Particular Topic'' in @i{A Printed Manual}, for details. @end quotation @noindent in a printed book. The five possible arguments for a cross reference are:@refill @enumerate @item The node name (required). This is the node to which the cross reference takes you. In a printed document, the location of the node provides the page reference only for references within the same document.@refill @item The cross reference name for the Info reference, if it is to be different from the node name. If you include this argument, it becomes the first part of the cross reference. It is usually omitted.@refill @item A topic description or section name. Often, this is the title of the section. This is used as the name of the reference in the printed manual. If omitted, the node name is used.@refill @item The name of the Info file in which the reference is located, if it is different from the current file. You need not include any @samp{.info} suffix on the file name, since Info readers try appending it automatically. @item The name of a printed manual from a different Texinfo file.@refill @end enumerate The template for a full five argument cross reference looks like this:@refill @example @group @@xref@{@var{node-name}, @var{cross-reference-name}, @var{title-or-topic}, @var{info-file-name}, @var{printed-manual-title}@}. @end group @end example Cross references with one, two, three, four, and five arguments are described separately following the description of @code{@@xref}.@refill Write a node name in a cross reference in exactly the same way as in the @code{@@node} line, including the same capitalization; otherwise, the formatters may not find the reference.@refill You can write cross reference commands within a paragraph, but note how Info and @TeX{} format the output of each of the various commands: write @code{@@xref} at the beginning of a sentence; write @code{@@pxref} only within parentheses, and so on.@refill @node xref, Top Node Naming, Cross Reference Parts, Cross References @comment node-name, next, previous, up @section @code{@@xref} @findex xref @cindex Cross references using @code{@@xref} @cindex References using @code{@@xref} The @code{@@xref} command generates a cross reference for the beginning of a sentence. The Info formatting commands convert it into an Info cross reference, which the Info @samp{f} command can use to bring you directly to another node. The @TeX{} typesetting commands convert it into a page reference, or a reference to another book or manual.@refill @menu * Reference Syntax:: What a reference looks like and requires. * One Argument:: @code{@@xref} with one argument. * Two Arguments:: @code{@@xref} with two arguments. * Three Arguments:: @code{@@xref} with three arguments. * Four and Five Arguments:: @code{@@xref} with four and five arguments. @end menu @node Reference Syntax, One Argument, xref, xref @ifinfo @subheading What a Reference Looks Like and Requires @end ifinfo Most often, an Info cross reference looks like this:@refill @example *Note @var{node-name}::. @end example @noindent or like this @example *Note @var{cross-reference-name}: @var{node-name}. @end example @noindent In @TeX{}, a cross reference looks like this: @example See Section @var{section-number} [@var{node-name}], page @var{page}. @end example @noindent or like this @example See Section @var{section-number} [@var{title-or-topic}], page @var{page}. @end example The @code{@@xref} command does not generate a period or comma to end the cross reference in either the Info file or the printed output. You must write that period or comma yourself; otherwise, Info will not recognize the end of the reference. (The @code{@@pxref} command works differently. @xref{pxref, , @code{@@pxref}}.)@refill @quotation @strong{Please note:} A period or comma @strong{must} follow the closing brace of an @code{@@xref}. It is required to terminate the cross reference. This period or comma will appear in the output, both in the Info file and in the printed manual.@refill @end quotation @code{@@xref} must refer to an Info node by name. Use @code{@@node} to define the node (@pxref{Writing a Node}).@refill @code{@@xref} is followed by several arguments inside braces, separated by commas. Whitespace before and after these commas is ignored.@refill A cross reference requires only the name of a node; but it may contain up to four additional arguments. Each of these variations produces a cross reference that looks somewhat different.@refill @quotation @strong{Please note:} Commas separate arguments in a cross reference; avoid including them in the title or other part lest the formatters mistake them for separators.@refill @end quotation @node One Argument, Two Arguments, Reference Syntax, xref @subsection @code{@@xref} with One Argument The simplest form of @code{@@xref} takes one argument, the name of another node in the same Info file. The Info formatters produce output that the Info readers can use to jump to the reference; @TeX{} produces output that specifies the page and section number for you.@refill @need 700 @noindent For example, @example @@xref@{Tropical Storms@}. @end example @noindent produces @example *Note Tropical Storms::. @end example @noindent and @quotation See Section 3.1 [Tropical Storms], page 24. @end quotation @noindent (Note that in the preceding example the closing brace is followed by a period.)@refill You can write a clause after the cross reference, like this:@refill @example @@xref@{Tropical Storms@}, for more info. @end example @noindent which produces @example *Note Tropical Storms::, for more info. @end example @quotation See Section 3.1 [Tropical Storms], page 24, for more info. @end quotation @noindent (Note that in the preceding example the closing brace is followed by a comma, and then by the clause, which is followed by a period.)@refill @node Two Arguments, Three Arguments, One Argument, xref @subsection @code{@@xref} with Two Arguments With two arguments, the second is used as the name of the Info cross reference, while the first is still the name of the node to which the cross reference points.@refill @need 750 @noindent The template is like this: @example @@xref@{@var{node-name}, @var{cross-reference-name}@}. @end example @need 700 @noindent For example, @example @@xref@{Electrical Effects, Lightning@}. @end example @noindent produces: @example *Note Lightning: Electrical Effects. @end example @noindent and @quotation See Section 5.2 [Electrical Effects], page 57. @end quotation @noindent (Note that in the preceding example the closing brace is followed by a period; and that the node name is printed, not the cross reference name.)@refill You can write a clause after the cross reference, like this:@refill @example @@xref@{Electrical Effects, Lightning@}, for more info. @end example @noindent which produces @example *Note Lightning: Electrical Effects, for more info. @end example @noindent and @quotation See Section 5.2 [Electrical Effects], page 57, for more info. @end quotation @noindent (Note that in the preceding example the closing brace is followed by a comma, and then by the clause, which is followed by a period.)@refill @node Three Arguments, Four and Five Arguments, Two Arguments, xref @subsection @code{@@xref} with Three Arguments A third argument replaces the node name in the @TeX{} output. The third argument should be the name of the section in the printed output, or else state the topic discussed by that section. Often, you will want to use initial upper case letters so it will be easier to read when the reference is printed. Use a third argument when the node name is unsuitable because of syntax or meaning.@refill Remember to avoid placing a comma within the title or topic section of a cross reference, or within any other section. The formatters divide cross references into arguments according to the commas; a comma within a title or other section will divide it into two arguments. In a reference, you need to write a title such as ``Clouds, Mist, and Fog'' without the commas.@refill Also, remember to write a comma or period after the closing brace of a @code{@@xref} to terminate the cross reference. In the following examples, a clause follows a terminating comma.@refill @need 750 @noindent The template is like this: @example @group @@xref@{@var{node-name}, @var{cross-reference-name}, @var{title-or-topic}@}. @end group @end example @need 700 @noindent For example, @example @group @@xref@{Electrical Effects, Lightning, Thunder and Lightning@}, for details. @end group @end example @noindent produces @example *Note Lightning: Electrical Effects, for details. @end example @noindent and @quotation See Section 5.2 [Thunder and Lightning], page 57, for details. @end quotation If a third argument is given and the second one is empty, then the third argument serves both. (Note how two commas, side by side, mark the empty second argument.)@refill @example @group @@xref@{Electrical Effects, , Thunder and Lightning@}, for details. @end group @end example @noindent produces @example *Note Thunder and Lightning: Electrical Effects, for details. @end example @noindent and @quotation See Section 5.2 [Thunder and Lightning], page 57, for details. @end quotation As a practical matter, it is often best to write cross references with just the first argument if the node name and the section title are the same, and with the first and third arguments if the node name and title are different.@refill Here are several examples from @cite{The GNU Awk User's Guide}:@refill @smallexample @@xref@{Sample Program@}. @@xref@{Glossary@}. @@xref@{Case-sensitivity, ,Case-sensitivity in Matching@}. @@xref@{Close Output, , Closing Output Files and Pipes@}, for more information. @@xref@{Regexp, , Regular Expressions as Patterns@}. @end smallexample @node Four and Five Arguments, , Three Arguments, xref @subsection @code{@@xref} with Four and Five Arguments In a cross reference, a fourth argument specifies the name of another Info file, different from the file in which the reference appears, and a fifth argument specifies its title as a printed manual.@refill Remember that a comma or period must follow the closing brace of an @code{@@xref} command to terminate the cross reference. In the following examples, a clause follows a terminating comma.@refill @need 800 @noindent The template is: @example @group @@xref@{@var{node-name}, @var{cross-reference-name}, @var{title-or-topic}, @var{info-file-name}, @var{printed-manual-title}@}. @end group @end example @need 700 @noindent For example, @example @@xref@{Electrical Effects, Lightning, Thunder and Lightning, weather, An Introduction to Meteorology@}, for details. @end example @noindent produces @example *Note Lightning: (weather)Electrical Effects, for details. @end example @noindent The name of the Info file is enclosed in parentheses and precedes the name of the node. @noindent In a printed manual, the reference looks like this:@refill @quotation See section ``Thunder and Lightning'' in @i{An Introduction to Meteorology}, for details. @end quotation @noindent The title of the printed manual is typeset in italics; and the reference lacks a page number since @TeX{} cannot know to which page a reference refers when that reference is to another manual.@refill Often, you will leave out the second argument when you use the long version of @code{@@xref}. In this case, the third argument, the topic description, will be used as the cross reference name in Info.@refill @noindent The template looks like this: @example @@xref@{@var{node-name}, , @var{title-or-topic}, @var{info-file-name}, @var{printed-manual-title}@}, for details. @end example @noindent which produces @example *Note @var{title-or-topic}: (@var{info-file-name})@var{node-name}, for details. @end example @noindent and @quotation See section @var{title-or-topic} in @var{printed-manual-title}, for details. @end quotation @need 700 @noindent For example, @example @@xref@{Electrical Effects, , Thunder and Lightning, weather, An Introduction to Meteorology@}, for details. @end example @noindent produces @example @group *Note Thunder and Lightning: (weather)Electrical Effects, for details. @end group @end example @noindent and @quotation See section ``Thunder and Lightning'' in @i{An Introduction to Meteorology}, for details. @end quotation On rare occasions, you may want to refer to another Info file that is within a single printed manual---when multiple Texinfo files are incorporated into the same @TeX{} run but make separate Info files. In this case, you need to specify only the fourth argument, and not the fifth.@refill @node Top Node Naming, ref, xref, Cross References @section Naming a `Top' Node @cindex Naming a `Top' Node in references @cindex @samp{@r{Top}} node naming for references In a cross reference, you must always name a node. This means that in order to refer to a whole manual, you must identify the `Top' node by writing it as the first argument to the @code{@@xref} command. (This is different from the way you write a menu entry; see @ref{Other Info Files, , Referring to Other Info Files}.) At the same time, to provide a meaningful section topic or title in the printed cross reference (instead of the word `Top'), you must write an appropriate entry for the third argument to the @code{@@xref} command. @refill @noindent Thus, to make a cross reference to @cite{The GNU Make Manual}, write:@refill @example @@xref@{Top, , Overview, make, The GNU Make Manual@}. @end example @noindent which produces @example *Note Overview: (make)Top. @end example @noindent and @quotation See section ``Overview'' in @i{The GNU Make Manual}. @end quotation @noindent In this example, @samp{Top} is the name of the first node, and @samp{Overview} is the name of the first section of the manual.@refill @node ref, pxref, Top Node Naming, Cross References @comment node-name, next, previous, up @section @code{@@ref} @cindex Cross references using @code{@@ref} @cindex References using @code{@@ref} @findex ref @code{@@ref} is nearly the same as @code{@@xref} except that it does not generate a `See' in the printed output, just the reference itself. This makes it useful as the last part of a sentence.@refill @need 700 @noindent For example, @example For more information, see @@ref@{Hurricanes@}. @end example @noindent produces @example For more information, see *Note Hurricanes. @end example @noindent and @quotation For more information, see Section 8.2 [Hurricanes], page 123. @end quotation The @code{@@ref} command sometimes leads writers to express themselves in a manner that is suitable for a printed manual but looks awkward in the Info format. Bear in mind that your audience will be using both the printed and the Info format.@refill @need 800 @noindent For example, @example @group Sea surges are described in @@ref@{Hurricanes@}. @end group @end example @need 800 @noindent produces @quotation Sea surges are described in Section 6.7 [Hurricanes], page 72. @end quotation @need 800 @noindent in a printed document, and the following in Info: @example Sea surges are described in *Note Hurricanes::. @end example @quotation @strong{Caution:} You @emph{must} write a period or comma immediately after an @code{@@ref} command with two or more arguments. Otherwise, Info will not find the end of the cross reference entry and its attempt to follow the cross reference will fail. As a general rule, you should write a period or comma after every @code{@@ref} command. This looks best in both the printed and the Info output.@refill @end quotation @node pxref, inforef, ref, Cross References @comment node-name, next, previous, up @section @code{@@pxref} @cindex Cross references using @code{@@pxref} @cindex References using @code{@@pxref} @findex pxref The parenthetical reference command, @code{@@pxref}, is nearly the same as @code{@@xref}, but you use it @emph{only} inside parentheses and you do @emph{not} type a comma or period after the command's closing brace. The command differs from @code{@@xref} in two ways:@refill @enumerate @item @TeX{} typesets the reference for the printed manual with a lower case `see' rather than an upper case `See'.@refill @item The Info formatting commands automatically end the reference with a closing colon or period.@refill @end enumerate Because one type of formatting automatically inserts closing punctuation and the other does not, you should use @code{@@pxref} @emph{only} inside parentheses as part of another sentence. Also, you yourself should not insert punctuation after the reference, as you do with @code{@@xref}.@refill @code{@@pxref} is designed so that the output looks right and works right between parentheses both in printed output and in an Info file. In a printed manual, a closing comma or period should not follow a cross reference within parentheses; such punctuation is wrong. But in an Info file, suitable closing punctuation must follow the cross reference so Info can recognize its end. @code{@@pxref} spares you the need to use complicated methods to put a terminator into one form of the output and not the other.@refill @noindent With one argument, a parenthetical cross reference looks like this:@refill @example @dots{} storms cause flooding (@@pxref@{Hurricanes@}) @dots{} @end example @need 800 @noindent which produces @example @group @dots{} storms cause flooding (*Note Hurricanes::) @dots{} @end group @end example @noindent and @quotation @dots{} storms cause flooding (see Section 6.7 [Hurricanes], page 72) @dots{} @end quotation With two arguments, a parenthetical cross reference has this template:@refill @example @dots{} (@@pxref@{@var{node-name}, @var{cross-reference-name}@}) @dots{} @end example @noindent which produces @example @dots{} (*Note @var{cross-reference-name}: @var{node-name}.) @dots{} @end example @noindent and @need 1500 @quotation @dots{} (see Section @var{nnn} [@var{node-name}], page @var{ppp}) @dots{} @end quotation @code{@@pxref} can be used with up to five arguments just like @code{@@xref} (@pxref{xref, , @code{@@xref}}).@refill @quotation @strong{Please note:} Use @code{@@pxref} only as a parenthetical reference. Do not try to use @code{@@pxref} as a clause in a sentence. It will look bad in either the Info file, the printed output, or both.@refill Also, parenthetical cross references look best at the ends of sentences. Although you may write them in the middle of a sentence, that location breaks up the flow of text.@refill @end quotation @node inforef, uref, pxref, Cross References @section @code{@@inforef} @cindex Cross references using @code{@@inforef} @cindex References using @code{@@inforef} @findex inforef @code{@@inforef} is used for cross references to Info files for which there are no printed manuals. Even in a printed manual, @code{@@inforef} generates a reference directing the user to look in an Info file.@refill The command takes either two or three arguments, in the following order:@refill @enumerate @item The node name. @item The cross reference name (optional). @item The Info file name. @end enumerate @noindent Separate the arguments with commas, as with @code{@@xref}. Also, you must terminate the reference with a comma or period after the @samp{@}}, as you do with @code{@@xref}.@refill @noindent The template is: @example @@inforef@{@var{node-name}, @var{cross-reference-name}, @var{info-file-name}@}, @end example @need 800 @noindent Thus, @example @group @@inforef@{Expert, Advanced Info commands, info@}, for more information. @end group @end example @need 800 @noindent produces @example @group *Note Advanced Info commands: (info)Expert, for more information. @end group @end example @need 800 @noindent and @quotation See Info file @file{info}, node @samp{Expert}, for more information. @end quotation @need 800 @noindent Similarly, @example @group @@inforef@{Expert, , info@}, for more information. @end group @end example @need 800 @noindent produces @example *Note (info)Expert::, for more information. @end example @need 800 @noindent and @quotation See Info file @file{info}, node @samp{Expert}, for more information. @end quotation The converse of @code{@@inforef} is @code{@@cite}, which is used to refer to printed works for which no Info form exists. @xref{cite, , @code{@@cite}}.@refill @node uref, , inforef, Cross References @section @code{@@uref@{@var{url}[, @var{displayed-text}]@}} @findex uref @cindex Uniform resource locator, referring to @cindex URL, referring to @code{@@uref} produces a reference to a uniform resource locator (URL). It takes one mandatory argument, the URL, and one optional argument, the text to display (the default is the URL itself). In HTML output, @code{@@uref} produces a link you can follow. For example: @example The official GNU ftp site is @@uref@{ftp://ftp.gnu.ai.mit.edu/pub/gnu@} @end example @noindent produces (in text): @display The official GNU ftp site is @uref{ftp://ftp.gnu.ai.mit.edu/pub/gnu} @end display @noindent whereas @example The official @@uref@{ftp://ftp.gnu.ai.mit.edu/pub/gnu, GNU ftp site@} holds programs and texts. @end example @noindent produces (in text): @display The official @uref{ftp://ftp.gnu.ai.mit.edu/pub/gnu, GNU ftp site} holds programs and texts. @end display @noindent and (in HTML): @example The official GNU ftp site holds programs and texts. @end example To merely indicate a URL, use @code{@@url} (@pxref{url, @code{@@url}}). @node Marking Text, Quotations and Examples, Cross References, Top @comment node-name, next, previous, up @chapter Marking Words and Phrases @cindex Paragraph, marking text within @cindex Marking words and phrases @cindex Words and phrases, marking them @cindex Marking text within a paragraph In Texinfo, you can mark words and phrases in a variety of ways. The Texinfo formatters use this information to determine how to highlight the text. You can specify, for example, whether a word or phrase is a defining occurrence, a metasyntactic variable, or a symbol used in a program. Also, you can emphasize text.@refill @menu * Indicating:: How to indicate definitions, files, etc. * Emphasis:: How to emphasize text. @end menu @node Indicating, Emphasis, Marking Text, Marking Text @comment node-name, next, previous, up @section Indicating Definitions, Commands, etc. @cindex Highlighting text @cindex Indicating commands, definitions, etc. Texinfo has commands for indicating just what kind of object a piece of text refers to. For example, metasyntactic variables are marked by @code{@@var}, and code by @code{@@code}. Since the pieces of text are labelled by commands that tell what kind of object they are, it is easy to change the way the Texinfo formatters prepare such text. (Texinfo is an @emph{intentional} formatting language rather than a @emph{typesetting} formatting language.)@refill For example, in a printed manual, code is usually illustrated in a typewriter font; @code{@@code} tells @TeX{} to typeset this text in this font. But it would be easy to change the way @TeX{} highlights code to use another font, and this change would not effect how keystroke examples are highlighted. If straight typesetting commands were used in the body of the file and you wanted to make a change, you would need to check every single occurrence to make sure that you were changing code and not something else that should not be changed.@refill @menu * Useful Highlighting:: Highlighting provides useful information. * code:: How to indicate code. * kbd:: How to show keyboard input. * key:: How to specify keys. * samp:: How to show a literal sequence of characters. * var:: How to indicate a metasyntactic variable. * file:: How to indicate the name of a file. * dfn:: How to specify a definition. * cite:: How to refer to a book that is not in Info. * url:: How to indicate a world wide web reference. * email:: How to indicate an electronic mail address. @end menu @node Useful Highlighting, code, Indicating, Indicating @ifinfo @subheading Highlighting Commands are Useful @end ifinfo The highlighting commands can be used to generate useful information from the file, such as lists of functions or file names. It is possible, for example, to write a program in Emacs Lisp (or a keyboard macro) to insert an index entry after every paragraph that contains words or phrases marked by a specified command. You could do this to construct an index of functions if you had not already made the entries.@refill The commands serve a variety of purposes:@refill @table @code @item @@code@{@var{sample-code}@} Indicate text that is a literal example of a piece of a program.@refill @item @@kbd@{@var{keyboard-characters}@} Indicate keyboard input.@refill @item @@key@{@var{key-name}@} Indicate the conventional name for a key on a keyboard.@refill @item @@samp@{@var{text}@} Indicate text that is a literal example of a sequence of characters.@refill @item @@var@{@var{metasyntactic-variable}@} Indicate a metasyntactic variable.@refill @item @@url@{@var{uniform-resource-locator}@} Indicate a uniform resource locator for the World Wide Web. @item @@file@{@var{file-name}@} Indicate the name of a file.@refill @item @@email@{@var{email-address}[, @var{displayed-text}]@} Indicate an electronic mail address. @item @@dfn@{@var{term}@} Indicate the introductory or defining use of a term.@refill @item @@cite@{@var{reference}@} Indicate the name of a book.@refill @ignore @item @@ctrl@{@var{ctrl-char}@} Use for an @sc{ascii} control character.@refill @end ignore @end table @node code, kbd, Useful Highlighting, Indicating @comment node-name, next, previous, up @subsection @code{@@code}@{@var{sample-code}@} @findex code Use the @code{@@code} command to indicate text that is a piece of a program and which consists of entire syntactic tokens. Enclose the text in braces.@refill Thus, you should use @code{@@code} for an expression in a program, for the name of a variable or function used in a program, or for a keyword. Also, you should use @code{@@code} for the name of a program, such as @code{diff}, that is a name used in the machine. (You should write the name of a program in the ordinary text font if you regard it as a new English word, such as `Emacs' or `Bison'.)@refill Use @code{@@code} for environment variables such as @code{TEXINPUTS}, and other variables.@refill Use @code{@@code} for command names in command languages that resemble programming languages, such as Texinfo or the shell. For example, @code{@@code} and @code{@@samp} are produced by writing @samp{@@code@{@@@@code@}} and @samp{@@code@{@@@@samp@}} in the Texinfo source, respectively.@refill Note, however, that you should not use @code{@@code} for shell options such as @samp{-c} when such options stand alone. (Use @code{@@samp}.) Also, an entire shell command often looks better if written using @code{@@samp} rather than @code{@@code}. In this case, the rule is to choose the more pleasing format.@refill It is incorrect to alter the case of a word inside an @code{@@code} command when it appears at the beginning of a sentence. Most computer languages are case sensitive. In C, for example, @code{Printf} is different from the identifier @code{printf}, and most likely is a misspelling of it. Even in languages which are not case sensitive, it is confusing to a human reader to see identifiers spelled in different ways. Pick one spelling and always use that. If you do not want to start a sentence with a command written all in lower case, you should rearrange the sentence.@refill Do not use the @code{@@code} command for a string of characters shorter than a syntactic token. If you are writing about @samp{TEXINPU}, which is just a part of the name for the @code{TEXINPUTS} environment variable, you should use @code{@@samp}.@refill In particular, you should not use the @code{@@code} command when writing about the characters used in a token; do not, for example, use @code{@@code} when you are explaining what letters or printable symbols can be used in the names of functions. (Use @code{@@samp}.) Also, you should not use @code{@@code} to mark text that is considered input to programs unless the input is written in a language that is like a programming language. For example, you should not use @code{@@code} for the keystroke commands of GNU Emacs (use @code{@@kbd} instead) although you may use @code{@@code} for the names of the Emacs Lisp functions that the keystroke commands invoke.@refill In the printed manual, @code{@@code} causes @TeX{} to typeset the argument in a typewriter face. In the Info file, it causes the Info formatting commands to use single quotation marks around the text. @need 700 For example, @example Use @@code@{diff@} to compare two files. @end example @noindent produces this in the printed manual:@refill @quotation Use @code{diff} to compare two files. @end quotation @iftex @noindent and this in the Info file:@refill @example Use `diff' to compare two files. @end example @end iftex @node kbd, key, code, Indicating @subsection @code{@@kbd}@{@var{keyboard-characters}@} @findex kbd @cindex keyboard input Use the @code{@@kbd} command for characters of input to be typed by users. For example, to refer to the characters @kbd{M-a}, write@refill @example @@kbd@{M-a@} @end example @noindent and to refer to the characters @kbd{M-x shell}, write@refill @example @@kbd@{M-x shell@} @end example @cindex user input @cindex slanted typewriter font, for @code{@@kbd} The @code{@@kbd} command has the same effect as @code{@@code} in Info, but by default produces a different font (slanted typewriter instead of normal typewriter) in the printed manual, so users can distinguish the characters they are supposed to type from those the computer outputs. @findex kbdinputstyle Since the usage of @code{@@kbd} varies from manual to manual, you can control the font switching with the @code{@@kbdinputstyle} command. This command has no effect on Info output. Write this command at the beginning of a line with a single word as an argument, one of the following: @vindex distinct@r{, arg to @@kbdinputstyle} @vindex example@r{, arg to @@kbdinputstyle} @vindex code@r{, arg to @@kbdinputstyle} @table @samp @item code Always use the same font for @code{@@kbd} as @code{@@code}. @item example Use the distinguishing font for @code{@@kbd} only in @code{@@example} and similar environments. @item example (the default) Always use the distinguishing font for @code{@@kbd}. @end table You can embed another @@-command inside the braces of an @code{@@kbd} command. Here, for example, is the way to describe a command that would be described more verbosely as ``press an @samp{r} and then press the @key{RET} key'':@refill @example @@kbd@{r @@key@{RET@}@} @end example @noindent This produces: @kbd{r @key{RET}} You also use the @code{@@kbd} command if you are spelling out the letters you type; for example:@refill @example To give the @@code@{logout@} command, type the characters @@kbd@{l o g o u t @@key@{RET@}@}. @end example @noindent This produces: @quotation To give the @code{logout} command, type the characters @kbd{l o g o u t @key{RET}}. @end quotation (Also, this example shows that you can add spaces for clarity. If you really want to mention a space character as one of the characters of input, write @kbd{@@key@{SPC@}} for it.)@refill @node key, samp, kbd, Indicating @comment node-name, next, previous, up @subsection @code{@@key}@{@var{key-name}@} @findex key Use the @code{@@key} command for the conventional name for a key on a keyboard, as in:@refill @example @@key@{RET@} @end example You can use the @code{@@key} command within the argument of an @code{@@kbd} command when the sequence of characters to be typed includes one or more keys that are described by name.@refill @need 700 For example, to produce @kbd{C-x @key{ESC}} you would type:@refill @example @@kbd@{C-x @@key@{ESC@}@} @end example Here is a list of the recommended names for keys: @cindex Recommended names for keys @cindex Keys, recommended names @cindex Names recommended for keys @cindex Abbreviations for keys @quotation @table @t @item SPC Space @item RET Return @item LFD Linefeed (however, since most keyboards nowadays do not have a Linefeed key, it might be better to call this character @kbd{C-j}. @item TAB Tab @item BS Backspace @item ESC Escape @item DEL Delete @item SHIFT Shift @item CTRL Control @item META Meta @end table @end quotation @cindex META key There are subtleties to handling words like `meta' or `ctrl' that are names of modifier keys. When mentioning a character in which the modifier key is used, such as @kbd{Meta-a}, use the @code{@@kbd} command alone; do not use the @code{@@key} command; but when you are referring to the modifier key in isolation, use the @code{@@key} command. For example, write @samp{@@kbd@{Meta-a@}} to produce @kbd{Meta-a} and @samp{@@key@{META@}} to produce @key{META}. @c I don't think this is a good explanation. @c I think it will puzzle readers more than it clarifies matters. -- rms. @c In other words, use @code{@@kbd} for what you do, and use @code{@@key} @c for what you talk about: ``Press @code{@@kbd@{M-a@}} to move point to @c the beginning of the sentence. The @code{@@key@{META@}} key is often in @c the lower left of the keyboard.''@refill @node samp, var, key, Indicating @comment node-name, next, previous, up @subsection @code{@@samp}@{@var{text}@} @findex samp Use the @code{@@samp} command to indicate text that is a literal example or `sample' of a sequence of characters in a file, string, pattern, etc. Enclose the text in braces. The argument appears within single quotation marks in both the Info file and the printed manual; in addition, it is printed in a fixed-width font.@refill @example To match @@samp@{foo@} at the end of the line, use the regexp @@samp@{foo$@}. @end example @noindent produces @quotation To match @samp{foo} at the end of the line, use the regexp @samp{foo$}.@refill @end quotation Any time you are referring to single characters, you should use @code{@@samp} unless @code{@@kbd} or @code{@@key} is more appropriate. Use @code{@@samp} for the names of command-line options (except in an @code{@@table}, where @code{@@code} seems to read more easily). Also, you may use @code{@@samp} for entire statements in C and for entire shell commands---in this case, @code{@@samp} often looks better than @code{@@code}. Basically, @code{@@samp} is a catchall for whatever is not covered by @code{@@code}, @code{@@kbd}, or @code{@@key}.@refill Only include punctuation marks within braces if they are part of the string you are specifying. Write punctuation marks outside the braces if those punctuation marks are part of the English text that surrounds the string. In the following sentence, for example, the commas and period are outside of the braces:@refill @example @group In English, the vowels are @@samp@{a@}, @@samp@{e@}, @@samp@{i@}, @@samp@{o@}, @@samp@{u@}, and sometimes @@samp@{y@}. @end group @end example @noindent This produces: @quotation In English, the vowels are @samp{a}, @samp{e}, @samp{i}, @samp{o}, @samp{u}, and sometimes @samp{y}. @end quotation @node var, file, samp, Indicating @comment node-name, next, previous, up @subsection @code{@@var}@{@var{metasyntactic-variable}@} @findex var Use the @code{@@var} command to indicate metasyntactic variables. A @dfn{metasyntactic variable} is something that stands for another piece of text. For example, you should use a metasyntactic variable in the documentation of a function to describe the arguments that are passed to that function.@refill Do not use @code{@@var} for the names of particular variables in programming languages. These are specific names from a program, so @code{@@code} is correct for them. For example, the Emacs Lisp variable @code{texinfo-tex-command} is not a metasyntactic variable; it is properly formatted using @code{@@code}.@refill The effect of @code{@@var} in the Info file is to change the case of the argument to all upper case; in the printed manual, to italicize it. @need 700 For example, @example To delete file @@var@{filename@}, type @@code@{rm @@var@{filename@}@}. @end example @noindent produces @quotation To delete file @var{filename}, type @code{rm @var{filename}}. @end quotation @noindent (Note that @code{@@var} may appear inside @code{@@code}, @code{@@samp}, @code{@@file}, etc.)@refill Write a metasyntactic variable all in lower case without spaces, and use hyphens to make it more readable. Thus, the Texinfo source for the illustration of how to begin a Texinfo manual looks like this:@refill @example @group \input texinfo @@@@setfilename @@var@{info-file-name@} @@@@settitle @@var@{name-of-manual@} @end group @end example @noindent This produces: @example @group \input texinfo @@setfilename @var{info-file-name} @@settitle @var{name-of-manual} @end group @end example In some documentation styles, metasyntactic variables are shown with angle brackets, for example:@refill @example @dots{}, type rm @end example @noindent However, that is not the style that Texinfo uses. (You can, of course, modify the sources to @TeX{} and the Info formatting commands to output the @code{<@dots{}>} format if you wish.)@refill @node file, dfn, var, Indicating @comment node-name, next, previous, up @subsection @code{@@file}@{@var{file-name}@} @findex file Use the @code{@@file} command to indicate text that is the name of a file, buffer, or directory, or is the name of a node in Info. You can also use the command for file name suffixes. Do not use @code{@@file} for symbols in a programming language; use @code{@@code}. Currently, @code{@@file} is equivalent to @code{@@samp} in its effects. For example,@refill @example The @@file@{.el@} files are in the @@file@{/usr/local/emacs/lisp@} directory. @end example @noindent produces @quotation The @file{.el} files are in the @file{/usr/local/emacs/lisp} directory. @end quotation @node dfn, cite, file, Indicating @comment node-name, next, previous, up @subsection @code{@@dfn}@{@var{term}@} @findex dfn Use the @code{@@dfn} command to identify the introductory or defining use of a technical term. Use the command only in passages whose purpose is to introduce a term which will be used again or which the reader ought to know. Mere passing mention of a term for the first time does not deserve @code{@@dfn}. The command generates italics in the printed manual, and double quotation marks in the Info file. For example:@refill @example Getting rid of a file is called @@dfn@{deleting@} it. @end example @noindent produces @quotation Getting rid of a file is called @dfn{deleting} it. @end quotation As a general rule, a sentence containing the defining occurrence of a term should be a definition of the term. The sentence does not need to say explicitly that it is a definition, but it should contain the information of a definition---it should make the meaning clear. @node cite, url, dfn, Indicating @comment node-name, next, previous, up @subsection @code{@@cite}@{@var{reference}@} @findex cite Use the @code{@@cite} command for the name of a book that lacks a companion Info file. The command produces italics in the printed manual, and quotation marks in the Info file.@refill (If a book is written in Texinfo, it is better to use a cross reference command since a reader can easily follow such a reference in Info. @xref{xref, , @code{@@xref}}.)@refill @ignore @c node ctrl, , cite, Indicating @comment node-name, next, previous, up @c subsection @code{@@ctrl}@{@var{ctrl-char}@} @findex ctrl The @code{@@ctrl} command is seldom used. It describes an @sc{ascii} control character by inserting the actual character into the Info file. Usually, in Texinfo, you talk what you type as keyboard entry by describing it with @code{@@kbd}: thus, @samp{@@kbd@{C-a@}} for @kbd{C-a}. Use @code{@@kbd} in this way when talking about a control character that is typed on the keyboard by the user. When talking about a control character appearing in a file or a string, do not use @code{@@kbd} since the control character is not typed. Also, do not use @samp{C-} but spell out @code{control-}, as in @samp{control-a}, to make it easier for a reader to understand.@refill @code{@@ctrl} is an idea from the beginnings of Texinfo which may not really fit in to the scheme of things. But there may be times when you want to use the command. The pattern is @code{@@ctrl@{@var{ch}@}}, where @var{ch} is an @sc{ascii} character whose control-equivalent is wanted. For example, to specify @samp{control-f}, you would enter@refill @example @@ctrl@{f@} @end example @noindent produces @quotation @ctrl{f} @end quotation In the Info file, this generates the specified control character, output literally into the file. This is done so a user can copy the specified control character (along with whatever else he or she wants) into another Emacs buffer and use it. Since the `control-h',`control-i', and `control-j' characters are formatting characters, they should not be indicated with @code{@@ctrl}.@refill In a printed manual, @code{@@ctrl} generates text to describe or identify that control character: an uparrow followed by the character @var{ch}.@refill @end ignore @node url, email, cite, Indicating @subsection @code{@@url}@{@var{uniform-resource-locator}@} @findex url @cindex Uniform resource locator, indicating @cindex URL, indicating Use the @code{@@url} to indicate a uniform resource locator on the World Wide Web. This is analogous to @code{@@file}, @code{@@var}, etc., and is purely for markup purposes. It does not produce a link you can follow in HTML output (the @code{@@uref} command does, @pxref{uref,, @code{@@uref}}). It is useful for example URL's which do not actually exist. For example: @c Two lines because one is too long for smallbook format. @example For example, the url might be @@url@{http://host.domain.org/path@}. @end example @node email, , url, Indicating @subsection @code{@@email}@{@var{email-address}[, @var{displayed-text}]@} @findex email Use the @code{@@email} command to indicate an electronic mail address. It takes one mandatory argument, the address, and one optional argument, the text to display (the default is the address itself). @cindex mailto link In Info and @TeX{}, the address is shown in angle brackets, preceded by the text to display if any. In HTML output, @code{@@email} produces a @samp{mailto} link that usually brings up a mail composition window. For example: @example Send bug reports to @@email@{bug-texinfo@@@@gnu.org@}. Send suggestions to the @@email@{bug-texinfo@@@@gnu.org, same place@}. @end example @noindent produces @example Send bug reports to @email{bug-texinfo@@gnu.org}. Send suggestions to the @email{bug-texinfo@@gnu.org, same place}. @end example @node Emphasis, , Indicating, Marking Text @comment node-name, next, previous, up @section Emphasizing Text @cindex Emphasizing text Usually, Texinfo changes the font to mark words in the text according to what category the words belong to; an example is the @code{@@code} command. Most often, this is the best way to mark words. However, sometimes you will want to emphasize text without indicating a category. Texinfo has two commands to do this. Also, Texinfo has several commands that specify the font in which @TeX{} will typeset text. These commands have no affect on Info and only one of them, the @code{@@r} command, has any regular use.@refill @menu * emph & strong:: How to emphasize text in Texinfo. * Smallcaps:: How to use the small caps font. * Fonts:: Various font commands for printed output. * Customized Highlighting:: How to define highlighting commands. @end menu @node emph & strong, Smallcaps, Emphasis, Emphasis @comment node-name, next, previous, up @subsection @code{@@emph}@{@var{text}@} and @code{@@strong}@{@var{text}@} @cindex Emphasizing text, font for @findex emph @findex strong The @code{@@emph} and @code{@@strong} commands are for emphasis; @code{@@strong} is stronger. In printed output, @code{@@emph} produces @emph{italics} and @code{@@strong} produces @strong{bold}.@refill @need 800 For example, @example @group @@quotation @@strong@{Caution:@} @@samp@{rm * .[^.]*@} removes @@emph@{all@} files in the directory. @@end quotation @end group @end example @iftex @noindent produces the following in printed output: @quotation @strong{Caution}: @code{rm * .[^.]*} removes @emph{all} files in the directory. @end quotation @noindent and the following in Info: @end iftex @ifinfo @noindent produces: @end ifinfo @example *Caution*: `rm * .[^.]*' removes *all* files in the directory. @end example The @code{@@strong} command is seldom used except to mark what is, in effect, a typographical element, such as the word `Caution' in the preceding example. In the Info file, both @code{@@emph} and @code{@@strong} put asterisks around the text.@refill @quotation @strong{Caution:} Do not use @code{@@emph} or @code{@@strong} with the word @samp{Note}; Info will mistake the combination for a cross reference. Use a phrase such as @strong{Please note} or @strong{Caution} instead.@refill @end quotation @node Smallcaps, Fonts, emph & strong, Emphasis @subsection @code{@@sc}@{@var{text}@}: The Small Caps Font @cindex Small caps font @findex sc @r{(small caps font)} @iftex Use the @samp{@@sc} command to set text in the printed output in @sc{a small caps font} and set text in the Info file in upper case letters.@refill @end iftex @ifinfo Use the @samp{@@sc} command to set text in the printed output in a small caps font and set text in the Info file in upper case letters.@refill @end ifinfo Write the text between braces in lower case, like this:@refill @example The @@sc@{acm@} and @@sc@{ieee@} are technical societies. @end example @noindent This produces: @display The @sc{acm} and @sc{ieee} are technical societies. @end display @TeX{} typesets the small caps font in a manner that prevents the letters from `jumping out at you on the page'. This makes small caps text easier to read than text in all upper case. The Info formatting commands set all small caps text in upper case.@refill @ifinfo If the text between the braces of an @code{@@sc} command is upper case, @TeX{} typesets in full-size capitals. Use full-size capitals sparingly.@refill @end ifinfo @iftex If the text between the braces of an @code{@@sc} command is upper case, @TeX{} typesets in @sc{FULL-SIZE CAPITALS}. Use full-size capitals sparingly.@refill @end iftex You may also use the small caps font for a jargon word such as @sc{ato} (a @sc{nasa} word meaning `abort to orbit').@refill There are subtleties to using the small caps font with a jargon word such as @sc{cdr}, a word used in Lisp programming. In this case, you should use the small caps font when the word refers to the second and subsequent elements of a list (the @sc{cdr} of the list), but you should use @samp{@@code} when the word refers to the Lisp function of the same spelling.@refill @node Fonts, Customized Highlighting, Smallcaps, Emphasis @comment node-name, next, previous, up @subsection Fonts for Printing, Not Info @cindex Fonts for printing, not for Info @findex i @r{(italic font)} @findex b @r{(bold font)} @findex t @r{(typewriter font)} @findex r @r{(Roman font)} Texinfo provides four font commands that specify font changes in the printed manual but have no effect in the Info file. @code{@@i} requests @i{italic} font (in some versions of @TeX{}, a slanted font is used), @code{@@b} requests @b{bold} face, @code{@@t} requests the @t{fixed-width}, typewriter-style font used by @code{@@code}, and @code{@@r} requests a @r{roman} font, which is the usual font in which text is printed. All four commands apply to an argument that follows, surrounded by braces.@refill Only the @code{@@r} command has much use: in example programs, you can use the @code{@@r} command to convert code comments from the fixed-width font to a roman font. This looks better in printed output.@refill @need 700 For example, @example @group @@lisp (+ 2 2) ; @@r@{Add two plus two.@} @@end lisp @end group @end example @noindent produces @lisp (+ 2 2) ; @r{Add two plus two.} @end lisp If possible, you should avoid using the other three font commands. If you need to use one, it probably indicates a gap in the Texinfo language.@refill @node Customized Highlighting, , Fonts, Emphasis @comment node-name, next, previous, up @subsection Customized Highlighting @cindex Highlighting, customized @cindex Customized highlighting @c I think this whole section is obsolete with the advent of macros @c --karl, 15sep96. You can use regular @TeX{} commands inside of @code{@@iftex} @dots{} @code{@@end iftex} to create your own customized highlighting commands for Texinfo. The easiest way to do this is to equate your customized commands with pre-existing commands, such as those for italics. Such new commands work only with @TeX{}.@refill @findex definfoenclose @cindex Enclosure command for Info You can use the @code{@@definfoenclose} command inside of @code{@@ifinfo} @dots{} @code{@@end ifinfo} to define commands for Info with the same names as new commands for @TeX{}. @code{@@definfoenclose} creates new commands for Info that mark text by enclosing it in strings that precede and follow the text. @footnote{Currently, @code{@@definfoenclose} works only with @code{texinfo-format-buffer} and @code{texinfo-format-region}, not with @code{makeinfo}.}@refill Here is how to create a new @@-command called @code{@@phoo} that causes @TeX{} to typeset its argument in italics and causes Info to display the argument between @samp{//} and @samp{\\}.@refill @need 1300 For @TeX{}, write the following to equate the @code{@@phoo} command with the existing @code{@@i} italics command:@refill @example @group @@iftex @@global@@let@@phoo=@@i @@end iftex @end group @end example @noindent This defines @code{@@phoo} as a command that causes @TeX{} to typeset the argument to @code{@@phoo} in italics. @code{@@global@@let} tells @TeX{} to equate the next argument with the argument that follows the equals sign. @need 1300 For Info, write the following to tell the Info formatters to enclose the argument between @samp{//} and @samp{\\}: @example @group @@ifinfo @@definfoenclose phoo, //, \\ @@end ifinfo @end group @end example @noindent Write the @code{@@definfoenclose} command on a line and follow it with three arguments separated by commas (commas are used as separators in an @code{@@node} line in the same way).@refill @itemize @bullet @item The first argument to @code{@@definfoenclose} is the @@-command name @strong{without} the @samp{@@}; @item the second argument is the Info start delimiter string; and, @item the third argument is the Info end delimiter string. @end itemize @noindent The latter two arguments enclose the highlighted text in the Info file. A delimiter string may contain spaces. Neither the start nor end delimiter is required. However, if you do not provide a start delimiter, you must follow the command name with two commas in a row; otherwise, the Info formatting commands will misinterpret the end delimiter string as a start delimiter string.@refill After you have defined @code{@@phoo} both for @TeX{} and for Info, you can then write @code{@@phoo@{bar@}} to see @samp{//bar\\} in Info and see @ifinfo @samp{bar} in italics in printed output. @end ifinfo @iftex @i{bar} in italics in printed output. @end iftex Note that each definition applies to its own formatter: one for @TeX{}, the other for Info. @need 1200 Here is another example: @example @group @@ifinfo @@definfoenclose headword, , : @@end ifinfo @@iftex @@global@@let@@headword=@@b @@end iftex @end group @end example @noindent This defines @code{@@headword} as an Info formatting command that inserts nothing before and a colon after the argument and as a @TeX{} formatting command to typeset its argument in bold. @node Quotations and Examples, Lists and Tables, Marking Text, Top @comment node-name, next, previous, up @chapter Quotations and Examples Quotations and examples are blocks of text consisting of one or more whole paragraphs that are set off from the bulk of the text and treated differently. They are usually indented.@refill In Texinfo, you always begin a quotation or example by writing an @@-command at the beginning of a line by itself, and end it by writing an @code{@@end} command that is also at the beginning of a line by itself. For instance, you begin an example by writing @code{@@example} by itself at the beginning of a line and end the example by writing @code{@@end example} on a line by itself, at the beginning of that line.@refill @findex end @menu * Block Enclosing Commands:: Use different constructs for different purposes. * quotation:: How to write a quotation. * example:: How to write an example in a fixed-width font. * noindent:: How to prevent paragraph indentation. * Lisp Example:: How to illustrate Lisp code. * smallexample & smalllisp:: Forms for the @code{@@smallbook} option. * display:: How to write an example in the current font. * format:: How to write an example that does not narrow the margins. * exdent:: How to undo the indentation of a line. * flushleft & flushright:: How to push text flushleft or flushright. * cartouche:: How to draw cartouches around examples. @end menu @node Block Enclosing Commands, quotation, Quotations and Examples, Quotations and Examples @section The Block Enclosing Commands Here are commands for quotations and examples:@refill @table @code @item @@quotation Indicate text that is quoted. The text is filled, indented, and printed in a roman font by default.@refill @item @@example Illustrate code, commands, and the like. The text is printed in a fixed-width font, and indented but not filled.@refill @item @@lisp Illustrate Lisp code. The text is printed in a fixed-width font, and indented but not filled.@refill @item @@smallexample Illustrate code, commands, and the like. Similar to @code{@@example}, except that in @TeX{} this command typesets text in a smaller font for the smaller @code{@@smallbook} format than for the 8.5 by 11 inch format.@refill @item @@smalllisp Illustrate Lisp code. Similar to @code{@@lisp}, except that in @TeX{} this command typesets text in a smaller font for the smaller @code{@@smallbook} format than for the 8.5 by 11 inch format.@refill @item @@display Display illustrative text. The text is indented but not filled, and no font is specified (so, by default, the font is roman).@refill @item @@format Print illustrative text. The text is not indented and not filled and no font is specified (so, by default, the font is roman).@refill @end table The @code{@@exdent} command is used within the above constructs to undo the indentation of a line. The @code{@@flushleft} and @code{@@flushright} commands are used to line up the left or right margins of unfilled text.@refill The @code{@@noindent} command may be used after one of the above constructs to prevent the following text from being indented as a new paragraph.@refill You can use the @code{@@cartouche} command within one of the above constructs to highlight the example or quotation by drawing a box with rounded corners around it. (The @code{@@cartouche} command affects only the printed manual; it has no effect in the Info file; see @ref{cartouche, , Drawing Cartouches Around Examples}.)@refill @node quotation, example, Block Enclosing Commands, Quotations and Examples @comment node-name, next, previous, up @section @code{@@quotation} @cindex Quotations @findex quotation The text of a quotation is processed normally except that:@refill @itemize @bullet @item the margins are closer to the center of the page, so the whole of the quotation is indented;@refill @item the first lines of paragraphs are indented no more than other lines;@refill @item in the printed output, interparagraph spacing is reduced.@refill @end itemize @quotation This is an example of text written between an @code{@@quotation} command and an @code{@@end quotation} command. An @code{@@quotation} command is most often used to indicate text that is excerpted from another (real or hypothetical) printed work.@refill @end quotation Write an @code{@@quotation} command as text on a line by itself. This line will disappear from the output. Mark the end of the quotation with a line beginning with and containing only @code{@@end quotation}. The @code{@@end quotation} line will likewise disappear from the output. Thus, the following,@refill @example @@quotation This is a foo. @@end quotation @end example @noindent produces @quotation This is a foo. @end quotation @node example, noindent, quotation, Quotations and Examples @comment node-name, next, previous, up @section @code{@@example} @cindex Examples, formatting them @cindex Formatting examples @findex example The @code{@@example} command is used to indicate an example that is not part of the running text, such as computer input or output.@refill @example @group This is an example of text written between an @code{@@example} command and an @code{@@end example} command. The text is indented but not filled. @end group @group In the printed manual, the text is typeset in a fixed-width font, and extra spaces and blank lines are significant. In the Info file, an analogous result is obtained by indenting each line with five spaces. @end group @end example Write an @code{@@example} command at the beginning of a line by itself. This line will disappear from the output. Mark the end of the example with an @code{@@end example} command, also written at the beginning of a line by itself. The @code{@@end example} will disappear from the output.@refill @need 700 For example, @example @@example mv foo bar @@end example @end example @noindent produces @example mv foo bar @end example Since the lines containing @code{@@example} and @code{@@end example} will disappear, you should put a blank line before the @code{@@example} and another blank line after the @code{@@end example}. (Remember that blank lines between the beginning @code{@@example} and the ending @code{@@end example} will appear in the output.)@refill @quotation @strong{Caution:} Do not use tabs in the lines of an example (or anywhere else in Texinfo, for that matter)! @TeX{} treats tabs as single spaces, and that is not what they look like. This is a problem with @TeX{}. (If necessary, in Emacs, you can use @kbd{M-x untabify} to convert tabs in a region to multiple spaces.)@refill @end quotation Examples are often, logically speaking, ``in the middle'' of a paragraph, and the text continues after an example should not be indented. The @code{@@noindent} command prevents a piece of text from being indented as if it were a new paragraph. @ifinfo (@xref{noindent}.) @end ifinfo (The @code{@@code} command is used for examples of code that are embedded within sentences, not set off from preceding and following text. @xref{code, , @code{@@code}}.) @node noindent, Lisp Example, example, Quotations and Examples @comment node-name, next, previous, up @section @code{@@noindent} @findex noindent An example or other inclusion can break a paragraph into segments. Ordinarily, the formatters indent text that follows an example as a new paragraph. However, you can prevent this by writing @code{@@noindent} at the beginning of a line by itself preceding the continuation text.@refill @need 1500 For example: @example @group @@example This is an example @@end example @@noindent This line is not indented. As you can see, the beginning of the line is fully flush left with the line that follows after it. (This whole example is between @@code@{@@@@display@} and @@code@{@@@@end display@}.) @end group @end example @noindent produces @display @example This is an example @end example @tex % Remove extra vskip; this is a kludge to counter the effect of display \vskip-3.5\baselineskip @end tex @noindent This line is not indented. As you can see, the beginning of the line is fully flush left with the line that follows after it. (This whole example is between @code{@@display} and @code{@@end display}.) @end display To adjust the number of blank lines properly in the Info file output, remember that the line containing @code{@@noindent} does not generate a blank line, and neither does the @code{@@end example} line.@refill In the Texinfo source file for this manual, each line that says `produces' is preceded by a line containing @code{@@noindent}.@refill Do not put braces after an @code{@@noindent} command; they are not necessary, since @code{@@noindent} is a command used outside of paragraphs (@pxref{Command Syntax}).@refill @node Lisp Example, smallexample & smalllisp, noindent, Quotations and Examples @comment node-name, next, previous, up @section @code{@@lisp} @cindex Lisp example @findex lisp The @code{@@lisp} command is used for Lisp code. It is synonymous with the @code{@@example} command. @lisp This is an example of text written between an @code{@@lisp} command and an @code{@@end lisp} command. @end lisp Use @code{@@lisp} instead of @code{@@example} to preserve information regarding the nature of the example. This is useful, for example, if you write a function that evaluates only and all the Lisp code in a Texinfo file. Then you can use the Texinfo file as a Lisp library.@footnote{It would be straightforward to extend Texinfo to work in a similar fashion for C, Fortran, or other languages.}@refill Mark the end of @code{@@lisp} with @code{@@end lisp} on a line by itself.@refill @node smallexample & smalllisp, display, Lisp Example, Quotations and Examples @comment node-name, next, previous, up @section @code{@@smallexample} and @code{@@smalllisp} @cindex Small book example @cindex Example for a small book @cindex Lisp example for a small book @findex smallexample @findex smalllisp In addition to the regular @code{@@example} and @code{@@lisp} commands, Texinfo has two other ``example-style'' commands. These are the @code{@@smallexample} and @code{@@smalllisp} commands. Both these commands are designed for use with the @code{@@smallbook} command that causes @TeX{} to produce a printed manual in a 7 by 9.25 inch format rather than the regular 8.5 by 11 inch format.@refill In @TeX{}, the @code{@@smallexample} and @code{@@smalllisp} commands typeset text in a smaller font for the smaller @code{@@smallbook} format than for the 8.5 by 11 inch format. Consequently, many examples containing long lines fit in a narrower, @code{@@smallbook} page without needing to be shortened. Both commands typeset in the normal font size when you format for the 8.5 by 11 inch size; indeed, in this situation, the @code{@@smallexample} and @code{@@smalllisp} commands are defined to be the @code{@@example} and @code{@@lisp} commands.@refill In Info, the @code{@@smallexample} and @code{@@smalllisp} commands are equivalent to the @code{@@example} and @code{@@lisp} commands, and work exactly the same.@refill Mark the end of @code{@@smallexample} or @code{@@smalllisp} with @code{@@end smallexample} or @code{@@end smalllisp}, respectively.@refill @iftex Here is an example written in the small font used by the @code{@@smallexample} and @code{@@smalllisp} commands: @ifclear smallbook @display @tex % Remove extra vskip; this is a kludge to counter the effect of display \vskip-3\baselineskip {\ninett \dots{} to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things.} @end tex @end display @end ifclear @end iftex @ifset smallbook @iftex @smallexample This is an example of text written between @code{@@smallexample} and @code{@@end smallexample}. In Info and in an 8.5 by 11 inch manual, this text appears in its normal size; but in a 7 by 9.25 inch manual, this text appears in a smaller font. @end smallexample @end iftex @end ifset @ifinfo @smallexample This is an example of text written between @code{@@smallexample} and @code{@@end smallexample}. In Info and in an 8.5 by 11 inch manual, this text appears in its normal size; but in a 7 by 9.25 inch manual, this text appears in a smaller font. @end smallexample @end ifinfo The @code{@@smallexample} and @code{@@smalllisp} commands make it easier to prepare smaller format manuals without forcing you to edit examples by hand to fit them onto narrower pages.@refill As a general rule, a printed document looks better if you write all the examples in a chapter consistently in @code{@@example} or in @code{@@smallexample}. Only occasionally should you mix the two formats.@refill @xref{smallbook, , Printing ``Small'' Books}, for more information about the @code{@@smallbook} command.@refill @node display, format, smallexample & smalllisp, Quotations and Examples @comment node-name, next, previous, up @section @code{@@display} @cindex Display formatting @findex display The @code{@@display} command begins a kind of example. It is like the @code{@@example} command except that, in a printed manual, @code{@@display} does not select the fixed-width font. In fact, it does not specify the font at all, so that the text appears in the same font it would have appeared in without the @code{@@display} command.@refill @display This is an example of text written between an @code{@@display} command and an @code{@@end display} command. The @code{@@display} command indents the text, but does not fill it. @end display @node format, exdent, display, Quotations and Examples @comment node-name, next, previous, up @section @code{@@format} @findex format The @code{@@format} command is similar to @code{@@example} except that, in the printed manual, @code{@@format} does not select the fixed-width font and does not narrow the margins.@refill @format This is an example of text written between an @code{@@format} command and an @code{@@end format} command. As you can see from this example, the @code{@@format} command does not fill the text. @end format @node exdent, flushleft & flushright, format, Quotations and Examples @section @code{@@exdent}: Undoing a Line's Indentation @cindex Indentation undoing @findex exdent The @code{@@exdent} command removes any indentation a line might have. The command is written at the beginning of a line and applies only to the text that follows the command that is on the same line. Do not use braces around the text. In a printed manual, the text on an @code{@@exdent} line is printed in the roman font.@refill @code{@@exdent} is usually used within examples. Thus,@refill @example @group @@example This line follows an @@@@example command. @@exdent This line is exdented. This line follows the exdented line. The @@@@end example comes on the next line. @@end group @end group @end example @noindent produces @example @group This line follows an @@example command. @exdent This line is exdented. This line follows the exdented line. The @@end example comes on the next line. @end group @end example In practice, the @code{@@exdent} command is rarely used. Usually, you un-indent text by ending the example and returning the page to its normal width.@refill @node flushleft & flushright, cartouche, exdent, Quotations and Examples @section @code{@@flushleft} and @code{@@flushright} @findex flushleft @findex flushright The @code{@@flushleft} and @code{@@flushright} commands line up the ends of lines on the left and right margins of a page, but do not fill the text. The commands are written on lines of their own, without braces. The @code{@@flushleft} and @code{@@flushright} commands are ended by @code{@@end flushleft} and @code{@@end flushright} commands on lines of their own.@refill @need 1500 For example, @example @group @@flushleft This text is written flushleft. @@end flushleft @end group @end example @noindent produces @quotation @flushleft This text is written flushleft. @end flushleft @end quotation @code{@@flushright} produces the type of indentation often used in the return address of letters. For example, @example @group @@flushright Here is an example of text written flushright. The @@code@{@@flushright@} command right justifies every line but leaves the left end ragged. @@end flushright @end group @end example @noindent produces @flushright Here is an example of text written flushright. The @code{@@flushright} command right justifies every line but leaves the left end ragged. @end flushright @node cartouche, , flushleft & flushright, Quotations and Examples @section Drawing Cartouches Around Examples @findex cartouche @cindex Box with rounded corners In a printed manual, the @code{@@cartouche} command draws a box with rounded corners around its contents. You can use this command to further highlight an example or quotation. For instance, you could write a manual in which one type of example is surrounded by a cartouche for emphasis.@refill The @code{@@cartouche} command affects only the printed manual; it has no effect in the Info file.@refill @need 1500 For example, @example @group @@example @@cartouche % pwd /usr/local/share/emacs @@end cartouche @@end example @end group @end example @noindent surrounds the two-line example with a box with rounded corners, in the printed manual. @iftex In a printed manual, the example looks like this:@refill @example @group @cartouche % pwd /usr/local/lib/emacs/info @end cartouche @end group @end example @end iftex @node Lists and Tables, Indices, Quotations and Examples, Top @chapter Lists and Tables @cindex Making lists and tables @cindex Lists and tables, making @cindex Tables and lists, making Texinfo has several ways of making lists and tables. Lists can be bulleted or numbered; two-column tables can highlight the items in the first column; multi-column tables are also supported. @menu * Introducing Lists:: Texinfo formats lists for you. * itemize:: How to construct a simple list. * enumerate:: How to construct a numbered list. * Two-column Tables:: How to construct a two-column table. * Multi-column Tables:: How to construct generalized tables. @end menu @ifinfo @node Introducing Lists, itemize, Lists and Tables, Lists and Tables @heading Introducing Lists @end ifinfo Texinfo automatically indents the text in lists or tables, and numbers an enumerated list. This last feature is useful if you modify the list, since you do not need to renumber it yourself.@refill Numbered lists and tables begin with the appropriate @@-command at the beginning of a line, and end with the corresponding @code{@@end} command on a line by itself. The table and itemized-list commands also require that you write formatting information on the same line as the beginning @@-command.@refill Begin an enumerated list, for example, with an @code{@@enumerate} command and end the list with an @code{@@end enumerate} command. Begin an itemized list with an @code{@@itemize} command, followed on the same line by a formatting command such as @code{@@bullet}, and end the list with an @code{@@end itemize} command.@refill @findex end Precede each element of a list with an @code{@@item} or @code{@@itemx} command.@refill @sp 1 @noindent Here is an itemized list of the different kinds of table and lists:@refill @itemize @bullet @item Itemized lists with and without bullets. @item Enumerated lists, using numbers or letters. @item Two-column tables with highlighting. @end itemize @sp 1 @noindent Here is an enumerated list with the same items:@refill @enumerate @item Itemized lists with and without bullets. @item Enumerated lists, using numbers or letters. @item Two-column tables with highlighting. @end enumerate @sp 1 @noindent And here is a two-column table with the same items and their @w{@@-commands}:@refill @table @code @item @@itemize Itemized lists with and without bullets. @item @@enumerate Enumerated lists, using numbers or letters. @item @@table @itemx @@ftable @itemx @@vtable Two-column tables with indexing. @end table @node itemize, enumerate, Introducing Lists, Lists and Tables @comment node-name, next, previous, up @section Making an Itemized List @cindex Itemization @findex itemize The @code{@@itemize} command produces sequences of indented paragraphs, with a bullet or other mark inside the left margin at the beginning of each paragraph for which such a mark is desired.@refill Begin an itemized list by writing @code{@@itemize} at the beginning of a line. Follow the command, on the same line, with a character or a Texinfo command that generates a mark. Usually, you will write @code{@@bullet} after @code{@@itemize}, but you can use @code{@@minus}, or any character or any special symbol that results in a single character in the Info file. (When you write @code{@@bullet} or @code{@@minus} after an @code{@@itemize} command, you may omit the @samp{@{@}}.)@refill Write the text of the indented paragraphs themselves after the @code{@@itemize}, up to another line that says @code{@@end itemize}.@refill Before each paragraph for which a mark in the margin is desired, write a line that says just @code{@@item}. Do not write any other text on this line.@refill @findex item Usually, you should put a blank line before an @code{@@item}. This puts a blank line in the Info file. (@TeX{} inserts the proper interline whitespace in either case.) Except when the entries are very brief, these blank lines make the list look better.@refill Here is an example of the use of @code{@@itemize}, followed by the output it produces. Note that @code{@@bullet} produces an @samp{*} in Info and a round dot in @TeX{}.@refill @example @group @@itemize @@bullet @@item Some text for foo. @@item Some text for bar. @@end itemize @end group @end example @noindent This produces: @quotation @itemize @bullet @item Some text for foo. @item Some text for bar. @end itemize @end quotation Itemized lists may be embedded within other itemized lists. Here is a list marked with dashes embedded in a list marked with bullets:@refill @example @group @@itemize @@bullet @@item First item. @@itemize @@minus @@item Inner item. @@item Second inner item. @@end itemize @@item Second outer item. @@end itemize @end group @end example @noindent This produces: @quotation @itemize @bullet @item First item. @itemize @minus @item Inner item. @item Second inner item. @end itemize @item Second outer item. @end itemize @end quotation @node enumerate, Two-column Tables, itemize, Lists and Tables @comment node-name, next, previous, up @section Making a Numbered or Lettered List @cindex Enumeration @findex enumerate @code{@@enumerate} is like @code{@@itemize} (@pxref{itemize,, @code{@@itemize}}), except that the labels on the items are successive integers or letters instead of bullets. Write the @code{@@enumerate} command at the beginning of a line. The command does not require an argument, but accepts either a number or a letter as an option. Without an argument, @code{@@enumerate} starts the list with the number @samp{1}. With a numeric argument, such as @samp{3}, the command starts the list with that number. With an upper or lower case letter, such as @samp{a} or @samp{A}, the command starts the list with that letter.@refill Write the text of the enumerated list in the same way you write an itemized list: put @code{@@item} on a line of its own before the start of each paragraph that you want enumerated. Do not write any other text on the line beginning with @code{@@item}.@refill You should put a blank line between entries in the list. This generally makes it easier to read the Info file.@refill @need 1500 Here is an example of @code{@@enumerate} without an argument:@refill @example @group @@enumerate @@item Underlying causes. @@item Proximate causes. @@end enumerate @end group @end example @noindent This produces: @enumerate @item Underlying causes. @item Proximate causes. @end enumerate @sp 1 Here is an example with an argument of @kbd{3}:@refill @sp 1 @example @group @@enumerate 3 @@item Predisposing causes. @@item Precipitating causes. @@item Perpetuating causes. @@end enumerate @end group @end example @noindent This produces: @enumerate 3 @item Predisposing causes. @item Precipitating causes. @item Perpetuating causes. @end enumerate @sp 1 Here is a brief summary of the alternatives. The summary is constructed using @code{@@enumerate} with an argument of @kbd{a}.@refill @sp 1 @enumerate a @item @code{@@enumerate} Without an argument, produce a numbered list, starting with the number 1.@refill @item @code{@@enumerate @var{positive-integer}} With a (positive) numeric argument, start a numbered list with that number. You can use this to continue a list that you interrupted with other text.@refill @item @code{@@enumerate @var{upper-case-letter}} With an upper case letter as argument, start a list in which each item is marked by a letter, beginning with that upper case letter.@refill @item @code{@@enumerate @var{lower-case-letter}} With a lower case letter as argument, start a list in which each item is marked by a letter, beginning with that lower case letter.@refill @end enumerate You can also nest enumerated lists, as in an outline.@refill @node Two-column Tables, Multi-column Tables, enumerate, Lists and Tables @section Making a Two-column Table @cindex Tables, making two-column @findex table @code{@@table} is similar to @code{@@itemize} (@pxref{itemize,, @code{@@itemize}}), but allows you to specify a name or heading line for each item. The @code{@@table} command is used to produce two-column tables, and is especially useful for glossaries, explanatory exhibits, and command-line option summaries. @menu * table:: How to construct a two-column table. * ftable vtable:: Automatic indexing for two-column tables. * itemx:: How to put more entries in the first column. @end menu @ifinfo @node table, ftable vtable, Two-column Tables, Two-column Tables @subheading Using the @code{@@table} Command Use the @code{@@table} command to produce two-column tables.@refill @end ifinfo Write the @code{@@table} command at the beginning of a line and follow it on the same line with an argument that is a Texinfo ``indicating'' command such as @code{@@code}, @code{@@samp}, @code{@@var}, or @code{@@kbd} (@pxref{Indicating}). Although these commands are usually followed by arguments in braces, in this case you use the command name without an argument because @code{@@item} will supply the argument. This command will be applied to the text that goes into the first column of each item and determines how it will be highlighted. For example, @code{@@code} will cause the text in the first column to be highlighted with an @code{@@code} command. (We recommend @code{@@code} for @code{@@table}'s of command-line options.) @findex asis You may also choose to use the @code{@@asis} command as an argument to @code{@@table}. @code{@@asis} is a command that does nothing; if you use this command after @code{@@table}, @TeX{} and the Info formatting commands output the first column entries without added highlighting (``as is'').@refill (The @code{@@table} command may work with other commands besides those listed here. However, you can only use commands that normally take arguments in braces.)@refill Begin each table entry with an @code{@@item} command at the beginning of a line. Write the first column text on the same line as the @code{@@item} command. Write the second column text on the line following the @code{@@item} line and on subsequent lines. (You do not need to type anything for an empty second column entry.) You may write as many lines of supporting text as you wish, even several paragraphs. But only text on the same line as the @code{@@item} will be placed in the first column.@refill @findex item Normally, you should put a blank line before an @code{@@item} line. This puts a blank like in the Info file. Except when the entries are very brief, a blank line looks better.@refill @need 1500 The following table, for example, highlights the text in the first column with an @code{@@samp} command:@refill @example @group @@table @@samp @@item foo This is the text for @@samp@{foo@}. @@item bar Text for @@samp@{bar@}. @@end table @end group @end example @noindent This produces: @table @samp @item foo This is the text for @samp{foo}. @item bar Text for @samp{bar}. @end table If you want to list two or more named items with a single block of text, use the @code{@@itemx} command. (@xref{itemx, , @code{@@itemx}}.)@refill @node ftable vtable, itemx, table, Two-column Tables @comment node-name, next, previous, up @subsection @code{@@ftable} and @code{@@vtable} @cindex Tables with indexes @cindex Indexing table entries automatically @findex ftable @findex vtable The @code{@@ftable} and @code{@@vtable} commands are the same as the @code{@@table} command except that @code{@@ftable} automatically enters each of the items in the first column of the table into the index of functions and @code{@@vtable} automatically enters each of the items in the first column of the table into the index of variables. This simplifies the task of creating indices. Only the items on the same line as the @code{@@item} commands are indexed, and they are indexed in exactly the form that they appear on that line. @xref{Indices, , Creating Indices}, for more information about indices.@refill Begin a two-column table using @code{@@ftable} or @code{@@vtable} by writing the @@-command at the beginning of a line, followed on the same line by an argument that is a Texinfo command such as @code{@@code}, exactly as you would for an @code{@@table} command; and end the table with an @code{@@end ftable} or @code{@@end vtable} command on a line by itself. See the example for @code{@@table} in the previous section. @node itemx, , ftable vtable, Two-column Tables @comment node-name, next, previous, up @subsection @code{@@itemx} @cindex Two named items for @code{@@table} @findex itemx Use the @code{@@itemx} command inside a table when you have two or more first column entries for the same item, each of which should appear on a line of its own. Use @code{@@itemx} for all but the first entry; @code{@@itemx} should always follow an @code{@@item} command. The @code{@@itemx} command works exactly like @code{@@item} except that it does not generate extra vertical space above the first column text. @need 1000 For example, @example @group @@table @@code @@item upcase @@itemx downcase These two functions accept a character or a string as argument, and return the corresponding upper case (lower case) character or string. @@end table @end group @end example @noindent This produces: @table @code @item upcase @itemx downcase These two functions accept a character or a string as argument, and return the corresponding upper case (lower case) character or string.@refill @end table @noindent (Note also that this example illustrates multi-line supporting text in a two-column table.)@refill @node Multi-column Tables, , Two-column Tables, Lists and Tables @section Multi-column Tables @cindex Tables, making multi-column @findex multitable @code{@@multitable} allows you to construct tables with any number of columns, with each column having any width you like. You define the column widths on the @code{@@multitable} line itself, and write each row of the actual table following an @code{@@item} command, with columns separated by an @code{@@tab} command. Finally, @code{@@end multitable} completes the table. Details in the sections below. @menu * Multitable Column Widths:: Defining multitable column widths. * Multitable Rows:: Defining multitable rows, with examples. @end menu @node Multitable Column Widths, Multitable Rows, Multi-column Tables, Multi-column Tables @subsection Multitable Column Widths @cindex Multitable column widths @cindex Column widths, defining for multitables @cindex Widths, defining multitable column You can define the column widths for a multitable in two ways: as fractions of the line length; or with a prototype row. Mixing the two methods is not supported. In either case, the widths are defined entirely on the same line as the @code{@@multitable} command. @enumerate @item @findex columnfractions @cindex Line length, column widths as fraction of To specify column widths as fractions of the line length, write @code{@@columnfractions} and the decimal numbers (presumably less than 1) after the @code{@@multitable} command, as in: @example @@multitable @@columnfractions .33 .33 .33 @end example @noindent The fractions need not add up exactly to 1.0, as these do not. This allows you to produce tables that do not need the full line length. @item @cindex Prototype row, column widths defined by To specify a prototype row, write the longest entry for each column enclosed in braces after the @code{@@multitable} command. For example: @example @@multitable @{some text for column one@} @{for column two@} @end example @noindent The first column will then have the width of the typeset `some text for column one', and the second column the width of `for column two'. The prototype entries need not appear in the table itself. Although we used simple text in this example, the prototype entries can contain Texinfo commands; markup commands such as @code{@@code} are particularly likely to be useful. @end enumerate @node Multitable Rows, , Multitable Column Widths, Multi-column Tables @subsection Multitable Rows @cindex Multitable rows @cindex Rows, of a multitable @findex item @cindex tab After the @code{@@multitable} command defining the column widths (see the previous section), you begin each row in the body of a multitable with @code{@@item}, and separate the column entries with @code{@@tab}. Line breaks are not special within the table body, and you may break input lines in your source file as necessary. Here is a complete example of a multi-column table (the text is from @cite{The GNU Emacs Manual}, @pxref{Split Window,, Splitting Windows, emacs, The GNU Emacs Manual}): @example @@multitable @@columnfractions .15 .45 .4 @@item Key @@tab Command @@tab Description @@item C-x 2 @@tab @@code@{split-window-vertically@} @@tab Split the selected window into two windows, with one above the other. @@item C-x 3 @@tab @@code@{split-window-horizontally@} @@tab Split the selected window into two windows positioned side by side. @@item C-Mouse-2 @@tab @@tab In the mode line or scroll bar of a window, split that window. @@end multitable @end example @noindent produces: @multitable @columnfractions .15 .45 .4 @item Key @tab Command @tab Description @item C-x 2 @tab @code{split-window-vertically} @tab Split the selected window into two windows, with one above the other. @item C-x 3 @tab @code{split-window-horizontally} @tab Split the selected window into two windows positioned side by side. @item C-Mouse-2 @tab @tab In the mode line or scroll bar of a window, split that window. @end multitable @node Indices, Insertions, Lists and Tables, Top @comment node-name, next, previous, up @chapter Creating Indices @cindex Indices @cindex Creating indices Using Texinfo, you can generate indices without having to sort and collate entries manually. In an index, the entries are listed in alphabetical order, together with information on how to find the discussion of each entry. In a printed manual, this information consists of page numbers. In an Info file, this information is a menu entry leading to the first node referenced.@refill Texinfo provides several predefined kinds of index: an index for functions, an index for variables, an index for concepts, and so on. You can combine indices or use them for other than their canonical purpose. If you wish, you can define your own indices.@refill @menu * Index Entries:: Choose different words for index entries. * Predefined Indices:: Use different indices for different kinds of entry. * Indexing Commands:: How to make an index entry. * Combining Indices:: How to combine indices. * New Indices:: How to define your own indices. @end menu @node Index Entries, Predefined Indices, Indices, Indices @comment node-name, next, previous, up @section Making Index Entries @cindex Index entries, making @cindex Entries, making index When you are making index entries, it is good practice to think of the different ways people may look for something. Different people @emph{do not} think of the same words when they look something up. A helpful index will have items indexed under all the different words that people may use. For example, one reader may think it obvious that the two-letter names for indices should be listed under ``Indices, two-letter names'', since the word ``Index'' is the general concept. But another reader may remember the specific concept of two-letter names and search for the entry listed as ``Two letter names for indices''. A good index will have both entries and will help both readers.@refill Like typesetting, the construction of an index is a highly skilled, professional art, the subtleties of which are not appreciated until you need to do it yourself.@refill @xref{Printing Indices & Menus}, for information about printing an index at the end of a book or creating an index menu in an Info file.@refill @node Predefined Indices, Indexing Commands, Index Entries, Indices @comment node-name, next, previous, up @section Predefined Indices Texinfo provides six predefined indices:@refill @itemize @bullet @item A @dfn{concept index} listing concepts that are discussed.@refill @item A @dfn{function index} listing functions (such as entry points of libraries).@refill @item A @dfn{variables index} listing variables (such as global variables of libraries).@refill @item A @dfn{keystroke index} listing keyboard commands.@refill @item A @dfn{program index} listing names of programs.@refill @item A @dfn{data type index} listing data types (such as structures defined in header files).@refill @end itemize @noindent Not every manual needs all of these, and most manuals use two or three of them. This manual has two indices: a concept index and an @@-command index (that is actually the function index but is called a command index in the chapter heading). Two or more indices can be combined into one using the @code{@@synindex} or @code{@@syncodeindex} commands. @xref{Combining Indices}.@refill @node Indexing Commands, Combining Indices, Predefined Indices, Indices @comment node-name, next, previous, up @section Defining the Entries of an Index @cindex Defining indexing entries @cindex Index entries @cindex Entries for an index @cindex Specifying index entries @cindex Creating index entries The data to make an index come from many individual indexing commands scattered throughout the Texinfo source file. Each command says to add one entry to a particular index; after formatting, the index will give the current page number or node name as the reference.@refill An index entry consists of an indexing command at the beginning of a line followed, on the rest of the line, by the entry.@refill For example, this section begins with the following five entries for the concept index:@refill @example @@cindex Defining indexing entries @@cindex Index entries @@cindex Entries for an index @@cindex Specifying index entries @@cindex Creating index entries @end example Each predefined index has its own indexing command---@code{@@cindex} for the concept index, @code{@@findex} for the function index, and so on.@refill @cindex Writing index entries @cindex Index entry writing Concept index entries consist of text. The best way to write an index is to choose entries that are terse yet clear. If you can do this, the index often looks better if the entries are not capitalized, but written just as they would appear in the middle of a sentence. (Capitalize proper names and acronyms that always call for upper case letters.) This is the case convention we use in most GNU manuals' indices. If you don't see how to make an entry terse yet clear, make it longer and clear---not terse and confusing. If many of the entries are several words long, the index may look better if you use a different convention: to capitalize the first word of each entry. But do not capitalize a case-sensitive name such as a C or Lisp function name or a shell command; that would be a spelling error. Whichever case convention you use, please use it consistently! @ignore Concept index entries consist of English text. The usual convention is to capitalize the first word of each such index entry, unless that word is the name of a function, variable, or other such entity that should not be capitalized. However, if your concept index entries are consistently short (one or two words each) it may look better for each regular entry to start with a lower case letter, aside from proper names and acronyms that always call for upper case letters. Whichever convention you adapt, please be consistent! @end ignore Entries in indices other than the concept index are symbol names in programming languages, or program names; these names are usually case-sensitive, so use upper and lower case as required for them. By default, entries for a concept index are printed in a small roman font and entries for the other indices are printed in a small @code{@@code} font. You may change the way part of an entry is printed with the usual Texinfo commands, such as @code{@@file} for file names and @code{@@emph} for emphasis (@pxref{Marking Text}).@refill @cindex Index font types @cindex Predefined indexing commands @cindex Indexing commands, predefined The six indexing commands for predefined indices are: @table @code @item @@cindex @var{concept} @findex cindex Make an entry in the concept index for @var{concept}.@refill @item @@findex @var{function} @findex findex Make an entry in the function index for @var{function}.@refill @item @@vindex @var{variable} @findex vindex Make an entry in the variable index for @var{variable}.@refill @item @@kindex @var{keystroke} @findex kindex Make an entry in the key index for @var{keystroke}.@refill @item @@pindex @var{program} @findex pindex Make an entry in the program index for @var{program}.@refill @item @@tindex @var{data type} @findex tindex Make an entry in the data type index for @var{data type}.@refill @end table @quotation @strong{Caution:} Do not use a colon in an index entry. In Info, a colon separates the menu entry name from the node name. An extra colon confuses Info. @xref{Menu Parts, , The Parts of a Menu}, for more information about the structure of a menu entry.@refill @end quotation If you write several identical index entries in different places in a Texinfo file, the index in the printed manual will list all the pages to which those entries refer. However, the index in the Info file will list @strong{only} the node that references the @strong{first} of those index entries. Therefore, it is best to write indices in which each entry refers to only one place in the Texinfo file. Fortunately, this constraint is a feature rather than a loss since it means that the index will be easy to use. Otherwise, you could create an index that lists several pages for one entry and your reader would not know to which page to turn. If you have two identical entries for one topic, change the topics slightly, or qualify them to indicate the difference.@refill You are not actually required to use the predefined indices for their canonical purposes. For example, suppose you wish to index some C preprocessor macros. You could put them in the function index along with actual functions, just by writing @code{@@findex} commands for them; then, when you print the ``Function Index'' as an unnumbered chapter, you could give it the title `Function and Macro Index' and all will be consistent for the reader. Or you could put the macros in with the data types by writing @code{@@tindex} commands for them, and give that index a suitable title so the reader will understand. (@xref{Printing Indices & Menus}.)@refill @node Combining Indices, New Indices, Indexing Commands, Indices @comment node-name, next, previous, up @section Combining Indices @cindex Combining indices @cindex Indices, combining them Sometimes you will want to combine two disparate indices such as functions and concepts, perhaps because you have few enough of one of them that a separate index for them would look silly.@refill You could put functions into the concept index by writing @code{@@cindex} commands for them instead of @code{@@findex} commands, and produce a consistent manual by printing the concept index with the title `Function and Concept Index' and not printing the `Function Index' at all; but this is not a robust procedure. It works only if your document is never included as part of another document that is designed to have a separate function index; if your document were to be included with such a document, the functions from your document and those from the other would not end up together. Also, to make your function names appear in the right font in the concept index, you would need to enclose every one of them between the braces of @code{@@code}.@refill @menu * syncodeindex:: How to merge two indices, using @code{@@code} font for the merged-from index. * synindex:: How to merge two indices, using the default font of the merged-to index. @end menu @node syncodeindex, synindex, Combining Indices, Combining Indices @subsection @code{@@syncodeindex} @findex syncodeindex When you want to combine functions and concepts into one index, you should index the functions with @code{@@findex} and index the concepts with @code{@@cindex}, and use the @code{@@syncodeindex} command to redirect the function index entries into the concept index.@refill @findex syncodeindex The @code{@@syncodeindex} command takes two arguments; they are the name of the index to redirect, and the name of the index to redirect it to. The template looks like this:@refill @example @@syncodeindex @var{from} @var{to} @end example @cindex Predefined names for indices @cindex Two letter names for indices @cindex Indices, two letter names @cindex Names for indices For this purpose, the indices are given two-letter names:@refill @table @samp @item cp concept index @item fn function index @item vr variable index @item ky key index @item pg program index @item tp data type index @end table Write an @code{@@syncodeindex} command before or shortly after the end-of-header line at the beginning of a Texinfo file. For example, to merge a function index with a concept index, write the following:@refill @example @@syncodeindex fn cp @end example @noindent This will cause all entries designated for the function index to merge in with the concept index instead.@refill To merge both a variables index and a function index into a concept index, write the following:@refill @example @group @@syncodeindex vr cp @@syncodeindex fn cp @end group @end example @cindex Fonts for indices The @code{@@syncodeindex} command puts all the entries from the `from' index (the redirected index) into the @code{@@code} font, overriding whatever default font is used by the index to which the entries are now directed. This way, if you direct function names from a function index into a concept index, all the function names are printed in the @code{@@code} font as you would expect.@refill @node synindex, , syncodeindex, Combining Indices @subsection @code{@@synindex} @findex synindex The @code{@@synindex} command is nearly the same as the @code{@@syncodeindex} command, except that it does not put the `from' index entries into the @code{@@code} font; rather it puts them in the roman font. Thus, you use @code{@@synindex} when you merge a concept index into a function index.@refill @xref{Printing Indices & Menus}, for information about printing an index at the end of a book or creating an index menu in an Info file.@refill @node New Indices, , Combining Indices, Indices @section Defining New Indices @cindex Defining new indices @cindex Indices, defining new @cindex New index defining @findex defindex @findex defcodeindex In addition to the predefined indices, you may use the @code{@@defindex} and @code{@@defcodeindex} commands to define new indices. These commands create new indexing @@-commands with which you mark index entries. The @code{@@defindex }command is used like this:@refill @example @@defindex @var{name} @end example The name of an index should be a two letter word, such as @samp{au}. For example:@refill @example @@defindex au @end example This defines a new index, called the @samp{au} index. At the same time, it creates a new indexing command, @code{@@auindex}, that you can use to make index entries. Use the new indexing command just as you would use a predefined indexing command.@refill For example, here is a section heading followed by a concept index entry and two @samp{au} index entries.@refill @example @@section Cognitive Semantics @@cindex kinesthetic image schemas @@auindex Johnson, Mark @@auindex Lakoff, George @end example @noindent (Evidently, @samp{au} serves here as an abbreviation for ``author''.) Texinfo constructs the new indexing command by concatenating the name of the index with @samp{index}; thus, defining an @samp{au} index leads to the automatic creation of an @code{@@auindex} command.@refill Use the @code{@@printindex} command to print the index, as you do with the predefined indices. For example:@refill @example @group @@node Author Index, Subject Index, , Top @@unnumbered Author Index @@printindex au @end group @end example The @code{@@defcodeindex} is like the @code{@@defindex} command, except that, in the printed output, it prints entries in an @code{@@code} font instead of a roman font. Thus, it parallels the @code{@@findex} command rather than the @code{@@cindex} command.@refill You should define new indices within or right after the end-of-header line of a Texinfo file, before any @code{@@synindex} or @code{@@syncodeindex} commands (@pxref{Header}).@refill @node Insertions, Breaks, Indices, Top @comment node-name, next, previous, up @chapter Special Insertions @cindex Inserting special characters and symbols @cindex Special insertions Texinfo provides several commands for inserting characters that have special meaning in Texinfo, such as braces, and for other graphic elements that do not correspond to simple characters you can type. @iftex These are: @itemize @bullet @item Braces, @samp{@@} and periods. @item Whitespace within and around a sentence. @item Accents. @item Dots and bullets. @item The @TeX{} logo and the copyright symbol. @item Mathematical expressions. @end itemize @end iftex @menu * Braces Atsigns:: How to insert braces, @samp{@@}. * Inserting Space:: How to insert the right amount of space within a sentence. * Inserting Accents:: How to insert accents and special characters. * Dots Bullets:: How to insert dots and bullets. * TeX and copyright:: How to insert the @TeX{} logo and the copyright symbol. * pounds:: How to insert the pounds currency symbol. * minus:: How to insert a minus sign. * math:: How to format a mathematical expression. * Glyphs:: How to indicate results of evaluation, expansion of macros, errors, etc. * Images:: How to include graphics. @end menu @node Braces Atsigns, Inserting Space, Insertions, Insertions @section Inserting @@ and Braces @cindex Inserting @@, braces @cindex Braces, inserting @cindex Special characters, commands to insert @cindex Commands to insert special characters @samp{@@} and curly braces are special characters in Texinfo. To insert these characters so they appear in text, you must put an @samp{@@} in front of these characters to prevent Texinfo from misinterpreting them. Do not put braces after any of these commands; they are not necessary. @menu * Inserting An Atsign:: How to insert @samp{@@}. * Inserting Braces:: How to insert @samp{@{} and @samp{@}}. @end menu @node Inserting An Atsign, Inserting Braces, Braces Atsigns, Braces Atsigns @subsection Inserting @samp{@@} with @@@@ @findex @@ @r{(single @samp{@@})} @code{@@@@} stands for a single @samp{@@} in either printed or Info output. Do not put braces after an @code{@@@@} command. @node Inserting Braces, , Inserting An Atsign, Braces Atsigns @subsection Inserting @samp{@{} and @samp{@}}with @@@{ and @@@} @findex @{ @r{(single @samp{@{})} @findex @} @r{(single @samp{@}})} @code{@@@{} stands for a single @samp{@{} in either printed or Info output. @code{@@@}} stands for a single @samp{@}} in either printed or Info output. Do not put braces after either an @code{@@@{} or an @code{@@@}} command. @node Inserting Space, Inserting Accents, Braces Atsigns, Insertions @section Inserting Space @cindex Inserting space @cindex Spacing, inserting @cindex Whitespace, inserting The following sections describe commands that control spacing of various kinds within and after sentences. @menu * Not Ending a Sentence:: Sometimes a . doesn't end a sentence. * Ending a Sentence:: Sometimes it does. * Multiple Spaces:: Inserting multiple spaces. * dmn:: How to format a dimension. @end menu @node Not Ending a Sentence, Ending a Sentence, Inserting Space, Inserting Space @subsection Not Ending a Sentence @cindex Not ending a sentence @cindex Sentence non-ending punctuation @cindex Periods, inserting Depending on whether a period or exclamation point or question mark is inside or at the end of a sentence, less or more space is inserted after a period in a typeset manual. Since it is not always possible for Texinfo to determine when a period ends a sentence and when it is used in an abbreviation, special commands are needed in some circumstances. (Usually, Texinfo can guess how to handle periods, so you do not need to use the special commands; you just enter a period as you would if you were using a typewriter, which means you put two spaces after the period, question mark, or exclamation mark that ends a sentence.) @findex : @r{(suppress widening)} Use the @code{@@:}@: command after a period, question mark, exclamation mark, or colon that should not be followed by extra space. For example, use @code{@@:}@: after periods that end abbreviations which are not at the ends of sentences. @need 700 For example, @example The s.o.p.@@: has three parts @dots{} The s.o.p. has three parts @dots{} @end example @noindent @ifinfo produces @end ifinfo @iftex produces the following. If you look carefully at this printed output, you will see a little more whitespace after @samp{s.o.p.} in the second line.@refill @end iftex @quotation The s.o.p.@: has three parts @dots{}@* The s.o.p. has three parts @dots{} @end quotation @noindent (Incidentally, @samp{s.o.p.} is an abbreviation for ``Standard Operating Procedure''.) @code{@@:} has no effect on the Info output. Do not put braces after @code{@@:}. @node Ending a Sentence, Multiple Spaces, Not Ending a Sentence, Inserting Space @subsection Ending a Sentence @cindex Ending a Sentence @cindex Sentence ending punctuation @findex . @r{(end of sentence)} @findex ! @r{(end of sentence)} @findex ? @r{(end of sentence)} Use @code{@@.}@: instead of a period, @code{@@!}@: instead of an exclamation point, and @code{@@?}@: instead of a question mark at the end of a sentence that ends with a single capital letter. Otherwise, @TeX{} will think the letter is an abbreviation and will not insert the correct end-of-sentence spacing. Here is an example: @example Give it to M.I.B. and to M.E.W@@. Also, give it to R.J.C@@. Give it to M.I.B. and to M.E.W. Also, give it to R.J.C. @end example @noindent @ifinfo produces @end ifinfo @iftex produces the following. If you look carefully at this printed output, you will see a little more whitespace after the @samp{W} in the first line. @end iftex @quotation Give it to M.I.B. and to M.E.W@. Also, give it to R.J.C@.@* Give it to M.I.B. and to M.E.W. Also, give it to R.J.C. @end quotation In the Info file output, @code{@@.}@: is equivalent to a simple @samp{.}; likewise for @code{@@!}@: and @code{@@?}@:. The meanings of @code{@@:} and @code{@@.}@: in Texinfo are designed to work well with the Emacs sentence motion commands (@pxref{Sentences,,, emacs, The GNU Emacs Manual}). This made it necessary for them to be incompatible with some other formatting systems that use @@-commands. Do not put braces after any of these commands. @node Multiple Spaces, dmn, Ending a Sentence, Inserting Space @subsection Multiple Spaces @cindex Multiple spaces @cindex Whitespace, inserting @findex (space) @findex (tab) @findex (newline) Ordinarily, @TeX{} collapses multiple whitespace characters (space, tab, and newline) into a single space. Info output, on the other hand, preserves whitespace as you type it, except for changing a newline into a space; this is why it is important to put two spaces at the end of sentences in Texinfo documents. Occasionally, you may want to actually insert several consecutive spaces, either for purposes of example (what your program does with multiple spaces as input), or merely for purposes of appearance in headings or lists. Texinfo supports three commands: @code{@@@kbd{SPACE}}, @code{@@@kbd{TAB}}, and @code{@@@kbd{NL}}, all of which insert a single space into the output. (Here, @code{@@@kbd{SPACE}} represents an @samp{@@} character followed by a space, i.e., @samp{@@ }, and @kbd{TAB} and @kbd{NL} represent the tab character and end-of-line, i.e., when @samp{@@} is the last character on a line.) For example, @example Spacey@@ @@ @@ @@ example. @end example @noindent produces @example Spacey@ @ @ @ example. @end example Other possible uses of @code{@@@kbd{SPACE}} have been subsumed by @code{@@multitable} (@pxref{Multi-column Tables}). Do not follow any of these commands with braces. @node dmn, , Multiple Spaces, Inserting Space @subsection @code{@@dmn}@{@var{dimension}@}: Format a Dimension @cindex Thin space between number, dimension @cindex Dimension formatting @cindex Format a dimension @findex dmn At times, you may want to write @samp{12@dmn{pt}} or @samp{8.5@dmn{in}} with little or no space between the number and the abbreviation for the dimension. You can use the @code{@@dmn} command to do this. On seeing the command, @TeX{} inserts just enough space for proper typesetting; the Info formatting commands insert no space at all, since the Info file does not require it.@refill To use the @code{@@dmn} command, write the number and then follow it immediately, with no intervening space, by @code{@@dmn}, and then by the dimension within braces. For example, @example A4 paper is 8.27@@dmn@{in@} wide. @end example @noindent produces @quotation A4 paper is 8.27@dmn{in} wide. @end quotation Not everyone uses this style. Some people prefer @w{@samp{8.27 in.@@:}} or @w{@samp{8.27 inches}} to @samp{8.27@@dmn@{in@}} in the Texinfo file. In these cases, however, the formatters may insert a line break between the number and the dimension, so use @code{@@w} (@pxref{w}). Also, if you write a period after an abbreviation within a sentence, you should write @samp{@@:} after the period to prevent @TeX{} from inserting extra whitespace, as shown here. @xref{Inserting Space}. @node Inserting Accents, Dots Bullets, Inserting Space, Insertions @section Inserting Accents @cindex Inserting accents @cindex Accents, inserting @cindex Floating accents, inserting Here is a table with the commands Texinfo provides for inserting floating accents. The commands with non-alphabetic names do not take braces around their argument (which is taken to be the next character). (Exception: @code{@@,} @emph{does} take braces around its argument.) This is so as to make the source as convenient to type and read as possible, since accented characters are very common in some languages. @findex " @cindex Umlaut accent @findex ' @cindex Acute accent @findex = @cindex Macron accent @findex ^ @cindex Circumflex accent @findex ` @cindex Grave accent @findex ~ @cindex Tilde accent @findex , @cindex Cedilla accent @findex dotaccent @cindex Dot accent @findex H @cindex Hungariam umlaut accent @findex ringaccent @cindex Ring accent @findex tieaccent @cindex Tie-after accent @findex u @cindex Breve accent @findex ubaraccent @cindex Underbar accent @findex udotaccent @cindex Underdot accent @findex v @cindex Check accent @multitable {@@questiondown@{@}} {Output} {macron/overbar accent} @item Command @tab Output @tab What @item @t{@@"o} @tab @"o @tab umlaut accent @item @t{@@'o} @tab @'o @tab acute accent @item @t{@@,@{c@}} @tab @,{c} @tab cedilla accent @item @t{@@=o} @tab @=o @tab macron/overbar accent @item @t{@@^o} @tab @^o @tab circumflex accent @item @t{@@`o} @tab @`o @tab grave accent @item @t{@@~o} @tab @~o @tab tilde accent @item @t{@@dotaccent@{o@}} @tab @dotaccent{o} @tab overdot accent @item @t{@@H@{o@}} @tab @H{o} @tab long Hungarian umlaut @item @t{@@ringaccent@{o@}} @tab @ringaccent{o} @tab ring accent @item @t{@@tieaccent@{oo@}} @tab @tieaccent{oo} @tab tie-after accent @item @t{@@u@{o@}} @tab @u{o} @tab breve accent @item @t{@@ubaraccent@{o@}} @tab @ubaraccent{o} @tab underbar accent @item @t{@@udotaccent@{o@}} @tab @udotaccent{o} @tab underdot accent @item @t{@@v@{o@}} @tab @v{o} @tab hacek or check accent @end multitable This table lists the Texinfo commands for inserting other characters commonly used in languages other than English. @findex questiondown @cindex @questiondown{} @findex exclamdown @cindex @exclamdown{} @findex aa @cindex @aa{} @findex AA @cindex @AA{} @findex ae @cindex @ae{} @findex AE @cindex @AE{} @findex dotless @cindex @dotless{i} @cindex @dotless{j} @cindex Dotless i, j @findex l @cindex @l{} @findex L @cindex @L{} @findex o @cindex @o{} @findex O @cindex @O{} @findex oe @cindex @oe{} @findex OE @cindex @OE{} @findex ss @cindex @ss{} @cindex Es-zet @cindex Sharp S @cindex German S @multitable {@@questiondown@{@}} {oe,OE} {es-zet or sharp S} @item @t{@@exclamdown@{@}} @tab @exclamdown{} @tab upside-down ! @item @t{@@questiondown@{@}} @tab @questiondown{} @tab upside-down ? @item @t{@@aa@{@},@@AA@{@}} @tab @aa{},@AA{} @tab A,a with circle @item @t{@@ae@{@},@@AE@{@}} @tab @ae{},@AE{} @tab ae,AE ligatures @item @t{@@dotless@{i@}} @tab @dotless{i} @tab dotless i @item @t{@@dotless@{j@}} @tab @dotless{j} @tab dotless j @item @t{@@l@{@},@@L@{@}} @tab @l{},@L{} @tab suppressed-L,l @item @t{@@o@{@},@@O@{@}} @tab @o{},@O{} @tab O,o with slash @item @t{@@oe@{@},@@OE@{@}} @tab @oe{},@OE{} @tab OE,oe ligatures @item @t{@@ss@{@}} @tab @ss{} @tab es-zet or sharp S @end multitable @node Dots Bullets, TeX and copyright, Inserting Accents, Insertions @section Inserting Ellipsis, Dots, and Bullets @cindex Dots, inserting @cindex Bullets, inserting @cindex Ellipsis, inserting @cindex Inserting ellipsis @cindex Inserting dots @cindex Special typesetting commands @cindex Typesetting commands for dots, etc. An @dfn{ellipsis} (a line of dots) is not typeset as a string of periods, so a special command is used for ellipsis in Texinfo. The @code{@@bullet} command is special, too. Each of these commands is followed by a pair of braces, @samp{@{@}}, without any whitespace between the name of the command and the braces. (You need to use braces with these commands because you can use them next to other text; without the braces, the formatters would be confused. @xref{Command Syntax, , @@-Command Syntax}, for further information.)@refill @menu * dots:: How to insert dots @dots{} * bullet:: How to insert a bullet. @end menu @node dots, bullet, Dots Bullets, Dots Bullets @subsection @code{@@dots}@{@} (@dots{}) @findex dots @cindex Inserting dots @cindex Dots, inserting Use the @code{@@dots@{@}} command to generate an ellipsis, which is three dots in a row, appropriately spaced, like this: `@dots{}'. Do not simply write three periods in the input file; that would work for the Info file output, but would produce the wrong amount of space between the periods in the printed manual. Similarly, the @code{@@enddots@{@}} command generates an end-of-sentence ellipsis (four dots) @enddots{} @iftex Here is an ellipsis: @dots{} Here are three periods in a row: ... In printed output, the three periods in a row are closer together than the dots in the ellipsis. @end iftex @node bullet, , dots, Dots Bullets @subsection @code{@@bullet}@{@} (@bullet{}) @findex bullet Use the @code{@@bullet@{@}} command to generate a large round dot, or the closest possible thing to one. In Info, an asterisk is used.@refill Here is a bullet: @bullet{} When you use @code{@@bullet} in @code{@@itemize}, you do not need to type the braces, because @code{@@itemize} supplies them. (@xref{itemize, , @code{@@itemize}}.)@refill @node TeX and copyright, pounds, Dots Bullets, Insertions @section Inserting @TeX{} and the Copyright Symbol The logo `@TeX{}' is typeset in a special fashion and it needs an @@-command. The copyright symbol, `@copyright{}', is also special. Each of these commands is followed by a pair of braces, @samp{@{@}}, without any whitespace between the name of the command and the braces.@refill @menu * tex:: How to insert the @TeX{} logo. * copyright symbol:: How to use @code{@@copyright}@{@}. @end menu @node tex, copyright symbol, TeX and copyright, TeX and copyright @subsection @code{@@TeX}@{@} (@TeX{}) @findex tex (command) Use the @code{@@TeX@{@}} command to generate `@TeX{}'. In a printed manual, this is a special logo that is different from three ordinary letters. In Info, it just looks like @samp{TeX}. The @code{@@TeX@{@}} command is unique among Texinfo commands in that the @kbd{T} and the @kbd{X} are in upper case.@refill @node copyright symbol, , tex, TeX and copyright @subsection @code{@@copyright}@{@} (@copyright{}) @findex copyright Use the @code{@@copyright@{@}} command to generate `@copyright{}'. In a printed manual, this is a @samp{c} inside a circle, and in Info, this is @samp{(C)}.@refill @node pounds, minus, TeX and copyright, Insertions @section @code{@@pounds}@{@} (@pounds{}): Pounds Sterling @findex pounds Use the @code{@@pounds@{@}} command to generate `@pounds{}'. In a printed manual, this is the symbol for the currency pounds sterling. In Info, it is a @samp{#}. Other currency symbols are unfortunately not available. @node minus, math, pounds, Insertions @section @code{@@minus}@{@} (@minus{}): Inserting a Minus Sign @findex minus Use the @code{@@minus@{@}} command to generate a minus sign. In a fixed-width font, this is a single hyphen, but in a proportional font, the symbol is the customary length for a minus sign---a little longer than a hyphen, shorter than an em-dash: @display @samp{@minus{}} is a minus sign generated with @samp{@@minus@{@}}, `-' is a hyphen generated with the character @samp{-}, `---' is an em-dash for text. @end display @noindent In the fixed-width font used by Info, @code{@@minus@{@}} is the same as a hyphen. You should not use @code{@@minus@{@}} inside @code{@@code} or @code{@@example} because the width distinction is not made in the fixed-width font they use. When you use @code{@@minus} to specify the mark beginning each entry in an itemized list, you do not need to type the braces (@pxref{itemize, , @code{@@itemize}}.) @node math, Glyphs, minus, Insertions @section @code{@@math}: Inserting Mathematical Expressions @findex math @cindex Mathematical expressions You can write a short mathematical expression with the @code{@@math} command. Write the mathematical expression between braces, like this: @example @@math@{(a + b)(a + b) = a^2 + 2ab + b^2@} @end example @iftex @need 1000 @noindent This produces the following in @TeX{}: @display @math{(a + b)(a + b) = a^2 + 2ab + b^2} @end display @noindent and the following in Info: @end iftex @ifinfo @noindent This produces the following in Info: @end ifinfo @example (a + b)(a + b) = a^2 + 2ab + b^2 @end example Thus, the @code{@@math} command has no effect on the Info output. For complex mathematical expressions, you can also use @TeX{} directly (@pxref{Raw Formatter Commands}). When you use @TeX{} directly, remember to write the mathematical expression between one or two @samp{$} (dollar-signs) as appropriate. @node Glyphs, Images, math, Insertions @section Glyphs for Examples @cindex Glyphs In Texinfo, code is often illustrated in examples that are delimited by @code{@@example} and @code{@@end example}, or by @code{@@lisp} and @code{@@end lisp}. In such examples, you can indicate the results of evaluation or an expansion using @samp{@result{}} or @samp{@expansion{}}. Likewise, there are commands to insert glyphs to indicate printed output, error messages, equivalence of expressions, and the location of point.@refill The glyph-insertion commands do not need to be used within an example, but most often they are. Every glyph-insertion command is followed by a pair of left- and right-hand braces.@refill @menu * Glyphs Summary:: * result:: How to show the result of expression. * expansion:: How to indicate an expansion. * Print Glyph:: How to indicate printed output. * Error Glyph:: How to indicate an error message. * Equivalence:: How to indicate equivalence. * Point Glyph:: How to indicate the location of point. @end menu @node Glyphs Summary, result, Glyphs, Glyphs @ifinfo @subheading Glyphs Summary Here are the different glyph commands:@refill @end ifinfo @table @asis @item @result{} @code{@@result@{@}} points to the result of an expression.@refill @item @expansion{} @code{@@expansion@{@}} shows the results of a macro expansion.@refill @item @print{} @code{@@print@{@}} indicates printed output.@refill @item @error{} @code{@@error@{@}} indicates that the following text is an error message.@refill @item @equiv{} @code{@@equiv@{@}} indicates the exact equivalence of two forms.@refill @item @point{} @code{@@point@{@}} shows the location of point.@refill @end table @menu * result:: * expansion:: * Print Glyph:: * Error Glyph:: * Equivalence:: * Point Glyph:: @end menu @node result, expansion, Glyphs Summary, Glyphs @subsection @code{@@result@{@}} (@result{}): Indicating Evaluation @cindex Result of an expression @cindex Indicating evaluation @cindex Evaluation glyph @cindex Value of an expression, indicating Use the @code{@@result@{@}} command to indicate the result of evaluating an expression.@refill @iftex The @code{@@result@{@}} command is displayed as @samp{=>} in Info and as @samp{@result{}} in the printed output. @end iftex @ifinfo The @code{@@result@{@}} command is displayed as @samp{@result{}} in Info and as a double stemmed arrow in the printed output.@refill @end ifinfo Thus, the following, @lisp (cdr '(1 2 3)) @result{} (2 3) @end lisp @noindent may be read as ``@code{(cdr '(1 2 3))} evaluates to @code{(2 3)}''. @node expansion, Print Glyph, result, Glyphs @subsection @code{@@expansion@{@}} (@expansion{}): Indicating an Expansion @cindex Expansion, indicating it When an expression is a macro call, it expands into a new expression. You can indicate the result of the expansion with the @code{@@expansion@{@}} command.@refill @iftex The @code{@@expansion@{@}} command is displayed as @samp{==>} in Info and as @samp{@expansion{}} in the printed output. @end iftex @ifinfo The @code{@@expansion@{@}} command is displayed as @samp{@expansion{}} in Info and as a long arrow with a flat base in the printed output.@refill @end ifinfo @need 700 For example, the following @example @group @@lisp (third '(a b c)) @@expansion@{@} (car (cdr (cdr '(a b c)))) @@result@{@} c @@end lisp @end group @end example @noindent produces @lisp @group (third '(a b c)) @expansion{} (car (cdr (cdr '(a b c)))) @result{} c @end group @end lisp @noindent which may be read as: @quotation @code{(third '(a b c))} expands to @code{(car (cdr (cdr '(a b c))))}; the result of evaluating the expression is @code{c}. @end quotation @noindent Often, as in this case, an example looks better if the @code{@@expansion@{@}} and @code{@@result@{@}} commands are indented five spaces.@refill @node Print Glyph, Error Glyph, expansion, Glyphs @subsection @code{@@print@{@}} (@print{}): Indicating Printed Output @cindex Printed output, indicating it Sometimes an expression will print output during its execution. You can indicate the printed output with the @code{@@print@{@}} command.@refill @iftex The @code{@@print@{@}} command is displayed as @samp{-|} in Info and as @samp{@print{}} in the printed output. @end iftex @ifinfo The @code{@@print@{@}} command is displayed as @samp{@print{}} in Info and similarly, as a horizontal dash butting against a vertical bar, in the printed output.@refill @end ifinfo In the following example, the printed text is indicated with @samp{@print{}}, and the value of the expression follows on the last line.@refill @lisp @group (progn (print 'foo) (print 'bar)) @print{} foo @print{} bar @result{} bar @end group @end lisp @noindent In a Texinfo source file, this example is written as follows: @lisp @group @@lisp (progn (print 'foo) (print 'bar)) @@print@{@} foo @@print@{@} bar @@result@{@} bar @@end lisp @end group @end lisp @node Error Glyph, Equivalence, Print Glyph, Glyphs @subsection @code{@@error@{@}} (@error{}): Indicating an Error Message @cindex Error message, indicating it A piece of code may cause an error when you evaluate it. You can designate the error message with the @code{@@error@{@}} command.@refill @iftex The @code{@@error@{@}} command is displayed as @samp{error-->} in Info and as @samp{@error{}} in the printed output. @end iftex @ifinfo The @code{@@error@{@}} command is displayed as @samp{@error{}} in Info and as the word `error' in a box in the printed output.@refill @end ifinfo @need 700 Thus, @example @@lisp (+ 23 'x) @@error@{@} Wrong type argument: integer-or-marker-p, x @@end lisp @end example @noindent produces @lisp (+ 23 'x) @error{} Wrong type argument: integer-or-marker-p, x @end lisp @noindent This indicates that the following error message is printed when you evaluate the expression: @lisp Wrong type argument: integer-or-marker-p, x @end lisp @samp{@error{}} itself is not part of the error message. @node Equivalence, Point Glyph, Error Glyph, Glyphs @subsection @code{@@equiv@{@}} (@equiv{}): Indicating Equivalence @cindex Equivalence, indicating it Sometimes two expressions produce identical results. You can indicate the exact equivalence of two forms with the @code{@@equiv@{@}} command.@refill @iftex The @code{@@equiv@{@}} command is displayed as @samp{==} in Info and as @samp{@equiv{}} in the printed output. @end iftex @ifinfo The @code{@@equiv@{@}} command is displayed as @samp{@equiv{}} in Info and as a three parallel horizontal lines in the printed output.@refill @end ifinfo Thus, @example @@lisp (make-sparse-keymap) @@equiv@{@} (list 'keymap) @@end lisp @end example @noindent produces @lisp (make-sparse-keymap) @equiv{} (list 'keymap) @end lisp @noindent This indicates that evaluating @code{(make-sparse-keymap)} produces identical results to evaluating @code{(list 'keymap)}. @node Point Glyph, , Equivalence, Glyphs @subsection @code{@@point@{@}} (@point{}): Indicating Point in a Buffer @cindex Point, indicating it in a buffer Sometimes you need to show an example of text in an Emacs buffer. In such examples, the convention is to include the entire contents of the buffer in question between two lines of dashes containing the buffer name.@refill You can use the @samp{@@point@{@}} command to show the location of point in the text in the buffer. (The symbol for point, of course, is not part of the text in the buffer; it indicates the place @emph{between} two characters where point is located.)@refill @iftex The @code{@@point@{@}} command is displayed as @samp{-!-} in Info and as @samp{@point{}} in the printed output. @end iftex @ifinfo The @code{@@point@{@}} command is displayed as @samp{@point{}} in Info and as a small five pointed star in the printed output.@refill @end ifinfo The following example shows the contents of buffer @file{foo} before and after evaluating a Lisp command to insert the word @code{changed}.@refill @example @group ---------- Buffer: foo ---------- This is the @point{}contents of foo. ---------- Buffer: foo ---------- @end group @end example @example @group (insert "changed ") @result{} nil ---------- Buffer: foo ---------- This is the changed @point{}contents of foo. ---------- Buffer: foo ---------- @end group @end example In a Texinfo source file, the example is written like this:@refill @example @@example ---------- Buffer: foo ---------- This is the @@point@{@}contents of foo. ---------- Buffer: foo ---------- (insert "changed ") @@result@{@} nil ---------- Buffer: foo ---------- This is the changed @@point@{@}contents of foo. ---------- Buffer: foo ---------- @@end example @end example @c this should be described with figures when we have them @c perhaps in the quotation/example chapter. @node Images, , Glyphs, Insertions @section Inserting Images @cindex Images, inserting @cindex Pictures, inserting @findex image You can insert an image in an external file with the @code{@@image} command: @example @@image@{@var{filename}, @r{[}@var{width}@r{]}, @r{[}@var{height}@r{]}@} @end example @cindex Formats for images @cindex Image formats The @var{filename} argument is mandatory, and must not have an extension, because the different processors support different formats: @TeX{} reads the file @file{@var{filename}.eps} (Encapsulated PostScript format); @code{makeinfo} uses @file{@var{filename}.txt} verbatim for Info output (more or less as if it was an @code{@@example}). HTML output requires @file{@var{filename}.jpg}. @cindex Width of images @cindex Height of images @cindex Aspect ratio of images @cindex Distorting images The optional @var{width} and @var{height} arguments specify the size to scale the image to (they are ignored for Info output). If they are both specified, the image is presented in its natural size (given in the file); if only one is specified, the other is scaled proportionately; and if both are specified, both are respected, thus possibly distorting the original image by changing its aspect ratio. @cindex Dimensions and image sizes The @var{width} and @var{height} may be specified using any valid @TeX{} dimension, namely: @table @asis @item pt @cindex Points (dimension) point (72.27pt = 1in) @item pc @cindex Picas pica (1pc = 12pt) @item bp @cindex Big points big point (72bp = 1in) @item in @cindex Inches inch @item cm @cindex Centimeters centimeter (2.54cm = 1in) @item mm @cindex Millimeters millimeter (10mm = 1cm) @item dd @cindex Did@^ot points did@^ot point (1157dd = 1238pt) @item cc @cindex Ciceros cicero (1cc = 12dd) @item sp @cindex Scaled points scaled point (65536sp = 1pt) @end table @pindex ridt.eps For example, the following will scale a file @file{ridt.eps} to one inch vertically, with the width scaled proportionately: @example @@image@{ridt,,1in@} @end example @pindex epsf.tex For @code{@@image} to work with @TeX{}, the file @file{epsf.tex} must be installed somewhere that @TeX{} can find it. This file is included in the Texinfo distribution and is available from @uref{ftp://ftp.tug.org/tex/epsf.tex}. @node Breaks, Definition Commands, Insertions, Top @chapter Making and Preventing Breaks @cindex Making line and page breaks @cindex Preventing line and page breaks Usually, a Texinfo file is processed both by @TeX{} and by one of the Info formatting commands. Line, paragraph, or page breaks sometimes occur in the `wrong' place in one or other form of output. You must ensure that text looks right both in the printed manual and in the Info file.@refill For example, in a printed manual, page breaks may occur awkwardly in the middle of an example; to prevent this, you can hold text together using a grouping command that keeps the text from being split across two pages. Conversely, you may want to force a page break where none would occur normally. Fortunately, problems like these do not often arise. When they do, use the break, break prevention, or pagination commands.@refill @menu * Break Commands:: Cause and prevent splits. * Line Breaks:: How to force a single line to use two lines. * - and hyphenation:: How to tell TeX about hyphenation points. * w:: How to prevent unwanted line breaks. * sp:: How to insert blank lines. * page:: How to force the start of a new page. * group:: How to prevent unwanted page breaks. * need:: Another way to prevent unwanted page breaks. @end menu @ifinfo @node Break Commands, Line Breaks, Breaks, Breaks @heading The Break Commands @end ifinfo @iftex @sp 1 @end iftex The break commands create or allow line and paragraph breaks:@refill @table @code @item @@* Force a line break. @item @@sp @var{n} Skip @var{n} blank lines.@refill @item @@- Insert a discretionary hyphen. @item @@hyphenation@{@var{hy-phen-a-ted words}@} Define hyphen points in @var{hy-phen-a-ted words}. @end table The line-break-prevention command holds text together all on one line:@refill @table @code @item @@w@{@var{text}@} Prevent @var{text} from being split and hyphenated across two lines.@refill @end table @iftex @sp 1 @end iftex The pagination commands apply only to printed output, since Info files do not have pages.@refill @table @code @item @@page Start a new page in the printed manual.@refill @item @@group Hold text together that must appear on one printed page.@refill @item @@need @var{mils} Start a new printed page if not enough space on this one.@refill @end table @node Line Breaks, - and hyphenation, Break Commands, Breaks @comment node-name, next, previous, up @section @code{@@*}: Generate Line Breaks @findex * @r{(force line break)} @cindex Line breaks @cindex Breaks in a line The @code{@@*} command forces a line break in both the printed manual and in Info.@refill @need 700 For example, @example This line @@* is broken @@*in two places. @end example @noindent produces @example @group This line is broken in two places. @end group @end example @noindent (Note that the space after the first @code{@@*} command is faithfully carried down to the next line.)@refill @need 800 The @code{@@*} command is often used in a file's copyright page:@refill @example @group This is edition 2.0 of the Texinfo documentation,@@* and is for @dots{} @end group @end example @noindent In this case, the @code{@@*} command keeps @TeX{} from stretching the line across the whole page in an ugly manner.@refill @quotation @strong{Please note:} Do not write braces after an @code{@@*} command; they are not needed.@refill Do not write an @code{@@refill} command at the end of a paragraph containing an @code{@@*} command; it will cause the paragraph to be refilled after the line break occurs, negating the effect of the line break.@refill @end quotation @node - and hyphenation, w, Line Breaks, Breaks @section @code{@@-} and @code{@@hyphenation}: Helping @TeX{} hyphenate @findex - @findex hyphenation @cindex Hyphenation, helping @TeX{} do @cindex Fine-tuning, and hyphenation Although @TeX{}'s hyphenation algorithm is generally pretty good, it does miss useful hyphenation points from time to time. (Or, far more rarely, insert an incorrect hyphenation.) So, for documents with an unusual vocabulary or when fine-tuning for a printed edition, you may wish to help @TeX{} out. Texinfo supports two commands for this: @table @code @item @@- Insert a discretionary hyphen, i.e., a place where @TeX{} can (but does not have to) hyphenate. This is especially useful when you notice an overfull hbox is due to @TeX{} missing a hyphenation (@pxref{Overfull hboxes}). @TeX{} will not insert any hyphenation points in a word containing @code{@@-}. @item @@hyphenation@{@var{hy-phen-a-ted words}@} Tell @TeX{} how to hyphenate @var{hy-phen-a-ted words}. As shown, you put a @samp{-} at each hyphenation point. For example: @example @@hyphenation@{man-u-script man-u-scripts@} @end example @noindent @TeX{} only uses the specified hyphenation points when the words match exactly, so give all necessary variants. @end table Info output is not hyphenated, so these commands have no effect there. @node w, sp, - and hyphenation, Breaks @comment node-name, next, previous, up @section @code{@@w}@{@var{text}@}: Prevent Line Breaks @findex w @r{(prevent line break)} @cindex Line breaks, preventing @cindex Hyphenation, preventing @code{@@w@{@var{text}@}} outputs @var{text} and prohibits line breaks within @var{text}.@refill You can use the @code{@@w} command to prevent @TeX{} from automatically hyphenating a long name or phrase that happens to fall near the end of a line.@refill @example You can copy GNU software from @@w@{@@samp@{ftp.gnu.ai.mit.edu@}@}. @end example @noindent produces @quotation You can copy GNU software from @w{@samp{ftp.gnu.ai.mit.edu}}. @end quotation @quotation @strong{Caution:} Do not write an @code{@@refill} command at the end of a paragraph containing an @code{@@w} command; it will cause the paragraph to be refilled and may thereby negate the effect of the @code{@@w} command.@refill @end quotation @node sp, page, w, Breaks @comment node-name, next, previous, up @section @code{@@sp} @var{n}: Insert Blank Lines @findex sp @r{(line spacing)} @cindex Spaces (blank lines) @cindex Blank lines @cindex Line spacing A line beginning with and containing only @code{@@sp @var{n}} generates @var{n} blank lines of space in both the printed manual and the Info file. @code{@@sp} also forces a paragraph break. For example,@refill @example @@sp 2 @end example @noindent generates two blank lines. The @code{@@sp} command is most often used in the title page.@refill @ignore @c node br, page, sp, Breaks @comment node-name, next, previous, up @c section @code{@@br}: Generate Paragraph Breaks @findex br @r{(paragraph breaks)} @cindex Paragraph breaks @cindex Breaks in a paragraph The @code{@@br} command forces a paragraph break. It inserts a blank line. You can use the command within or at the end of a line. If used within a line, the @code{@@br@{@}} command must be followed by left and right braces (as shown here) to mark the end of the command.@refill @need 700 For example, @example @group This line @@br@{@}contains and is ended by paragraph breaks@@br and is followed by another line. @end group @end example @noindent produces @example @group This line contains and is ended by paragraph breaks and is followed by another line. @end group @end example The @code{@@br} command is seldom used. @end ignore @node page, group, sp, Breaks @comment node-name, next, previous, up @section @code{@@page}: Start a New Page @cindex Page breaks @findex page A line containing only @code{@@page} starts a new page in a printed manual. The command has no effect on Info files since they are not paginated. An @code{@@page} command is often used in the @code{@@titlepage} section of a Texinfo file to start the copyright page.@refill @node group, need, page, Breaks @comment node-name, next, previous, up @section @code{@@group}: Prevent Page Breaks @cindex Group (hold text together vertically) @cindex Holding text together vertically @cindex Vertically holding text together @findex group The @code{@@group} command (on a line by itself) is used inside an @code{@@example} or similar construct to begin an unsplittable vertical group, which will appear entirely on one page in the printed output. The group is terminated by a line containing only @code{@@end group}. These two lines produce no output of their own, and in the Info file output they have no effect at all.@refill @c Once said that these environments @c turn off vertical spacing between ``paragraphs''. @c Also, quotation used to work, but doesn't in texinfo-2.72 Although @code{@@group} would make sense conceptually in a wide variety of contexts, its current implementation works reliably only within @code{@@example} and variants, and within @code{@@display}, @code{@@format}, @code{@@flushleft} and @code{@@flushright}. @xref{Quotations and Examples}. (What all these commands have in common is that each line of input produces a line of output.) In other contexts, @code{@@group} can cause anomalous vertical spacing.@refill @need 750 This formatting requirement means that you should write: @example @group @@example @@group @dots{} @@end group @@end example @end group @end example @noindent with the @code{@@group} and @code{@@end group} commands inside the @code{@@example} and @code{@@end example} commands. The @code{@@group} command is most often used to hold an example together on one page. In this Texinfo manual, more than 100 examples contain text that is enclosed between @code{@@group} and @code{@@end group}. If you forget to end a group, you may get strange and unfathomable error messages when you run @TeX{}. This is because @TeX{} keeps trying to put the rest of the Texinfo file onto the one page and does not start to generate error messages until it has processed considerable text. It is a good rule of thumb to look for a missing @code{@@end group} if you get incomprehensible error messages in @TeX{}.@refill @node need, , group, Breaks @comment node-name, next, previous, up @section @code{@@need @var{mils}}: Prevent Page Breaks @cindex Need space at page bottom @findex need A line containing only @code{@@need @var{n}} starts a new page in a printed manual if fewer than @var{n} mils (thousandths of an inch) remain on the current page. Do not use braces around the argument @var{n}. The @code{@@need} command has no effect on Info files since they are not paginated.@refill @need 800 This paragraph is preceded by an @code{@@need} command that tells @TeX{} to start a new page if fewer than 800 mils (eight-tenths inch) remain on the page. It looks like this:@refill @example @group @@need 800 This paragraph is preceded by @dots{} @end group @end example The @code{@@need} command is useful for preventing orphans (single lines at the bottoms of printed pages).@refill @node Definition Commands, Footnotes, Breaks, Top @chapter Definition Commands @cindex Definition commands The @code{@@deffn} command and the other @dfn{definition commands} enable you to describe functions, variables, macros, commands, user options, special forms and other such artifacts in a uniform format.@refill In the Info file, a definition causes the entity category---`Function', `Variable', or whatever---to appear at the beginning of the first line of the definition, followed by the entity's name and arguments. In the printed manual, the command causes @TeX{} to print the entity's name and its arguments on the left margin and print the category next to the right margin. In both output formats, the body of the definition is indented. Also, the name of the entity is entered into the appropriate index: @code{@@deffn} enters the name into the index of functions, @code{@@defvr} enters it into the index of variables, and so on.@refill A manual need not and should not contain more than one definition for a given name. An appendix containing a summary should use @code{@@table} rather than the definition commands.@refill @menu * Def Cmd Template:: How to structure a description using a definition command. * Optional Arguments:: How to handle optional and repeated arguments. * deffnx:: How to group two or more `first' lines. * Def Cmds in Detail:: All the definition commands. * Def Cmd Conventions:: Conventions for writing definitions. * Sample Function Definition:: @end menu @node Def Cmd Template, Optional Arguments, Definition Commands, Definition Commands @section The Template for a Definition @cindex Definition template @cindex Template for a definition The @code{@@deffn} command is used for definitions of entities that resemble functions. To write a definition using the @code{@@deffn} command, write the @code{@@deffn} command at the beginning of a line and follow it on the same line by the category of the entity, the name of the entity itself, and its arguments (if any). Then write the body of the definition on succeeding lines. (You may embed examples in the body.) Finally, end the definition with an @code{@@end deffn} command written on a line of its own. (The other definition commands follow the same format.)@refill The template for a definition looks like this: @example @group @@deffn @var{category} @var{name} @var{arguments}@dots{} @var{body-of-definition} @@end deffn @end group @end example @need 700 @noindent For example, @example @group @@deffn Command forward-word count This command moves point forward @@var@{count@} words (or backward if @@var@{count@} is negative). @dots{} @@end deffn @end group @end example @noindent produces @quotation @deffn Command forward-word count This function moves point forward @var{count} words (or backward if @var{count} is negative). @dots{} @end deffn @end quotation Capitalize the category name like a title. If the name of the category contains spaces, as in the phrase `Interactive Command', write braces around it. For example:@refill @example @group @@deffn @{Interactive Command@} isearch-forward @dots{} @@end deffn @end group @end example @noindent Otherwise, the second word will be mistaken for the name of the entity.@refill Some of the definition commands are more general than others. The @code{@@deffn} command, for example, is the general definition command for functions and the like---for entities that may take arguments. When you use this command, you specify the category to which the entity belongs. The @code{@@deffn} command possesses three predefined, specialized variations, @code{@@defun}, @code{@@defmac}, and @code{@@defspec}, that specify the category for you: ``Function'', ``Macro'', and ``Special Form'' respectively. (In Lisp, a special form is an entity much like a function.) The @code{@@defvr} command also is accompanied by several predefined, specialized variations for describing particular kinds of variables.@refill The template for a specialized definition, such as @code{@@defun}, is similar to the template for a generalized definition, except that you do not need to specify the category:@refill @example @group @@defun @var{name} @var{arguments}@dots{} @var{body-of-definition} @@end defun @end group @end example @noindent Thus, @example @group @@defun buffer-end flag This function returns @@code@{(point-min)@} if @@var@{flag@} is less than 1, @@code@{(point-max)@} otherwise. @dots{} @@end defun @end group @end example @noindent produces @quotation @defun buffer-end flag This function returns @code{(point-min)} if @var{flag} is less than 1, @code{(point-max)} otherwise. @dots{} @end defun @end quotation @noindent @xref{Sample Function Definition, Sample Function Definition, A Sample Function Definition}, for a more detailed example of a function definition, including the use of @code{@@example} inside the definition.@refill The other specialized commands work like @code{@@defun}.@refill @node Optional Arguments, deffnx, Def Cmd Template, Definition Commands @section Optional and Repeated Arguments @cindex Optional and repeated arguments @cindex Repeated and optional arguments @cindex Arguments, repeated and optional @cindex Syntax, optional & repeated arguments @cindex Meta-syntactic chars for arguments Some entities take optional or repeated arguments, which may be specified by a distinctive glyph that uses square brackets and ellipses. For @w{example}, a special form often breaks its argument list into separate arguments in more complicated ways than a straightforward function.@refill @iftex An argument enclosed within square brackets is optional. Thus, the phrase @samp{@code{@r{[}@var{optional-arg}@r{]}}} means that @var{optional-arg} is optional. An argument followed by an ellipsis is optional and may be repeated more than once. @c This is consistent with Emacs Lisp Reference manual Thus, @samp{@var{repeated-args}@dots{}} stands for zero or more arguments. Parentheses are used when several arguments are grouped into additional levels of list structure in Lisp. @end iftex @c The following looks better in Info (no `r', `samp' and `code'): @ifinfo An argument enclosed within square brackets is optional. Thus, [@var{optional-arg}] means that @var{optional-arg} is optional. An argument followed by an ellipsis is optional and may be repeated more than once. @c This is consistent with Emacs Lisp Reference manual Thus, @var{repeated-args}@dots{} stands for zero or more arguments. Parentheses are used when several arguments are grouped into additional levels of list structure in Lisp. @end ifinfo Here is the @code{@@defspec} line of an example of an imaginary special form:@refill @quotation @defspec foobar (@var{var} [@var{from} @var{to} [@var{inc}]]) @var{body}@dots{} @end defspec @tex \vskip \parskip @end tex @end quotation @noindent In this example, the arguments @var{from} and @var{to} are optional, but must both be present or both absent. If they are present, @var{inc} may optionally be specified as well. These arguments are grouped with the argument @var{var} into a list, to distinguish them from @var{body}, which includes all remaining elements of the form.@refill In a Texinfo source file, this @code{@@defspec} line is written like this (except it would not be split over two lines, as it is in this example).@refill @example @group @@defspec foobar (@@var@{var@} [@@var@{from@} @@var@{to@} [@@var@{inc@}]]) @@var@{body@}@@dots@{@} @end group @end example @noindent The function is listed in the Command and Variable Index under @samp{foobar}.@refill @node deffnx, Def Cmds in Detail, Optional Arguments, Definition Commands @section Two or More `First' Lines @cindex Two `First' Lines for @code{@@deffn} @cindex Grouping two definitions together @cindex Definitions grouped together @findex deffnx To create two or more `first' or header lines for a definition, follow the first @code{@@deffn} line by a line beginning with @code{@@deffnx}. The @code{@@deffnx} command works exactly like @code{@@deffn} except that it does not generate extra vertical white space between it and the preceding line.@refill @need 1000 For example, @example @group @@deffn @{Interactive Command@} isearch-forward @@deffnx @{Interactive Command@} isearch-backward These two search commands are similar except @dots{} @@end deffn @end group @end example @noindent produces @deffn {Interactive Command} isearch-forward @deffnx {Interactive Command} isearch-backward These two search commands are similar except @dots{} @end deffn Each of the other definition commands has an `x' form: @code{@@defunx}, @code{@@defvrx}, @code{@@deftypefunx}, etc. The `x' forms work just like @code{@@itemx}; see @ref{itemx, , @code{@@itemx}}. @node Def Cmds in Detail, Def Cmd Conventions, deffnx, Definition Commands @section The Definition Commands Texinfo provides more than a dozen definition commands, all of which are described in this section.@refill The definition commands automatically enter the name of the entity in the appropriate index: for example, @code{@@deffn}, @code{@@defun}, and @code{@@defmac} enter function names in the index of functions; @code{@@defvr} and @code{@@defvar} enter variable names in the index of variables.@refill Although the examples that follow mostly illustrate Lisp, the commands can be used for other programming languages.@refill @menu * Functions Commands:: Commands for functions and similar entities. * Variables Commands:: Commands for variables and similar entities. * Typed Functions:: Commands for functions in typed languages. * Typed Variables:: Commands for variables in typed languages. * Abstract Objects:: Commands for object-oriented programming. * Data Types:: The definition command for data types. @end menu @node Functions Commands, Variables Commands, Def Cmds in Detail, Def Cmds in Detail @subsection Functions and Similar Entities This section describes the commands for describing functions and similar entities:@refill @table @code @findex deffn @item @@deffn @var{category} @var{name} @var{arguments}@dots{} The @code{@@deffn} command is the general definition command for functions, interactive commands, and similar entities that may take arguments. You must choose a term to describe the category of entity being defined; for example, ``Function'' could be used if the entity is a function. The @code{@@deffn} command is written at the beginning of a line and is followed on the same line by the category of entity being described, the name of this particular entity, and its arguments, if any. Terminate the definition with @code{@@end deffn} on a line of its own.@refill @need 750 For example, here is a definition: @example @group @@deffn Command forward-char nchars Move point forward @@var@{nchars@} characters. @@end deffn @end group @end example @noindent This shows a rather terse definition for a ``command'' named @code{forward-char} with one argument, @var{nchars}. @code{@@deffn} prints argument names such as @var{nchars} in italics or upper case, as if @code{@@var} had been used, because we think of these names as metasyntactic variables---they stand for the actual argument values. Within the text of the description, write an argument name explicitly with @code{@@var} to refer to the value of the argument. In the example above, we used @samp{@@var@{nchars@}} in this way. The template for @code{@@deffn} is: @example @group @@deffn @var{category} @var{name} @var{arguments}@dots{} @var{body-of-definition} @@end deffn @end group @end example @findex defun @item @@defun @var{name} @var{arguments}@dots{} The @code{@@defun} command is the definition command for functions. @code{@@defun} is equivalent to @samp{@@deffn Function @dots{}}.@refill @need 800 @noindent For example, @example @group @@defun set symbol new-value Change the value of the symbol @@var@{symbol@} to @@var@{new-value@}. @@end defun @end group @end example @noindent shows a rather terse definition for a function @code{set} whose arguments are @var{symbol} and @var{new-value}. The argument names on the @code{@@defun} line automatically appear in italics or upper case as if they were enclosed in @code{@@var}. Terminate the definition with @code{@@end defun} on a line of its own.@refill The template is: @example @group @@defun @var{function-name} @var{arguments}@dots{} @var{body-of-definition} @@end defun @end group @end example @code{@@defun} creates an entry in the index of functions. @findex defmac @item @@defmac @var{name} @var{arguments}@dots{} The @code{@@defmac} command is the definition command for macros. @code{@@defmac} is equivalent to @samp{@@deffn Macro @dots{}} and works like @code{@@defun}.@refill @findex defspec @item @@defspec @var{name} @var{arguments}@dots{} The @code{@@defspec} command is the definition command for special forms. (In Lisp, a special form is an entity much like a function, @pxref{Special Forms,,, elisp, GNU Emacs Lisp Reference Manual}.) @code{@@defspec} is equivalent to @samp{@@deffn @{Special Form@} @dots{}} and works like @code{@@defun}.@refill @end table @node Variables Commands, Typed Functions, Functions Commands, Def Cmds in Detail @subsection Variables and Similar Entities Here are the commands for defining variables and similar entities:@refill @table @code @findex defvr @item @@defvr @var{category} @var{name} The @code{@@defvr} command is a general definition command for something like a variable---an entity that records a value. You must choose a term to describe the category of entity being defined; for example, ``Variable'' could be used if the entity is a variable. Write the @code{@@defvr} command at the beginning of a line and followed it on the same line by the category of the entity and the name of the entity.@refill Capitalize the category name like a title. If the name of the category contains spaces, as in the name ``User Option'', enclose it in braces. Otherwise, the second word will be mistaken for the name of the entity. For example, @example @group @@defvr @{User Option@} fill-column This buffer-local variable specifies the maximum width of filled lines. @dots{} @@end defvr @end group @end example Terminate the definition with @code{@@end defvr} on a line of its own.@refill The template is: @example @group @@defvr @var{category} @var{name} @var{body-of-definition} @@end defvr @end group @end example @code{@@defvr} creates an entry in the index of variables for @var{name}. @findex defvar @item @@defvar @var{name} The @code{@@defvar} command is the definition command for variables. @code{@@defvar} is equivalent to @samp{@@defvr Variable @dots{}}.@refill @need 750 For example: @example @group @@defvar kill-ring @dots{} @@end defvar @end group @end example The template is: @example @group @@defvar @var{name} @var{body-of-definition} @@end defvar @end group @end example @code{@@defvar} creates an entry in the index of variables for @var{name}.@refill @findex defopt @item @@defopt @var{name} @cindex User options, marking The @code{@@defopt} command is the definition command for @dfn{user options}, i.e., variables intended for users to change according to taste; Emacs has many such (@pxref{Variables,,, emacs, The GNU Emacs Manual}). @code{@@defopt} is equivalent to @samp{@@defvr @{User Option@} @dots{}} and works like @code{@@defvar}.@refill @end table @node Typed Functions, Typed Variables, Variables Commands, Def Cmds in Detail @subsection Functions in Typed Languages The @code{@@deftypefn} command and its variations are for describing functions in languages in which you must declare types of variables and functions, such as C and C++. @table @code @findex deftypefn @item @@deftypefn @var{category} @var{data-type} @var{name} @var{arguments}@dots{} The @code{@@deftypefn} command is the general definition command for functions and similar entities that may take arguments and that are typed. The @code{@@deftypefn} command is written at the beginning of a line and is followed on the same line by the category of entity being described, the type of the returned value, the name of this particular entity, and its arguments, if any.@refill @need 800 @noindent For example, @example @group @@deftypefn @{Library Function@} int foobar (int @@var@{foo@}, float @@var@{bar@}) @dots{} @@end deftypefn @end group @end example @need 1000 @noindent (where the text before the ``@dots{}'', shown above as two lines, would actually be a single line in a real Texinfo file) produces the following in Info: @smallexample @group -- Library Function: int foobar (int FOO, float BAR) @dots{} @end group @end smallexample @iftex In a printed manual, it produces: @quotation @deftypefn {Library Function} int foobar (int @var{foo}, float @var{bar}) @dots{} @end deftypefn @end quotation @end iftex This means that @code{foobar} is a ``library function'' that returns an @code{int}, and its arguments are @var{foo} (an @code{int}) and @var{bar} (a @code{float}).@refill The argument names that you write in @code{@@deftypefn} are not subject to an implicit @code{@@var}---since the actual names of the arguments in @code{@@deftypefn} are typically scattered among data type names and keywords, Texinfo cannot find them without help. Instead, you must write @code{@@var} explicitly around the argument names. In the example above, the argument names are @samp{foo} and @samp{bar}.@refill The template for @code{@@deftypefn} is:@refill @example @group @@deftypefn @var{category} @var{data-type} @var{name} @var{arguments} @dots{} @var{body-of-description} @@end deftypefn @end group @end example @noindent Note that if the @var{category} or @var{data type} is more than one word then it must be enclosed in braces to make it a single argument.@refill If you are describing a procedure in a language that has packages, such as Ada, you might consider using @code{@@deftypefn} in a manner somewhat contrary to the convention described in the preceding paragraphs.@refill @need 800 @noindent For example: @example @group @@deftypefn stacks private push (@@var@{s@}:in out stack; @@var@{n@}:in integer) @dots{} @@end deftypefn @end group @end example @noindent (The @code{@@deftypefn} arguments are shown split into three lines, but would be a single line in a real Texinfo file.) In this instance, the procedure is classified as belonging to the package @code{stacks} rather than classified as a `procedure' and its data type is described as @code{private}. (The name of the procedure is @code{push}, and its arguments are @var{s} and @var{n}.)@refill @code{@@deftypefn} creates an entry in the index of functions for @var{name}.@refill @item @@deftypefun @var{data-type} @var{name} @var{arguments}@dots{} @findex deftypefun The @code{@@deftypefun} command is the specialized definition command for functions in typed languages. The command is equivalent to @samp{@@deftypefn Function @dots{}}.@refill @need 800 @noindent Thus, @smallexample @group @@deftypefun int foobar (int @@var@{foo@}, float @@var@{bar@}) @dots{} @@end deftypefun @end group @end smallexample @noindent produces the following in Info: @example @group -- Function: int foobar (int FOO, float BAR) @dots{} @end group @end example @iftex @need 800 @noindent and the following in a printed manual: @quotation @deftypefun int foobar (int @var{foo}, float @var{bar}) @dots{} @end deftypefun @end quotation @end iftex @need 800 The template is: @example @group @@deftypefun @var{type} @var{name} @var{arguments}@dots{} @var{body-of-description} @@end deftypefun @end group @end example @code{@@deftypefun} creates an entry in the index of functions for @var{name}.@refill @end table @node Typed Variables, Abstract Objects, Typed Functions, Def Cmds in Detail @subsection Variables in Typed Languages Variables in typed languages are handled in a manner similar to functions in typed languages. @xref{Typed Functions}. The general definition command @code{@@deftypevr} corresponds to @code{@@deftypefn} and the specialized definition command @code{@@deftypevar} corresponds to @code{@@deftypefun}.@refill @table @code @findex deftypevr @item @@deftypevr @var{category} @var{data-type} @var{name} The @code{@@deftypevr} command is the general definition command for something like a variable in a typed language---an entity that records a value. You must choose a term to describe the category of the entity being defined; for example, ``Variable'' could be used if the entity is a variable.@refill The @code{@@deftypevr} command is written at the beginning of a line and is followed on the same line by the category of the entity being described, the data type, and the name of this particular entity.@refill @need 800 @noindent For example: @example @group @@deftypevr @{Global Flag@} int enable @dots{} @@end deftypevr @end group @end example @noindent produces the following in Info: @example @group -- Global Flag: int enable @dots{} @end group @end example @iftex @noindent and the following in a printed manual: @quotation @deftypevr {Global Flag} int enable @dots{} @end deftypevr @end quotation @end iftex @need 800 The template is: @example @@deftypevr @var{category} @var{data-type} @var{name} @var{body-of-description} @@end deftypevr @end example @code{@@deftypevr} creates an entry in the index of variables for @var{name}.@refill @findex deftypevar @item @@deftypevar @var{data-type} @var{name} The @code{@@deftypevar} command is the specialized definition command for variables in typed languages. @code{@@deftypevar} is equivalent to @samp{@@deftypevr Variable @dots{}}.@refill @need 800 @noindent For example: @example @group @@deftypevar int fubar @dots{} @@end deftypevar @end group @end example @noindent produces the following in Info: @example @group -- Variable: int fubar @dots{} @end group @end example @iftex @need 800 @noindent and the following in a printed manual: @quotation @deftypevar int fubar @dots{} @end deftypevar @end quotation @end iftex @need 800 @noindent The template is: @example @group @@deftypevar @var{data-type} @var{name} @var{body-of-description} @@end deftypevar @end group @end example @code{@@deftypevar} creates an entry in the index of variables for @var{name}.@refill @end table @node Abstract Objects, Data Types, Typed Variables, Def Cmds in Detail @subsection Object-Oriented Programming Here are the commands for formatting descriptions about abstract objects, such as are used in object-oriented programming. A class is a defined type of abstract object. An instance of a class is a particular object that has the type of the class. An instance variable is a variable that belongs to the class but for which each instance has its own value.@refill In a definition, if the name of a class is truly a name defined in the programming system for a class, then you should write an @code{@@code} around it. Otherwise, it is printed in the usual text font.@refill @table @code @findex defcv @item @@defcv @var{category} @var{class} @var{name} The @code{@@defcv} command is the general definition command for variables associated with classes in object-oriented programming. The @code{@@defcv} command is followed by three arguments: the category of thing being defined, the class to which it belongs, and its name. Thus,@refill @example @group @@defcv @{Class Option@} Window border-pattern @dots{} @@end defcv @end group @end example @noindent illustrates how you would write the first line of a definition of the @code{border-pattern} class option of the class @code{Window}.@refill The template is @example @group @@defcv @var{category} @var{class} @var{name} @dots{} @@end defcv @end group @end example @code{@@defcv} creates an entry in the index of variables. @findex defivar @item @@defivar @var{class} @var{name} The @code{@@defivar} command is the definition command for instance variables in object-oriented programming. @code{@@defivar} is equivalent to @samp{@@defcv @{Instance Variable@} @dots{}}@refill The template is: @example @group @@defivar @var{class} @var{instance-variable-name} @var{body-of-definition} @@end defivar @end group @end example @code{@@defivar} creates an entry in the index of variables. @findex defop @item @@defop @var{category} @var{class} @var{name} @var{arguments}@dots{} The @code{@@defop} command is the general definition command for entities that may resemble methods in object-oriented programming. These entities take arguments, as functions do, but are associated with particular classes of objects.@refill For example, some systems have constructs called @dfn{wrappers} that are associated with classes as methods are, but that act more like macros than like functions. You could use @code{@@defop Wrapper} to describe one of these.@refill Sometimes it is useful to distinguish methods and @dfn{operations}. You can think of an operation as the specification for a method. Thus, a window system might specify that all window classes have a method named @code{expose}; we would say that this window system defines an @code{expose} operation on windows in general. Typically, the operation has a name and also specifies the pattern of arguments; all methods that implement the operation must accept the same arguments, since applications that use the operation do so without knowing which method will implement it.@refill Often it makes more sense to document operations than methods. For example, window application developers need to know about the @code{expose} operation, but need not be concerned with whether a given class of windows has its own method to implement this operation. To describe this operation, you would write:@refill @example @@defop Operation windows expose @end example The @code{@@defop} command is written at the beginning of a line and is followed on the same line by the overall name of the category of operation, the name of the class of the operation, the name of the operation, and its arguments, if any.@refill @need 800 @noindent The template is: @example @group @@defop @var{category} @var{class} @var{name} @var{arguments}@dots{} @var{body-of-definition} @@end defop @end group @end example @code{@@defop} creates an entry, such as `@code{expose} on @code{windows}', in the index of functions.@refill @item @@defmethod @var{class} @var{name} @var{arguments}@dots{} @findex defmethod The @code{@@defmethod} command is the definition command for methods in object-oriented programming. A method is a kind of function that implements an operation for a particular class of objects and its subclasses. In the Lisp Machine, methods actually were functions, but they were usually defined with @code{defmethod}. @code{@@defmethod} is equivalent to @samp{@@defop Method @dots{}}. The command is written at the beginning of a line and is followed by the name of the class of the method, the name of the method, and its arguments, if any.@refill @need 800 @noindent For example, @example @group @@defmethod @code{bar-class} bar-method argument @dots{} @@end defmethod @end group @end example @noindent illustrates the definition for a method called @code{bar-method} of the class @code{bar-class}. The method takes an argument.@refill The template is: @example @group @@defmethod @var{class} @var{method-name} @var{arguments}@dots{} @var{body-of-definition} @@end defmethod @end group @end example @code{@@defmethod} creates an entry, such as `@code{bar-method} on @code{bar-class}', in the index of functions.@refill @item @@deftypemethod @var{class} @var{data-type} @var{name} @var{arguments}@dots{} @findex defmethod The @code{@@deftypemethod} command is the definition command for methods in object-oriented typed languages, such as C++ and Java. It is similar to the @code{@@defmethod} command with the addition of the @var{data-type} parameter to specify the return type of the method. @end table @node Data Types, , Abstract Objects, Def Cmds in Detail @subsection Data Types Here is the command for data types:@refill @table @code @findex deftp @item @@deftp @var{category} @var{name} @var{attributes}@dots{} The @code{@@deftp} command is the generic definition command for data types. The command is written at the beginning of a line and is followed on the same line by the category, by the name of the type (which is a word like @code{int} or @code{float}), and then by names of attributes of objects of that type. Thus, you could use this command for describing @code{int} or @code{float}, in which case you could use @code{data type} as the category. (A data type is a category of certain objects for purposes of deciding which operations can be performed on them.)@refill In Lisp, for example, @dfn{pair} names a particular data type, and an object of that type has two slots called the @sc{car} and the @sc{cdr}. Here is how you would write the first line of a definition of @code{pair}.@refill @example @group @@deftp @{Data type@} pair car cdr @dots{} @@end deftp @end group @end example @need 950 The template is: @example @group @@deftp @var{category} @var{name-of-type} @var{attributes}@dots{} @var{body-of-definition} @@end deftp @end group @end example @code{@@deftp} creates an entry in the index of data types. @end table @node Def Cmd Conventions, Sample Function Definition, Def Cmds in Detail, Definition Commands @section Conventions for Writing Definitions @cindex Definition conventions @cindex Conventions for writing definitions When you write a definition using @code{@@deffn}, @code{@@defun}, or one of the other definition commands, please take care to use arguments that indicate the meaning, as with the @var{count} argument to the @code{forward-word} function. Also, if the name of an argument contains the name of a type, such as @var{integer}, take care that the argument actually is of that type.@refill @node Sample Function Definition, , Def Cmd Conventions, Definition Commands @section A Sample Function Definition @cindex Function definitions @cindex Command definitions @cindex Macro definitions @cindex Sample function definition A function definition uses the @code{@@defun} and @code{@@end defun} commands. The name of the function follows immediately after the @code{@@defun} command and it is followed, on the same line, by the parameter list.@refill Here is a definition from @ref{Calling Functions,,, elisp, The GNU Emacs Lisp Reference Manual}. @quotation @defun apply function &rest arguments @code{apply} calls @var{function} with @var{arguments}, just like @code{funcall} but with one difference: the last of @var{arguments} is a list of arguments to give to @var{function}, rather than a single argument. We also say that this list is @dfn{appended} to the other arguments. @code{apply} returns the result of calling @var{function}. As with @code{funcall}, @var{function} must either be a Lisp function or a primitive function; special forms and macros do not make sense in @code{apply}. @example (setq f 'list) @result{} list (apply f 'x 'y 'z) @error{} Wrong type argument: listp, z (apply '+ 1 2 '(3 4)) @result{} 10 (apply '+ '(1 2 3 4)) @result{} 10 (apply 'append '((a b c) nil (x y z) nil)) @result{} (a b c x y z) @end example An interesting example of using @code{apply} is found in the description of @code{mapcar}.@refill @end defun @end quotation @need 1200 In the Texinfo source file, this example looks like this: @example @group @@defun apply function &rest arguments @@code@{apply@} calls @@var@{function@} with @@var@{arguments@}, just like @@code@{funcall@} but with one difference: the last of @@var@{arguments@} is a list of arguments to give to @@var@{function@}, rather than a single argument. We also say that this list is @@dfn@{appended@} to the other arguments. @end group @group @@code@{apply@} returns the result of calling @@var@{function@}. As with @@code@{funcall@}, @@var@{function@} must either be a Lisp function or a primitive function; special forms and macros do not make sense in @@code@{apply@}. @end group @group @@example (setq f 'list) @@result@{@} list (apply f 'x 'y 'z) @@error@{@} Wrong type argument: listp, z (apply '+ 1 2 '(3 4)) @@result@{@} 10 (apply '+ '(1 2 3 4)) @@result@{@} 10 (apply 'append '((a b c) nil (x y z) nil)) @@result@{@} (a b c x y z) @@end example @end group @group An interesting example of using @@code@{apply@} is found in the description of @@code@{mapcar@}.@@refill @@end defun @end group @end example @noindent In this manual, this function is listed in the Command and Variable Index under @code{apply}.@refill Ordinary variables and user options are described using a format like that for functions except that variables do not take arguments. @node Footnotes, Conditionals, Definition Commands, Top @chapter Footnotes @cindex Footnotes @findex footnote A @dfn{footnote} is for a reference that documents or elucidates the primary text.@footnote{A footnote should complement or expand upon the primary text, but a reader should not need to read a footnote to understand the primary text. For a thorough discussion of footnotes, see @cite{The Chicago Manual of Style}, which is published by the University of Chicago Press.}@refill @menu * Footnote Commands:: How to write a footnote in Texinfo. * Footnote Styles:: Controlling how footnotes appear in Info. @end menu @node Footnote Commands, Footnote Styles, Footnotes, Footnotes @section Footnote Commands In Texinfo, footnotes are created with the @code{@@footnote} command. This command is followed immediately by a left brace, then by the text of the footnote, and then by a terminating right brace. Footnotes may be of any length (they will be broken across pages if necessary), but are usually short. The template is: @example ordinary text@@footnote@{@var{text of footnote}@} @end example As shown here, the @code{@@footnote} command should come right after the text being footnoted, with no intervening space; otherwise, the formatters the footnote mark might end up starting up a line. For example, this clause is followed by a sample footnote@footnote{Here is the sample footnote.}; in the Texinfo source, it looks like this:@refill @example @dots{}a sample footnote@@footnote@{Here is the sample footnote.@}; in the Texinfo source@dots{} @end example @strong{Warning:} Don't use footnotes in the argument of the @code{@@item} command for a @code{@@table} table. This doesn't work, and because of limitations of @TeX{}, there is no way to fix it. You must put the footnote into the body text of the table. In a printed manual or book, the reference mark for a footnote is a small, superscripted number; the text of the footnote appears at the bottom of the page, below a horizontal line.@refill In Info, the reference mark for a footnote is a pair of parentheses with the footnote number between them, like this: @samp{(1)}.@refill @node Footnote Styles, , Footnote Commands, Footnotes @section Footnote Styles Info has two footnote styles, which determine where the text of the footnote is located:@refill @itemize @bullet @cindex @samp{@r{End}} node footnote style @item In the `End' node style, all the footnotes for a single node are placed at the end of that node. The footnotes are separated from the rest of the node by a line of dashes with the word @samp{Footnotes} within it. Each footnote begins with an @samp{(@var{n})} reference mark.@refill @need 700 @noindent Here is an example of a single footnote in the end of node style:@refill @example @group --------- Footnotes --------- (1) Here is a sample footnote. @end group @end example @cindex @samp{@r{Separate}} footnote style @item In the `Separate' node style, all the footnotes for a single node are placed in an automatically constructed node of their own. In this style, a ``footnote reference'' follows each @samp{(@var{n})} reference mark in the body of the node. The footnote reference is actually a cross reference which you use to reach the footnote node.@refill The name of the node containing the footnotes is constructed by appending @w{@samp{-Footnotes}} to the name of the node that contains the footnotes. (Consequently, the footnotes' node for the @file{Footnotes} node is @w{@file{Footnotes-Footnotes}}!) The footnotes' node has an `Up' node pointer that leads back to its parent node.@refill @noindent Here is how the first footnote in this manual looks after being formatted for Info in the separate node style:@refill @smallexample @group File: texinfo.info Node: Overview-Footnotes, Up: Overview (1) Note that the first syllable of "Texinfo" is pronounced like "speck", not "hex". @dots{} @end group @end smallexample @end itemize A Texinfo file may be formatted into an Info file with either footnote style.@refill @findex footnotestyle Use the @code{@@footnotestyle} command to specify an Info file's footnote style. Write this command at the beginning of a line followed by an argument, either @samp{end} for the end node style or @samp{separate} for the separate node style. @need 700 For example, @example @@footnotestyle end @end example @noindent or @example @@footnotestyle separate @end example Write an @code{@@footnotestyle} command before or shortly after the end-of-header line at the beginning of a Texinfo file. (If you include the @code{@@footnotestyle} command between the start-of-header and end-of-header lines, the region formatting commands will format footnotes as specified.)@refill If you do not specify a footnote style, the formatting commands use their default style. Currently, @code{texinfo-format-buffer} and @code{texinfo-format-region} use the `separate' style and @code{makeinfo} uses the `end' style.@refill @c !!! note: makeinfo's --footnote-style option overrides footnotestyle @ignore If you use @code{makeinfo} to create the Info file, the @samp{--footnote-style} option determines which style is used, @samp{end} for the end of node style or @samp{separate} for the separate node style. Thus, to format the Texinfo manual in the separate node style, you would use the following shell command:@refill @example makeinfo --footnote-style=separate texinfo.texi @end example @noindent To format the Texinfo manual in the end of node style, you would type:@refill @example makeinfo --footnote-style=end texinfo.texi @end example @end ignore @ignore If you use @code{texinfo-format-buffer} or @code{texinfo-format-region} to create the Info file, the value of the @code{texinfo-footnote-style} variable controls the footnote style. It can be either @samp{"separate"} for the separate node style or @samp{"end"} for the end of node style. (You can change the value of this variable with the @kbd{M-x edit-options} command (@pxref{Edit Options, , Editing Variable Values, emacs, The GNU Emacs Manual}), or with the @kbd{M-x set-variable} command (@pxref{Examining, , Examining and Setting Variables, emacs, The GNU Emacs Manual}).@refill The @code{texinfo-footnote-style} variable also controls the style if you use the @kbd{M-x makeinfo-region} or @kbd{M-x makeinfo-buffer} command in Emacs.@refill @end ignore This chapter contains two footnotes.@refill @node Conditionals, Macros, Footnotes, Top @comment node-name, next, previous, up @chapter Conditionally Visible Text @cindex Conditionally visible text @cindex Text, conditionally visible @cindex Visibility of conditional text @cindex If text conditionally visible Sometimes it is good to use different text for a printed manual and its corresponding Info file. In this case, you can use the @dfn{conditional commands} to specify which text is for the printed manual and which is for the Info file.@refill @menu * Conditional Commands:: Specifying text for HTML, Info, or @TeX{}. * Conditional Not Commands:: Specifying text for not HTML, Info, or @TeX{}. * Raw Formatter Commands:: Using raw @TeX{} or HTML commands. * set clear value:: Designating which text to format (for all output formats); and how to set a flag to a string that you can insert. @end menu @node Conditional Commands, Conditional Not Commands, Conditionals, Conditionals @ifinfo @heading Conditional Commands @end ifinfo @findex ifinfo @code{@@ifinfo} begins segments of text that should be ignored by @TeX{} when it typesets the printed manual. The segment of text appears only in the Info file. The @code{@@ifinfo} command should appear on a line by itself; end the Info-only text with a line containing @code{@@end ifinfo} by itself. At the beginning of a Texinfo file, the Info permissions are contained within a region marked by @code{@@ifinfo} and @code{@@end ifinfo}. (@xref{Info Summary and Permissions}.)@refill @findex iftex @findex ifhtml The @code{@@iftex} and @code{@@end iftex} commands are similar to the @code{@@ifinfo} and @code{@@end ifinfo} commands, except that they specify text that will appear in the printed manual but not in the Info file. Likewise for @code{@@ifhtml} and @code{@@end ifhtml}, which specify text to appear only in HTML output.@refill For example, @example @@iftex This text will appear only in the printed manual. @@end iftex @@ifinfo However, this text will appear only in Info. @@end ifinfo @end example @noindent The preceding example produces the following line: @iftex This text will appear only in the printed manual. @end iftex @ifinfo However, this text will appear only in Info. @end ifinfo @noindent Note how you only see one of the two lines, depending on whether you are reading the Info version or the printed version of this manual.@refill The @code{@@titlepage} command is a special variant of @code{@@iftex} that is used for making the title and copyright pages of the printed manual. (@xref{titlepage, , @code{@@titlepage}}.) @refill @node Conditional Not Commands, Raw Formatter Commands, Conditional Commands, Conditionals @section Conditional Not Commands @findex ifnothtml @findex ifnotinfo @findex ifnottex You can specify text to be included in any output format @emph{other} than some given one with the @code{@@ifnot@dots{}} commands: @example @@ifnothtml @dots{} @@end ifnothtml @@ifnotinfo @dots{} @@end ifnotinfo @@ifnottex @dots{} @@end ifnottex @end example @noindent (The @code{@@ifnot@dots{}} command and the @code{@@end} command must actually appear on lines by themselves.) If the output file is not being made for the given format, the region is included. Otherwise, it is ignored. The regions delimited by these commands are ordinary Texinfo source as with @code{@@iftex}, not raw formatter source as with @code{@@tex}. @node Raw Formatter Commands, set clear value, Conditional Not Commands, Conditionals @section Raw Formatter Commands @cindex @TeX{} commands, using ordinary @cindex HTML commands, using ordinary @cindex Raw formatter commands @cindex Ordinary @TeX{} commands, using @cindex Ordinary HTML commands, using @cindex Commands using raw @TeX{} @cindex Commands using raw HTML @cindex plain @TeX{} Inside a region delineated by @code{@@iftex} and @code{@@end iftex}, you can embed some raw @TeX{} commands. Info will ignore these commands since they are only in that part of the file which is seen by @TeX{}. You can write the @TeX{} commands as you would write them in a normal @TeX{} file, except that you must replace the @samp{\} used by @TeX{} with an @samp{@@}. For example, in the @code{@@titlepage} section of a Texinfo file, you can use the @TeX{} command @code{@@vskip} to format the copyright page. (The @code{@@titlepage} command causes Info to ignore the region automatically, as it does with the @code{@@iftex} command.) However, many features of plain @TeX{} will not work, as they are overridden by Texinfo features. @findex tex You can enter plain @TeX{} completely, and use @samp{\} in the @TeX{} commands, by delineating a region with the @code{@@tex} and @code{@@end tex} commands. (The @code{@@tex} command also causes Info to ignore the region, like the @code{@@iftex} command.) The sole exception is that @code{@@} chracter still introduces a command, so that @code{@@end tex} can be recognized properly. @cindex Mathematical expressions For example, here is a mathematical expression written in plain @TeX{}: @example @@tex $$ \chi^2 = \sum_@{i=1@}^N \left (y_i - (a + b x_i) \over \sigma_i\right)^2 $$ @@end tex @end example @noindent The output of this example will appear only in a printed manual. If you are reading this in Info, you will not see the equation that appears in the printed manual. @iftex In a printed manual, the above expression looks like this: @end iftex @tex $$ \chi^2 = \sum_{i=1}^N \left(y_i - (a + b x_i) \over \sigma_i\right)^2 $$ @end tex @findex ifhtml @findex html Analogously, you can use @code{@@ifhtml @dots{} @@end ifhtml} to delimit a region to be included in HTML output only, and @code{@@html @dots{} @@end ifhtml} for a region of raw HTML (again, except that @code{@@} is still the escape character, so the @code{@@end} command can be recognized.) @node set clear value, , Raw Formatter Commands, Conditionals @comment node-name, next, previous, up @section @code{@@set}, @code{@@clear}, and @code{@@value} You can direct the Texinfo formatting commands to format or ignore parts of a Texinfo file with the @code{@@set}, @code{@@clear}, @code{@@ifset}, and @code{@@ifclear} commands.@refill In addition, you can use the @code{@@set @var{flag}} command to set the value of @var{flag} to a string of characters; and use @code{@@value@{@var{flag}@}} to insert that string. You can use @code{@@set}, for example, to set a date and use @code{@@value} to insert the date in several places in the Texinfo file.@refill @menu * ifset ifclear:: Format a region if a flag is set. * value:: Replace a flag with a string. * value Example:: An easy way to update edition information. @end menu @node ifset ifclear, value, set clear value, set clear value @subsection @code{@@ifset} and @code{@@ifclear} @findex ifset When a @var{flag} is set, the Texinfo formatting commands format text between subsequent pairs of @code{@@ifset @var{flag}} and @code{@@end ifset} commands. When the @var{flag} is cleared, the Texinfo formatting commands do @emph{not} format the text. Use the @code{@@set @var{flag}} command to turn on, or @dfn{set}, a @var{flag}; a @dfn{flag} can be any single word. The format for the command looks like this:@refill @findex set @example @@set @var{flag} @end example Write the conditionally formatted text between @code{@@ifset @var{flag}} and @code{@@end ifset} commands, like this:@refill @example @group @@ifset @var{flag} @var{conditional-text} @@end ifset @end group @end example For example, you can create one document that has two variants, such as a manual for a `large' and `small' model:@refill @example You can use this machine to dig up shrubs without hurting them. @@set large @@ifset large It can also dig up fully grown trees. @@end ifset Remember to replant promptly @dots{} @end example @noindent In the example, the formatting commands will format the text between @code{@@ifset large} and @code{@@end ifset} because the @code{large} flag is set.@refill @findex clear Use the @code{@@clear @var{flag}} command to turn off, or @dfn{clear}, a flag. Clearing a flag is the opposite of setting a flag. The command looks like this:@refill @example @@clear @var{flag} @end example @noindent Write the command on a line of its own. When @var{flag} is cleared, the Texinfo formatting commands do @emph{not} format the text between @code{@@ifset @var{flag}} and @code{@@end ifset}; that text is ignored and does not appear in either printed or Info output.@refill For example, if you clear the flag of the preceding example by writing an @code{@@clear large} command after the @code{@@set large} command (but before the conditional text), then the Texinfo formatting commands ignore the text between the @code{@@ifset large} and @code{@@end ifset} commands. In the formatted output, that text does not appear; in both printed and Info output, you see only the lines that say, ``You can use this machine to dig up shrubs without hurting them. Remember to replant promptly @dots{}''. @findex ifclear If a flag is cleared with an @code{@@clear @var{flag}} command, then the formatting commands format text between subsequent pairs of @code{@@ifclear} and @code{@@end ifclear} commands. But if the flag is set with @code{@@set @var{flag}}, then the formatting commands do @emph{not} format text between an @code{@@ifclear} and an @code{@@end ifclear} command; rather, they ignore that text. An @code{@@ifclear} command looks like this:@refill @example @@ifclear @var{flag} @end example @need 700 In brief, the commands are:@refill @table @code @item @@set @var{flag} Tell the Texinfo formatting commands that @var{flag} is set.@refill @item @@clear @var{flag} Tell the Texinfo formatting commands that @var{flag} is cleared.@refill @item @@ifset @var{flag} If @var{flag} is set, tell the Texinfo formatting commands to format the text up to the following @code{@@end ifset} command.@refill If @var{flag} is cleared, tell the Texinfo formatting commands to ignore text up to the following @code{@@end ifset} command.@refill @item @@ifclear @var{flag} If @var{flag} is set, tell the Texinfo formatting commands to ignore the text up to the following @code{@@end ifclear} command.@refill If @var{flag} is cleared, tell the Texinfo formatting commands to format the text up to the following @code{@@end ifclear} command.@refill @end table @node value, value Example, ifset ifclear, set clear value @subsection @code{@@value} @findex value You can use the @code{@@set} command to specify a value for a flag, which is expanded by the @code{@@value} command. The value is a string a characters. Write the @code{@@set} command like this: @example @@set foo This is a string. @end example @noindent This sets the value of @code{foo} to ``This is a string.'' The Texinfo formatters replace an @code{@@value@{@var{flag}@}} command with the string to which @var{flag} is set.@refill Thus, when @code{foo} is set as shown above, the Texinfo formatters convert @example @group @@value@{foo@} @exdent @r{to} This is a string. @end group @end example You can write an @code{@@value} command within a paragraph; but you must write an @code{@@set} command on a line of its own. If you write the @code{@@set} command like this: @example @@set foo @end example @noindent without specifying a string, the value of @code{foo} is an empty string. If you clear a previously set flag with an @code{@@clear @var{flag}} command, a subsequent @code{@@value@{flag@}} command is invalid and the string is replaced with an error message that says @samp{@{No value for "@var{flag}"@}}. For example, if you set @code{foo} as follows:@refill @example @@set how-much very, very, very @end example @noindent then the formatters transform @example @group It is a @@value@{how-much@} wet day. @exdent @r{into} It is a very, very, very wet day. @end group @end example If you write @example @@clear how-much @end example @noindent then the formatters transform @example @group It is a @@value@{how-much@} wet day. @exdent @r{into} It is a @{No value for "how-much"@} wet day. @end group @end example @node value Example, , value, set clear value @subsection @code{@@value} Example You can use the @code{@@value} command to limit the number of places you need to change when you record an update to a manual. Here is how it is done in @cite{The GNU Make Manual}: @need 1000 @noindent Set the flags: @example @group @@set EDITION 0.35 Beta @@set VERSION 3.63 Beta @@set UPDATED 14 August 1992 @@set UPDATE-MONTH August 1992 @end group @end example @need 750 @noindent Write text for the first @code{@@ifinfo} section, for people reading the Texinfo file: @example @group This is Edition @@value@{EDITION@}, last updated @@value@{UPDATED@}, of @@cite@{The GNU Make Manual@}, for @@code@{make@}, Version @@value@{VERSION@}. @end group @end example @need 1000 @noindent Write text for the title page, for people reading the printed manual: @c List only the month and the year since that looks less fussy on a @c printed cover than a date that lists the day as well. @example @group @@title GNU Make @@subtitle A Program for Directing Recompilation @@subtitle Edition @@value@{EDITION@}, @dots{} @@subtitle @@value@{UPDATE-MONTH@} @end group @end example @noindent (On a printed cover, a date listing the month and the year looks less fussy than a date listing the day as well as the month and year.) @need 750 @noindent Write text for the Top node, for people reading the Info file: @example @group This is Edition @@value@{EDITION@} of the @@cite@{GNU Make Manual@}, last updated @@value@{UPDATED@} for @@code@{make@} Version @@value@{VERSION@}. @end group @end example @need 950 After you format the manual, the text in the first @code{@@ifinfo} section looks like this: @example @group This is Edition 0.35 Beta, last updated 14 August 1992, of `The GNU Make Manual', for `make', Version 3.63 Beta. @end group @end example When you update the manual, change only the values of the flags; you do not need to rewrite the three sections. @node Macros, Format/Print Hardcopy, Conditionals, Top @chapter Macros: Defining New Texinfo Commands @cindex Macros @cindex Defining new Texinfo commands @cindex New Texinfo commands, defining @cindex Texinfo commands, defining new @cindex User-defined Texinfo commands A Texinfo @dfn{macro} allows you to define a new Texinfo command as any sequence of text and/or existing commands (including other macros). The macro can have any number of @dfn{parameters}---text you supply each time you use the macro. (This has nothing to do with the @code{@@defmac} command, which is for documenting macros in the subject of the manual; @pxref{Def Cmd Template}.) @menu * Defining Macros:: Both defining and undefining new commands. * Invoking Macros:: Using a macro, once you've defined it. @end menu @node Defining Macros, Invoking Macros, Macros, Macros @section Defining Macros @cindex Defining macros @cindex Macro definitions @findex macro You use the Texinfo @code{@@macro} command to define a macro. For example: @example @@macro @var{macro-name}@{@var{param1}, @var{param2}, @dots{}@} @var{text} @dots{} \@var{param1}\ @dots{} @@end macro @end example The @dfn{parameters} @var{param1}, @var{param2}, @dots{} correspond to arguments supplied when the macro is subsequently used in the document (see the next section). If a macro needs no parameters, you can define it either with an empty list (@samp{@@macro foo @{@}}) or with no braces at all (@samp{@@macro foo}). @cindex Body of a macro @cindex Mutually recursive macros @cindex Recursion, mutual The definition or @dfn{body} of the macro can contain any Texinfo commands, including previously-defined macros. (It is not possible to have mutually recursive Texinfo macros.) In the body, instances of a parameter name surrounded by backslashes, as in @samp{\@var{param1}\} in the example above, are replaced by the corresponding argument from the macro invocation. @findex unmacro @cindex Macros, undefining @cindex Undefining macros You can undefine a macro @var{foo} with @code{@@unmacro @var{foo}}. It is not an error to undefine a macro that is already undefined. For example: @example @@unmacro foo @end example @node Invoking Macros, , Defining Macros, Macros @section Invoking Macros @cindex Invoking macros @cindex Macro invocation After a macro is defined (see the previous section), you can use (@dfn{invoke}) it in your document like this: @example @@@var{macro-name} @{@var{arg1}, @var{arg2}, @dots{}@} @end example @noindent and the result will be just as if you typed the body of @var{macro-name} at that spot. For example: @example @@macro foo @{p, q@} Together: \p\ & \q\. @@end macro @@foo@{a, b@} @end example @noindent produces: @display Together: a & b. @end display @cindex Backslash, and macros Thus, the arguments and parameters are separated by commas and delimited by braces; any whitespace after (but not before) a comma is ignored. To insert a comma, brace, or backslash in an argument, prepend a backslash, as in @example @@@var{macro-name} @{\\\@{\@}\,@} @end example @noindent which will pass the (almost certainly error-producing) argument @samp{\@{@},} to @var{macro-name}. If the macro is defined to take a single argument, and is invoked without any braces, the entire rest of the line after the macro name is supplied as the argument. For example: @example @@macro bar @{p@} Twice: \p\, \p\. @@end macro @@bar aah @end example @noindent produces: @display Twice: aah, aah. @end display @node Format/Print Hardcopy, Create an Info File, Macros, Top @comment node-name, next, previous, up @chapter Format and Print Hardcopy @cindex Format and print hardcopy @cindex Hardcopy, printing it @cindex Making a printed manual @cindex Sorting indices @cindex Indices, sorting @cindex @TeX{} index sorting @pindex texindex There are three major shell commands for making a printed manual from a Texinfo file: one for converting the Texinfo file into a file that will be printed, a second for sorting indices, and a third for printing the formatted document. When you use the shell commands, you can either work directly in the operating system shell or work within a shell inside GNU Emacs.@refill If you are using GNU Emacs, you can use commands provided by Texinfo mode instead of shell commands. In addition to the three commands to format a file, sort the indices, and print the result, Texinfo mode offers key bindings for commands to recenter the output buffer, show the print queue, and delete a job from the print queue.@refill @menu * Use TeX:: Use @TeX{} to format for hardcopy. * Format with tex/texindex:: How to format in a shell. * Format with texi2dvi:: A simpler way to use the shell. * Print with lpr:: How to print. * Within Emacs:: How to format and print from an Emacs shell. * Texinfo Mode Printing:: How to format and print in Texinfo mode. * Compile-Command:: How to print using Emacs's compile command. * Requirements Summary:: @TeX{} formatting requirements summary. * Preparing for TeX:: What you need to do to use @TeX{}. * Overfull hboxes:: What are and what to do with overfull hboxes. * smallbook:: How to print small format books and manuals. * A4 Paper:: How to print on European A4 paper. * Cropmarks and Magnification:: How to print marks to indicate the size of pages and how to print scaled up output. @end menu @node Use TeX, Format with tex/texindex, Format/Print Hardcopy, Format/Print Hardcopy @ifinfo @heading Use @TeX{} @end ifinfo The typesetting program called @TeX{} is used for formatting a Texinfo file. @TeX{} is a very powerful typesetting program and, if used right, does an exceptionally good job. (@xref{Obtaining TeX, , How to Obtain @TeX{}}, for information on how to obtain @TeX{}.) The @code{makeinfo}, @code{texinfo-format-region}, and @code{texinfo-format-buffer} commands read the very same @@-commands in the Texinfo file as does @TeX{}, but process them differently to make an Info file; see @ref{Create an Info File}.@refill @node Format with tex/texindex, Format with texi2dvi, Use TeX, Format/Print Hardcopy @comment node-name, next, previous, up @section Format using @code{tex} and @code{texindex} @cindex Shell formatting with @code{tex} and @code{texindex} @cindex Formatting with @code{tex} and @code{texindex} @cindex DVI file Format the Texinfo file with the shell command @code{tex} followed by the name of the Texinfo file. For example: @example tex foo.texi @end example @noindent @TeX{} will produce a @dfn{DVI file} as well as several auxiliary files containing information for indices, cross references, etc. The DVI file (for @dfn{DeVice Independent} file) can be printed on virtually any printe (see the following sections). @pindex texindex The @code{tex} formatting command itself does not sort the indices; it writes an output file of unsorted index data. (The @code{texi2dvi} command automatically generates indices; see @ref{Format with texi2dvi,, Format using @code{texi2dvi}}.) To generate a printed index after running the @code{tex} command, you first need a sorted index to work from. The @code{texindex} command sorts indices. (The source file @file{texindex.c} comes as part of the standard Texinfo distribution, among other places.)@refill @cindex Names of index files The @code{tex} formatting command outputs unsorted index files under names that obey a standard convention: the name of your main input file with any @samp{.tex} (or similar, @pxref{tex invocation,,, web2c, Web2c}) extension removed, followed by the two letter names of indices. For example, the raw index output files for the input file @file{foo.texinfo} would be @file{foo.cp}, @file{foo.vr}, @file{foo.fn}, @file{foo.tp}, @file{foo.pg} and @file{foo.ky}. Those are exactly the arguments to give to @code{texindex}.@refill @need 1000 @cindex Wildcards @cindex Globbing Instead of specifying all the unsorted index file names explicitly, you can use @samp{??} as shell wildcards and give the command in this form:@refill @example texindex foo.?? @end example @noindent This command will run @code{texindex} on all the unsorted index files, including any that you have defined yourself using @code{@@defindex} or @code{@@defcodeindex}. (You may execute @samp{texindex foo.??} even if there are similarly named files with two letter extensions that are not index files, such as @samp{foo.el}. The @code{texindex} command reports but otherwise ignores such files.)@refill For each file specified, @code{texindex} generates a sorted index file whose name is made by appending @samp{s} to the input file name. The @code{@@printindex} command knows to look for a file of that name (@pxref{Printing Indices & Menus}). @code{texindex} does not alter the raw index output file.@refill After you have sorted the indices, you need to rerun the @code{tex} formatting command on the Texinfo file. This regenerates the DVI file, this time with up-to-date index entries. Finally, you may need to run @code{tex} one more time, to get the page numbers in the cross-references correct. To summarize, this is a four step process: @enumerate @item Run @code{tex} on your Texinfo file. This generates a DVI file (with undefined cross-references and no indices), and the raw index files (with two letter extensions). @item Run @code{texindex} on the raw index files. This creates the corresponding sorted index files (with three letter extensions). @item Run @code{tex} again on your Texinfo file. This regenerates the DVI file, this time with indices and defined cross-references, but with page numbers for the cross-references from last time, generally incorrect. @item Run @code{tex} one last time. This time the correct page numbers are written for the cross-references. @end enumerate @pindex texi2dvi Alternatively, it's a one-step process: run @code{texi2dvi}. You need not run @code{texindex} each time after you run @code{tex}. If you do not, on the next run, the @code{tex} formatting command will use whatever sorted index files happen to exist from the previous use of @code{texindex}. This is usually ok while you are debugging.@refill @node Format with texi2dvi, Print with lpr, Format with tex/texindex, Format/Print Hardcopy @comment node-name, next, previous, up @section Format using @code{texi2dvi} @pindex texi2dvi @r{(shell script)} The @code{texi2dvi} command automatically runs both @code{tex} and @code{texindex} as many times as necessary to produce a DVI file with up-to-date, sorted indices. It simplifies the @code{tex}---@code{texindex}---@code{tex} sequence described in the previous section. The syntax for @code{texi2dvi} is like this (where @samp{prompt$} is your shell prompt):@refill @example prompt$ @kbd{texi2dvi @var{filename}@dots{}} @end example For a list of options, run @samp{texi2dvi --help}. @node Print with lpr, Within Emacs, Format with texi2dvi, Format/Print Hardcopy @comment node-name, next, previous, up @section Shell Print Using @code{lpr -d} @pindex lpr @r{(DVI print command)} The precise command to print a DVI file depends on your system installation, but @samp{lpr -d} is common. The command may require the DVI file name without any extension or with a @samp{.dvi} extension. (If it is @samp{lpr}, you must include the @samp{.dvi}.) The following commands, for example, will (probably) suffice to sort the indices, format, and print the @cite{Bison Manual}: @example @group tex bison.texinfo texindex bison.?? tex bison.texinfo lpr -d bison.dvi @end group @end example @noindent (Remember that the shell commands may be different at your site; but these are commonly used versions.)@refill @need 1000 Using the @code{texi2dvi} shell script, you simply need type:@refill @example @group texi2dvi bison.texinfo lpr -d bison.dvi @end group @end example @node Within Emacs, Texinfo Mode Printing, Print with lpr, Format/Print Hardcopy @comment node-name, next, previous, up @section From an Emacs Shell @cindex Print, format from Emacs shell @cindex Format, print from Emacs shell @cindex Shell, format, print from @cindex Emacs shell, format, print from @cindex GNU Emacs shell, format, print from You can give formatting and printing commands from a shell within GNU Emacs. To create a shell within Emacs, type @kbd{M-x shell}. In this shell, you can format and print the document. @xref{Format/Print Hardcopy, , Format and Print Hardcopy}, for details.@refill You can switch to and from the shell buffer while @code{tex} is running and do other editing. If you are formatting a long document on a slow machine, this can be very convenient.@refill You can also use @code{texi2dvi} from an Emacs shell. For example, here is how to use @code{texi2dvi} to format and print @cite{Using and Porting GNU CC} from a shell within Emacs: @example @group texi2dvi gcc.texinfo lpr -d gcc.dvi @end group @end example @ifinfo @xref{Texinfo Mode Printing}, for more information about formatting and printing in Texinfo mode.@refill @end ifinfo @node Texinfo Mode Printing, Compile-Command, Within Emacs, Format/Print Hardcopy @section Formatting and Printing in Texinfo Mode @cindex Region printing in Texinfo mode @cindex Format and print in Texinfo mode @cindex Print and format in Texinfo mode Texinfo mode provides several predefined key commands for @TeX{} formatting and printing. These include commands for sorting indices, looking at the printer queue, killing the formatting job, and recentering the display of the buffer in which the operations occur.@refill @table @kbd @item C-c C-t C-b @itemx M-x texinfo-tex-buffer Run @code{texi2dvi} on the current buffer.@refill @item C-c C-t C-r @itemx M-x texinfo-tex-region Run @TeX{} on the current region.@refill @item C-c C-t C-i @itemx M-x texinfo-texindex Sort the indices of a Texinfo file formatted with @code{texinfo-tex-region}.@refill @item C-c C-t C-p @itemx M-x texinfo-tex-print Print a DVI file that was made with @code{texinfo-tex-region} or @code{texinfo-tex-buffer}.@refill @item C-c C-t C-q @itemx M-x tex-show-print-queue Show the print queue.@refill @item C-c C-t C-d @itemx M-x texinfo-delete-from-print-queue Delete a job from the print queue; you will be prompted for the job number shown by a preceding @kbd{C-c C-t C-q} command (@code{texinfo-show-tex-print-queue}).@refill @item C-c C-t C-k @itemx M-x tex-kill-job Kill the currently running @TeX{} job started by @code{texinfo-tex-region} or @code{texinfo-tex-buffer}, or any other process running in the Texinfo shell buffer.@refill @item C-c C-t C-x @itemx M-x texinfo-quit-job Quit a @TeX{} formatting job that has stopped because of an error by sending an @key{x} to it. When you do this, @TeX{} preserves a record of what it did in a @file{.log} file.@refill @item C-c C-t C-l @itemx M-x tex-recenter-output-buffer Redisplay the shell buffer in which the @TeX{} printing and formatting commands are run to show its most recent output.@refill @end table @need 1000 Thus, the usual sequence of commands for formatting a buffer is as follows (with comments to the right):@refill @example @group C-c C-t C-b @r{Run @code{texi2dvi} on the buffer.} C-c C-t C-p @r{Print the DVI file.} C-c C-t C-q @r{Display the printer queue.} @end group @end example The Texinfo mode @TeX{} formatting commands start a subshell in Emacs called the @file{*tex-shell*}. The @code{texinfo-tex-command}, @code{texinfo-texindex-command}, and @code{tex-dvi-print-command} commands are all run in this shell. You can watch the commands operate in the @samp{*tex-shell*} buffer, and you can switch to and from and use the @samp{*tex-shell*} buffer as you would any other shell buffer.@refill @need 1500 The formatting and print commands depend on the values of several variables. The default values are:@refill @example @group @r{Variable} @r{Default value} texinfo-texi2dvi-command "texi2dvi" texinfo-tex-command "tex" texinfo-texindex-command "texindex" texinfo-delete-from-print-queue-command "lprm" texinfo-tex-trailer "@@bye" tex-start-of-header "%**start" tex-end-of-header "%**end" tex-dvi-print-command "lpr -d" tex-show-queue-command "lpq" @end group @end example You can change the values of these variables with the @kbd{M-x edit-options} command (@pxref{Edit Options, , Editing Variable Values, emacs, The GNU Emacs Manual}), with the @kbd{M-x set-variable} command (@pxref{Examining, , Examining and Setting Variables, emacs, The GNU Emacs Manual}), or with your @file{.emacs} initialization file (@pxref{Init File, , , emacs, The GNU Emacs Manual}).@refill @node Compile-Command, Requirements Summary, Texinfo Mode Printing, Format/Print Hardcopy @comment node-name, next, previous, up @section Using the Local Variables List @cindex Local variables @cindex Compile command for formatting @cindex Format with the compile command Yet another way to apply the @TeX{} formatting command to a Texinfo file is to put that command in a @dfn{local variables list} at the end of the Texinfo file. You can then specify the @code{tex} or @code{texi2dvi} commands as a @code{compile-command} and have Emacs run it by typing @kbd{M-x compile}. This creates a special shell called the @file{*compilation*} buffer in which Emacs runs the compile command. For example, at the end of the @file{gdb.texinfo} file, after the @code{@@bye}, you could put the following:@refill @example @group Local Variables: compile-command: "texi2dvi gdb.texinfo" End: @end group @end example @noindent This technique is most often used by programmers who also compile programs this way; see @ref{Compilation, , , emacs, The GNU Emacs Manual}.@refill @node Requirements Summary, Preparing for TeX, Compile-Command, Format/Print Hardcopy @comment node-name, next, previous, up @section @TeX{} Formatting Requirements Summary @cindex Requirements for formatting @cindex Minimal requirements for formatting @cindex Formatting requirements Every Texinfo file that is to be input to @TeX{} must begin with a @code{\input} command and must contain an @code{@@setfilename} command: @example \input texinfo @@setfilename @var{arg-not-used-by-@TeX{}} @end example @noindent The first command instructs @TeX{} to load the macros it needs to process a Texinfo file and the second command opens auxiliary files. Every Texinfo file must end with a line that terminates @TeX{}'s processing and forces out unfinished pages: @example @@bye @end example Strictly speaking, these lines are all a Texinfo file needs to be processed successfully by @TeX{}. Usually, however, the beginning includes an @code{@@settitle} command to define the title of the printed manual, an @code{@@setchapternewpage} command, a title page, a copyright page, and permissions. Besides an @code{@@bye}, the end of a file usually includes indices and a table of contents. (And of course most manuals contain a body of text as well.) @iftex For more information, see @ref{settitle, , @code{@@settitle}}, @ref{setchapternewpage, , @code{@@setchapternewpage}}, @ref{Headings, ,Page Headings}, @ref{Titlepage & Copyright Page}, @ref{Printing Indices & Menus}, and @ref{Contents}. @end iftex @noindent @ifinfo For more information, see@* @ref{settitle, , @code{@@settitle}},@* @ref{setchapternewpage, , @code{@@setchapternewpage}},@* @ref{Headings, ,Page Headings},@* @ref{Titlepage & Copyright Page},@* @ref{Printing Indices & Menus}, and@* @ref{Contents}. @end ifinfo @node Preparing for TeX, Overfull hboxes, Requirements Summary, Format/Print Hardcopy @comment node-name, next, previous, up @section Preparing to Use @TeX{} @cindex Preparing to use @TeX{} @cindex @TeX{} input initialization @cindex @code{TEXINPUTS} environment variable @vindex TEXINPUTS @cindex @b{.profile} initialization file @cindex @b{.cshrc} initialization file @cindex Initialization file for @TeX{} input @TeX{} needs to know where to find the @file{texinfo.tex} file that you have told it to input with the @samp{\input texinfo} command at the beginning of the first line. The @file{texinfo.tex} file tells @TeX{} how to handle @@-commands; it is included in all standard GNU distributions. @pindex texinfo.tex@r{, installing} Usually, the @file{texinfo.tex} file is put under the default directory that contains @TeX{} macros (@file{/usr/local/share/texmf/tex/texinfo/texinfo.tex} by default) when GNU Emacs or other GNU software is installed. In this case, @TeX{} will find the file and you do not need to do anything special. Alternatively, you can put @file{texinfo.tex} in the current directory when you run @TeX{}, and @TeX{} will find it there. @pindex epsf.tex@r{, installing} Also, you should install @file{epsf.tex} in the same place as @file{texinfo.tex}, if it is not already installed from another distribution. This file is needed to support the @code{@@image} command (@pxref{Images}). @pindex texinfo.cnf @r{installation} @cindex Customizing of @TeX{} for Texinfo @cindex Site-wide Texinfo configuration file Optionally, you may create an additional @file{texinfo.cnf}, and install it as well. This file is read by @TeX{} at the @code{@@setfilename} command (@pxref{setfilename,, @code{@@setfilename}}). You can put any commands you like there according to local site-wide conventions, and they will be read by @TeX{} when processing any Texinfo document. For example, if @file{texinfo.cnf} contains the a single line @samp{@@afourpaper} (@pxref{A4 Paper}), then all Texinfo documents will be processed with that page size in effect. If you have nothing to put in @file{texinfo.cnf}, you do not need to create it. @vindex TEXINPUTS If neither of the above locations for these system files suffice for you, you can specify the directories explicitly. For @file{texinfo.tex}, you can do this by writing the complete path for the file after the @code{\input} command. Another way, that works for both @file{texinfo.tex} and @file{texinfo.cnf} (and any other file @TeX{} might read), is to set the @code{TEXINPUTS} environment variable in your @file{.cshrc} or @file{.profile} file. Which you use of @file{.cshrc} or @file{.profile} depends on whether you use a Bourne shell-compatible (@code{sh}, @code{bash}, @code{ksh}, @dots{}) or C shell-compatible (@code{csh}, @code{tcsh}) command interpreter. The latter read the @file{.cshrc} file for initialization information, and the former read @file{.profile}. In a @file{.cshrc} file, you could use the following @code{csh} command sequence: @example setenv TEXINPUTS .:/home/me/mylib:/usr/lib/tex/macros @end example @need 1000 In a @file{.profile} file, you could use the following @code{sh} command sequence: @example @group TEXINPUTS=.:/home/me/mylib:/usr/lib/tex/macros export TEXINPUTS @end group @end example @noindent This would cause @TeX{} to look for @file{\input} file first in the current directory, indicated by the @samp{.}, then in a hypothetical user's @file{me/mylib} directory, and finally in a system directory. @node Overfull hboxes, smallbook, Preparing for TeX, Format/Print Hardcopy @comment node-name, next, previous, up @section Overfull ``hboxes'' @cindex Overfull @samp{hboxes} @cindex @samp{hboxes}, overfull @cindex Final output @TeX{} is sometimes unable to typeset a line without extending it into the right margin. This can occur when @TeX{} comes upon what it interprets as a long word that it cannot hyphenate, such as an electronic mail network address or a very long title. When this happens, @TeX{} prints an error message like this:@refill @example Overfull \hbox (20.76302pt too wide) @end example @noindent (In @TeX{}, lines are in ``horizontal boxes'', hence the term, ``hbox''. The backslash, @samp{\}, is the @TeX{} equivalent of @samp{@@}.)@refill @TeX{} also provides the line number in the Texinfo source file and the text of the offending line, which is marked at all the places that @TeX{} knows how to hyphenate words. @xref{Debugging with TeX, , Catching Errors with @TeX{} Formatting}, for more information about typesetting errors.@refill If the Texinfo file has an overfull hbox, you can rewrite the sentence so the overfull hbox does not occur, or you can decide to leave it. A small excursion into the right margin often does not matter and may not even be noticeable.@refill @cindex Black rectangle in hardcopy @cindex Rectangle, ugly, black in hardcopy However, unless told otherwise, @TeX{} will print a large, ugly, black rectangle beside the line that contains the overfull hbox. This is so you will notice the location of the problem if you are correcting a draft.@refill @need 1000 @findex finalout To prevent such a monstrosity from marring your final printout, write the following in the beginning of the Texinfo file on a line of its own, before the @code{@@titlepage} command:@refill @example @@finalout @end example @node smallbook, A4 Paper, Overfull hboxes, Format/Print Hardcopy @comment node-name, next, previous, up @section Printing ``Small'' Books @findex smallbook @cindex Small book size @cindex Book, printing small @cindex Page sizes for books @cindex Size of printed book By default, @TeX{} typesets pages for printing in an 8.5 by 11 inch format. However, you can direct @TeX{} to typeset a document in a 7 by 9.25 inch format that is suitable for bound books by inserting the following command on a line by itself at the beginning of the Texinfo file, before the title page:@refill @example @@smallbook @end example @noindent (Since regular sized books are often about 7 by 9.25 inches, this command might better have been called the @code{@@regularbooksize} command, but it came to be called the @code{@@smallbook} command by comparison to the 8.5 by 11 inch format.)@refill If you write the @code{@@smallbook} command between the start-of-header and end-of-header lines, the Texinfo mode @TeX{} region formatting command, @code{texinfo-tex-region}, will format the region in ``small'' book size (@pxref{Start of Header}).@refill The Free Software Foundation distributes printed copies of @cite{The GNU Emacs Manual} and other manuals in the ``small'' book size. @xref{smallexample & smalllisp, , @code{@@smallexample} and @code{@@smalllisp}}, for information about commands that make it easier to produce examples for a smaller manual.@refill Alternatively, to avoid embedding this physical paper size in your document, use @code{texi2dvi} to format your document (@pxref{Format with texi2dvi}), and supply @samp{-t @@smallbook} as an argument. Then other people do not have to change the document source file to format it differently. @node A4 Paper, Cropmarks and Magnification, smallbook, Format/Print Hardcopy @comment node-name, next, previous, up @section Printing on A4 Paper @cindex A4 paper, printing on @cindex Paper size, European A4 @cindex European A4 paper @findex afourpaper You can tell @TeX{} to typeset a document for printing on European size A4 paper with the @code{@@afourpaper} command. Write the command on a line by itself between @code{@@iftex} and @code{@@end iftex} lines near the beginning of the Texinfo file, before the title page:@refill For example, this is how you would write the header for this manual:@refill @example @group \input texinfo @@c -*-texinfo-*- @@c %**start of header @@setfilename texinfo @@settitle Texinfo @@syncodeindex vr fn @@iftex @@afourpaper @@end iftex @@c %**end of header @end group @end example Alternatively, to avoid embedding this physical paper size in your document, use @code{texi2dvi} to format your document (@pxref{Format with texi2dvi}), and supply @samp{-t @@afourpaper} as an argument. Then other people do not have to change the document source file to format it differently. @pindex texinfo.cnf Another alternative: put the @code{@@afourpaper} command in the file @file{texinfo.cnf} that @TeX{} will read. (No need for @code{@@iftex} there.) This will automatically typeset all the Texinfo documents at your site with that paper size in effect. @node Cropmarks and Magnification, , A4 Paper, Format/Print Hardcopy @comment node-name, next, previous, up @section Cropmarks and Magnification @findex cropmarks @cindex Cropmarks for printing @cindex Printing cropmarks You can attempt to direct @TeX{} to print cropmarks at the corners of pages with the @code{@@cropmarks} command. Write the @code{@@cropmarks} command on a line by itself between @code{@@iftex} and @code{@@end iftex} lines near the beginning of the Texinfo file, before the title page, like this:@refill @example @group @@iftex @@cropmarks @@end iftex @end group @end example This command is mainly for printers that typeset several pages on one sheet of film; but you can attempt to use it to mark the corners of a book set to 7 by 9.25 inches with the @code{@@smallbook} command. (Printers will not produce cropmarks for regular sized output that is printed on regular sized paper.) Since different printing machines work in different ways, you should explore the use of this command with a spirit of adventure. You may have to redefine the command in the @file{texinfo.tex} definitions file.@refill @findex mag @r{(@TeX{} command)} @cindex Magnified printing @cindex Larger or smaller pages You can attempt to direct @TeX{} to typeset pages larger or smaller than usual with the @code{\mag} @TeX{} command. Everything that is typeset is scaled proportionally larger or smaller. (@code{\mag} stands for ``magnification''.) This is @emph{not} a Texinfo @@-command, but is a plain @TeX{} command that is prefixed with a backslash. You have to write this command between @code{@@tex} and @code{@@end tex} (@pxref{Raw Formatter Commands}). Follow the @code{\mag} command with an @samp{=} and then a number that is 1000 times the magnification you desire. For example, to print pages at 1.2 normal size, write the following near the beginning of the Texinfo file, before the title page:@refill @example @group @@tex \mag=1200 @@end tex @end group @end example With some printing technologies, you can print normal-sized copies that look better than usual by using a larger-than-normal master.@refill Depending on your system, @code{\mag} may not work or may work only at certain magnifications. Be prepared to experiment.@refill @node Create an Info File, Install an Info File, Format/Print Hardcopy, Top @comment node-name, next, previous, up @chapter Creating an Info File @cindex Creating an Info file @cindex Info, creating an on-line file @cindex Formatting a file for Info @code{makeinfo} is a utility that converts a Texinfo file into an Info file; @code{texinfo-format-region} and @code{texinfo-format-buffer} are GNU Emacs functions that do the same.@refill A Texinfo file must contain an @code{@@setfilename} line near its beginning, otherwise the Info formatting commands will fail. For information on installing the Info file in the Info system, see @ref{Install an Info File}.@refill @menu * makeinfo advantages:: @code{makeinfo} provides better error checking. * Invoking makeinfo:: How to run @code{makeinfo} from a shell. * makeinfo options:: Specify fill-column and other options. * Pointer Validation:: How to check that pointers point somewhere. * makeinfo in Emacs:: How to run @code{makeinfo} from Emacs. * texinfo-format commands:: Two Info formatting commands written in Emacs Lisp are an alternative to @code{makeinfo}. * Batch Formatting:: How to format for Info in Emacs Batch mode. * Tag and Split Files:: How tagged and split files help Info to run better. @end menu @node makeinfo advantages, Invoking makeinfo, Create an Info File, Create an Info File @ifinfo @heading @code{makeinfo} Preferred @end ifinfo The @code{makeinfo} utility creates an Info file from a Texinfo source file more quickly than either of the Emacs formatting commands and provides better error messages. We recommend it. @code{makeinfo} is a C program that is independent of Emacs. You do not need to run Emacs to use @code{makeinfo}, which means you can use @code{makeinfo} on machines that are too small to run Emacs. You can run @code{makeinfo} in any one of three ways: from an operating system shell, from a shell inside Emacs, or by typing a key command in Texinfo mode in Emacs. @refill The @code{texinfo-format-region} and the @code{texinfo-format-buffer} commands are useful if you cannot run @code{makeinfo}. Also, in some circumstances, they format short regions or buffers more quickly than @code{makeinfo}.@refill @node Invoking makeinfo, makeinfo options, makeinfo advantages, Create an Info File @section Running @code{makeinfo} from a Shell To create an Info file from a Texinfo file, type @code{makeinfo} followed by the name of the Texinfo file. Thus, to create the Info file for Bison, type the following to the shell: is the prompt):@refill @example makeinfo bison.texinfo @end example (You can run a shell inside Emacs by typing @kbd{M-x shell}.)@refill @ifinfo Sometimes you will want to specify options. For example, if you wish to discover which version of @code{makeinfo} you are using, type:@refill @example makeinfo --version @end example @xref{makeinfo options}, for more information. @end ifinfo @node makeinfo options, Pointer Validation, Invoking makeinfo, Create an Info File @comment node-name, next, previous, up @section Options for @code{makeinfo} @cindex @code{makeinfo} options @cindex Options for @code{makeinfo} The @code{makeinfo} command takes a number of options. Most often, options are used to set the value of the fill column and specify the footnote style. Each command line option is a word preceded by @samp{--} or a letter preceded by @samp{-}. You can use abbreviations for the long option names as long as they are unique.@refill For example, you could use the following shell command to create an Info file for @file{bison.texinfo} in which each line is filled to only 68 columns:@refill @example makeinfo --fill-column=68 bison.texinfo @end example You can write two or more options in sequence, like this:@refill @example makeinfo --no-split --fill-column=70 @dots{} @end example @noindent This would keep the Info file together as one possibly very long file and would also set the fill column to 70.@refill The options are: @table @code @item -D @var{var} @opindex -D @var{var} Cause the variable @var{var} to be defined. This is equivalent to @code{@@set @var{var}} in the Texinfo file (@pxref{set clear value}). @item --error-limit=@var{limit} @opindex --error-limit=@var{limit} Set the maximum number of errors that @code{makeinfo} will report before exiting (on the assumption that continuing would be useless); default 100. @need 150 @item --fill-column=@var{width} @opindex --fill-column=@var{width} Specify the maximum number of columns in a line; this is the right-hand edge of a line. Paragraphs that are filled will be filled to this width. (Filling is the process of breaking up and connecting lines so that lines are the same length as or shorter than the number specified as the fill column. Lines are broken between words.) The default value is 72. @item --footnote-style=@var{style} @opindex --footnote-style=@var{style} Set the footnote style to @var{style}, either @samp{end} for the end node style (the default) or @samp{separate} for the separate node style. The value set by this option overrides the value set in a Texinfo file by an @code{@@footnotestyle} command (@pxref{Footnotes}). When the footnote style is @samp{separate}, @code{makeinfo} makes a new node containing the footnotes found in the current node. When the footnote style is @samp{end}, @code{makeinfo} places the footnote references at the end of the current node. @item --force @opindex --force Ordinarily, if the input file has errors, the output files are not created. With this option, they are preserved. @item --help @opindex --help Print a usage message listing all available options, then exit successfully. @item -I @var{dir} @opindex -I @var{dir} Add @code{dir} to the directory search list for finding files that are included using the @code{@@include} command. By default, @code{makeinfo} searches only the current directory. @item --no-headers @opindex --no-headers Do not include menus or node lines in the output. This results in an @sc{ascii} file that you cannot read in Info since it does not contain the requisite nodes or menus. It is primarily useful to extract certain pieces of a manual into separate files to be included in a distribution, such as @file{INSTALL} files. @item --no-split @opindex --no-split Suppress the splitting stage of @code{makeinfo}. By default, large output files (where the size is greater than 70k bytes) are split into smaller subfiles, each one approximately 50k bytes. @item --no-pointer-validate @itemx --no-validate @opindex --no-pointer-validate @opindex --no-validate Suppress the pointer-validation phase of @code{makeinfo}. Normally, after a Texinfo file is processed, some consistency checks are made to ensure that cross references can be resolved, etc. @xref{Pointer Validation}.@refill @item --no-warn @opindex --no-warn Suppress warning messages (but @emph{not} error messages). You might want this if the file you are creating has examples of Texinfo cross references within it, and the nodes that are referenced do not actually exist. @item --no-number-footnotes @opindex --no-number-footnotes Suppress automatic footnote numbering. By default, @code{makeinfo} numbers each footnote sequentially in a single node, resetting the current footnote number to 1 at the start of each node. @item --output=@var{file} @itemx -o @var{file} @opindex --output=@var{file} @opindex -o @var{file} Specify that the output should be directed to @var{file} and not to the file name specified in the @code{@@setfilename} command found in the Texinfo source (@pxref{setfilename}). If @var{file} is @samp{-}, output goes to standard output and @samp{--no-split} is implied. @item -P @var{dir} @opindex -P @var{dir} Prepend @code{dir} to the directory search list for @code{@@include}. See @samp{-I} for more details. @item --paragraph-indent=@var{indent} @opindex --paragraph-indent=@var{indent} Set the paragraph indentation style to @var{indent}. The value set by this option overrides the value set in a Texinfo file by an @code{@@paragraphindent} command (@pxref{paragraphindent}). The value of @var{indent} is interpreted as follows: @table @asis @item @samp{asis} Preserve any existing indentation at the starts of paragraphs. @item @samp{0} or @samp{none} Delete any existing indentation. @item @var{num} Indent each paragraph by that number of spaces. @end table @item --reference-limit=@var{limit} @opindex --reference-limit=@var{limit} Set the value of the number of references to a node that @code{makeinfo} will make without reporting a warning. If a node has more than this number of references in it, @code{makeinfo} will make the references but also report a warning. The default is 1000. @item -U @var{var} Cause @var{var} to be undefined. This is equivalent to @code{@@clear @var{var}} in the Texinfo file (@pxref{set clear value}). @item --verbose @opindex --verbose Cause @code{makeinfo} to display messages saying what it is doing. Normally, @code{makeinfo} only outputs messages if there are errors or warnings. @item --version @opindex --version Print the version number, then exit successfully. @end table @node Pointer Validation, makeinfo in Emacs, makeinfo options, Create an Info File @section Pointer Validation @cindex Pointer validation with @code{makeinfo} @cindex Validation of pointers If you do not suppress pointer-validation, @code{makeinfo} will check the validity of the final Info file. Mostly, this means ensuring that nodes you have referenced really exist. Here is a complete list of what is checked:@refill @enumerate @item If a `Next', `Previous', or `Up' node reference is a reference to a node in the current file and is not an external reference such as to @file{(dir)}, then the referenced node must exist.@refill @item In every node, if the `Previous' node is different from the `Up' node, then the `Previous' node must also be pointed to by a `Next' node.@refill @item Every node except the `Top' node must have an `Up' pointer.@refill @item The node referenced by an `Up' pointer must contain a reference to the current node in some manner other than through a `Next' reference. This includes menu entries and cross references.@refill @item If the `Next' reference of a node is not the same as the `Next' reference of the `Up' reference, then the node referenced by the `Next' pointer must have a `Previous' pointer that points back to the current node. This rule allows the last node in a section to point to the first node of the next chapter.@refill @end enumerate @node makeinfo in Emacs, texinfo-format commands, Pointer Validation, Create an Info File @section Running @code{makeinfo} inside Emacs @cindex Running @code{makeinfo} in Emacs @cindex @code{makeinfo} inside Emacs @cindex Shell, running @code{makeinfo} in You can run @code{makeinfo} in GNU Emacs Texinfo mode by using either the @code{makeinfo-region} or the @code{makeinfo-buffer} commands. In Texinfo mode, the commands are bound to @kbd{C-c C-m C-r} and @kbd{C-c C-m C-b} by default.@refill @table @kbd @item C-c C-m C-r @itemx M-x makeinfo-region Format the current region for Info.@refill @findex makeinfo-region @item C-c C-m C-b @itemx M-x makeinfo-buffer Format the current buffer for Info.@refill @findex makeinfo-buffer @end table When you invoke either @code{makeinfo-region} or @code{makeinfo-buffer}, Emacs prompts for a file name, offering the name of the visited file as the default. You can edit the default file name in the minibuffer if you wish, before pressing @key{RET} to start the @code{makeinfo} process.@refill The Emacs @code{makeinfo-region} and @code{makeinfo-buffer} commands run the @code{makeinfo} program in a temporary shell buffer. If @code{makeinfo} finds any errors, Emacs displays the error messages in the temporary buffer.@refill @cindex Errors, parsing @cindex Parsing errors @findex next-error You can parse the error messages by typing @kbd{C-x `} (@code{next-error}). This causes Emacs to go to and position the cursor on the line in the Texinfo source that @code{makeinfo} thinks caused the error. @xref{Compilation, , Running @code{make} or Compilers Generally, emacs, The GNU Emacs Manual}, for more information about using the @code{next-error} command.@refill In addition, you can kill the shell in which the @code{makeinfo} command is running or make the shell buffer display its most recent output.@refill @table @kbd @item C-c C-m C-k @itemx M-x makeinfo-kill-job @findex makeinfo-kill-job Kill the current running @code{makeinfo} job created by @code{makeinfo-region} or @code{makeinfo-buffer}.@refill @item C-c C-m C-l @itemx M-x makeinfo-recenter-output-buffer @findex makeinfo-recenter-output-buffer Redisplay the @code{makeinfo} shell buffer to display its most recent output.@refill @end table @noindent (Note that the parallel commands for killing and recentering a @TeX{} job are @kbd{C-c C-t C-k} and @kbd{C-c C-t C-l}. @xref{Texinfo Mode Printing}.)@refill You can specify options for @code{makeinfo} by setting the @code{makeinfo-options} variable with either the @kbd{M-x edit-options} or the @kbd{M-x set-variable} command, or by setting the variable in your @file{.emacs} initialization file.@refill For example, you could write the following in your @file{.emacs} file:@refill @example @group (setq makeinfo-options "--paragraph-indent=0 --no-split --fill-column=70 --verbose") @end group @end example @c If you write these three cross references using xref, you see @c three references to the same named manual, which looks strange. @iftex For more information, see @ref{makeinfo options, , Options for @code{makeinfo}}, as well as ``Editing Variable Values,''``Examining and Setting Variables,'' and ``Init File'' in the @cite{The GNU Emacs Manual}. @end iftex @noindent @ifinfo For more information, see@* @ref{Edit Options, , Editing Variable Values, emacs, The GNU Emacs Manual},@* @ref{Examining, , Examining and Setting Variables, emacs, The GNU Emacs Manual},@* @ref{Init File, , , emacs, The GNU Emacs Manual}, and@* @ref{makeinfo options, , Options for @code{makeinfo}}. @end ifinfo @node texinfo-format commands, Batch Formatting, makeinfo in Emacs, Create an Info File @comment node-name, next, previous, up @section The @code{texinfo-format@dots{}} Commands @findex texinfo-format-region @findex texinfo-format-buffer In GNU Emacs in Texinfo mode, you can format part or all of a Texinfo file with the @code{texinfo-format-region} command. This formats the current region and displays the formatted text in a temporary buffer called @samp{*Info Region*}.@refill Similarly, you can format a buffer with the @code{texinfo-format-buffer} command. This command creates a new buffer and generates the Info file in it. Typing @kbd{C-x C-s} will save the Info file under the name specified by the @code{@@setfilename} line which must be near the beginning of the Texinfo file.@refill @table @kbd @item C-c C-e C-r @itemx @code{texinfo-format-region} Format the current region for Info. @findex texinfo-format-region @item C-c C-e C-b @itemx @code{texinfo-format-buffer} Format the current buffer for Info. @findex texinfo-format-buffer @end table The @code{texinfo-format-region} and @code{texinfo-format-buffer} commands provide you with some error checking, and other functions can provide you with further help in finding formatting errors. These procedures are described in an appendix; see @ref{Catching Mistakes}. However, the @code{makeinfo} program is often faster and provides better error checking (@pxref{makeinfo in Emacs}).@refill @node Batch Formatting, Tag and Split Files, texinfo-format commands, Create an Info File @comment node-name, next, previous, up @section Batch Formatting @cindex Batch formatting for Info @cindex Info batch formatting You can format Texinfo files for Info using @code{batch-texinfo-format} and Emacs Batch mode. You can run Emacs in Batch mode from any shell, including a shell inside of Emacs. (@xref{Command Switches, , Command Line Switches and Arguments, emacs, The GNU Emacs Manual}.)@refill Here is a shell command to format all the files that end in @file{.texinfo} in the current directory: @example emacs -batch -funcall batch-texinfo-format *.texinfo @end example @noindent Emacs processes all the files listed on the command line, even if an error occurs while attempting to format some of them.@refill Run @code{batch-texinfo-format} only with Emacs in Batch mode as shown; it is not interactive. It kills the Batch mode Emacs on completion.@refill @code{batch-texinfo-format} is convenient if you lack @code{makeinfo} and want to format several Texinfo files at once. When you use Batch mode, you create a new Emacs process. This frees your current Emacs, so you can continue working in it. (When you run @code{texinfo-format-region} or @code{texinfo-format-buffer}, you cannot use that Emacs for anything else until the command finishes.)@refill @node Tag and Split Files, , Batch Formatting, Create an Info File @comment node-name, next, previous, up @section Tag Files and Split Files @cindex Making a tag table automatically @cindex Tag table, making automatically If a Texinfo file has more than 30,000 bytes, @code{texinfo-format-buffer} automatically creates a tag table for its Info file; @code{makeinfo} always creates a tag table. With a @dfn{tag table}, Info can jump to new nodes more quickly than it can otherwise.@refill @cindex Indirect subfiles In addition, if the Texinfo file contains more than about 70,000 bytes, @code{texinfo-format-buffer} and @code{makeinfo} split the large Info file into shorter @dfn{indirect} subfiles of about 50,000 bytes each. Big files are split into smaller files so that Emacs does not need to make a large buffer to hold the whole of a large Info file; instead, Emacs allocates just enough memory for the small, split off file that is needed at the time. This way, Emacs avoids wasting memory when you run Info. (Before splitting was implemented, Info files were always kept short and @dfn{include files} were designed as a way to create a single, large printed manual out of the smaller Info files. @xref{Include Files}, for more information. Include files are still used for very large documents, such as @cite{The Emacs Lisp Reference Manual}, in which each chapter is a separate file.)@refill When a file is split, Info itself makes use of a shortened version of the original file that contains just the tag table and references to the files that were split off. The split off files are called @dfn{indirect} files.@refill The split off files have names that are created by appending @w{@samp{-1}}, @w{@samp{-2}}, @w{@samp{-3}} and so on to the file name specified by the @code{@@setfilename} command. The shortened version of the original file continues to have the name specified by @code{@@setfilename}.@refill At one stage in writing this document, for example, the Info file was saved as @file{test-texinfo} and that file looked like this:@refill @example @group Info file: test-texinfo, -*-Text-*- produced by texinfo-format-buffer from file: new-texinfo-manual.texinfo ^_ Indirect: test-texinfo-1: 102 test-texinfo-2: 50422 @end group @group test-texinfo-3: 101300 ^_^L Tag table: (Indirect) Node: overview^?104 Node: info file^?1271 @end group @group Node: printed manual^?4853 Node: conventions^?6855 @dots{} @end group @end example @noindent (But @file{test-texinfo} had far more nodes than are shown here.) Each of the split off, indirect files, @file{test-texinfo-1}, @file{test-texinfo-2}, and @file{test-texinfo-3}, is listed in this file after the line that says @samp{Indirect:}. The tag table is listed after the line that says @samp{Tag table:}. @refill In the list of indirect files, the number following the file name records the cumulative number of bytes in the preceding indirect files, not counting the file list itself, the tag table, or the permissions text in each file. In the tag table, the number following the node name records the location of the beginning of the node, in bytes from the beginning.@refill If you are using @code{texinfo-format-buffer} to create Info files, you may want to run the @code{Info-validate} command. (The @code{makeinfo} command does such a good job on its own, you do not need @code{Info-validate}.) However, you cannot run the @kbd{M-x Info-validate} node-checking command on indirect files. For information on how to prevent files from being split and how to validate the structure of the nodes, see @ref{Using Info-validate}.@refill @node Install an Info File, Command List, Create an Info File, Top @comment node-name, next, previous, up @chapter Installing an Info File @cindex Installing an Info file @cindex Info file installation @cindex @file{dir} directory for Info installation Info files are usually kept in the @file{info} directory. You can read Info files using the standalone Info program or the Info reader built into Emacs. (@inforef{Top, info, info}, for an introduction to Info.) @menu * Directory file:: The top level menu for all Info files. * New Info File:: Listing a new info file. * Other Info Directories:: How to specify Info files that are located in other directories. * Installing Dir Entries:: How to specify what menu entry to add to the Info directory. * Invoking install-info:: @code{install-info} options. @end menu @node Directory file, New Info File, Install an Info File, Install an Info File @ifinfo @heading The @file{dir} File @end ifinfo For Info to work, the @file{info} directory must contain a file that serves as a top level directory for the Info system. By convention, this file is called @file{dir}. (You can find the location of this file within Emacs by typing @kbd{C-h i} to enter Info and then typing @kbd{C-x C-f} to see the pathname to the @file{info} directory.) The @file{dir} file is itself an Info file. It contains the top level menu for all the Info files in the system. The menu looks like this:@refill @example @group * Menu: * Info: (info). Documentation browsing system. * Emacs: (emacs). The extensible, self-documenting text editor. * Texinfo: (texinfo). With one source file, make either a printed manual using TeX or an Info file. @dots{} @end group @end example Each of these menu entries points to the `Top' node of the Info file that is named in parentheses. (The menu entry does not need to specify the `Top' node, since Info goes to the `Top' node if no node name is mentioned. @xref{Other Info Files, , Nodes in Other Info Files}.)@refill Thus, the @samp{Info} entry points to the `Top' node of the @file{info} file and the @samp{Emacs} entry points to the `Top' node of the @file{emacs} file.@refill In each of the Info files, the `Up' pointer of the `Top' node refers back to the @code{dir} file. For example, the line for the `Top' node of the Emacs manual looks like this in Info:@refill @example File: emacs Node: Top, Up: (DIR), Next: Distrib @end example @noindent (Note that in this case, the @file{dir} file name is written in upper case letters---it can be written in either upper or lower case. Info has a feature that it will change the case of the file name to lower case if it cannot find the name as written.)@refill @c !!! Can any file name be written in upper or lower case, @c or is dir a special case? @c Yes, apparently so, at least with Gillespie's Info. --rjc 24mar92 @node New Info File, Other Info Directories, Directory file, Install an Info File @section Listing a New Info File @cindex Adding a new info file @cindex Listing a new info file @cindex New info file, listing it in @file{dir} file @cindex Info file, listing new one @cindex @file{dir} file listing To add a new Info file to your system, you must write a menu entry to add to the menu in the @file{dir} file in the @file{info} directory. For example, if you were adding documentation for GDB, you would write the following new entry:@refill @example * GDB: (gdb). The source-level C debugger. @end example @noindent The first part of the menu entry is the menu entry name, followed by a colon. The second part is the name of the Info file, in parentheses, followed by a period. The third part is the description. The name of an Info file often has a @file{.info} extension. Thus, the Info file for GDB might be called either @file{gdb} or @file{gdb.info}. The Info reader programs automatically try the file name both with and without @file{.info}; so it is better to avoid clutter and not to write @samp{.info} explicitly in the menu entry. For example, the GDB menu entry should use just @samp{gdb} for the file name, not @samp{gdb.info}. @node Other Info Directories, Installing Dir Entries, New Info File, Install an Info File @comment node-name, next, previous, up @section Info Files in Other Directories @cindex Installing Info in another directory @cindex Info installed in another directory @cindex Another Info directory If an Info file is not in the @file{info} directory, there are three ways to specify its location:@refill @itemize @bullet @item Write the pathname in the @file{dir} file as the second part of the menu.@refill @item If you are using Emacs, list the name of the file in a second @file{dir} file, in its directory; and then add the name of that directory to the @code{Info-directory-list} variable in your personal or site initialization file. This tells Emacs where to look for @file{dir} files. Emacs merges the files named @file{dir} from each of the listed directories. (In Emacs version 18, you can set the @code{Info-directory} variable to the name of only one directory.)@refill @item Specify the Info directory name in the @code{INFOPATH} environment variable in your @file{.profile} or @file{.cshrc} initialization file. (Only you and others who set this environment variable will be able to find Info files whose location is specified this way.)@refill @end itemize For example, to reach a test file in the @file{/home/bob/manuals} directory, you could add an entry like this to the menu in the @file{dir} file:@refill @example * Test: (/home/bob/manuals/info-test). Bob's own test file. @end example @noindent In this case, the absolute file name of the @file{info-test} file is written as the second part of the menu entry.@refill @vindex Info-directory-list Alternatively, you could write the following in your @file{.emacs} file:@refill @example @group (setq Info-directory-list '("/home/bob/manuals" "/usr/local/info")) @end group @end example @c reworded to avoid overfill hbox This tells Emacs to merge the @file{dir} file from the @file{/home/bob/manuals} directory with the @file{dir} file from the @file{/usr/local/info} directory. Info will list the @file{/home/bob/manuals/info-test} file as a menu entry in the @file{/home/bob/manuals/dir} file.@refill @vindex INFOPATH Finally, you can tell Info where to look by setting the @code{INFOPATH} environment variable in your @file{.cshrc} or @file{.profile} file. If you use a Bourne-compatible shell such as @code{sh} or @code{bash} for your shell command interpreter, you set the @code{INFOPATH} environment variable in the @file{.profile} initialization file; but if you use @code{csh} or @code{tcsh}, you must set the variable in the @file{.cshrc} initialization file. The two types of shells use different syntax. @itemize @bullet @item In a @file{.cshrc} file, you could set the @code{INFOPATH} variable as follows:@refill @smallexample setenv INFOPATH .:~/manuals:/usr/local/emacs/info @end smallexample @item In a @file{.profile} file, you would achieve the same effect by writing:@refill @smallexample INFOPATH=.:$HOME/manuals:/usr/local/emacs/info export INFOPATH @end smallexample @end itemize @noindent The @samp{.} indicates the current directory as usual. Emacs uses the @code{INFOPATH} environment variable to initialize the value of Emacs's own @code{Info-directory-list} variable. @cindex @samp{:} @r{last in @code{INFOPATH}} However you set @code{INFOPATH}, if its last character is a colon, this is replaced by the default (compiled-in) path. This gives you a way to augment the default path with new directories without having to list all the standard places. For example (using @code{sh} syntax: @example INFOPATH=/local/info: export INFOPATH @end example @noindent will search @file{/local/info} first, then the standard directories. Leading or doubled colons are not treated specially. @node Installing Dir Entries, Invoking install-info, Other Info Directories, Install an Info File @section Installing Info Directory Files When you install an Info file onto your system, you can use the program @code{install-info} to update the Info directory file @file{dir}. Normally the makefile for the package runs @code{install-info}, just after copying the Info file into its proper installed location. @findex dircategory @findex direntry In order for the Info file to work with @code{install-info}, you should use the commands @code{@@dircategory} and @code{@@direntry} in the Texinfo source file. Use @code{@@direntry} to specify the menu entry to add to the Info directory file, and use @code{@@dircategory} to specify which part of the Info directory to put it in. Here is how these commands are used in this manual: @smallexample @@dircategory Texinfo documentation system @@direntry * Texinfo: (texinfo). The GNU documentation format. * install-info: (texinfo)Invoking install-info. @dots{} @dots{} @@end direntry @end smallexample Here's what this produces in the Info file: @smallexample INFO-DIR-SECTION Texinfo documentation system START-INFO-DIR-ENTRY * Texinfo: (texinfo). The GNU documentation format. * install-info: (texinfo)Invoking install-info. @dots{} @dots{} END-INFO-DIR-ENTRY @end smallexample @noindent The @code{install-info} program sees these lines in the Info file, and that is how it knows what to do. Always use the @code{@@direntry} and @code{@@dircategory} commands near the beginning of the Texinfo input, before the first @code{@@node} command. If you use them later on in the input, @code{install-info} will not notice them. If you use @code{@@dircategory} more than once in the Texinfo source, each usage specifies one category; the new menu entry is added to the Info directory file in each of the categories you specify. If you use @code{@@direntry} more than once, each usage specifies one menu entry; each of these menu entries is added to the directory in each of the specified categories. @node Invoking install-info, , Installing Dir Entries, Install an Info File @section Invoking install-info @pindex install-info @code{install-info} inserts menu entries from an Info file into the top-level @file{dir} file in the Info system (see the previous sections for an explanation of how the @file{dir} file works). It's most often run as part of software installation, or when constructing a dir file for all manuals on a system. Synopsis: @example install-info [@var{option}]@dots{} [@var{info-file} [@var{dir-file}]] @end example If @var{info-file} or @var{dir-file} are not specified, the various options (described below) that define them must be. There are no compile-time defaults, and standard input is never used. @code{install-info} can read only one info file and write only one dir file per invocation. @cindex @file{dir}, created by @code{install-info} If @var{dir-file} (however specified) does not exist, @code{install-info} creates it if possible (with no entries). Options: @table @code @item --delete @opindex --delete Delete the entries in @var{info-file} from @var{dir-file}. The file name in the entry in @var{dir-file} must be @var{info-file} (except for an optional @samp{.info} in either one). Don't insert any new entries. @item --dir-file=@var{name} @opindex --dir-file=@var{name} Specify file name of the Info directory file. This is equivalent to using the @var{dir-file} argument. @item --entry=@var{text} @opindex --entry=@var{text} Insert @var{text} as an Info directory entry; @var{text} should have the form of an Info menu item line plus zero or more extra lines starting with whitespace. If you specify more than one entry, they are all added. If you don't specify any entries, they are determined from information in the Info file itself. @item --help @opindex --help Display a usage message listing basic usage and all available options, then exit successfully. @item --info-file=@var{file} @opindex --info-file=@var{file} Specify Info file to install in the directory. This is equivalent to using the @var{info-file} argument. @item --info-dir=@var{dir} @opindex --info-dir=@var{dir} Equivalent to @samp{--dir-file=@var{dir}/dir}. @item --item=@var{text} @opindex --item=@var{text} Same as @samp{--entry=@var{text}}. An Info directory entry is actually a menu item. @item --quiet @opindex --quiet Suppress warnings. @item --remove @opindex --remove Same as @samp{--delete}. @item --section=@var{sec} @opindex --section=@var{sec} Put this file's entries in section @var{sec} of the directory. If you specify more than one section, all the entries are added in each of the sections. If you don't specify any sections, they are determined from information in the Info file itself. @item --version @opindex --version @cindex version number, finding Display version information and exit successfully. @end table @node Command List, Tips, Install an Info File, Top @appendix @@-Command List @cindex Alphabetical @@-command list @cindex List of @@-commands @cindex @@-command list Here is an alphabetical list of the @@-commands in Texinfo. Square brackets, @t{[}@w{ }@t{]}, indicate optional arguments; an ellipsis, @samp{@dots{}}, indicates repeated text.@refill @sp 1 @table @code @item @@@var{whitespace} An @code{@@} followed by a space, tab, or newline produces a normal, stretchable, interword space. @xref{Multiple Spaces}. @item @@! Generate an exclamation point that really does end a sentence (usually after an end-of-sentence capital letter). @xref{Ending a Sentence}. @item @@" @itemx @@' Generate an umlaut or acute accent, respectively, over the next character, as in @"o and @'o. @xref{Inserting Accents}. @item @@* Force a line break. Do not end a paragraph that uses @code{@@*} with an @code{@@refill} command. @xref{Line Breaks}.@refill @item @@,@{@var{c}@} Generate a cedilla accent under @var{c}, as in @,{c}. @xref{Inserting Accents}. @item @@- Insert a discretionary hyphenation point. @xref{- and hyphenation}. @item @@. Produce a period that really does end a sentence (usually after an end-of-sentence capital letter). @xref{Ending a Sentence}. @item @@: Indicate to @TeX{} that an immediately preceding period, question mark, exclamation mark, or colon does not end a sentence. Prevent @TeX{} from inserting extra whitespace as it does at the end of a sentence. The command has no effect on the Info file output. @xref{Not Ending a Sentence}.@refill @item @@= Generate a macro (bar) accent over the next character, as in @=o. @xref{Inserting Accents}. @item @@? Generate a question mark that really does end a sentence (usually after an end-of-sentence capital letter). @xref{Ending a Sentence}. @item @@@@ Stands for an at sign, @samp{@@}. @xref{Braces Atsigns, , Inserting @@ and braces}. @item @@^ @itemx @@` Generate a circumflex (hat) or grave accent, respectively, over the next character, as in @^o. @xref{Inserting Accents}. @item @@@{ Stands for a left brace, @samp{@{}. @xref{Braces Atsigns, , Inserting @@ and braces}. @item @@@} Stands for a right-hand brace, @samp{@}}.@* @xref{Braces Atsigns, , Inserting @@ and braces}. @item @@= Generate a tilde accent over the next character, as in @~N. @xref{Inserting Accents}. @item @@AA@{@} @itemx @@aa@{@} Generate the uppercase and lowercase Scandinavian A-ring letters, respectively: @AA{}, @aa{}. @xref{Inserting Accents}. @item @@AE@{@} @itemx @@ae@{@} Generate the uppercase and lowercase AE ligatures, respectively: @AE{}, @ae{}. @xref{Inserting Accents}. @item @@afourpaper Change page dimensions for the A4 paper size. Only allowed inside @code{@@iftex} @dots{} @code{@@end iftex}. @xref{A4 Paper}. @item @@appendix @var{title} Begin an appendix. The title appears in the table of contents of a printed manual. In Info, the title is underlined with asterisks. @xref{unnumbered & appendix, , The @code{@@unnumbered} and @code{@@appendix} Commands}.@refill @item @@appendixsec @var{title} @itemx @@appendixsection @var{title} Begin an appendix section within an appendix. The section title appears in the table of contents of a printed manual. In Info, the title is underlined with equal signs. @code{@@appendixsection} is a longer spelling of the @code{@@appendixsec} command. @xref{unnumberedsec appendixsec heading, , Section Commands}.@refill @item @@appendixsubsec @var{title} Begin an appendix subsection within an appendix. The title appears in the table of contents of a printed manual. In Info, the title is underlined with hyphens. @xref{unnumberedsubsec appendixsubsec subheading, , Subsection Commands}.@refill @item @@appendixsubsubsec @var{title} Begin an appendix subsubsection within an appendix subsection. The title appears in the table of contents of a printed manual. In Info, the title is underlined with periods. @xref{subsubsection,, The `subsub' Commands}.@refill @item @@asis Used following @code{@@table}, @code{@@ftable}, and @code{@@vtable} to print the table's first column without highlighting (``as is''). @xref{Two-column Tables, , Making a Two-column Table}.@refill @item @@author @var{author} Typeset @var{author} flushleft and underline it. @xref{title subtitle author, , The @code{@@title} and @code{@@author} Commands}.@refill @item @@b@{@var{text}@} Print @var{text} in @b{bold} font. No effect in Info. @xref{Fonts}.@refill @ignore @item @@br Force a paragraph break. If used within a line, follow @code{@@br} with braces. @xref{br, , @code{@@br}}.@refill @end ignore @item @@bullet@{@} Generate a large round dot, or the closest possible thing to one. @xref{bullet, , @code{@@bullet}}.@refill @item @@bye Stop formatting a file. The formatters do not see the contents of a file following an @code{@@bye} command. @xref{Ending a File}.@refill @item @@c @var{comment} Begin a comment in Texinfo. The rest of the line does not appear in either the Info file or the printed manual. A synonym for @code{@@comment}. @xref{Comments, , Comments}.@refill @item @@cartouche Highlight an example or quotation by drawing a box with rounded corners around it. Pair with @code{@@end cartouche}. No effect in Info. @xref{cartouche, , Drawing Cartouches Around Examples}.)@refill @item @@center @var{line-of-text} Center the line of text following the command. @xref{titlefont center sp, , @code{@@center}}.@refill @item @@centerchap @var{line-of-text} Like @code{@@chapter}, but centers the chapter title. @xref{chapter,, @code{@@chapter}}. @item @@chapheading @var{title} Print a chapter-like heading in the text, but not in the table of contents of a printed manual. In Info, the title is underlined with asterisks. @xref{majorheading & chapheading, , @code{@@majorheading} and @code{@@chapheading}}.@refill @item @@chapter @var{title} Begin a chapter. The chapter title appears in the table of contents of a printed manual. In Info, the title is underlined with asterisks. @xref{chapter, , @code{@@chapter}}.@refill @item @@cindex @var{entry} Add @var{entry} to the index of concepts. @xref{Index Entries, , Defining the Entries of an Index}.@refill @item @@cite@{@var{reference}@} Highlight the name of a book or other reference that lacks a companion Info file. @xref{cite, , @code{@@cite}}.@refill @item @@clear @var{flag} Unset @var{flag}, preventing the Texinfo formatting commands from formatting text between subsequent pairs of @code{@@ifset @var{flag}} and @code{@@end ifset} commands, and preventing @code{@@value@{@var{flag}@}} from expanding to the value to which @var{flag} is set. @xref{set clear value, , @code{@@set} @code{@@clear} @code{@@value}}.@refill @item @@code@{@var{sample-code}@} Highlight text that is an expression, a syntactically complete token of a program, or a program name. @xref{code, , @code{@@code}}.@refill @item @@comment @var{comment} Begin a comment in Texinfo. The rest of the line does not appear in either the Info file or the printed manual. A synonym for @code{@@c}. @xref{Comments, , Comments}.@refill @item @@contents Print a complete table of contents. Has no effect in Info, which uses menus instead. @xref{Contents, , Generating a Table of Contents}.@refill @item @@copyright@{@} Generate a copyright symbol. @xref{copyright symbol, , @code{@@copyright}}.@refill @ignore @item @@ctrl@{@var{ctrl-char}@} Describe an @sc{ascii} control character. Insert actual control character into Info file. @xref{ctrl, , @code{@@ctrl}}.@refill @end ignore @item @@defcodeindex @var{index-name} Define a new index and its indexing command. Print entries in an @code{@@code} font. @xref{New Indices, , Defining New Indices}.@refill @item @@defcv @var{category} @var{class} @var{name} @itemx @@defcvx @var{category} @var{class} @var{name} Format a description for a variable associated with a class in object-oriented programming. Takes three arguments: the category of thing being defined, the class to which it belongs, and its name. @xref{Definition Commands}, and @ref{deffnx,, Def Cmds in Detail}. @item @@deffn @var{category} @var{name} @var{arguments}@dots{} @itemx @@deffnx @var{category} @var{name} @var{arguments}@dots{} Format a description for a function, interactive command, or similar entity that may take arguments. @code{@@deffn} takes as arguments the category of entity being described, the name of this particular entity, and its arguments, if any. @xref{Definition Commands}.@refill @item @@defindex @var{index-name} Define a new index and its indexing command. Print entries in a roman font. @xref{New Indices, , Defining New Indices}.@refill @c Unused so far as I can see and unsupported by makeinfo -- karl, 15sep96. @item @@definfoenclose @var{new-command}, @var{before}, @var{after}, Create new @@-command for Info that marks text by enclosing it in strings that precede and follow the text. Write definition inside of @code{@@ifinfo} @dots{} @code{@@end ifinfo}. @xref{Customized Highlighting}.@refill @item @@defivar @var{class} @var{instance-variable-name} @itemx @@defivarx @var{class} @var{instance-variable-name} This command formats a description for an instance variable in object-oriented programming. The command is equivalent to @samp{@@defcv @{Instance Variable@} @dots{}}. @xref{Definition Commands}, and @ref{deffnx,, Def Cmds in Detail}. @item @@defmac @var{macro-name} @var{arguments}@dots{} @itemx @@defmacx @var{macro-name} @var{arguments}@dots{} Format a description for a macro. The command is equivalent to @samp{@@deffn Macro @dots{}}. @xref{Definition Commands}, and @ref{deffnx,, Def Cmds in Detail}. @item @@defmethod @var{class} @var{method-name} @var{arguments}@dots{} @itemx @@defmethodx @var{class} @var{method-name} @var{arguments}@dots{} Format a description for a method in object-oriented programming. The command is equivalent to @samp{@@defop Method @dots{}}. Takes as arguments the name of the class of the method, the name of the method, and its arguments, if any. @xref{Definition Commands}, and @ref{deffnx,, Def Cmds in Detail}. @item @@defop @var{category} @var{class} @var{name} @var{arguments}@dots{} @itemx @@defopx @var{category} @var{class} @var{name} @var{arguments}@dots{} Format a description for an operation in object-oriented programming. @code{@@defop} takes as arguments the overall name of the category of operation, the name of the class of the operation, the name of the operation, and its arguments, if any. @xref{Definition Commands}, and @ref{deffnx,, Def Cmds in Detail}. @item @@defopt @var{option-name} @itemx @@defoptx @var{option-name} Format a description for a user option. The command is equivalent to @samp{@@defvr @{User Option@} @dots{}}. @xref{Definition Commands}, and @ref{deffnx,, Def Cmds in Detail}. @item @@defspec @var{special-form-name} @var{arguments}@dots{} @itemx @@defspecx @var{special-form-name} @var{arguments}@dots{} Format a description for a special form. The command is equivalent to @samp{@@deffn @{Special Form@} @dots{}}. @xref{Definition Commands}, and @ref{deffnx,, Def Cmds in Detail}. @item @@deftp @var{category} @var{name-of-type} @var{attributes}@dots{} @itemx @@deftpx @var{category} @var{name-of-type} @var{attributes}@dots{} Format a description for a data type. @code{@@deftp} takes as arguments the category, the name of the type (which is a word like @samp{int} or @samp{float}), and then the names of attributes of objects of that type. @xref{Definition Commands}, and @ref{deffnx,, Def Cmds in Detail}. @item @@deftypefn @var{classification} @var{data-type} @var{name} @var{arguments}@dots{} @itemx @@deftypefnx @var{classification} @var{data-type} @var{name} @var{arguments}@dots{} Format a description for a function or similar entity that may take arguments and that is typed. @code{@@deftypefn} takes as arguments the classification of entity being described, the type, the name of the entity, and its arguments, if any. @xref{Definition Commands}, and @ref{deffnx,, Def Cmds in Detail}. @item @@deftypefun @var{data-type} @var{function-name} @var{arguments}@dots{} @itemx @@deftypefunx @var{data-type} @var{function-name} @var{arguments}@dots{} Format a description for a function in a typed language. The command is equivalent to @samp{@@deftypefn Function @dots{}}. @xref{Definition Commands}, and @ref{deffnx,, Def Cmds in Detail}. @item @@deftypemethod @var{class} @var{data-type} @var{method-name} @var{arguments}@dots{} @itemx @@deftypemethodx @var{class} @var{data-type} @var{method-name} @var{arguments}@dots{} Format a description for a typed method in object-oriented programming. Takes as arguments the name of the class of the method, the return type of the method, the name of the method, and its arguments, if any. @xref{Definition Commands}, and @ref{deffnx,, Def Cmds in Detail}. @item @@deftypevr @var{classification} @var{data-type} @var{name} @itemx @@deftypevrx @var{classification} @var{data-type} @var{name} Format a description for something like a variable in a typed language---an entity that records a value. Takes as arguments the classification of entity being described, the type, and the name of the entity. @xref{Definition Commands}, and @ref{deffnx,, Def Cmds in Detail}. @item @@deftypevar @var{data-type} @var{variable-name} @itemx @@deftypevarx @var{data-type} @var{variable-name} Format a description for a variable in a typed language. The command is equivalent to @samp{@@deftypevr Variable @dots{}}. @xref{Definition Commands}, and @ref{deffnx,, Def Cmds in Detail}. @item @@defun @var{function-name} @var{arguments}@dots{} @itemx @@defunx @var{function-name} @var{arguments}@dots{} Format a description for functions. The command is equivalent to @samp{@@deffn Function @dots{}}. @xref{Definition Commands}, and @ref{deffnx,, Def Cmds in Detail}. @item @@defvar @var{variable-name} @itemx @@defvarx @var{variable-name} Format a description for variables. The command is equivalent to @samp{@@defvr Variable @dots{}}. @xref{Definition Commands}, and @ref{deffnx,, Def Cmds in Detail}. @item @@defvr @var{category} @var{name} @itemx @@defvrx @var{category} @var{name} Format a description for any kind of variable. @code{@@defvr} takes as arguments the category of the entity and the name of the entity. @xref{Definition Commands}, and @ref{deffnx,, Def Cmds in Detail}. @item @@detailmenu@{@} Avoid @code{makeinfo} confusion stemming from the detailed node listing in a master menu. @xref{Master Menu Parts}. @item @@dfn@{@var{term}@} Highlight the introductory or defining use of a term. @xref{dfn, , @code{@@dfn}}.@refill @item @@dircategory @var{dirpart} Specify a part of the Info directory menu where this file's entry should go. @xref{Installing Dir Entries}. @item @@direntry Begin the Info directory menu entry for this file. @xref{Installing Dir Entries}. @need 100 @item @@display Begin a kind of example. Indent text, do not fill, do not select a new font. Pair with @code{@@end display}. @xref{display, , @code{@@display}}.@refill @item @@dmn@{@var{dimension}@} Format a unit of measure, as in 12@dmn{pt}. Causes @TeX{} to insert a thin space before @var{dimension}. No effect in Info. @xref{dmn, , @code{@@dmn}}.@refill @item @@dotaccent@{@var{c}@} Generate a dot accent over the character @var{c}, as in @dotaccent{oo}. @xref{Inserting Accents}. @item @@dots@{@} Insert an ellipsis: @samp{@dots{}}. @xref{dots, , @code{@@dots}}.@refill @item @@email@{@var{address}[, @var{displayed-text}]@} Indicate an electronic mail address. @xref{email, , @code{@@email}}.@refill @need 100 @item @@emph@{@var{text}@} Highlight @var{text}; text is displayed in @emph{italics} in printed output, and surrounded by asterisks in Info. @xref{Emphasis, , Emphasizing Text}. @item @@end @var{environment} Ends @var{environment}, as in @samp{@@end example}. @xref{Formatting Commands,,@@-commands}. @item @@enddots@{@} Generate an end-of-sentence of ellipsis, like this @enddots{} @xref{dots,,@code{@@dots@{@}}}. @need 100 @item @@enumerate [@var{number-or-letter}] Begin a numbered list, using @code{@@item} for each entry. Optionally, start list with @var{number-or-letter}. Pair with @code{@@end enumerate}. @xref{enumerate, , @code{@@enumerate}}.@refill @need 100 @item @@equiv@{@} Indicate to the reader the exact equivalence of two forms with a glyph: @samp{@equiv{}}. @xref{Equivalence}.@refill @item @@error@{@} Indicate to the reader with a glyph that the following text is an error message: @samp{@error{}}. @xref{Error Glyph}.@refill @item @@evenfooting [@var{left}] @@| [@var{center}] @@| [@var{right}] @itemx @@evenheading [@var{left}] @@| [@var{center}] @@| [@var{right}] Specify page footings resp.@: headings for even-numbered (left-hand) pages. Only allowed inside @code{@@iftex}. @xref{Custom Headings, , How to Make Your Own Headings}.@refill @item @@everyfooting [@var{left}] @@| [@var{center}] @@| [@var{right}] @itemx @@everyheading [@var{left}] @@| [@var{center}] @@| [@var{right}] Specify page footings resp.@: headings for every page. Not relevant to Info. @xref{Custom Headings, , How to Make Your Own Headings}.@refill @item @@example Begin an example. Indent text, do not fill, and select fixed-width font. Pair with @code{@@end example}. @xref{example, , @code{@@example}}.@refill @item @@exclamdown@{@} Produce an upside-down exclamation point. @xref{Inserting Accents}. @item @@exdent @var{line-of-text} Remove any indentation a line might have. @xref{exdent, , Undoing the Indentation of a Line}.@refill @item @@expansion@{@} Indicate the result of a macro expansion to the reader with a special glyph: @samp{@expansion{}}. @xref{expansion, , @expansion{} Indicating an Expansion}.@refill @item @@file@{@var{filename}@} Highlight the name of a file, buffer, node, or directory. @xref{file, , @code{@@file}}.@refill @item @@finalout Prevent @TeX{} from printing large black warning rectangles beside over-wide lines. @xref{Overfull hboxes}.@refill @need 100 @item @@findex @var{entry} Add @var{entry} to the index of functions. @xref{Index Entries, , Defining the Entries of an Index}.@refill @need 200 @item @@flushleft @itemx @@flushright Left justify every line but leave the right end ragged. Leave font as is. Pair with @code{@@end flushleft}. @code{@@flushright} analogous. @xref{flushleft & flushright, , @code{@@flushleft} and @code{@@flushright}}.@refill @need 200 @item @@footnote@{@var{text-of-footnote}@} Enter a footnote. Footnote text is printed at the bottom of the page by @TeX{}; Info may format in either `End' node or `Separate' node style. @xref{Footnotes}.@refill @item @@footnotestyle @var{style} Specify an Info file's footnote style, either @samp{end} for the end node style or @samp{separate} for the separate node style. @xref{Footnotes}.@refill @item @@format Begin a kind of example. Like @code{@@example} or @code{@@display}, but do not narrow the margins and do not select the fixed-width font. Pair with @code{@@end format}. @xref{example, , @code{@@example}}.@refill @item @@ftable @var{formatting-command} Begin a two-column table, using @code{@@item} for each entry. Automatically enter each of the items in the first column into the index of functions. Pair with @code{@@end ftable}. The same as @code{@@table}, except for indexing. @xref{ftable vtable, , @code{@@ftable} and @code{@@vtable}}.@refill @item @@group Hold text together that must appear on one printed page. Pair with @code{@@end group}. Not relevant to Info. @xref{group, , @code{@@group}}.@refill @item @@H@{@var{c}@} Generate the long Hungarian umlaut accent over @var{c}, as in @H{o}. @item @@heading @var{title} Print an unnumbered section-like heading in the text, but not in the table of contents of a printed manual. In Info, the title is underlined with equal signs. @xref{unnumberedsec appendixsec heading, , Section Commands}.@refill @item @@headings @var{on-off-single-double} Turn page headings on or off, and/or specify single-sided or double-sided page headings for printing. @xref{headings on off, , The @code{@@headings} Command}. @item @@html Enter HTML completely. Pair with @code{@@end html}. @xref{Raw Formatter Commands}. @item @@hyphenation@{@var{hy-phen-a-ted words}@} Explicitly define hyphenation points. @xref{- and hyphenation,, @code{@@-} and @code{@@hyphenation}}. @item @@i@{@var{text}@} Print @var{text} in @i{italic} font. No effect in Info. @xref{Fonts}.@refill @item @@ifclear @var{flag} If @var{flag} is cleared, the Texinfo formatting commands format text between @code{@@ifclear @var{flag}} and the following @code{@@end ifclear} command. @xref{set clear value, , @code{@@set} @code{@@clear} @code{@@value}}.@refill @item @@ifhtml @itemx @@ifinfo Begin a stretch of text that will be ignored by @TeX{} when it typesets the printed manual. The text appears only in the HTML resp.@: Info file. Pair with @code{@@end ifhtml} resp.@: @code{@@end ifinfo}. @xref{Conditionals}. @item @@ifnothtml @itemx @@ifnotinfo @itemx @@ifnottex Begin a stretch of text that will be ignored in one output format but not the others. The text appears only in the format not specified. Pair with @code{@@end ifnothtml} resp.@: @code{@@end ifnotinfo} resp.@: @code{@@end ifnotinfo}. @xref{Conditionals}. @item @@ifset @var{flag} If @var{flag} is set, the Texinfo formatting commands format text between @code{@@ifset @var{flag}} and the following @code{@@end ifset} command. @xref{set clear value, , @code{@@set} @code{@@clear} @code{@@value}}.@refill @item @@iftex Begin a stretch of text that will not appear in the Info file, but will be processed only by @TeX{}. Pair with @code{@@end iftex}. @xref{Conditionals, , Conditionally Visible Text}.@refill @item @@ignore Begin a stretch of text that will not appear in either the Info file or the printed output. Pair with @code{@@end ignore}. @xref{Comments, , Comments and Ignored Text}.@refill @item @@image@{@var{filename}, [@var{width}], [@var{height}]@} Include graphics image in external @var{filename} scaled to the given @var{width} and/or @var{height}. @xref{Images}. @item @@include @var{filename} Incorporate the contents of the file @var{filename} into the Info file or printed document. @xref{Include Files}.@refill @item @@inforef@{@var{node-name}, [@var{entry-name}], @var{info-file-name}@} Make a cross reference to an Info file for which there is no printed manual. @xref{inforef, , Cross references using @code{@@inforef}}.@refill @item \input @var{macro-definitions-file} Use the specified macro definitions file. This command is used only in the first line of a Texinfo file to cause @TeX{} to make use of the @file{texinfo} macro definitions file. The backslash in @code{\input} is used instead of an @code{@@} because @TeX{} does not recognize @code{@@} until after it has read the definitions file. @xref{Header, , The Texinfo File Header}.@refill @item @@item Indicate the beginning of a marked paragraph for @code{@@itemize} and @code{@@enumerate}; indicate the beginning of the text of a first column entry for @code{@@table}, @code{@@ftable}, and @code{@@vtable}. @xref{Lists and Tables}.@refill @item @@itemize @var{mark-generating-character-or-command} Produce a sequence of indented paragraphs, with a mark inside the left margin at the beginning of each paragraph. Pair with @code{@@end itemize}. @xref{itemize, , @code{@@itemize}}.@refill @item @@itemx Like @code{@@item} but do not generate extra vertical space above the item text. @xref{itemx, , @code{@@itemx}}.@refill @item @@kbd@{@var{keyboard-characters}@} Indicate text that is characters of input to be typed by users. @xref{kbd, , @code{@@kbd}}.@refill @item @@kbdinputstyle @var{style} Specify when @code{@@kbd} should use a font distinct from @code{@@code}. @xref{kbd, , @code{@@kbd}}.@refill @item @@key@{@var{key-name}@} Indicate a name for a key on a keyboard. @xref{key, , @code{@@key}}.@refill @item @@kindex @var{entry} Add @var{entry} to the index of keys. @xref{Index Entries, , Defining the Entries of an Index}.@refill @item @@L@{@} @itemx @@l@{@} Generate the uppercase and lowercase Polish suppressed-L letters, respectively: @L{}, @l{}. @c Possibly this can be tossed now that we have macros. --karl, 16sep96. @c Yes, let's toss it, it's pretty weird. --karl, 15jun97. @c @item @@global@@let@var{new-command}=@var{existing-command} @c Equate a new highlighting command with an existing one. Only for @c @TeX{}. Write definition inside of @code{@@iftex} @dots{} @code{@@end @c iftex}. @xref{Customized Highlighting}.@refill @item @@lisp Begin an example of Lisp code. Indent text, do not fill, and select fixed-width font. Pair with @code{@@end lisp}. @xref{Lisp Example, , @code{@@lisp}}.@refill @item @@lowersections Change subsequent chapters to sections, sections to subsections, and so on. @xref{Raise/lower sections, , @code{@@raisesections} and @code{@@lowersections}}.@refill @item @@macro @var{macro-name} @{@var{params}@} Define a new Texinfo command @code{@@@var{macro-name}@{@var{params}@}}. Only supported by @code{makeinfo} and @code{texi2dvi}. @xref{Defining Macros}. @item @@majorheading @var{title} Print a chapter-like heading in the text, but not in the table of contents of a printed manual. Generate more vertical whitespace before the heading than the @code{@@chapheading} command. In Info, the chapter heading line is underlined with asterisks. @xref{majorheading & chapheading, , @code{@@majorheading} and @code{@@chapheading}}.@refill @item @@math@{@var{mathematical-expression}@} Format a mathematical expression. @xref{math, , @code{@@math}: Inserting Mathematical Expressions}. @item @@menu Mark the beginning of a menu of nodes in Info. No effect in a printed manual. Pair with @code{@@end menu}. @xref{Menus}.@refill @item @@minus@{@} Generate a minus sign, `@minus{}'. @xref{minus, , @code{@@minus}}.@refill @item @@multitable @var{column-width-spec} Begin a multi-column table. Pair with @code{@@end multitable}. @xref{Multitable Column Widths}. @item @@need @var{n} Start a new page in a printed manual if fewer than @var{n} mils (thousandths of an inch) remain on the current page. @xref{need, , @code{@@need}}.@refill @item @@node @var{name, next, previous, up} Define the beginning of a new node in Info, and serve as a locator for references for @TeX{}. @xref{node, , @code{@@node}}.@refill @item @@noindent Prevent text from being indented as if it were a new paragraph. @xref{noindent, , @code{@@noindent}}.@refill @item @@O@{@} @itemx @@o@{@} Generate the uppercase and lowercase O-with-slash letters, respectively: @O{}, @o{}. @item @@oddfooting [@var{left}] @@| [@var{center}] @@| [@var{right}] @itemx @@oddheading [@var{left}] @@| [@var{center}] @@| [@var{right}] Specify page footings resp.@: headings for odd-numbered (right-hand) pages. Only allowed inside @code{@@iftex}. @xref{Custom Headings, , How to Make Your Own Headings}.@refill @item @@OE@{@} @itemx @@oe@{@} Generate the uppercase and lowercase OE ligatures, respectively: @OE{}, @oe{}. @xref{Inserting Accents}. @item @@page Start a new page in a printed manual. No effect in Info. @xref{page, , @code{@@page}}.@refill @item @@paragraphindent @var{indent} Indent paragraphs by @var{indent} number of spaces; delete indentation if the value of @var{indent} is 0; and do not change indentation if @var{indent} is @code{asis}. @xref{paragraphindent, , Paragraph Indenting}.@refill @item @@pindex @var{entry} Add @var{entry} to the index of programs. @xref{Index Entries, , Defining the Entries of an Index}.@refill @item @@point@{@} Indicate the position of point in a buffer to the reader with a glyph: @samp{@point{}}. @xref{Point Glyph, , Indicating Point in a Buffer}.@refill @item @@pounds@{@} Generate the pounds sterling currency sign. @xref{pounds,,@code{@@pounds@{@}}}. @item @@print@{@} Indicate printed output to the reader with a glyph: @samp{@print{}}. @xref{Print Glyph}.@refill @item @@printindex @var{index-name} Print an alphabetized two-column index in a printed manual or generate an alphabetized menu of index entries for Info. @xref{Printing Indices & Menus}.@refill @item @@pxref@{@var{node-name}, [@var{entry}], [@var{topic-or-title}], [@var{info-file}], [@var{manual}]@} Make a reference that starts with a lower case `see' in a printed manual. Use within parentheses only. Do not follow command with a punctuation mark---the Info formatting commands automatically insert terminating punctuation as needed. Only the first argument is mandatory. @xref{pxref, , @code{@@pxref}}.@refill @item @@questiondown@{@} Generate an upside-down question mark. @xref{Inserting Accents}. @item @@quotation Narrow the margins to indicate text that is quoted from another real or imaginary work. Write command on a line of its own. Pair with @code{@@end quotation}. @xref{quotation, , @code{@@quotation}}.@refill @need 100 @item @@r@{@var{text}@} Print @var{text} in @r{roman} font. No effect in Info. @xref{Fonts}.@refill @item @@raisesections Change subsequent sections to chapters, subsections to sections, and so on. @xref{Raise/lower sections, , @code{@@raisesections} and @code{@@lowersections}}.@refill @need 300 @item @@ref@{@var{node-name}, [@var{entry}], [@var{topic-or-title}], [@var{info-file}], [@var{manual}]@} Make a reference. In a printed manual, the reference does not start with a `See'. Follow command with a punctuation mark. Only the first argument is mandatory. @xref{ref, , @code{@@ref}}.@refill @need 300 @item @@refill In Info, refill and indent the paragraph after all the other processing has been done. No effect on @TeX{}, which always refills. This command is no longer needed, since all formatters now automatically refill. @xref{Refilling Paragraphs}.@refill @need 300 @item @@result@{@} Indicate the result of an expression to the reader with a special glyph: @samp{@result{}}. @xref{result, , @code{@@result}}.@refill @item @@ringaccent@{@var{c}@} Generate a ring accent over the next character, as in @ringaccent{o}. @xref{Inserting Accents}. @item @@samp@{@var{text}@} Highlight @var{text} that is a literal example of a sequence of characters. Used for single characters, for statements, and often for entire shell commands. @xref{samp, , @code{@@samp}}.@refill @item @@sc@{@var{text}@} Set @var{text} in a printed output in @sc{the small caps font} and set text in the Info file in uppercase letters. @xref{Smallcaps}.@refill @item @@section @var{title} Begin a section within a chapter. In a printed manual, the section title is numbered and appears in the table of contents. In Info, the title is underlined with equal signs. @xref{section, , @code{@@section}}.@refill @item @@set @var{flag} [@var{string}] Make @var{flag} active, causing the Texinfo formatting commands to format text between subsequent pairs of @code{@@ifset @var{flag}} and @code{@@end ifset} commands. Optionally, set value of @var{flag} to @var{string}. @xref{set clear value, , @code{@@set} @code{@@clear} @code{@@value}}.@refill @item @@setchapternewpage @var{on-off-odd} Specify whether chapters start on new pages, and if so, whether on odd-numbered (right-hand) new pages. @xref{setchapternewpage, , @code{@@setchapternewpage}}.@refill @item @@setfilename @var{info-file-name} Provide a name to be used by the Info file. This command is essential for @TeX{} formatting as well, even though it produces no output. @xref{setfilename, , @code{@@setfilename}}.@refill @item @@settitle @var{title} Provide a title for page headers in a printed manual. @xref{settitle, , @code{@@settitle}}.@refill @item @@shortcontents Print a short table of contents. Not relevant to Info, which uses menus rather than tables of contents. A synonym for @code{@@summarycontents}. @xref{Contents, , Generating a Table of Contents}.@refill @item @@shorttitlepage@{@var{title}@} Generate a minimal title page. @xref{titlepage,,@code{@@titlepage}}. @need 400 @item @@smallbook Cause @TeX{} to produce a printed manual in a 7 by 9.25 inch format rather than the regular 8.5 by 11 inch format. @xref{smallbook, , Printing Small Books}. Also, see @ref{smallexample & smalllisp, , @code{@@smallexample} and @code{@@smalllisp}}.@refill @need 400 @item @@smallexample Indent text to indicate an example. Do not fill, select fixed-width font. In @code{@@smallbook} format, print text in a smaller font than with @code{@@example}. Pair with @code{@@end smallexample}. @xref{smallexample & smalllisp, , @code{@@smallexample} and @code{@@smalllisp}}.@refill @need 400 @item @@smalllisp Begin an example of Lisp code. Indent text, do not fill, select fixed-width font. In @code{@@smallbook} format, print text in a smaller font. Pair with @code{@@end smalllisp}. @xref{smallexample & smalllisp, , @code{@@smallexample} and @code{@@smalllisp}}.@refill @need 700 @item @@sp @var{n} Skip @var{n} blank lines. @xref{sp, , @code{@@sp}}.@refill @item @@ss@{@} Generate the German sharp-S es-zet letter, @ss{}. @xref{Inserting Accents}. @need 700 @item @@strong @var{text} Emphasize @var{text} by typesetting it in a @strong{bold} font for the printed manual and by surrounding it with asterisks for Info. @xref{emph & strong, , Emphasizing Text}.@refill @item @@subheading @var{title} Print an unnumbered subsection-like heading in the text, but not in the table of contents of a printed manual. In Info, the title is underlined with hyphens. @xref{unnumberedsubsec appendixsubsec subheading, , @code{@@unnumberedsubsec} @code{@@appendixsubsec} @code{@@subheading}}.@refill @item @@subsection @var{title} Begin a subsection within a section. In a printed manual, the subsection title is numbered and appears in the table of contents. In Info, the title is underlined with hyphens. @xref{subsection, , @code{@@subsection}}.@refill @item @@subsubheading @var{title} Print an unnumbered subsubsection-like heading in the text, but not in the table of contents of a printed manual. In Info, the title is underlined with periods. @xref{subsubsection, , The `subsub' Commands}.@refill @item @@subsubsection @var{title} Begin a subsubsection within a subsection. In a printed manual, the subsubsection title is numbered and appears in the table of contents. In Info, the title is underlined with periods. @xref{subsubsection, , The `subsub' Commands}.@refill @item @@subtitle @var{title} In a printed manual, set a subtitle in a normal sized font flush to the right-hand side of the page. Not relevant to Info, which does not have title pages. @xref{title subtitle author, , @code{@@title} @code{@@subtitle} and @code{@@author} Commands}.@refill @item @@summarycontents Print a short table of contents. Not relevant to Info, which uses menus rather than tables of contents. A synonym for @code{@@shortcontents}. @xref{Contents, , Generating a Table of Contents}.@refill @need 300 @item @@syncodeindex @var{from-index} @var{into-index} Merge the index named in the first argument into the index named in the second argument, printing the entries from the first index in @code{@@code} font. @xref{Combining Indices}.@refill @need 300 @item @@synindex @var{from-index} @var{into-index} Merge the index named in the first argument into the index named in the second argument. Do not change the font of @var{from-index} entries. @xref{Combining Indices}.@refill @need 100 @item @@t@{@var{text}@} Print @var{text} in a @t{fixed-width}, typewriter-like font. No effect in Info. @xref{Fonts}.@refill @item @@tab Separate columns in a multitable. @xref{Multitable Rows}. @need 400 @item @@table @var{formatting-command} Begin a two-column table, using @code{@@item} for each entry. Write each first column entry on the same line as @code{@@item}. First column entries are printed in the font resulting from @var{formatting-command}. Pair with @code{@@end table}. @xref{Two-column Tables, , Making a Two-column Table}. Also see @ref{ftable vtable, , @code{@@ftable} and @code{@@vtable}}, and @ref{itemx, , @code{@@itemx}}.@refill @item @@TeX@{@} Insert the logo @TeX{}. @xref{TeX and copyright, , Inserting @TeX{} and @copyright{}}.@refill @item @@tex Enter @TeX{} completely. Pair with @code{@@end tex}. @xref{Raw Formatter Commands}. @item @@thischapter @itemx @@thischaptername @itemx @@thisfile @itemx @@thispage @itemx @@thistitle Only allowed in a heading or footing. Stands for the number and name of the current chapter (in the format `Chapter 1: Title'), the chapter name only, the filename, the current page number, and the title of the document, respectively. @xref{Custom Headings, , How to Make Your Own Headings}.@refill @item @@tieaccent@{@var{cc}@} Generate a tie-after accent over the next two characters @var{cc}, as in `@tieaccent{oo}'. @xref{Inserting Accents}. @item @@tindex @var{entry} Add @var{entry} to the index of data types. @xref{Index Entries, , Defining the Entries of an Index}.@refill @item @@title @var{title} In a printed manual, set a title flush to the left-hand side of the page in a larger than normal font and underline it with a black rule. Not relevant to Info, which does not have title pages. @xref{title subtitle author, , The @code{@@title} @code{@@subtitle} and @code{@@author} Commands}.@refill @need 400 @item @@titlefont@{@var{text}@} In a printed manual, print @var{text} in a larger than normal font. Not relevant to Info, which does not have title pages. @xref{titlefont center sp, , The @code{@@titlefont} @code{@@center} and @code{@@sp} Commands}.@refill @need 300 @item @@titlepage Indicate to Texinfo the beginning of the title page. Write command on a line of its own. Pair with @code{@@end titlepage}. Nothing between @code{@@titlepage} and @code{@@end titlepage} appears in Info. @xref{titlepage, , @code{@@titlepage}}.@refill @need 150 @item @@today@{@} Insert the current date, in `1 Jan 1900' style. @xref{Custom Headings, , How to Make Your Own Headings}.@refill @item @@top @var{title} In a Texinfo file to be formatted with @code{makeinfo}, identify the topmost @code{@@node} line in the file, which must be written on the line immediately preceding the @code{@@top} command. Used for @code{makeinfo}'s node pointer insertion feature. The title is underlined with asterisks. Both the @code{@@node} line and the @code{@@top} line normally should be enclosed by @code{@@ifinfo} and @code{@@end ifinfo}. In @TeX{} and @code{texinfo-format-buffer}, the @code{@@top} command is merely a synonym for @code{@@unnumbered}. @xref{makeinfo Pointer Creation, , Creating Pointers with @code{makeinfo}}. @item @@u@{@var{c}@} @itemx @@ubaraccent@{@var{c}@} @itemx @@udotaccent@{@var{c}@} Generate a breve, underbar, or underdot accent, respectively, over or under the character @var{c}, as in @u{o}, @ubaraccent{o}, @udotaccent{o}. @xref{Inserting Accents}. @item @@unnumbered @var{title} In a printed manual, begin a chapter that appears without chapter numbers of any kind. The title appears in the table of contents of a printed manual. In Info, the title is underlined with asterisks. @xref{unnumbered & appendix, , @code{@@unnumbered} and @code{@@appendix}}.@refill @item @@unnumberedsec @var{title} In a printed manual, begin a section that appears without section numbers of any kind. The title appears in the table of contents of a printed manual. In Info, the title is underlined with equal signs. @xref{unnumberedsec appendixsec heading, , Section Commands}.@refill @item @@unnumberedsubsec @var{title} In a printed manual, begin an unnumbered subsection within a chapter. The title appears in the table of contents of a printed manual. In Info, the title is underlined with hyphens. @xref{unnumberedsubsec appendixsubsec subheading, , @code{@@unnumberedsubsec} @code{@@appendixsubsec} @code{@@subheading}}.@refill @item @@unnumberedsubsubsec @var{title} In a printed manual, begin an unnumbered subsubsection within a chapter. The title appears in the table of contents of a printed manual. In Info, the title is underlined with periods. @xref{subsubsection, , The `subsub' Commands}.@refill @item @@uref@{@var{url}[, @var{displayed-text}@} Define a cross reference to an external uniform resource locator for the World Wide Web. @xref{url, , @code{@@url}}.@refill @item @@url@{@var{url}@} Indicate text that is a uniform resource locator for the World Wide Web. @xref{url, , @code{@@url}}.@refill @item @@v@{@var{c}@} Generate check accent over the character @var{c}, as in @v{o}. @xref{Inserting Accents}. @item @@value@{@var{flag}@} Replace @var{flag} with the value to which it is set by @code{@@set @var{flag}}. @xref{set clear value, , @code{@@set} @code{@@clear} @code{@@value}}.@refill @item @@var@{@var{metasyntactic-variable}@} Highlight a metasyntactic variable, which is something that stands for another piece of text. @xref{var, , Indicating Metasyntactic Variables}.@refill @need 400 @item @@vindex @var{entry} Add @var{entry} to the index of variables. @xref{Index Entries, , Defining the Entries of an Index}.@refill @need 400 @item @@vskip @var{amount} In a printed manual, insert whitespace so as to push text on the remainder of the page towards the bottom of the page. Used in formatting the copyright page with the argument @samp{0pt plus 1filll}. (Note spelling of @samp{filll}.) @code{@@vskip} may be used only in contexts ignored for Info. @xref{Copyright & Permissions, , The Copyright Page and Printed Permissions}.@refill @need 400 @item @@vtable @var{formatting-command} Begin a two-column table, using @code{@@item} for each entry. Automatically enter each of the items in the first column into the index of variables. Pair with @code{@@end vtable}. The same as @code{@@table}, except for indexing. @xref{ftable vtable, , @code{@@ftable} and @code{@@vtable}}.@refill @need 400 @item @@w@{@var{text}@} Prevent @var{text} from being split across two lines. Do not end a paragraph that uses @code{@@w} with an @code{@@refill} command. @xref{w, , @code{@@w}}.@refill @need 400 @item @@xref@{@var{node-name}, [@var{entry}], [@var{topic-or-title}], [@var{info-file}], [@var{manual}]@} Make a reference that starts with `See' in a printed manual. Follow command with a punctuation mark. Only the first argument is mandatory. @xref{xref, , @code{@@xref}}.@refill @end table @node Tips, Sample Texinfo File, Command List, Top @appendix Tips and Hints Here are some tips for writing Texinfo documentation:@refill @cindex Tips @cindex Usage tips @cindex Hints @itemize @bullet @item Write in the present tense, not in the past or the future. @item Write actively! For example, write ``We recommend that @dots{}'' rather than ``It is recommended that @dots{}''. @item Use 70 or 72 as your fill column. Longer lines are hard to read. @item Include a copyright notice and copying permissions. @end itemize @subsubheading Index, Index, Index! Write many index entries, in different ways. Readers like indices; they are helpful and convenient. Although it is easiest to write index entries as you write the body of the text, some people prefer to write entries afterwards. In either case, write an entry before the paragraph to which it applies. This way, an index entry points to the first page of a paragraph that is split across pages. Here are more hints we have found valuable: @itemize @bullet @item Write each index entry differently, so each entry refers to a different place in the document. @item Write index entries only where a topic is discussed significantly. For example, it is not useful to index ``debugging information'' in a chapter on reporting bugs. Someone who wants to know about debugging information will certainly not find it in that chapter. @item Consistently capitalize the first word of every concept index entry, or else consistently use lower case. Terse entries often call for lower case; longer entries for capitalization. Whichever case convention you use, please use one or the other consistently! Mixing the two styles looks bad. @item Always capitalize or use upper case for those words in an index for which this is proper, such as names of countries or acronyms. Always use the appropriate case for case-sensitive names, such as those in C or Lisp. @item Write the indexing commands that refer to a whole section immediately after the section command, and write the indexing commands that refer to the paragraph before the paragraph. @need 1000 In the example that follows, a blank line comes after the index entry for ``Leaping'': @example @group @@section The Dog and the Fox @@cindex Jumping, in general @@cindex Leaping @@cindex Dog, lazy, jumped over @@cindex Lazy dog jumped over @@cindex Fox, jumps over dog @@cindex Quick fox jumps over dog The quick brown fox jumps over the lazy dog. @end group @end example @noindent (Note that the example shows entries for the same concept that are written in different ways---@samp{Lazy dog}, and @samp{Dog, lazy}---so readers can look up the concept in different ways.) @end itemize @subsubheading Blank Lines @itemize @bullet @item Insert a blank line between a sectioning command and the first following sentence or paragraph, or between the indexing commands associated with the sectioning command and the first following sentence or paragraph, as shown in the tip on indexing. Otherwise, a formatter may fold title and paragraph together. @item Always insert a blank line before an @code{@@table} command and after an @code{@@end table} command; but never insert a blank line after an @code{@@table} command or before an @code{@@end table} command. @need 1000 For example, @example @group Types of fox: @@table @@samp @@item Quick Jump over lazy dogs. @end group @group @@item Brown Also jump over lazy dogs. @@end table @end group @group @@noindent On the other hand, @dots{} @end group @end example Insert blank lines before and after @code{@@itemize} @dots{} @code{@@end itemize} and @code{@@enumerate} @dots{} @code{@@end enumerate} in the same way. @end itemize @subsubheading Complete Phrases Complete phrases are easier to read than @dots{} @itemize @bullet @item Write entries in an itemized list as complete sentences; or at least, as complete phrases. Incomplete expressions @dots{} awkward @dots{} like this. @item Write the prefatory sentence or phrase for a multi-item list or table as a complete expression. Do not write ``You can set:''; instead, write ``You can set these variables:''. The former expression sounds cut off. @end itemize @subsubheading Editions, Dates and Versions Write the edition and version numbers and date in three places in every manual: @enumerate @item In the first @code{@@ifinfo} section, for people reading the Texinfo file. @item In the @code{@@titlepage} section, for people reading the printed manual. @item In the `Top' node, for people reading the Info file. @end enumerate @noindent Also, it helps to write a note before the first @code{@@ifinfo} section to explain what you are doing. @need 800 @noindent For example: @example @group @@c ===> NOTE! <== @@c Specify the edition and version numbers and date @@c in *three* places: @@c 1. First ifinfo section 2. title page 3. top node @@c To find the locations, search for !!set @end group @group @@ifinfo @@c !!set edition, date, version This is Edition 4.03, January 1992, of the @@cite@{GDB Manual@} for GDB Version 4.3. @dots{} @end group @end example @noindent ---or use @code{@@set} and @code{@@value} (@pxref{value Example, , @code{@@value} Example}). @subsubheading Definition Commands Definition commands are @code{@@deffn}, @code{@@defun}, @code{@@defmac}, and the like, and enable you to write descriptions in a uniform format.@refill @itemize @bullet @item Write just one definition command for each entity you define with a definition command. The automatic indexing feature creates an index entry that leads the reader to the definition. @item Use @code{@@table} @dots{} @code{@@end table} in an appendix that contains a summary of functions, not @code{@@deffn} or other definition commands. @end itemize @subsubheading Capitalization @itemize @bullet @item Capitalize ``Texinfo''; it is a name. Do not write the @samp{x} or @samp{i} in upper case. @item Capitalize ``Info''; it is a name. @item Write @TeX{} using the @code{@@TeX@{@}} command. Note the uppercase @samp{T} and @samp{X}. This command causes the formatters to typeset the name according to the wishes of Donald Knuth, who wrote @TeX{}. @end itemize @subsubheading Spaces Do not use spaces to format a Texinfo file, except inside of @code{@@example} @dots{} @code{@@end example} and similar commands. @need 700 For example, @TeX{} fills the following: @example @group @@kbd@{C-x v@} @@kbd@{M-x vc-next-action@} Perform the next logical operation on the version-controlled file corresponding to the current buffer. @end group @end example @need 950 @noindent so it looks like this: @iftex @quotation @kbd{C-x v} @kbd{M-x vc-next-action} Perform the next logical operation on the version-controlled file corresponding to the current buffer. @end quotation @end iftex @ifinfo @quotation `C-x v' `M-x vc-next-action' Perform the next logical operation on the version-controlled file corresponding to the current buffer. @end quotation @end ifinfo @noindent In this case, the text should be formatted with @code{@@table}, @code{@@item}, and @code{@@itemx}, to create a table. @subsubheading @@code, @@samp, @@var, and @samp{---} @itemize @bullet @item Use @code{@@code} around Lisp symbols, including command names. For example, @example The main function is @@code@{vc-next-action@}, @dots{} @end example @item Avoid putting letters such as @samp{s} immediately after an @samp{@@code}. Such letters look bad. @item Use @code{@@var} around meta-variables. Do not write angle brackets around them. @item Use three hyphens in a row, @samp{---}, to indicate a long dash. @TeX{} typesets these as a long dash and the Info formatters reduce three hyphens to two. @end itemize @subsubheading Periods Outside of Quotes Place periods and other punctuation marks @emph{outside} of quotations, unless the punctuation is part of the quotation. This practice goes against publishing conventions in the United States, but enables the reader to distinguish between the contents of the quotation and the whole passage. For example, you should write the following sentence with the period outside the end quotation marks: @example Evidently, @samp{au} is an abbreviation for ``author''. @end example @noindent since @samp{au} does @emph{not} serve as an abbreviation for @samp{author.} (with a period following the word). @subsubheading Introducing New Terms @itemize @bullet @item Introduce new terms so that a reader who does not know them can understand them from context; or write a definition for the term. For example, in the following, the terms ``check in'', ``register'' and ``delta'' are all appearing for the first time; the example sentence should be rewritten so they are understandable. @quotation The major function assists you in checking in a file to your version control system and registering successive sets of changes to it as deltas. @end quotation @item Use the @code{@@dfn} command around a word being introduced, to indicate that the reader should not expect to know the meaning already, and should expect to learn the meaning from this passage. @end itemize @subsubheading @@pxref @c !!! maybe include this in the tips on pxref @ignore By the way, it is okay to use pxref with something else in front of it within the parens, as long as the pxref is followed by the close paren, and the material inside the parens is not part of a larger sentence. Also, you can use xref inside parens as part of a complete sentence so long as you terminate the cross reference with punctuation. @end ignore Absolutely never use @code{@@pxref} except in the special context for which it is designed: inside parentheses, with the closing parenthesis following immediately after the closing brace. One formatter automatically inserts closing punctuation and the other does not. This means that the output looks right both in printed output and in an Info file, but only when the command is used inside parentheses. @subsubheading Invoking from a Shell You can invoke programs such as Emacs, GCC, and @code{gawk} from a shell. The documentation for each program should contain a section that describes this. Unfortunately, if the node names and titles for these sections are all different, readers find it hard to search for the section.@refill Name such sections with a phrase beginning with the word @w{`Invoking @dots{}'}, as in `Invoking Emacs'; this way users can find the section easily. @subsubheading ANSI C Syntax When you use @code{@@example} to describe a C function's calling conventions, use the ANSI C syntax, like this:@refill @example void dld_init (char *@@var@{path@}); @end example @noindent And in the subsequent discussion, refer to the argument values by writing the same argument names, again highlighted with @code{@@var}.@refill @need 800 Avoid the obsolete style that looks like this:@refill @example #include dld_init (path) char *path; @end example Also, it is best to avoid writing @code{#include} above the declaration just to indicate that the function is declared in a header file. The practice may give the misimpression that the @code{#include} belongs near the declaration of the function. Either state explicitly which header file holds the declaration or, better yet, name the header file used for a group of functions at the beginning of the section that describes the functions.@refill @subsubheading Bad Examples Here are several examples of bad writing to avoid: In this example, say, `` @dots{} you must @code{@@dfn}@{check in@} the new version.'' That flows better. @quotation When you are done editing the file, you must perform a @code{@@dfn}@{check in@}. @end quotation In the following example, say, ``@dots{} makes a unified interface such as VC mode possible.'' @quotation SCCS, RCS and other version-control systems all perform similar functions in broadly similar ways (it is this resemblance which makes a unified control mode like this possible). @end quotation And in this example, you should specify what `it' refers to: @quotation If you are working with other people, it assists in coordinating everyone's changes so they do not step on each other. @end quotation @subsubheading And Finally @dots{} @itemize @bullet @item Pronounce @TeX{} as if the @samp{X} were a Greek `chi', as the last sound in the name `Bach'. But pronounce Texinfo as in `speck': ``teckinfo''. @item Write notes for yourself at the very end of a Texinfo file after the @code{@@bye}. None of the formatters process text after the @code{@@bye}; it is as if the text were within @code{@@ignore} @dots{} @code{@@end ignore}. @end itemize @node Sample Texinfo File, Sample Permissions, Tips, Top @appendix A Sample Texinfo File @cindex Sample Texinfo file, no comments Here is a complete, short sample Texinfo file, without any commentary. You can see this file, with comments, in the first chapter. @xref{Short Sample, , A Short Sample Texinfo File}. @sp 1 @example \input texinfo @@c -*-texinfo-*- @@c %**start of header @@setfilename sample.info @@settitle Sample Document @@c %**end of header @@setchapternewpage odd @@ifinfo This is a short example of a complete Texinfo file. Copyright 1990 Free Software Foundation, Inc. @@end ifinfo @@titlepage @@sp 10 @@comment The title is printed in a large font. @@center @@titlefont@{Sample Title@} @@c The following two commands start the copyright page. @@page @@vskip 0pt plus 1filll Copyright @@copyright@{@} 1990 Free Software Foundation, Inc. @@end titlepage @@node Top, First Chapter, , (dir) @@comment node-name, next, previous, up @@menu * First Chapter:: The first chapter is the only chapter in this sample. * Concept Index:: This index has two entries. @@end menu @@node First Chapter, Concept Index, Top, Top @@comment node-name, next, previous, up @@chapter First Chapter @@cindex Sample index entry This is the contents of the first chapter. @@cindex Another sample index entry Here is a numbered list. @@enumerate @@item This is the first item. @@item This is the second item. @@end enumerate The @@code@{makeinfo@} and @@code@{texinfo-format-buffer@} commands transform a Texinfo file such as this into an Info file; and @@TeX@{@} typesets it for a printed manual. @@node Concept Index, , First Chapter, Top @@comment node-name, next, previous, up @@unnumbered Concept Index @@printindex cp @@contents @@bye @end example @node Sample Permissions, Include Files, Sample Texinfo File, Top @appendix Sample Permissions @cindex Permissions @cindex Copying permissions Texinfo files should contain sections that tell the readers that they have the right to copy and distribute the Texinfo file, the Info file, and the printed manual.@refill Also, if you are writing a manual about software, you should explain that the software is free and either include the GNU General Public License (GPL) or provide a reference to it. @xref{Distrib, , Distribution, emacs, The GNU Emacs Manual}, for an example of the text that could be used in the software ``Distribution'', ``General Public License'', and ``NO WARRANTY'' sections of a document. @xref{Copying, , Texinfo Copying Conditions}, for an example of a brief explanation of how the copying conditions provide you with rights. @refill @menu * Inserting Permissions:: How to put permissions in your document. * ifinfo Permissions:: Sample @samp{ifinfo} copying permissions. * Titlepage Permissions:: Sample Titlepage copying permissions. @end menu @node Inserting Permissions, ifinfo Permissions, Sample Permissions, Sample Permissions @ifinfo @appendixsec Inserting Permissions @end ifinfo In a Texinfo file, the first @code{@@ifinfo} section usually begins with a line that says what the file documents. This is what a person reading the unprocessed Texinfo file or using the advanced Info command @kbd{g *} sees first. @inforef{Expert, Advanced Info commands, info}, for more information. (A reader using the regular Info commands usually starts reading at the first node and skips this first section, which is not in a node.)@refill In the @code{@@ifinfo} section, the summary sentence is followed by a copyright notice and then by the copying permission notice. One of the copying permission paragraphs is enclosed in @code{@@ignore} and @code{@@end ignore} commands. This paragraph states that the Texinfo file can be processed through @TeX{} and printed, provided the printed manual carries the proper copying permission notice. This paragraph is not made part of the Info file since it is not relevant to the Info file; but it is a mandatory part of the Texinfo file since it permits people to process the Texinfo file in @TeX{} and print the results.@refill In the printed manual, the Free Software Foundation copying permission notice follows the copyright notice and publishing information and is located within the region delineated by the @code{@@titlepage} and @code{@@end titlepage} commands. The copying permission notice is exactly the same as the notice in the @code{@@ifinfo} section except that the paragraph enclosed in @code{@@ignore} and @code{@@end ignore} commands is not part of the notice.@refill To make it simple to insert a permission notice into each section of the Texinfo file, sample permission notices for each section are reproduced in full below.@refill Note that you may need to specify the correct name of a section mentioned in the permission notice. For example, in @cite{The GDB Manual}, the name of the section referring to the General Public License is called the ``GDB General Public License'', but in the sample shown below, that section is referred to generically as the ``GNU General Public License''. If the Texinfo file does not carry a copy of the General Public License, leave out the reference to it, but be sure to include the rest of the sentence.@refill @node ifinfo Permissions, Titlepage Permissions, Inserting Permissions, Sample Permissions @comment node-name, next, previous, up @appendixsec @samp{ifinfo} Copying Permissions @cindex @samp{ifinfo} permissions In the @code{@@ifinfo} section of a Texinfo file, the standard Free Software Foundation permission notice reads as follows:@refill @example This file documents @dots{} Copyright 1998 Free Software Foundation, Inc. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. @@ignore Permission is granted to process this file through TeX and print the results, provided the printed document carries a copying permission notice identical to this one except for the removal of this paragraph (this paragraph not being relevant to the printed manual). @@end ignore Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided also that the sections entitled ``Copying'' and ``GNU General Public License'' are included exactly as in the original, and provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation. @end example @node Titlepage Permissions, , ifinfo Permissions, Sample Permissions @comment node-name, next, previous, up @appendixsec Titlepage Copying Permissions @cindex Titlepage permissions In the @code{@@titlepage} section of a Texinfo file, the standard Free Software Foundation copying permission notice follows the copyright notice and publishing information. The standard phrasing is as follows:@refill @example Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided also that the sections entitled ``Copying'' and ``GNU General Public License'' are included exactly as in the original, and provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation. @end example @node Include Files, Headings, Sample Permissions, Top @appendix Include Files @cindex Include files When @TeX{} or an Info formatting command sees an @code{@@include} command in a Texinfo file, it processes the contents of the file named by the command and incorporates them into the DVI or Info file being created. Index entries from the included file are incorporated into the indices of the output file.@refill Include files let you keep a single large document as a collection of conveniently small parts.@refill @menu * Using Include Files:: How to use the @code{@@include} command. * texinfo-multiple-files-update:: How to create and update nodes and menus when using included files. * Include File Requirements:: What @code{texinfo-multiple-files-update} expects. * Sample Include File:: A sample outer file with included files within it; and a sample included file. * Include Files Evolution:: How use of the @code{@@include} command has changed over time. @end menu @node Using Include Files, texinfo-multiple-files-update, Include Files, Include Files @appendixsec How to Use Include Files @findex include To include another file within a Texinfo file, write the @code{@@include} command at the beginning of a line and follow it on the same line by the name of a file to be included. For example:@refill @example @@include buffers.texi @end example An included file should simply be a segment of text that you expect to be included as is into the overall or @dfn{outer} Texinfo file; it should not contain the standard beginning and end parts of a Texinfo file. In particular, you should not start an included file with a line saying @samp{\input texinfo}; if you do, that phrase is inserted into the output file as is. Likewise, you should not end an included file with an @code{@@bye} command; nothing after @code{@@bye} is formatted.@refill In the past, you were required to write an @code{@@setfilename} line at the beginning of an included file, but no longer. Now, it does not matter whether you write such a line. If an @code{@@setfilename} line exists in an included file, it is ignored.@refill Conventionally, an included file begins with an @code{@@node} line that is followed by an @code{@@chapter} line. Each included file is one chapter. This makes it easy to use the regular node and menu creating and updating commands to create the node pointers and menus within the included file. However, the simple Emacs node and menu creating and updating commands do not work with multiple Texinfo files. Thus you cannot use these commands to fill in the `Next', `Previous', and `Up' pointers of the @code{@@node} line that begins the included file. Also, you cannot use the regular commands to create a master menu for the whole file. Either you must insert the menus and the `Next', `Previous', and `Up' pointers by hand, or you must use the GNU Emacs Texinfo mode command, @code{texinfo-multiple-files-update}, that is designed for @code{@@include} files.@refill @node texinfo-multiple-files-update, Include File Requirements, Using Include Files, Include Files @appendixsec @code{texinfo-multiple-files-update} @findex texinfo-multiple-files-update GNU Emacs Texinfo mode provides the @code{texinfo-multiple-files-update} command. This command creates or updates `Next', `Previous', and `Up' pointers of included files as well as those in the outer or overall Texinfo file, and it creates or updates a main menu in the outer file. Depending whether you call it with optional arguments, the command updates only the pointers in the first @code{@@node} line of the included files or all of them:@refill @table @kbd @item M-x texinfo-multiple-files-update Called without any arguments:@refill @itemize @minus @item Create or update the `Next', `Previous', and `Up' pointers of the first @code{@@node} line in each file included in an outer or overall Texinfo file.@refill @item Create or update the `Top' level node pointers of the outer or overall file.@refill @item Create or update a main menu in the outer file.@refill @end itemize @item C-u M-x texinfo-multiple-files-update Called with @kbd{C-u} as a prefix argument: @itemize @minus{} @item Create or update pointers in the first @code{@@node} line in each included file. @item Create or update the `Top' level node pointers of the outer file. @item Create and insert a master menu in the outer file. The master menu is made from all the menus in all the included files.@refill @end itemize @item C-u 8 M-x texinfo-multiple-files-update Called with a numeric prefix argument, such as @kbd{C-u 8}: @itemize @minus @item Create or update @strong{all} the `Next', `Previous', and `Up' pointers of all the included files.@refill @item Create or update @strong{all} the menus of all the included files.@refill @item Create or update the `Top' level node pointers of the outer or overall file.@refill @item And then create a master menu in the outer file. This is similar to invoking @code{texinfo-master-menu} with an argument when you are working with just one file.@refill @end itemize @end table Note the use of the prefix argument in interactive use: with a regular prefix argument, just @w{@kbd{C-u}}, the @code{texinfo-multiple-files-update} command inserts a master menu; with a numeric prefix argument, such as @kbd{C-u 8}, the command updates @strong{every} pointer and menu in @strong{all} the files and then inserts a master menu.@refill @node Include File Requirements, Sample Include File, texinfo-multiple-files-update, Include Files @appendixsec Include File Requirements @cindex Include file requirements @cindex Requirements for include files If you plan to use the @code{texinfo-multiple-files-update} command, the outer Texinfo file that lists included files within it should contain nothing but the beginning and end parts of a Texinfo file, and a number of @code{@@include} commands listing the included files. It should not even include indices, which should be listed in an included file of their own.@refill Moreover, each of the included files must contain exactly one highest level node (conventionally, @code{@@chapter} or equivalent), and this node must be the first node in the included file. Furthermore, each of these highest level nodes in each included file must be at the same hierarchical level in the file structure. Usually, each is an @code{@@chapter}, an @code{@@appendix}, or an @code{@@unnumbered} node. Thus, normally, each included file contains one, and only one, chapter or equivalent-level node.@refill The outer file should contain only @emph{one} node, the `Top' node. It should @emph{not} contain any nodes besides the single `Top' node. The @code{texinfo-multiple-files-update} command will not process them.@refill @node Sample Include File, Include Files Evolution, Include File Requirements, Include Files @appendixsec Sample File with @code{@@include} @cindex Sample @code{@@include} file @cindex Include file sample @cindex @code{@@include} file sample Here is an example of a complete outer Texinfo file with @code{@@include} files within it before running @code{texinfo-multiple-files-update}, which would insert a main or master menu:@refill @example @group \input texinfo @@c -*-texinfo-*- @c %**start of header @@setfilename include-example.info @@settitle Include Example @c %**end of header @end group @group @@setchapternewpage odd @@titlepage @@sp 12 @@center @@titlefont@{Include Example@} @@sp 2 @@center by Whom Ever @end group @group @@page @@vskip 0pt plus 1filll Copyright @@copyright@{@} 1998 Free Software Foundation, Inc. @@end titlepage @end group @group @@ifinfo @@node Top, First, , (dir) @@top Master Menu @@end ifinfo @end group @group @@include foo.texinfo @@include bar.texinfo @@include concept-index.texinfo @end group @group @@summarycontents @@contents @@bye @end group @end example An included file, such as @file{foo.texinfo}, might look like this:@refill @example @group @@node First, Second, , Top @@chapter First Chapter Contents of first chapter @dots{} @end group @end example The full contents of @file{concept-index.texinfo} might be as simple as this: @example @group @@node Concept Index, , Second, Top @@unnumbered Concept Index @@printindex cp @end group @end example The outer Texinfo source file for @cite{The GNU Emacs Lisp Reference Manual} is named @file{elisp.texi}. This outer file contains a master menu with 417 entries and a list of 41 @code{@@include} files.@refill @node Include Files Evolution, , Sample Include File, Include Files @comment node-name, next, previous, up @appendixsec Evolution of Include Files When Info was first created, it was customary to create many small Info files on one subject. Each Info file was formatted from its own Texinfo source file. This custom meant that Emacs did not need to make a large buffer to hold the whole of a large Info file when someone wanted information; instead, Emacs allocated just enough memory for the small Info file that contained the particular information sought. This way, Emacs could avoid wasting memory.@refill References from one file to another were made by referring to the file name as well as the node name. (@xref{Other Info Files, , Referring to Other Info Files}. Also, see @ref{Four and Five Arguments, , @code{@@xref} with Four and Five Arguments}.)@refill Include files were designed primarily as a way to create a single, large printed manual out of several smaller Info files. In a printed manual, all the references were within the same document, so @TeX{} could automatically determine the references' page numbers. The Info formatting commands used include files only for creating joint indices; each of the individual Texinfo files had to be formatted for Info individually. (Each, therefore, required its own @code{@@setfilename} line.)@refill However, because large Info files are now split automatically, it is no longer necessary to keep them small.@refill Nowadays, multiple Texinfo files are used mostly for large documents, such as @cite{The GNU Emacs Lisp Reference Manual}, and for projects in which several different people write different sections of a document simultaneously.@refill In addition, the Info formatting commands have been extended to work with the @code{@@include} command so as to create a single large Info file that is split into smaller files if necessary. This means that you can write menus and cross references without naming the different Texinfo files.@refill @node Headings, Catching Mistakes, Include Files, Top @appendix Page Headings @cindex Headings @cindex Footings @cindex Page numbering @cindex Page headings @cindex Formatting headings and footings Most printed manuals contain headings along the top of every page except the title and copyright pages. Some manuals also contain footings. (Headings and footings have no meaning to Info, which is not paginated.)@refill @menu * Headings Introduced:: Conventions for using page headings. * Heading Format:: Standard page heading formats. * Heading Choice:: How to specify the type of page heading. * Custom Headings:: How to create your own headings and footings. @end menu @node Headings Introduced, Heading Format, Headings, Headings @ifinfo @heading Headings Introduced @end ifinfo Texinfo provides standard page heading formats for manuals that are printed on one side of each sheet of paper and for manuals that are printed on both sides of the paper. Typically, you will use these formats, but you can specify your own format if you wish.@refill In addition, you can specify whether chapters should begin on a new page, or merely continue the same page as the previous chapter; and if chapters begin on new pages, you can specify whether they must be odd-numbered pages.@refill By convention, a book is printed on both sides of each sheet of paper. When you open a book, the right-hand page is odd-numbered, and chapters begin on right-hand pages---a preceding left-hand page is left blank if necessary. Reports, however, are often printed on just one side of paper, and chapters begin on a fresh page immediately following the end of the preceding chapter. In short or informal reports, chapters often do not begin on a new page at all, but are separated from the preceding text by a small amount of whitespace.@refill The @code{@@setchapternewpage} command controls whether chapters begin on new pages, and whether one of the standard heading formats is used. In addition, Texinfo has several heading and footing commands that you can use to generate your own heading and footing formats.@refill In Texinfo, headings and footings are single lines at the tops and bottoms of pages; you cannot create multiline headings or footings. Each header or footer line is divided into three parts: a left part, a middle part, and a right part. Any part, or a whole line, may be left blank. Text for the left part of a header or footer line is set flushleft; text for the middle part is centered; and, text for the right part is set flushright.@refill @node Heading Format, Heading Choice, Headings Introduced, Headings @comment node-name, next, previous, up @appendixsec Standard Heading Formats Texinfo provides two standard heading formats, one for manuals printed on one side of each sheet of paper, and the other for manuals printed on both sides of the paper. By default, nothing is specified for the footing of a Texinfo file, so the footing remains blank.@refill The standard format for single-sided printing consists of a header line in which the left-hand part contains the name of the chapter, the central part is blank, and the right-hand part contains the page number.@refill @need 950 A single-sided page looks like this: @example @group _______________________ | | | chapter page number | | | | Start of text ... | | ... | | | @end group @end example The standard format for two-sided printing depends on whether the page number is even or odd. By convention, even-numbered pages are on the left- and odd-numbered pages are on the right. (@TeX{} will adjust the widths of the left- and right-hand margins. Usually, widths are correct, but during double-sided printing, it is wise to check that pages will bind properly---sometimes a printer will produce output in which the even-numbered pages have a larger right-hand margin than the odd-numbered pages.)@refill In the standard double-sided format, the left part of the left-hand (even-numbered) page contains the page number, the central part is blank, and the right part contains the title (specified by the @code{@@settitle} command). The left part of the right-hand (odd-numbered) page contains the name of the chapter, the central part is blank, and the right part contains the page number.@refill @need 750 Two pages, side by side as in an open book, look like this:@refill @example @group _______________________ _______________________ | | | | | page number title | | chapter page number | | | | | | Start of text ... | | More text ... | | ... | | ... | | | | | @end group @end example @noindent The chapter name is preceded by the word ``Chapter'', the chapter number and a colon. This makes it easier to keep track of where you are in the manual.@refill @node Heading Choice, Custom Headings, Heading Format, Headings @comment node-name, next, previous, up @appendixsec Specifying the Type of Heading @TeX{} does not begin to generate page headings for a standard Texinfo file until it reaches the @code{@@end titlepage} command. Thus, the title and copyright pages are not numbered. The @code{@@end titlepage} command causes @TeX{} to begin to generate page headings according to a standard format specified by the @code{@@setchapternewpage} command that precedes the @code{@@titlepage} section.@refill @need 1000 There are four possibilities:@refill @table @asis @item No @code{@@setchapternewpage} command Cause @TeX{} to specify the single-sided heading format, with chapters on new pages. This is the same as @code{@@setchapternewpage on}.@refill @item @code{@@setchapternewpage on} Specify the single-sided heading format, with chapters on new pages.@refill @item @code{@@setchapternewpage off} Cause @TeX{} to start a new chapter on the same page as the last page of the preceding chapter, after skipping some vertical whitespace. Also cause @TeX{} to typeset for single-sided printing. (You can override the headers format with the @code{@@headings double} command; see @ref{headings on off, , The @code{@@headings} Command}.)@refill @item @code{@@setchapternewpage odd} Specify the double-sided heading format, with chapters on new pages.@refill @end table @noindent Texinfo lacks an @code{@@setchapternewpage even} command.@refill @node Custom Headings, , Heading Choice, Headings @comment node-name, next, previous, up @appendixsec How to Make Your Own Headings You can use the standard headings provided with Texinfo or specify your own. By default, Texinfo has no footers, so if you specify them, the available page size for the main text will be slightly reduced. @c Following paragraph is verbose to prevent overfull hboxes. Texinfo provides six commands for specifying headings and footings. The @code{@@everyheading} command and @code{@@everyfooting} command generate page headers and footers that are the same for both even- and odd-numbered pages. The @code{@@evenheading} command and @code{@@evenfooting} command generate headers and footers for even-numbered (left-hand) pages; and the @code{@@oddheading} command and @code{@@oddfooting} command generate headers and footers for odd-numbered (right-hand) pages.@refill Write custom heading specifications in the Texinfo file immediately after the @code{@@end titlepage} command. Enclose your specifications between @code{@@iftex} and @code{@@end iftex} commands since the @code{texinfo-format-buffer} command may not recognize them. Also, you must cancel the predefined heading commands with the @code{@@headings off} command before defining your own specifications.@refill @need 1000 Here is how to tell @TeX{} to place the chapter name at the left, the page number in the center, and the date at the right of every header for both even- and odd-numbered pages:@refill @example @group @@iftex @@headings off @@everyheading @@thischapter @@| @@thispage @@| @@today@{@} @@end iftex @end group @end example @noindent You need to divide the left part from the central part and the central part from the right part by inserting @samp{@@|} between parts. Otherwise, the specification command will not be able to tell where the text for one part ends and the next part begins.@refill Each part can contain text or @@-commands. The text is printed as if the part were within an ordinary paragraph in the body of the page. The @@-commands replace themselves with the page number, date, chapter name, or whatever.@refill @need 950 Here are the six heading and footing commands:@refill @findex everyheading @findex everyfooting @table @code @item @@everyheading @var{left} @@| @var{center} @@| @var{right} @itemx @@everyfooting @var{left} @@| @var{center} @@| @var{right} The `every' commands specify the format for both even- and odd-numbered pages. These commands are for documents that are printed on one side of each sheet of paper, or for documents in which you want symmetrical headers or footers.@refill @findex evenheading @findex evenfooting @findex oddheading @findex oddfooting @item @@evenheading @var{left} @@| @var{center} @@| @var{right} @itemx @@oddheading @var{left} @@| @var{center} @@| @var{right} @itemx @@evenfooting @var{left} @@| @var{center} @@| @var{right} @itemx @@oddfooting @var{left} @@| @var{center} @@| @var{right} The `even' and `odd' commands specify the format for even-numbered pages and odd-numbered pages. These commands are for books and manuals that are printed on both sides of each sheet of paper. @end table Use the @samp{@@this@dots{}} series of @@-commands to provide the names of chapters and sections and the page number. You can use the @samp{@@this@dots{}} commands in the left, center, or right portions of headers and footers, or anywhere else in a Texinfo file so long as they are between @code{@@iftex} and @code{@@end iftex} commands.@refill @need 1000 Here are the @samp{@@this@dots{}} commands:@refill @table @code @findex thispage @item @@thispage Expands to the current page number.@refill @c !!! Karl Berry says that `thissection' can fail on page breaks. @ignore @item @@thissection Expands to the name of the current section.@refill @end ignore @findex thischaptername @item @@thischaptername Expands to the name of the current chapter.@refill @findex thischapter @item @@thischapter Expands to the number and name of the current chapter, in the format `Chapter 1: Title'.@refill @findex thistitle @item @@thistitle Expands to the name of the document, as specified by the @code{@@settitle} command.@refill @findex thisfile @item @@thisfile For @code{@@include} files only: expands to the name of the current @code{@@include} file. If the current Texinfo source file is not an @code{@@include} file, this command has no effect. This command does @emph{not} provide the name of the current Texinfo source file unless it is an @code{@@include} file. (@xref{Include Files}, for more information about @code{@@include} files.)@refill @end table @noindent You can also use the @code{@@today@{@}} command, which expands to the current date, in `1 Jan 1900' format.@refill @findex today Other @@-commands and text are printed in a header or footer just as if they were in the body of a page. It is useful to incorporate text, particularly when you are writing drafts:@refill @example @group @@iftex @@headings off @@everyheading @@emph@{Draft!@} @@| @@thispage @@| @@thischapter @@everyfooting @@| @@| Version: 0.27: @@today@{@} @@end iftex @end group @end example Beware of overlong titles: they may overlap another part of the header or footer and blot it out.@refill @node Catching Mistakes, Refilling Paragraphs, Headings, Top @appendix Formatting Mistakes @cindex Structure, catching mistakes in @cindex Nodes, catching mistakes @cindex Catching mistakes @cindex Correcting mistakes @cindex Mistakes, catching @cindex Problems, catching @cindex Debugging the Texinfo structure Besides mistakes in the content of your documentation, there are two kinds of mistake you can make with Texinfo: you can make mistakes with @@-commands, and you can make mistakes with the structure of the nodes and chapters.@refill Emacs has two tools for catching the @@-command mistakes and two for catching structuring mistakes.@refill For finding problems with @@-commands, you can run @TeX{} or a region formatting command on the region that has a problem; indeed, you can run these commands on each region as you write it.@refill For finding problems with the structure of nodes and chapters, you can use @kbd{C-c C-s} (@code{texinfo-show-structure}) and the related @code{occur} command and you can use the @kbd{M-x Info-validate} command.@refill @menu * makeinfo Preferred:: @code{makeinfo} finds errors. * Debugging with Info:: How to catch errors with Info formatting. * Debugging with TeX:: How to catch errors with @TeX{} formatting. * Using texinfo-show-structure:: How to use @code{texinfo-show-structure}. * Using occur:: How to list all lines containing a pattern. * Running Info-Validate:: How to find badly referenced nodes. @end menu @node makeinfo Preferred, Debugging with Info, Catching Mistakes, Catching Mistakes @ifinfo @heading @code{makeinfo} Find Errors @end ifinfo The @code{makeinfo} program does an excellent job of catching errors and reporting them---far better than @code{texinfo-format-region} or @code{texinfo-format-buffer}. In addition, the various functions for automatically creating and updating node pointers and menus remove many opportunities for human error.@refill If you can, use the updating commands to create and insert pointers and menus. These prevent many errors. Then use @code{makeinfo} (or its Texinfo mode manifestations, @code{makeinfo-region} and @code{makeinfo-buffer}) to format your file and check for other errors. This is the best way to work with Texinfo. But if you cannot use @code{makeinfo}, or your problem is very puzzling, then you may want to use the tools described in this appendix.@refill @node Debugging with Info, Debugging with TeX, makeinfo Preferred, Catching Mistakes @comment node-name, next, previous, up @appendixsec Catching Errors with Info Formatting @cindex Catching errors with Info formatting @cindex Debugging with Info formatting After you have written part of a Texinfo file, you can use the @code{texinfo-format-region} or the @code{makeinfo-region} command to see whether the region formats properly.@refill Most likely, however, you are reading this section because for some reason you cannot use the @code{makeinfo-region} command; therefore, the rest of this section presumes that you are using @code{texinfo-format-region}.@refill If you have made a mistake with an @@-command, @code{texinfo-format-region} will stop processing at or after the error and display an error message. To see where in the buffer the error occurred, switch to the @samp{*Info Region*} buffer; the cursor will be in a position that is after the location of the error. Also, the text will not be formatted after the place where the error occurred (or more precisely, where it was detected).@refill For example, if you accidentally end a menu with the command @code{@@end menus} with an `s' on the end, instead of with @code{@@end menu}, you will see an error message that says:@refill @example @@end menus is not handled by texinfo @end example @noindent The cursor will stop at the point in the buffer where the error occurs, or not long after it. The buffer will look like this:@refill @example @group ---------- Buffer: *Info Region* ---------- * Menu: * Using texinfo-show-structure:: How to use `texinfo-show-structure' to catch mistakes. * Running Info-Validate:: How to check for unreferenced nodes. @@end menus @point{} ---------- Buffer: *Info Region* ---------- @end group @end example The @code{texinfo-format-region} command sometimes provides slightly odd error messages. For example, the following cross reference fails to format:@refill @example (@@xref@{Catching Mistakes, for more info.) @end example @noindent In this case, @code{texinfo-format-region} detects the missing closing brace but displays a message that says @samp{Unbalanced parentheses} rather than @samp{Unbalanced braces}. This is because the formatting command looks for mismatches between braces as if they were parentheses.@refill Sometimes @code{texinfo-format-region} fails to detect mistakes. For example, in the following, the closing brace is swapped with the closing parenthesis:@refill @example (@@xref@{Catching Mistakes), for more info.@} @end example @noindent Formatting produces: @example (*Note for more info.: Catching Mistakes) @end example The only way for you to detect this error is to realize that the reference should have looked like this:@refill @example (*Note Catching Mistakes::, for more info.) @end example Incidentally, if you are reading this node in Info and type @kbd{f @key{RET}} (@code{Info-follow-reference}), you will generate an error message that says: @example No such node: "Catching Mistakes) The only way @dots{} @end example @noindent This is because Info perceives the example of the error as the first cross reference in this node and if you type a @key{RET} immediately after typing the Info @kbd{f} command, Info will attempt to go to the referenced node. If you type @kbd{f catch @key{TAB} @key{RET}}, Info will complete the node name of the correctly written example and take you to the `Catching Mistakes' node. (If you try this, you can return from the `Catching Mistakes' node by typing @kbd{l} (@code{Info-last}).) @c !!! section on using Elisp debugger ignored. @ignore Sometimes @code{texinfo-format-region} will stop long after the original error; this is because it does not discover the problem until then. In this case, you will need to backtrack.@refill @c menu @c * Using the Emacs Lisp Debugger:: How to use the Emacs Lisp debugger. @c end menu @c node Using the Emacs Lisp Debugger @c appendixsubsec Using the Emacs Lisp Debugger @c index Using the Emacs Lisp debugger @c index Emacs Lisp debugger @c index Debugger, using the Emacs Lisp If an error is especially elusive, you can turn on the Emacs Lisp debugger and look at the backtrace; this tells you where in the @code{texinfo-format-region} function the problem occurred. You can turn on the debugger with the command:@refill @example M-x set-variable @key{RET} debug-on-error @key{RET} t @key{RET} @end example @noindent and turn it off with @example M-x set-variable @key{RET} debug-on-error @key{RET} nil @key{RET} @end example Often, when you are using the debugger, it is easier to follow what is going on if you use the Emacs Lisp files that are not byte-compiled. The byte-compiled sources send octal numbers to the debugger that may look mysterious. To use the uncompiled source files, load @file{texinfmt.el} and @file{texinfo.el} with the @kbd{M-x load-file} command.@refill The debugger will not catch an error if @code{texinfo-format-region} does not detect one. In the example shown above, @code{texinfo-format-region} did not find the error when the whole list was formatted, but only when part of the list was formatted. When @code{texinfo-format-region} did not find an error, the debugger did not find one either. @refill However, when @code{texinfo-format-region} did report an error, it invoked the debugger. This is the backtrace it produced:@refill @example ---------- Buffer: *Backtrace* ---------- Signalling: (search-failed "[@},]") re-search-forward("[@},]") (while ...) (let ...) texinfo-format-parse-args() (let ...) texinfo-format-xref() funcall(texinfo-format-xref) (if ...) (let ...) (if ...) (while ...) texinfo-format-scan() (save-excursion ...) (let ...) texinfo-format-region(103370 103631) * call-interactively(texinfo-format-region) ---------- Buffer: *Backtrace* ---------- @end example The backtrace is read from the bottom up. @code{texinfo-format-region} was called interactively; and it, in turn, called various functions, including @code{texinfo-format-scan}, @code{texinfo-format-xref} and @code{texinfo-format-parse-args}. Inside the function @code{texinfo-format-parse-args}, the function @code{re-search-forward} was called; it was this function that could not find the missing right-hand brace.@refill @xref{Lisp Debug, , Debugging Emacs Lisp, emacs, The GNU Emacs Manual}, for more information.@refill @end ignore @node Debugging with TeX, Using texinfo-show-structure, Debugging with Info, Catching Mistakes @comment node-name, next, previous, up @appendixsec Catching Errors with @TeX{} Formatting @cindex Catching errors with @TeX{} formatting @cindex Debugging with @TeX{} formatting You can also catch mistakes when you format a file with @TeX{}.@refill Usually, you will want to do this after you have run @code{texinfo-format-buffer} (or, better, @code{makeinfo-buffer}) on the same file, because @code{texinfo-format-buffer} sometimes displays error messages that make more sense than @TeX{}. (@xref{Debugging with Info}, for more information.)@refill For example, @TeX{} was run on a Texinfo file, part of which is shown here:@refill @example ---------- Buffer: texinfo.texi ---------- name of the Texinfo file as an extension. The @@samp@{??@} are `wildcards' that cause the shell to substitute all the raw index files. (@@xref@{sorting indices, for more information about sorting indices.)@@refill ---------- Buffer: texinfo.texi ---------- @end example @noindent (The cross reference lacks a closing brace.) @TeX{} produced the following output, after which it stopped:@refill @example ---------- Buffer: *tex-shell* ---------- Runaway argument? @{sorting indices, for more information about sorting indices.) @@refill @@ETC. ! Paragraph ended before @@xref was complete. @@par l.27 ? ---------- Buffer: *tex-shell* ---------- @end example In this case, @TeX{} produced an accurate and understandable error message: @example Paragraph ended before @@xref was complete. @end example @noindent @samp{@@par} is an internal @TeX{} command of no relevance to Texinfo. @samp{l.27} means that @TeX{} detected the problem on line 27 of the Texinfo file. The @samp{?} is the prompt @TeX{} uses in this circumstance.@refill Unfortunately, @TeX{} is not always so helpful, and sometimes you must truly be a Sherlock Holmes to discover what went wrong.@refill In any case, if you run into a problem like this, you can do one of three things.@refill @enumerate @item You can tell @TeX{} to continue running and ignore just this error by typing @key{RET} at the @samp{?} prompt.@refill @item You can tell @TeX{} to continue running and to ignore all errors as best it can by typing @kbd{r @key{RET}} at the @samp{?} prompt.@refill This is often the best thing to do. However, beware: the one error may produce a cascade of additional error messages as its consequences are felt through the rest of the file. To stop @TeX{} when it is producing such an avalanche of error messages, type @kbd{C-c} (or @kbd{C-c C-c}, if you are running a shell inside Emacs). @item You can tell @TeX{} to stop this run by typing @kbd{x @key{RET}} at the @samp{?} prompt.@refill @end enumerate Please note that if you are running @TeX{} inside Emacs, you need to switch to the shell buffer and line at which @TeX{} offers the @samp{?} prompt.@refill Sometimes @TeX{} will format a file without producing error messages even though there is a problem. This usually occurs if a command is not ended but @TeX{} is able to continue processing anyhow. For example, if you fail to end an itemized list with the @code{@@end itemize} command, @TeX{} will write a DVI file that you can print out. The only error message that @TeX{} will give you is the somewhat mysterious comment that@refill @example (@@end occurred inside a group at level 1) @end example @noindent However, if you print the DVI file, you will find that the text of the file that follows the itemized list is entirely indented as if it were part of the last item in the itemized list. The error message is the way @TeX{} says that it expected to find an @code{@@end} command somewhere in the file; but that it could not determine where it was needed.@refill Another source of notoriously hard-to-find errors is a missing @code{@@end group} command. If you ever are stumped by incomprehensible errors, look for a missing @code{@@end group} command first.@refill If the Texinfo file lacks header lines, @TeX{} may stop in the beginning of its run and display output that looks like the following. The @samp{*} indicates that @TeX{} is waiting for input.@refill @example This is TeX, Version 3.14159 (Web2c 7.0) (test.texinfo [1]) * @end example @noindent In this case, simply type @kbd{\end @key{RET}} after the asterisk. Then write the header lines in the Texinfo file and run the @TeX{} command again. (Note the use of the backslash, @samp{\}. @TeX{} uses @samp{\} instead of @samp{@@}; and in this circumstance, you are working directly with @TeX{}, not with Texinfo.)@refill @node Using texinfo-show-structure, Using occur, Debugging with TeX, Catching Mistakes @comment node-name, next, previous, up @appendixsec Using @code{texinfo-show-structure} @cindex Showing the structure of a file @findex texinfo-show-structure It is not always easy to keep track of the nodes, chapters, sections, and subsections of a Texinfo file. This is especially true if you are revising or adding to a Texinfo file that someone else has written.@refill In GNU Emacs, in Texinfo mode, the @code{texinfo-show-structure} command lists all the lines that begin with the @@-commands that specify the structure: @code{@@chapter}, @code{@@section}, @code{@@appendix}, and so on. With an argument (@w{@kbd{C-u}} as prefix argument, if interactive), the command also shows the @code{@@node} lines. The @code{texinfo-show-structure} command is bound to @kbd{C-c C-s} in Texinfo mode, by default.@refill The lines are displayed in a buffer called the @samp{*Occur*} buffer, indented by hierarchical level. For example, here is a part of what was produced by running @code{texinfo-show-structure} on this manual:@refill @example @group Lines matching "^@@\\(chapter \\|sect\\|subs\\|subh\\| unnum\\|major\\|chapheading \\|heading \\|appendix\\)" in buffer texinfo.texi. @dots{} 4177:@@chapter Nodes 4198: @@heading Two Paths 4231: @@section Node and Menu Illustration 4337: @@section The @@code@{@@@@node@} Command 4393: @@subheading Choosing Node and Pointer Names 4417: @@subsection How to Write an @@code@{@@@@node@} Line 4469: @@subsection @@code@{@@@@node@} Line Tips @dots{} @end group @end example This says that lines 4337, 4393, and 4417 of @file{texinfo.texi} begin with the @code{@@section}, @code{@@subheading}, and @code{@@subsection} commands respectively. If you move your cursor into the @samp{*Occur*} window, you can position the cursor over one of the lines and use the @kbd{C-c C-c} command (@code{occur-mode-goto-occurrence}), to jump to the corresponding spot in the Texinfo file. @xref{Other Repeating Search, , Using Occur, emacs, The GNU Emacs Manual}, for more information about @code{occur-mode-goto-occurrence}.@refill The first line in the @samp{*Occur*} window describes the @dfn{regular expression} specified by @var{texinfo-heading-pattern}. This regular expression is the pattern that @code{texinfo-show-structure} looks for. @xref{Regexps, , Using Regular Expressions, emacs, The GNU Emacs Manual}, for more information.@refill When you invoke the @code{texinfo-show-structure} command, Emacs will display the structure of the whole buffer. If you want to see the structure of just a part of the buffer, of one chapter, for example, use the @kbd{C-x n n} (@code{narrow-to-region}) command to mark the region. (@xref{Narrowing, , , emacs, The GNU Emacs Manual}.) This is how the example used above was generated. (To see the whole buffer again, use @kbd{C-x n w} (@code{widen}).)@refill If you call @code{texinfo-show-structure} with a prefix argument by typing @w{@kbd{C-u C-c C-s}}, it will list lines beginning with @code{@@node} as well as the lines beginning with the @@-sign commands for @code{@@chapter}, @code{@@section}, and the like.@refill You can remind yourself of the structure of a Texinfo file by looking at the list in the @samp{*Occur*} window; and if you have mis-named a node or left out a section, you can correct the mistake.@refill @node Using occur, Running Info-Validate, Using texinfo-show-structure, Catching Mistakes @comment node-name, next, previous, up @appendixsec Using @code{occur} @cindex Occurrences, listing with @code{@@occur} @findex occur Sometimes the @code{texinfo-show-structure} command produces too much information. Perhaps you want to remind yourself of the overall structure of a Texinfo file, and are overwhelmed by the detailed list produced by @code{texinfo-show-structure}. In this case, you can use the @code{occur} command directly. To do this, type@refill @example @kbd{M-x occur} @end example @noindent and then, when prompted, type a @dfn{regexp}, a regular expression for the pattern you want to match. (@xref{Regexps, , Regular Expressions, emacs, The GNU Emacs Manual}.) The @code{occur} command works from the current location of the cursor in the buffer to the end of the buffer. If you want to run @code{occur} on the whole buffer, place the cursor at the beginning of the buffer.@refill For example, to see all the lines that contain the word @samp{@@chapter} in them, just type @samp{@@chapter}. This will produce a list of the chapters. It will also list all the sentences with @samp{@@chapter} in the middle of the line.@refill If you want to see only those lines that start with the word @samp{@@chapter}, type @samp{^@@chapter} when prompted by @code{occur}. If you want to see all the lines that end with a word or phrase, end the last word with a @samp{$}; for example, @samp{catching mistakes$}. This can be helpful when you want to see all the nodes that are part of the same chapter or section and therefore have the same `Up' pointer.@refill @xref{Other Repeating Search, , Using Occur, emacs , The GNU Emacs Manual}, for more information.@refill @node Running Info-Validate, , Using occur, Catching Mistakes @comment node-name, next, previous, up @appendixsec Finding Badly Referenced Nodes @findex Info-validate @cindex Nodes, checking for badly referenced @cindex Checking for badly referenced nodes @cindex Looking for badly referenced nodes @cindex Finding badly referenced nodes @cindex Badly referenced nodes You can use the @code{Info-validate} command to check whether any of the `Next', `Previous', `Up' or other node pointers fail to point to a node. This command checks that every node pointer points to an existing node. The @code{Info-validate} command works only on Info files, not on Texinfo files.@refill The @code{makeinfo} program validates pointers automatically, so you do not need to use the @code{Info-validate} command if you are using @code{makeinfo}. You only may need to use @code{Info-validate} if you are unable to run @code{makeinfo} and instead must create an Info file using @code{texinfo-format-region} or @code{texinfo-format-buffer}, or if you write an Info file from scratch.@refill @menu * Using Info-validate:: How to run @code{Info-validate}. * Unsplit:: How to create an unsplit file. * Tagifying:: How to tagify a file. * Splitting:: How to split a file manually. @end menu @node Using Info-validate, Unsplit, Running Info-Validate, Running Info-Validate @appendixsubsec Running @code{Info-validate} @cindex Running @code{Info-validate} @cindex Info validating a large file @cindex Validating a large file To use @code{Info-validate}, visit the Info file you wish to check and type:@refill @example M-x Info-validate @end example @noindent (Note that the @code{Info-validate} command requires an upper case `I'. You may also need to create a tag table before running @code{Info-validate}. @xref{Tagifying}.)@refill If your file is valid, you will receive a message that says ``File appears valid''. However, if you have a pointer that does not point to a node, error messages will be displayed in a buffer called @samp{*problems in info file*}.@refill For example, @code{Info-validate} was run on a test file that contained only the first node of this manual. One of the messages said:@refill @example In node "Overview", invalid Next: Texinfo Mode @end example @noindent This meant that the node called @samp{Overview} had a `Next' pointer that did not point to anything (which was true in this case, since the test file had only one node in it).@refill Now suppose we add a node named @samp{Texinfo Mode} to our test case but we do not specify a `Previous' for this node. Then we will get the following error message:@refill @example In node "Texinfo Mode", should have Previous: Overview @end example @noindent This is because every `Next' pointer should be matched by a `Previous' (in the node where the `Next' points) which points back.@refill @code{Info-validate} also checks that all menu entries and cross references point to actual nodes.@refill Note that @code{Info-validate} requires a tag table and does not work with files that have been split. (The @code{texinfo-format-buffer} command automatically splits large files.) In order to use @code{Info-validate} on a large file, you must run @code{texinfo-format-buffer} with an argument so that it does not split the Info file; and you must create a tag table for the unsplit file.@refill @node Unsplit, Tagifying, Using Info-validate, Running Info-Validate @comment node-name, next, previous, up @appendixsubsec Creating an Unsplit File @cindex Creating an unsplit file @cindex Unsplit file creation You can run @code{Info-validate} only on a single Info file that has a tag table. The command will not work on the indirect subfiles that are generated when a master file is split. If you have a large file (longer than 70,000 bytes or so), you need to run the @code{texinfo-format-buffer} or @code{makeinfo-buffer} command in such a way that it does not create indirect subfiles. You will also need to create a tag table for the Info file. After you have done this, you can run @code{Info-validate} and look for badly referenced nodes.@refill The first step is to create an unsplit Info file. To prevent @code{texinfo-format-buffer} from splitting a Texinfo file into smaller Info files, give a prefix to the @kbd{M-x texinfo-format-buffer} command:@refill @example C-u M-x texinfo-format-buffer @end example @noindent or else @example C-u C-c C-e C-b @end example @noindent When you do this, Texinfo will not split the file and will not create a tag table for it. @refill @cindex Making a tag table manually @cindex Tag table, making manually @node Tagifying, Splitting, Unsplit, Running Info-Validate @appendixsubsec Tagifying a File After creating an unsplit Info file, you must create a tag table for it. Visit the Info file you wish to tagify and type:@refill @example M-x Info-tagify @end example @noindent (Note the upper case @samp{I} in @code{Info-tagify}.) This creates an Info file with a tag table that you can validate.@refill The third step is to validate the Info file:@refill @example M-x Info-validate @end example @noindent (Note the upper case @samp{I} in @code{Info-validate}.) In brief, the steps are:@refill @example @group C-u M-x texinfo-format-buffer M-x Info-tagify M-x Info-validate @end group @end example After you have validated the node structure, you can rerun @code{texinfo-format-buffer} in the normal way so it will construct a tag table and split the file automatically, or you can make the tag table and split the file manually.@refill @node Splitting, , Tagifying, Running Info-Validate @comment node-name, next, previous, up @appendixsubsec Splitting a File Manually @cindex Splitting an Info file manually @cindex Info file, splitting manually You should split a large file or else let the @code{texinfo-format-buffer} or @code{makeinfo-buffer} command do it for you automatically. (Generally you will let one of the formatting commands do this job for you. @xref{Create an Info File}.)@refill The split-off files are called the indirect subfiles.@refill Info files are split to save memory. With smaller files, Emacs does not have make such a large buffer to hold the information.@refill If an Info file has more than 30 nodes, you should also make a tag table for it. @xref{Using Info-validate}, for information about creating a tag table. (Again, tag tables are usually created automatically by the formatting command; you only need to create a tag table yourself if you are doing the job manually. Most likely, you will do this for a large, unsplit file on which you have run @code{Info-validate}.)@refill @c Info-split is autoloaded in `loaddefs.el' in Emacs 18.51 @ignore Before running @code{Info-split}, you need to load the @code{info} library into Emacs by giving the command @kbd{M-x load-library @key{RET} info @key{RET}}. @end ignore Visit the Info file you wish to tagify and split and type the two commands:@refill @example M-x Info-tagify M-x Info-split @end example @noindent (Note that the @samp{I} in @samp{Info} is upper case.)@refill When you use the @code{Info-split} command, the buffer is modified into a (small) Info file which lists the indirect subfiles. This file should be saved in place of the original visited file. The indirect subfiles are written in the same directory the original file is in, with names generated by appending @samp{-} and a number to the original file name.@refill The primary file still functions as an Info file, but it contains just the tag table and a directory of subfiles.@refill @node Refilling Paragraphs, Command Syntax, Catching Mistakes, Top @appendix Refilling Paragraphs @cindex Refilling paragraphs @cindex Filling paragraphs @findex refill The @code{@@refill} command refills and, optionally, indents the first line of a paragraph.@footnote{Perhaps the command should have been called the @code{@@refillandindent} command, but @code{@@refill} is shorter and the name was chosen before indenting was possible.} The @code{@@refill} command is no longer important, but we describe it here because you once needed it. You will see it in many old Texinfo files.@refill Without refilling, paragraphs containing long @@-constructs may look bad after formatting because the formatter removes @@-commands and shortens some lines more than others. In the past, neither the @code{texinfo-format-region} command nor the @code{texinfo-format-buffer} command refilled paragraphs automatically. The @code{@@refill} command had to be written at the end of every paragraph to cause these formatters to fill them. (Both @TeX{} and @code{makeinfo} have always refilled paragraphs automatically.) Now, all the Info formatters automatically fill and indent those paragraphs that need to be filled and indented.@refill The @code{@@refill} command causes @code{texinfo-format-region} and @code{texinfo-format-buffer} to refill a paragraph in the Info file @emph{after} all the other processing has been done. For this reason, you can not use @code{@@refill} with a paragraph containing either @code{@@*} or @code{@@w@{ @dots{} @}} since the refilling action will override those two commands.@refill The @code{texinfo-format-region} and @code{texinfo-format-buffer} commands now automatically append @code{@@refill} to the end of each paragraph that should be filled. They do not append @code{@@refill} to the ends of paragraphs that contain @code{@@*} or @w{@code{@@w@{ @dots{}@}}} and therefore do not refill or indent them.@refill @node Command Syntax, Obtaining TeX, Refilling Paragraphs, Top @comment node-name, next, previous, up @appendix @@-Command Syntax @cindex @@-command syntax The character @samp{@@} is used to start special Texinfo commands. (It has the same meaning that @samp{\} has in plain @TeX{}.) Texinfo has four types of @@-command:@refill @table @asis @item 1. Non-alphabetic commands. These commands consist of an @@ followed by a punctuation mark or other character that is not part of the alphabet. Non-alphabetic commands are almost always part of the text within a paragraph, and never take any argument. The two characters (@@ and the other one) are complete in themselves; none is followed by braces. The non-alphabetic commands are: @code{@@.}, @code{@@:}, @code{@@*}, @code{@@@kbd{SPACE}}, @code{@@@kbd{TAB}}, @code{@@@kbd{NL}}, @code{@@@@}, @code{@@@{}, and @code{@@@}}.@refill @item 2. Alphabetic commands that do not require arguments. These commands start with @@ followed by a word followed by left- and right-hand braces. These commands insert special symbols in the document; they do not require arguments. For example, @code{@@dots@{@}} @result{} @samp{@dots{}}, @code{@@equiv@{@}} @result{} @samp{@equiv{}}, @code{@@TeX@{@}} @result{} `@TeX{}', and @code{@@bullet@{@}} @result{} @samp{@bullet{}}.@refill @item 3. Alphabetic commands that require arguments within braces. These commands start with @@ followed by a letter or a word, followed by an argument within braces. For example, the command @code{@@dfn} indicates the introductory or defining use of a term; it is used as follows: @samp{In Texinfo, @@@@-commands are @@dfn@{mark-up@} commands.}@refill @item 4. Alphabetic commands that occupy an entire line. These commands occupy an entire line. The line starts with @@, followed by the name of the command (a word); for example, @code{@@center} or @code{@@cindex}. If no argument is needed, the word is followed by the end of the line. If there is an argument, it is separated from the command name by a space. Braces are not used.@refill @end table @cindex Braces and argument syntax Thus, the alphabetic commands fall into classes that have different argument syntaxes. You cannot tell to which class a command belongs by the appearance of its name, but you can tell by the command's meaning: if the command stands for a glyph, it is in class 2 and does not require an argument; if it makes sense to use the command together with other text as part of a paragraph, the command is in class 3 and must be followed by an argument in braces; otherwise, it is in class 4 and uses the rest of the line as its argument.@refill The purpose of having a different syntax for commands of classes 3 and 4 is to make Texinfo files easier to read, and also to help the GNU Emacs paragraph and filling commands work properly. There is only one exception to this rule: the command @code{@@refill}, which is always used at the end of a paragraph immediately following the final period or other punctuation character. @code{@@refill} takes no argument and does @emph{not} require braces. @code{@@refill} never confuses the Emacs paragraph commands because it cannot appear at the beginning of a line.@refill @node Obtaining TeX, Command and Variable Index, Command Syntax, Top @appendix How to Obtain @TeX{} @cindex Obtaining @TeX{} @cindex @TeX{}, how to obtain @c !!! Here is information about obtaining TeX. Update it whenever. @c !!! Also consider updating TeX.README on ftp.gnu.org. @c Updated by RJC on 1 March 1995, conversation with MacKay. @c Updated by kb@cs.umb.edu on 29 July 1996. @c Updated by kb@cs.umb.edu on 25 April 1997. @c Updated by kb@cs.umb.edu on 27 February 1998. @TeX{} is freely redistributable. You can obtain @TeX{} for Unix systems via anonymous ftp or on physical media. The core material consists of the Web2c @TeX{} distribution (@uref{http://tug.org/web2c}). Instructions for retrieval by anonymous ftp and information on other available distributions: @example @uref{ftp://tug.org/tex/unixtex.ftp} @uref{http://tug.org/unixtex.ftp} @end example The Free Software Foundation provides a core distribution on its Source Code CD-ROM suitable for printing Texinfo manuals; the University of Washington maintains and supports a tape distribution; the @TeX{} Users Group co-sponsors a complete CD-ROM @TeX{} distribution. @itemize @bullet @item For the FSF Source Code CD-ROM, please contact: @iftex @display @group Free Software Foundation, Inc. 59 Temple Place Suite 330 Boston, MA @ @ 02111-1307 USA Telephone: @w{+1-617-542-5942} Fax: (including Japan) @w{+1-617-542-2652} Free Dial Fax (in Japan): @w{ } @w{ } @w{ } 0031-13-2473 (KDD) @w{ } @w{ } @w{ } 0066-3382-0158 (IDC) Electronic mail: @code{gnu@@gnu.org} @end group @end display @end iftex @ifinfo @display @group Free Software Foundation, Inc. 59 Temple Place Suite 330 Boston, MA @w{ } 02111-1307 USA Telephone: @w{+1-617-542-5942} Fax: (including Japan) @w{+1-617-542-2652} Free Dial Fax (in Japan): @w{ } @w{ } @w{ } 0031-13-2473 (KDD) @w{ } @w{ } @w{ } 0066-3382-0158 (IDC) Electronic mail: @code{gnu@@gnu.org} @end group @end display @end ifinfo @item To order a complete distribution on CD-ROM, please see @uref{http://tug.org/tex-live.html}. (This distribution is also available by FTP; see the URL's above.) @item To order a full distribution from the University of Washington on either a 1/4@dmn{in} 4-track QIC-24 cartridge or a 4@dmn{mm} DAT cartridge, send $210 to: @display @group Pierre A. MacKay Denny Hall, Mail Stop DH-10 University of Washington Seattle, WA @w{ } 98195 USA Telephone: +1-206-543-2268 Electronic mail: @code{mackay@@cs.washington.edu} @end group @end display @noindent Please make checks payable to the University of Washington. Checks must be in U.S.@: dollars, drawn on a U.S.@: bank. Overseas sites: please add to the base cost, if desired, $20.00 for shipment via air parcel post, or $30.00 for shipment via courier. @end itemize Many other @TeX{} distributions are available; see @uref{http://tug.org/}. @c These are no longer ``new'', and the explanations @c are all given elsewhere anyway, I think. --karl, 25apr97. @ignore (the entire appendix) @c node New Features, Command and Variable Index, Obtaining TeX, Top @c appendix Second Edition Features @tex % Widen the space for the first column so three control-character % strings fit in the first column. Switched back to default .8in % value at end of chapter. \global\tableindent=1.0in @end tex The second edition of the Texinfo manual describes more than 20 new Texinfo mode commands and more than 50 previously undocumented Texinfo @@-commands. This edition is more than twice the length of the first edition.@refill Here is a brief description of the new commands.@refill @menu * New Texinfo Mode Commands:: The updating commands are especially useful. * New Commands:: Many newly described @@-commands. @end menu @c node New Texinfo Mode Commands, New Commands, Obtaining TeX, Obtaining TeX @c appendixsec New Texinfo Mode Commands Texinfo mode provides commands and features especially designed for working with Texinfo files. More than 20 new commands have been added, including commands for automatically creating and updating both nodes and menus. This is a tedious task when done by hand.@refill The keybindings are intended to be somewhat mnemonic.@refill @c subheading Update all nodes and menus The @code{texinfo-master-menu} command is the primary command: @table @kbd @item C-c C-u m @itemx M-x texinfo-master-menu Create or update a master menu. With @kbd{C-u} as a prefix argument, first create or update all nodes and regular menus. @end table @c subheading Update Pointers @noindent Create or update `Next', `Previous', and `Up' node pointers.@refill @noindent @xref{Updating Nodes and Menus}. @table @kbd @item C-c C-u C-n @itemx M-x texinfo-update-node Update a node. @item C-c C-u C-e @itemx M-x texinfo-every-node-update Update every node in the buffer. @end table @c subheading Update Menus @noindent Create or update menus.@refill @noindent @xref{Updating Nodes and Menus}. @table @kbd @item C-c C-u C-m @itemx M-x texinfo-make-menu Make or update a menu. @item C-c C-u C-a @itemx M-x texinfo-all-menus-update Make or update all the menus in a buffer. With @kbd{C-u} as a prefix argument, first update all the nodes. @end table @c subheading Insert Title as Description @noindent Insert a node's chapter or section title in the space for the description in a menu entry line; position point so you can edit the insert. (This command works somewhat differently than the other insertion commands, which insert only a predefined string.)@refill @noindent @xref{Inserting, Inserting Frequently Used Commands}. @table @kbd @item C-c C-c C-d Insert title. @end table @c subheading Format for Info @noindent Provide keybindings both for the Info formatting commands that are written in Emacs Lisp and for @code{makeinfo} that is written in C.@refill @noindent @xref{Info Formatting}. @noindent Use the Emacs lisp @code{texinfo-format@dots{}} commands: @table @kbd @item C-c C-e C-r Format the region. @item C-c C-e C-b Format the buffer. @end table @noindent Use @code{makeinfo}: @table @kbd @item C-c C-m C-r Format the region. @item C-c C-m C-b Format the buffer. @item C-c C-m C-l Recenter the @code{makeinfo} output buffer. @item C-c C-m C-k Kill the @code{makeinfo} formatting job. @end table @c subheading Typeset and Print @noindent Typeset and print Texinfo documents from within Emacs.@refill @ifinfo @noindent @xref{Printing}. @end ifinfo @iftex @noindent @xref{Printing, , Formatting and Printing}. @end iftex @table @kbd @item C-c C-t C-b Run @code{texi2dvi} on the buffer. @item C-c C-t C-r Run @TeX{} on the region. @item C-c C-t C-i Run @code{texindex}. @item C-c C-t C-p Print the DVI file. @item C-c C-t C-q Show the print queue. @item C-c C-t C-d Delete a job from the print queue. @item C-c C-t C-k Kill the current @TeX{} formatting job. @item C-c C-t C-x Quit a currently stopped @TeX{} formatting job. @item C-c C-t C-l Recenter the output buffer. @end table @c subheading Other Updating Commands @noindent The ``other updating commands'' do not have standard keybindings because they are used less frequently.@refill @noindent @xref{Other Updating Commands}. @table @kbd @item M-x texinfo-insert-node-lines Insert missing @code{@@node} lines using section titles as node names. @item M-x texinfo-multiple-files-update Update a multi-file document. With a numeric prefix, such as @kbd{C-u 8}, update @strong{every} pointer and menu in @strong{all} the files and then insert a master menu. @item M-x texinfo-indent-menu-description Indent descriptions in menus. @item M-x texinfo-sequential-node-update Insert node pointers in strict sequence. @end table @c node New Commands, , New Texinfo Mode Commands, Obtaining TeX @c appendixsec New Texinfo @@-Commands The second edition of the Texinfo manual describes more than 50 commands that were not described in the first edition. A third or so of these commands existed in Texinfo but were not documented in the manual; the others are new. Here is a listing, with brief descriptions of them:@refill @c subheading Indexing @noindent Create your own index, and merge indices.@refill @noindent @xref{Indices}. @table @kbd @item @@defindex @var{index-name} Define a new index and its indexing command. See also the @code{@@defcodeindex} command. @c written verbosely to avoid overfull hbox @item @@synindex @var{from-index} @var{into-index} Merge the @var{from-index} index into the @var{into-index} index. See also the @code{@@syncodeindex} command. @end table @c subheading Definitions @noindent Describe functions, variables, macros, commands, user options, special forms, and other such artifacts in a uniform format.@refill @noindent @xref{Definition Commands}. @table @kbd @item @@deffn @var{category} @var{name} @var{arguments}@dots{} Format a description for functions, interactive commands, and similar entities. @item @@defvr, @@defop, @dots{} 15 other related commands. @end table @c subheading Glyphs @noindent Indicate the results of evaluation, expansion, printed output, an error message, equivalence of expressions, and the location of point.@refill @noindent @xref{Glyphs}. @table @kbd @item @@equiv@{@} @itemx @equiv{} Equivalence: @item @@error@{@} @itemx @error{} Error message @item @@expansion@{@} @itemx @expansion{} Macro expansion @item @@point@{@} @itemx @point{} Position of point @item @@print@{@} @itemx @print{} Printed output @item @@result@{@} @itemx @result{} Result of an expression @end table @c subheading Page Headings @noindent Customize page headings. @noindent @xref{Headings}. @table @kbd @item @@headings @var{on-off-single-double} Headings on or off, single, or double-sided. @item @@evenfooting [@var{left}] @@| [@var{center}] @@| [@var{right}] Footings for even-numbered (left-hand) pages. @item @@evenheading, @@everyheading, @@oddheading, @dots{} Five other related commands. @item @@thischapter Insert name of chapter and chapter number. @item @@thischaptername, @@thisfile, @@thistitle, @@thispage Related commands. @end table @c subheading Formatting @noindent Format blocks of text. @noindent @xref{Quotations and Examples}, and@* @ref{Lists and Tables, , Making Lists and Tables}. @table @kbd @item @@cartouche Draw rounded box surrounding text (not in Info). @item @@enumerate @var{optional-arg} Enumerate a list with letters or numbers. @item @@exdent @var{line-of-text} Remove indentation. @item @@flushleft Left justify. @item @@flushright Right justify. @item @@format Do not narrow nor change font. @item @@ftable @var{formatting-command} @itemx @@vtable @var{formatting-command} Two-column table with indexing. @item @@lisp For an example of Lisp code. @item @@smallexample @itemx @@smalllisp Like @@table and @@lisp @r{but for} @@smallbook. @end table @c subheading Conditionals @noindent Conditionally format text. @noindent @xref{set clear value, , @code{@@set} @code{@@clear} @code{@@value}}.@refill @table @kbd @item @@set @var{flag} [@var{string}] Set a flag. Optionally, set value of @var{flag} to @var{string}. @item @@clear @var{flag} Clear a flag. @item @@value@{@var{flag}@} Replace with value to which @var{flag} is set. @item @@ifset @var{flag} Format, if @var{flag} is set. @item @@ifclear @var{flag} Ignore, if @var{flag} is set. @end table @c subheading @@heading series for Titles @noindent Produce unnumbered headings that do not appear in a table of contents. @noindent @xref{Structuring}. @table @kbd @item @@heading @var{title} Unnumbered section-like heading not listed in the table of contents of a printed manual. @item @@chapheading, @@majorheading, @@c subheading, @@subsubheading Related commands. @end table @need 1000 @c subheading Font commands @need 1000 @noindent @xref{Smallcaps}, and @* @ref{Fonts}. @table @kbd @item @@r@{@var{text}@} Print in roman font. @item @@sc@{@var{text}@} Print in @sc{small caps} font. @end table @c subheading Miscellaneous @noindent See @ref{title subtitle author, , @code{@@title} @code{@@subtitle} and @code{@@author} Commands},@* see @ref{Customized Highlighting},@* see @ref{Overfull hboxes},@* see @ref{Footnotes},@* see @ref{dmn, , Format a Dimension},@* see @ref{Raise/lower sections, , @code{@@raisesections} and @code{@@lowersections}},@* see @ref{math, , @code{@@math}: Inserting Mathematical Expressions}.@* see @ref{minus, , Inserting a Minus Sign},@* see @ref{paragraphindent, , Paragraph Indenting},@* see @ref{Cross Reference Commands},@* see @ref{title subtitle author, , @code{@@title} @code{@@subtitle} and @code{@@author}}, and@* see @ref{Custom Headings, , How to Make Your Own Headings}. @table @kbd @item @@author @var{author} Typeset author's name. @c @item @@definfoenclose @var{new-command}, @var{before}, @var{after}, @c Define a highlighting command for Info. (Info only.) @item @@finalout Produce cleaner printed output. @item @@footnotestyle @var{end-or-separate} Specify footnote style. @item @@dmn@{@var{dimension}@} Format a dimension. @item @@global@@let@var{new-cmd}=@var{existing-cmd} Define a highlighting command for @TeX{}. (@TeX{} only.) @item @@lowersections Reduce hierarchical level of sectioning commands. @item @@math@{@var{mathematical-expression}@} Format a mathematical expression. @item @@minus@{@} Generate a minus sign. @item @@paragraphindent @var{asis-or-number} Specify paragraph indentation. @item @@raisesections Raise hierarchical level of sectioning commands. @item @@ref@{@var{node-name}, @r{[}@var{entry}@r{]}, @r{[}@var{topic-or-title}@r{]}, @r{[}@var{info-file}@r{]}, @r{[}@var{manual}@r{]}@} Make a reference. In the printed manual, the reference does not start with the word `see'. @item @@title @var{title} Typeset @var{title} in the alternative title page format. @item @@subtitle @var{subtitle} Typeset @var{subtitle} in the alternative title page format. @item @@today@{@} Insert the current date. @end table @tex % Switch width of first column of tables back to default value \global\tableindent=.8in @end tex @end ignore @node Command and Variable Index, Concept Index, Obtaining TeX, Top @comment node-name, next, previous, up @unnumbered Command and Variable Index This is an alphabetical list of all the @@-commands, assorted Emacs Lisp functions, and several variables. To make the list easier to use, the commands are listed without their preceding @samp{@@}.@refill @printindex fn @node Concept Index, , Command and Variable Index, Top @unnumbered Concept Index @printindex cp @summarycontents @contents @bye texinfo-3.12/doc/README0000664000175000017500000000245706475365505012027 0ustar ggThis directory contains documentation on the Texinfo system and the TeX sources needed to process Texinfo sources. (Use texi2dvi to run a Texinfo manual through TeX to produce a DVI file.) The .tex files are not installed automatically because TeX installations vary so widely. Installing them in the wrong place would give a false sense of security. So, you should simply cp *.tex to the appropriate place. If your installation follows the TeX Directory Structure standard (http://www.tug.org/tds/), this will be the directory /tex/texinfo/ for texinfo.tex and /tex/plain/dvips/ for epsf.tex. If you use the default installation paths, will be /usr/local/share/texmf. If you have teTeX, you can find by running: texconfig confall | grep \^TEXMF= (The configure script tries to do this for you.) You can get the latest texinfo.tex from ftp://ftp.tug.org/tex/texinfo.tex ftp://ftp.cs.umb.edu/pub/tex/texinfo.tex or on the FSF machines in /home/gd/gnu/doc/texinfo.tex. If you have problems with the version in this distribution, please check for a newer version. epsf.tex comes with dvips distributions, and you may already have it installed. The version here is functionally identical but slightly nicer than the one in dvips574. The changes have been sent to the epsf.tex maintainer. texinfo-3.12/configure.in0000444000175000017500000000462006477045775012707 0ustar ggdnl Process this file with autoconf to produce a configure script. dnl $Id: configure.in,v 1.32 1998/03/03 18:29:17 karl Exp $ dnl AC_INIT(makeinfo/makeinfo.c) AC_PREREQ(2.12)dnl Minimum Autoconf version required. AM_CONFIG_HEADER(config.h) AM_INIT_AUTOMAKE([texinfo], [3.12]) dnl Checks for programs. AC_PROG_CC AC_PROG_GCC_TRADITIONAL AC_PROG_INSTALL AC_PROG_RANLIB # We do this for the sake of a more helpful warning in doc/Makefile. TEXMF='$(datadir)/texmf' AC_CHECK_PROG(TEXCONFIG, texconfig, true, false) $TEXCONFIG && eval `texconfig conf unless we're linking with ncurses. if test "x$termlib" = xncurses; then dnl Use AC_CHECK_HEADERS so the HAVE_*_H symbol gets defined. AC_CHECK_HEADERS(ncurses/termcap.h) fi AC_HEADER_STDC AC_CHECK_HEADERS(fcntl.h pwd.h string.h strings.h termcap.h termio.h \ termios.h unistd.h \ sys/fcntl.h sys/file.h sys/ptem.h sys/time.h sys/ttold.h sys/wait.h) dnl Checks for typedefs, structures, and compiler characteristics. AC_TYPE_OFF_T AC_TYPE_SIGNAL AC_C_CONST AC_STRUCT_TM dnl Checks for library functions. AC_FUNC_ALLOCA AC_FUNC_VPRINTF AC_FUNC_SETVBUF_REVERSED AC_CHECK_FUNCS(setvbuf getcwd memset bzero strchr strcasecmp \ sigprocmask sigsetmask) dnl strcasecmp, strerror, xmalloc, xrealloc, probably others should be added. AC_REPLACE_FUNCS(memcpy memmove strdup strerror) dnl Set of available languages and i18n macros. ALL_LINGUAS="de fr" AM_GNU_GETTEXT AC_LINK_FILES($nls_cv_header_libgt, $nls_cv_header_intl) AC_OUTPUT([Makefile \ doc/Makefile \ info/Makefile \ intl/Makefile \ lib/Makefile \ makeinfo/Makefile \ po/Makefile.in \ util/Makefile \ ], [sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in >po/Makefile]) texinfo-3.12/aclocal.m40000664000175000017500000004062306477046067012240 0ustar ggdnl aclocal.m4 generated automatically by aclocal 1.2f dnl Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. dnl This Makefile.in is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl This program is distributed in the hope that it will be useful, dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A dnl PARTICULAR PURPOSE. # Like AC_CONFIG_HEADER, but automatically create stamp file. AC_DEFUN(AM_CONFIG_HEADER, [AC_PREREQ([2.12]) AC_CONFIG_HEADER([$1]) dnl When config.status generates a header, we must update the stamp-h file. dnl This file resides in the same directory as the config header dnl that is generated. We must strip everything past the first ":", dnl and everything past the last "/". AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>, <>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>, <>; do case " <<$>>CONFIG_HEADERS " in *" <<$>>am_file "*<<)>> echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx ;; esac am_indx=`expr "<<$>>am_indx" + 1` done<<>>dnl>>) changequote([,]))]) # Do all the work for Automake. This macro actually does too much -- # some checks are only needed if your package does certain things. # But this isn't really a big deal. # serial 1 dnl Usage: dnl AM_INIT_AUTOMAKE(package,version, [no-define]) AC_DEFUN(AM_INIT_AUTOMAKE, [AC_REQUIRE([AM_PROG_INSTALL]) PACKAGE=[$1] AC_SUBST(PACKAGE) VERSION=[$2] AC_SUBST(VERSION) dnl test to see if srcdir already configured if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi ifelse([$3],, AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE") AC_DEFINE_UNQUOTED(VERSION, "$VERSION")) AC_REQUIRE([AM_SANITY_CHECK]) AC_REQUIRE([AC_ARG_PROGRAM]) dnl FIXME This is truly gross. missing_dir=`cd $ac_aux_dir && pwd` AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir) AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir) AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir) AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir) AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir) AC_REQUIRE([AC_PROG_MAKE_SET])]) # serial 1 AC_DEFUN(AM_PROG_INSTALL, [AC_REQUIRE([AC_PROG_INSTALL]) test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' AC_SUBST(INSTALL_SCRIPT)dnl ]) # # Check to make sure that the build environment is sane. # AC_DEFUN(AM_SANITY_CHECK, [AC_MSG_CHECKING([whether build environment is sane]) # Just in case sleep 1 echo timestamp > conftestfile # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` if test "[$]*" = "X"; then # -L didn't work. set X `ls -t $srcdir/configure conftestfile` fi if test "[$]*" != "X $srcdir/configure conftestfile" \ && test "[$]*" != "X conftestfile $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi test "[$]2" = conftestfile ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi rm -f conftest* AC_MSG_RESULT(yes)]) dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY) dnl The program must properly implement --version. AC_DEFUN(AM_MISSING_PROG, [AC_MSG_CHECKING(for working $2) # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. if ($2 --version) < /dev/null > /dev/null 2>&1; then $1=$2 AC_MSG_RESULT(found) else $1="$3/missing $2" AC_MSG_RESULT(missing) fi AC_SUBST($1)]) # Macro to add for using GNU gettext. # Ulrich Drepper , 1995. # # This file file be copied and used freely without restrictions. It can # be used in projects which are not available under the GNU Public License # but which still want to provide support for the GNU gettext functionality. # Please note that the actual code is *not* freely available. # serial 3 AC_DEFUN(AM_WITH_NLS, [AC_MSG_CHECKING([whether NLS is requested]) dnl Default is enabled NLS AC_ARG_ENABLE(nls, [ --disable-nls do not use Native Language Support], USE_NLS=$enableval, USE_NLS=yes) AC_MSG_RESULT($USE_NLS) AC_SUBST(USE_NLS) USE_INCLUDED_LIBINTL=no dnl If we use NLS figure out what method if test "$USE_NLS" = "yes"; then AC_DEFINE(ENABLE_NLS) AC_MSG_CHECKING([whether included gettext is requested]) AC_ARG_WITH(included-gettext, [ --with-included-gettext use the GNU gettext library included here], nls_cv_force_use_gnu_gettext=$withval, nls_cv_force_use_gnu_gettext=no) AC_MSG_RESULT($nls_cv_force_use_gnu_gettext) nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext" if test "$nls_cv_force_use_gnu_gettext" != "yes"; then dnl User does not insist on using GNU NLS library. Figure out what dnl to use. If gettext or catgets are available (in this order) we dnl use this. Else we have to fall back to GNU NLS library. dnl catgets is only used if permitted by option --with-catgets. nls_cv_header_intl= nls_cv_header_libgt= CATOBJEXT=NONE AC_CHECK_HEADER(libintl.h, [AC_CACHE_CHECK([for gettext in libc], gt_cv_func_gettext_libc, [AC_TRY_LINK([#include ], [return (int) gettext ("")], gt_cv_func_gettext_libc=yes, gt_cv_func_gettext_libc=no)]) if test "$gt_cv_func_gettext_libc" != "yes"; then AC_CHECK_LIB(intl, bindtextdomain, [AC_CACHE_CHECK([for gettext in libintl], gt_cv_func_gettext_libintl, [AC_TRY_LINK([], [return (int) gettext ("")], gt_cv_func_gettext_libintl=yes, gt_cv_func_gettext_libintl=no)])]) fi if test "$gt_cv_func_gettext_libc" = "yes" \ || test "$gt_cv_func_gettext_libintl" = "yes"; then AC_DEFINE(HAVE_GETTEXT) AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)dnl if test "$MSGFMT" != "no"; then AC_CHECK_FUNCS(dcgettext) AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :) AC_TRY_LINK(, [extern int _nl_msg_cat_cntr; return _nl_msg_cat_cntr], [CATOBJEXT=.gmo DATADIRNAME=share], [CATOBJEXT=.mo DATADIRNAME=lib]) INSTOBJEXT=.mo fi fi ]) if test "$CATOBJEXT" = "NONE"; then AC_MSG_CHECKING([whether catgets can be used]) AC_ARG_WITH(catgets, [ --with-catgets use catgets functions if available], nls_cv_use_catgets=$withval, nls_cv_use_catgets=no) AC_MSG_RESULT($nls_cv_use_catgets) if test "$nls_cv_use_catgets" = "yes"; then dnl No gettext in C library. Try catgets next. AC_CHECK_LIB(i, main) AC_CHECK_FUNC(catgets, [AC_DEFINE(HAVE_CATGETS) INTLOBJS="\$(CATOBJS)" AC_PATH_PROG(GENCAT, gencat, no)dnl if test "$GENCAT" != "no"; then AC_PATH_PROG(GMSGFMT, gmsgfmt, no) if test "$GMSGFMT" = "no"; then AM_PATH_PROG_WITH_TEST(GMSGFMT, msgfmt, [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no) fi AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :) USE_INCLUDED_LIBINTL=yes CATOBJEXT=.cat INSTOBJEXT=.cat DATADIRNAME=lib INTLDEPS='$(top_builddir)/intl/libintl.a' INTLLIBS=$INTLDEPS LIBS=`echo $LIBS | sed -e 's/-lintl//'` nls_cv_header_intl=intl/libintl.h nls_cv_header_libgt=intl/libgettext.h fi]) fi fi if test "$CATOBJEXT" = "NONE"; then dnl Neither gettext nor catgets in included in the C library. dnl Fall back on GNU gettext library. nls_cv_use_gnu_gettext=yes fi fi if test "$nls_cv_use_gnu_gettext" = "yes"; then dnl Mark actions used to generate GNU NLS library. INTLOBJS="\$(GETTOBJS)" AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], msgfmt) AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :) AC_SUBST(MSGFMT) USE_INCLUDED_LIBINTL=yes CATOBJEXT=.gmo INSTOBJEXT=.mo DATADIRNAME=share INTLDEPS='$(top_builddir)/intl/libintl.a' INTLLIBS=$INTLDEPS LIBS=`echo $LIBS | sed -e 's/-lintl//'` nls_cv_header_intl=intl/libintl.h nls_cv_header_libgt=intl/libgettext.h fi dnl Test whether we really found GNU xgettext. if test "$XGETTEXT" != ":"; then dnl If it is no GNU xgettext we define it as : so that the dnl Makefiles still can work. if $XGETTEXT --omit-header /dev/null 2> /dev/null; then : ; else AC_MSG_RESULT( [found xgettext programs is not GNU xgettext; ignore it]) XGETTEXT=":" fi fi # We need to process the po/ directory. POSUB=po else DATADIRNAME=share nls_cv_header_intl=intl/libintl.h nls_cv_header_libgt=intl/libgettext.h fi # If this is used in GNU gettext we have to set USE_NLS to `yes' # because some of the sources are only built for this goal. if test "$PACKAGE" = gettext; then USE_NLS=yes USE_INCLUDED_LIBINTL=yes fi dnl These rules are solely for the distribution goal. While doing this dnl we only have to keep exactly one list of the available catalogs dnl in configure.in. for lang in $ALL_LINGUAS; do GMOFILES="$GMOFILES $lang.gmo" POFILES="$POFILES $lang.po" done dnl Make all variables we use known to autoconf. AC_SUBST(USE_INCLUDED_LIBINTL) AC_SUBST(CATALOGS) AC_SUBST(CATOBJEXT) AC_SUBST(DATADIRNAME) AC_SUBST(GMOFILES) AC_SUBST(INSTOBJEXT) AC_SUBST(INTLDEPS) AC_SUBST(INTLLIBS) AC_SUBST(INTLOBJS) AC_SUBST(POFILES) AC_SUBST(POSUB) ]) AC_DEFUN(AM_GNU_GETTEXT, [AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_PROG_RANLIB])dnl AC_REQUIRE([AC_ISC_POSIX])dnl AC_REQUIRE([AC_HEADER_STDC])dnl AC_REQUIRE([AC_C_CONST])dnl AC_REQUIRE([AC_C_INLINE])dnl AC_REQUIRE([AC_TYPE_OFF_T])dnl AC_REQUIRE([AC_TYPE_SIZE_T])dnl AC_REQUIRE([AC_FUNC_ALLOCA])dnl AC_REQUIRE([AC_FUNC_MMAP])dnl AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h string.h \ unistd.h values.h sys/param.h]) AC_CHECK_FUNCS([getcwd munmap putenv setenv setlocale strchr strcasecmp \ __argz_count __argz_stringify __argz_next]) if test "${ac_cv_func_stpcpy+set}" != "set"; then AC_CHECK_FUNCS(stpcpy) fi if test "${ac_cv_func_stpcpy}" = "yes"; then AC_DEFINE(HAVE_STPCPY) fi AM_LC_MESSAGES AM_WITH_NLS if test "x$CATOBJEXT" != "x"; then if test "x$ALL_LINGUAS" = "x"; then LINGUAS= else AC_MSG_CHECKING(for catalogs to be installed) NEW_LINGUAS= for lang in ${LINGUAS=$ALL_LINGUAS}; do case "$ALL_LINGUAS" in *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;; esac done LINGUAS=$NEW_LINGUAS AC_MSG_RESULT($LINGUAS) fi dnl Construct list of names of catalog files to be constructed. if test -n "$LINGUAS"; then for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done fi fi dnl The reference to in the installed file dnl must be resolved because we cannot expect the users of this dnl to define HAVE_LOCALE_H. if test $ac_cv_header_locale_h = yes; then INCLUDE_LOCALE_H="#include " else INCLUDE_LOCALE_H="\ /* The system does not provide the header . Take care yourself. */" fi AC_SUBST(INCLUDE_LOCALE_H) dnl Determine which catalog format we have (if any is needed) dnl For now we know about two different formats: dnl Linux libc-5 and the normal X/Open format test -d intl || mkdir intl if test "$CATOBJEXT" = ".cat"; then AC_CHECK_HEADER(linux/version.h, msgformat=linux, msgformat=xopen) dnl Transform the SED scripts while copying because some dumb SEDs dnl cannot handle comments. sed -e '/^#/d' $srcdir/intl/$msgformat-msg.sed > intl/po2msg.sed fi dnl po2tbl.sed is always needed. sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \ $srcdir/intl/po2tbl.sed.in > intl/po2tbl.sed dnl In the intl/Makefile.in we have a special dependency which makes dnl only sense for gettext. We comment this out for non-gettext dnl packages. if test "$PACKAGE" = "gettext"; then GT_NO="#NO#" GT_YES= else GT_NO= GT_YES="#YES#" fi AC_SUBST(GT_NO) AC_SUBST(GT_YES) dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly dnl find the mkinstalldirs script in another subdir but ($top_srcdir). dnl Try to locate is. MKINSTALLDIRS= if test -n "$ac_aux_dir"; then MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" fi if test -z "$MKINSTALLDIRS"; then MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" fi AC_SUBST(MKINSTALLDIRS) dnl *** For now the libtool support in intl/Makefile is not for real. l= AC_SUBST(l) dnl Generate list of files to be processed by xgettext which will dnl be included in po/Makefile. test -d po || mkdir po if test "x$srcdir" != "x."; then if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then posrcprefix="$srcdir/" else posrcprefix="../$srcdir/" fi else posrcprefix="../" fi rm -f po/POTFILES sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \ < $srcdir/po/POTFILES.in > po/POTFILES ]) # Search path for a program which passes the given test. # Ulrich Drepper , 1996. # # This file file be copied and used freely without restrictions. It can # be used in projects which are not available under the GNU Public License # but which still want to provide support for the GNU gettext functionality. # Please note that the actual code is *not* freely available. # serial 1 dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) AC_DEFUN(AM_PATH_PROG_WITH_TEST, [# Extract the first word of "$2", so it can be a program name with args. set dummy $2; ac_word=[$]2 AC_MSG_CHECKING([for $ac_word]) AC_CACHE_VAL(ac_cv_path_$1, [case "[$]$1" in /*) ac_cv_path_$1="[$]$1" # Let the user override the test with a path. ;; *) IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" for ac_dir in ifelse([$5], , $PATH, [$5]); do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then if [$3]; then ac_cv_path_$1="$ac_dir/$ac_word" break fi fi done IFS="$ac_save_ifs" dnl If no 4th arg is given, leave the cache variable unset, dnl so AC_PATH_PROGS will keep looking. ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" ])dnl ;; esac])dnl $1="$ac_cv_path_$1" if test -n "[$]$1"; then AC_MSG_RESULT([$]$1) else AC_MSG_RESULT(no) fi AC_SUBST($1)dnl ]) # Check whether LC_MESSAGES is available in . # Ulrich Drepper , 1995. # # This file file be copied and used freely without restrictions. It can # be used in projects which are not available under the GNU Public License # but which still want to provide support for the GNU gettext functionality. # Please note that the actual code is *not* freely available. # serial 1 AC_DEFUN(AM_LC_MESSAGES, [if test $ac_cv_header_locale_h = yes; then AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES, [AC_TRY_LINK([#include ], [return LC_MESSAGES], am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)]) if test $am_cv_val_LC_MESSAGES = yes; then AC_DEFINE(HAVE_LC_MESSAGES) fi fi]) texinfo-3.12/config.sub0000555000175000017500000004646206471034606012354 0ustar gg#! /bin/sh # Configuration validation subroutine script, version 1.1. # Copyright (C) 1991, 92-97, 1998 Free Software Foundation, Inc. # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # 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 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. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. if [ x$1 = x ] then echo Configuration name missing. 1>&2 echo "Usage: $0 CPU-MFR-OPSYS" 1>&2 echo "or $0 ALIAS" 1>&2 echo where ALIAS is a recognized configuration type. 1>&2 exit 1 fi # First pass through any local machine types. case $1 in *local*) echo $1 exit 0 ;; *) ;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in linux-gnu*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple) os= basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco5) os=sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. tahoe | i860 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \ | arme[lb] | pyramid | mn10200 | mn10300 \ | tron | a29k | 580 | i960 | h8300 | hppa | hppa1.0 | hppa1.1 \ | alpha | alphaev5 | alphaev56 | we32k | ns16k | clipper \ | i370 | sh | powerpc | powerpcle | 1750a | dsp16xx | pdp11 \ | mips64 | mipsel | mips64el | mips64orion | mips64orionel \ | mipstx39 | mipstx39el \ | sparc | sparclet | sparclite | sparc64 | v850) basic_machine=$basic_machine-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i[34567]86) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. vax-* | tahoe-* | i[34567]86-* | i860-* | m32r-* | m68k-* | m68000-* \ | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \ | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \ | power-* | none-* | 580-* | cray2-* | h8300-* | i960-* \ | xmp-* | ymp-* | hppa-* | hppa1.0-* | hppa1.1-* \ | alpha-* | alphaev5-* | alphaev56-* | we32k-* | cydra-* \ | ns16k-* | pn-* | np1-* | xps100-* | clipper-* | orion-* \ | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \ | sparc64-* | mips64-* | mipsel-* \ | mips64el-* | mips64orion-* | mips64orionel-* \ | mipstx39-* | mipstx39el-* \ | f301-*) ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-cbm ;; amigaos | amigados) basic_machine=m68k-cbm os=-amigaos ;; amigaunix | amix) basic_machine=m68k-cbm os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | ymp) basic_machine=ymp-cray os=-unicos ;; cray2) basic_machine=cray2-cray os=-unicos ;; [ctj]90-cray) basic_machine=c90-cray os=-unicos ;; crds | unos) basic_machine=m68k-crds ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; i370-ibm* | ibm*) basic_machine=i370-ibm os=-mvs ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? i[34567]86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i[34567]86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i[34567]86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i[34567]86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; miniframe) basic_machine=m68000-convergent ;; mipsel*-linux*) basic_machine=mipsel-unknown os=-linux-gnu ;; mips*-linux*) basic_machine=mips-unknown os=-linux-gnu ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; np1) basic_machine=np1-gould ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pentium | p5 | k5 | nexen) basic_machine=i586-pc ;; pentiumpro | p6 | k6 | 6x86) basic_machine=i686-pc ;; pentiumii | pentium2) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | nexen-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | k6-* | 6x86-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=rs6000-ibm ;; ppc) basic_machine=powerpc-unknown ;; ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; symmetry) basic_machine=i386-sequent os=-dynix ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; tower | tower-32) basic_machine=m68k-ncr ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; xmp) basic_machine=xmp-cray os=-unicos ;; xps | xps100) basic_machine=xps100-honeywell ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. mips) if [ x$os = x-linux-gnu ]; then basic_machine=mips-unknown else basic_machine=mips-mips fi ;; romp) basic_machine=romp-ibm ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sparc) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -cygwin32* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -uxpv*) # Remember, each alternative MUST END IN *, to match a version number. ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -ctix* | -uts*) os=-sysv ;; -ns2 ) os=-nextstep2 ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -xenix) os=-xenix ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in *-acorn) os=-riscix1.2 ;; arm*-semi) os=-aout ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 # This also exists in the configure program, but was not the # default. # os=-sunos4 ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-ibm) os=-aix ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f301-fujitsu) os=-uxpv ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -aix*) vendor=ibm ;; -hpux*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs*) vendor=ibm ;; -ptx*) vendor=sequent ;; -vxsim* | -vxworks*) vendor=wrs ;; -aux*) vendor=apple ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os texinfo-3.12/TODO0000664000175000017500000000666206475624204011066 0ustar ggIf you are interested in working on any of these, email bug-texinfo@gnu.org. * Makeinfo: - HTML output is being actively worked on, and with luck will be in the next release. - A detexinfo program, like detex or delatex. This command would strip all the texinfo commands out, and would be used as a filter on the way to a speller. An option would be to NOT strip comments out. makeinfo --no-headers comes close. - If node name contains an @ command, complain explicitly. - Better ASCII output: convert menus to single table of contents, enumerate chapters and sections, convert cross-refs and indices to chapter/section references. See: ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2/faq201s.zip - Call Ghostscript to get ASCII output for the @image command. * TeX: - Use @ as the escape character, and Texinfo syntax generally, in the table of contents, aux, and index files. Eliminate all the crazy multiple redefinitions of every Texinfo command in different contexts. - Handle @hsep and @vsep in @multitables. * General: - Better i18n support, including support for 8-bit input characters, and 8-bit output in info. Perhaps have to use the ec fonts. - Support compressed image files, automatic generation of .txt or .jpg from .eps by Ghostscript. - Repeat TeX run until cross-references stabilize, not just twice. (Document this in manual and fix texi2dvi.) - Handle reference card creation, perhaps by only paying attention to sectioning and @def... commands. - Allow : in node names for info files, for names like `class::method'. - Get Info declared as a MIME Content-Type. * Language: - @figure: @figure [xref-label] @figureinclude , [], [] @figurehsize @figurevsize @caption ... @end caption @end figure - @flushboth to combine @flushleft and @flushright, for RFC's. - @part sectioning command. - Anchors a la HTML? - Allow subitems and `see' and `see also' in indices. - @exercise/@answer command for, e.g., gawk. - Allow @hsep/@vsep at @item, instead of just in template. - The dark corner symbol for the gawk manual. - Change bars. This is difficult or impossible in TeX, unfortunately. To do it right requires device driver support. * Doc: - Include a complete functional summary, as in a reference card, in the manual. - Improve the manuals for makeinfo, standalone info, etc. - Page 39, need a new section on doing dedication pages. See gawk.texi for an example of doing it in both the tex and info versions. * Info: - Search all nodes of dir file at startup, then can have INFO-DIR-SEPARATE-GROUPS and other such. - Better dir file merging. - Steal interface ideas from Lynx: TAB for navigating to next link within a page, number links, etc. - q within help should quit help like C-x 0. - Full-text search on all available info files. - Incorporate an X-based viewer, perhaps tkinfo: http://www.math.ucsb.edu/~boldt/tkinfo/. - Perhaps process Texinfo files directly instead of converting to Info: ftp://ftp.cs.berkeley.edu/ucb/people/phelps/tcltk/tkman.tar.Z + ftp://ftp.cs.berkeley.edu/ucb/people/phelps/tcltk/rman.tar.Z + Tcl/Tk 8.0 from ftp.smli.com in the /pub/tcl directory. From: phelps@ecstasy.CS.Berkeley.EDU (Tom Phelps) * Install-info: - be able to copy the info file to compile-time $(infodir), to simplify by-hand installation. texinfo-3.12/configure0000775000175000017500000035543706477046072012317 0ustar gg#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated automatically using autoconf version 2.12 # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. # Defaults: ac_help= ac_default_prefix=/usr/local # Any additions from configure.in: ac_help="$ac_help --disable-nls do not use Native Language Support" ac_help="$ac_help --with-included-gettext use the GNU gettext library included here" ac_help="$ac_help --with-catgets use catgets functions if available" # Initialize some variables set by options. # The variables have the same names as the options, with # dashes changed to underlines. build=NONE cache_file=./config.cache exec_prefix=NONE host=NONE no_create= nonopt=NONE no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= target=NONE verbose= x_includes=NONE x_libraries=NONE bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datadir='${prefix}/share' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' libdir='${exec_prefix}/lib' includedir='${prefix}/include' oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' # Initialize some other variables. subdirs= MFLAGS= MAKEFLAGS= # Maximum number of lines to put in a shell here document. ac_max_here_lines=12 ac_prev= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval "$ac_prev=\$ac_option" ac_prev= continue fi case "$ac_option" in -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; *) ac_optarg= ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case "$ac_option" in -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir="$ac_optarg" ;; -build | --build | --buil | --bui | --bu) ac_prev=build ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build="$ac_optarg" ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file="$ac_optarg" ;; -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ | --da=*) datadir="$ac_optarg" ;; -disable-* | --disable-*) ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` eval "enable_${ac_feature}=no" ;; -enable-* | --enable-*) ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "enable_${ac_feature}='$ac_optarg'" ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix="$ac_optarg" ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he) # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat << EOF Usage: configure [options] [host] Options: [defaults in brackets after descriptions] Configuration: --cache-file=FILE cache test results in FILE --help print this message --no-create do not create output files --quiet, --silent do not print \`checking...' messages --version print the version of autoconf that created configure Directory and file names: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [same as prefix] --bindir=DIR user executables in DIR [EPREFIX/bin] --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] --libexecdir=DIR program executables in DIR [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data in DIR [PREFIX/share] --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data in DIR [PREFIX/com] --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] --libdir=DIR object code libraries in DIR [EPREFIX/lib] --includedir=DIR C header files in DIR [PREFIX/include] --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] --infodir=DIR info documentation in DIR [PREFIX/info] --mandir=DIR man documentation in DIR [PREFIX/man] --srcdir=DIR find the sources in DIR [configure dir or ..] --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names EOF cat << EOF Host type: --build=BUILD configure for building on BUILD [BUILD=HOST] --host=HOST configure for HOST [guessed] --target=TARGET configure for TARGET [TARGET=HOST] Features and packages: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --x-includes=DIR X include files are in DIR --x-libraries=DIR X library files are in DIR EOF if test -n "$ac_help"; then echo "--enable and --with options recognized:$ac_help" fi exit 0 ;; -host | --host | --hos | --ho) ac_prev=host ;; -host=* | --host=* | --hos=* | --ho=*) host="$ac_optarg" ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir="$ac_optarg" ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir="$ac_optarg" ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir="$ac_optarg" ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir="$ac_optarg" ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst \ | --locals | --local | --loca | --loc | --lo) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* \ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) localstatedir="$ac_optarg" ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir="$ac_optarg" ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir="$ac_optarg" ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix="$ac_optarg" ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix="$ac_optarg" ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix="$ac_optarg" ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name="$ac_optarg" ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir="$ac_optarg" ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir="$ac_optarg" ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site="$ac_optarg" ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir="$ac_optarg" ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir="$ac_optarg" ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target="$ac_optarg" ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers) echo "configure generated by autoconf version 2.12" exit 0 ;; -with-* | --with-*) ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "with_${ac_package}='$ac_optarg'" ;; -without-* | --without-*) ac_package=`echo $ac_option|sed -e 's/-*without-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` eval "with_${ac_package}=no" ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes="$ac_optarg" ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries="$ac_optarg" ;; -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } ;; *) if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then echo "configure: warning: $ac_option: invalid host type" 1>&2 fi if test "x$nonopt" != xNONE; then { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } fi nonopt="$ac_option" ;; esac done if test -n "$ac_prev"; then { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } fi trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 # File descriptor usage: # 0 standard input # 1 file creation # 2 errors and warnings # 3 some systems may open it to /dev/tty # 4 used on the Kubota Titan # 6 checking for... messages and results # 5 compiler messages saved in config.log if test "$silent" = yes; then exec 6>/dev/null else exec 6>&1 fi exec 5>./config.log echo "\ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. " 1>&5 # Strip out --no-create and --no-recursion so they do not pile up. # Also quote any args containing shell metacharacters. ac_configure_args= for ac_arg do case "$ac_arg" in -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) ac_configure_args="$ac_configure_args '$ac_arg'" ;; *) ac_configure_args="$ac_configure_args $ac_arg" ;; esac done # NLS nuisances. # Only set these to C if already set. These must not be set unconditionally # because not all systems understand e.g. LANG=C (notably SCO). # Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! # Non-C LC_CTYPE values break the ctype check. if test "${LANG+set}" = set; then LANG=C; export LANG; fi if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -rf conftest* confdefs.h # AIX cpp loses on an empty file, so make sure it contains at least a newline. echo > confdefs.h # A filename unique to this package, relative to the directory that # configure is in, which we can look for to find out if srcdir is correct. ac_unique_file=makeinfo/makeinfo.c # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then its parent. ac_prog=$0 ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. srcdir=$ac_confdir if test ! -r $srcdir/$ac_unique_file; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r $srcdir/$ac_unique_file; then if test "$ac_srcdir_defaulted" = yes; then { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } else { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } fi fi srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` # Prefer explicitly selected file to automatically selected ones. if test -z "$CONFIG_SITE"; then if test "x$prefix" != xNONE; then CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" else CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi fi for ac_site_file in $CONFIG_SITE; do if test -r "$ac_site_file"; then echo "loading site script $ac_site_file" . "$ac_site_file" fi done if test -r "$cache_file"; then echo "loading cache $cache_file" . $cache_file else echo "creating cache $cache_file" > $cache_file fi ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then ac_n= ac_c=' ' ac_t=' ' else ac_n=-n ac_c= ac_t= fi else ac_n= ac_c='\c' ac_t= fi ac_aux_dir= for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do if test -f $ac_dir/install-sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f $ac_dir/install.sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break fi done if test -z "$ac_aux_dir"; then { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } fi ac_config_guess=$ac_aux_dir/config.guess ac_config_sub=$ac_aux_dir/config.sub ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 echo "configure:562: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="${IFS}:" for ac_dir in $PATH; do # Account for people who put trailing slashes in PATH elements. case "$ac_dir/" in /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. for ac_prog in ginstall installbsd scoinst install; do if test -f $ac_dir/$ac_prog; then if test $ac_prog = install && grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. # OSF/1 installbsd also uses dspmsg, but is usable. : else ac_cv_path_install="$ac_dir/$ac_prog -c" break 2 fi fi done ;; esac done IFS="$ac_save_IFS" fi if test "${ac_cv_path_install+set}" = set; then INSTALL="$ac_cv_path_install" else # As a last resort, use the slow shell script. We don't cache a # path for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the path is relative. INSTALL="$ac_install_sh" fi fi echo "$ac_t""$INSTALL" 1>&6 # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6 echo "configure:615: checking whether build environment is sane" >&5 # Just in case sleep 1 echo timestamp > conftestfile # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t $srcdir/configure conftestfile` fi if test "$*" != "X $srcdir/configure conftestfile" \ && test "$*" != "X conftestfile $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". { echo "configure: error: ls -t appears to fail. Make sure there is not a broken alias in your environment" 1>&2; exit 1; } fi test "$2" = conftestfile ) then # Ok. : else { echo "configure: error: newly created file is older than distributed files! Check your system clock" 1>&2; exit 1; } fi rm -f conftest* echo "$ac_t""yes" 1>&6 if test "$program_transform_name" = s,x,x,; then program_transform_name= else # Double any \ or $. echo might interpret backslashes. cat <<\EOF_SED > conftestsed s,\\,\\\\,g; s,\$,$$,g EOF_SED program_transform_name="`echo $program_transform_name|sed -f conftestsed`" rm -f conftestsed fi test "$program_prefix" != NONE && program_transform_name="s,^,${program_prefix},; $program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s,\$\$,${program_suffix},; $program_transform_name" # sed with no file args requires a program. test "$program_transform_name" = "" && program_transform_name="s,x,x," echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 echo "configure:672: checking whether ${MAKE-make} sets \${MAKE}" >&5 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftestmake <<\EOF all: @echo 'ac_maketemp="${MAKE}"' EOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` if test -n "$ac_maketemp"; then eval ac_cv_prog_make_${ac_make}_set=yes else eval ac_cv_prog_make_${ac_make}_set=no fi rm -f conftestmake fi if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then echo "$ac_t""yes" 1>&6 SET_MAKE= else echo "$ac_t""no" 1>&6 SET_MAKE="MAKE=${MAKE-make}" fi PACKAGE=texinfo VERSION=3.12 if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; } fi cat >> confdefs.h <> confdefs.h <&6 echo "configure:718: checking for working aclocal" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. if (aclocal --version) < /dev/null > /dev/null 2>&1; then ACLOCAL=aclocal echo "$ac_t""found" 1>&6 else ACLOCAL="$missing_dir/missing aclocal" echo "$ac_t""missing" 1>&6 fi echo $ac_n "checking for working autoconf""... $ac_c" 1>&6 echo "configure:731: checking for working autoconf" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. if (autoconf --version) < /dev/null > /dev/null 2>&1; then AUTOCONF=autoconf echo "$ac_t""found" 1>&6 else AUTOCONF="$missing_dir/missing autoconf" echo "$ac_t""missing" 1>&6 fi echo $ac_n "checking for working automake""... $ac_c" 1>&6 echo "configure:744: checking for working automake" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. if (automake --version) < /dev/null > /dev/null 2>&1; then AUTOMAKE=automake echo "$ac_t""found" 1>&6 else AUTOMAKE="$missing_dir/missing automake" echo "$ac_t""missing" 1>&6 fi echo $ac_n "checking for working autoheader""... $ac_c" 1>&6 echo "configure:757: checking for working autoheader" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. if (autoheader --version) < /dev/null > /dev/null 2>&1; then AUTOHEADER=autoheader echo "$ac_t""found" 1>&6 else AUTOHEADER="$missing_dir/missing autoheader" echo "$ac_t""missing" 1>&6 fi echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6 echo "configure:770: checking for working makeinfo" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. if (makeinfo --version) < /dev/null > /dev/null 2>&1; then MAKEINFO=makeinfo echo "$ac_t""found" 1>&6 else MAKEINFO="$missing_dir/missing makeinfo" echo "$ac_t""missing" 1>&6 fi # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:787: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CC="gcc" break fi done IFS="$ac_save_ifs" fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:816: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" ac_prog_rejected=no for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" break fi done IFS="$ac_save_ifs" if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# -gt 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift set dummy "$ac_dir/$ac_word" "$@" shift ac_cv_prog_CC="$@" fi fi fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 echo "configure:864: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then ac_cv_prog_cc_cross=no else ac_cv_prog_cc_cross=yes fi else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 ac_cv_prog_cc_works=no fi rm -fr conftest* echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 if test $ac_cv_prog_cc_works = no; then { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 echo "configure:898: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 echo "configure:903: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no fi fi echo "$ac_t""$ac_cv_prog_gcc" 1>&6 if test $ac_cv_prog_gcc = yes; then GCC=yes ac_test_CFLAGS="${CFLAGS+set}" ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 echo "configure:927: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else echo 'void f(){}' > conftest.c if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then ac_cv_prog_cc_g=yes else ac_cv_prog_cc_g=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 if test "$ac_test_CFLAGS" = set; then CFLAGS="$ac_save_CFLAGS" elif test $ac_cv_prog_cc_g = yes; then CFLAGS="-g -O2" else CFLAGS="-O2" fi else GCC= test "${CFLAGS+set}" = set || CFLAGS="-g" fi echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 echo "configure:955: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else # This must be in double quotes, not single quotes, because CPP may get # substituted into the Makefile and "${CC-cc}" will confuse make. CPP="${CC-cc} -E" # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:976: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:993: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP=/lib/cpp fi rm -f conftest* fi rm -f conftest* ac_cv_prog_CPP="$CPP" fi CPP="$ac_cv_prog_CPP" else ac_cv_prog_CPP="$CPP" fi echo "$ac_t""$CPP" 1>&6 if test $ac_cv_prog_gcc = yes; then echo $ac_n "checking whether ${CC-cc} needs -traditional""... $ac_c" 1>&6 echo "configure:1017: checking whether ${CC-cc} needs -traditional" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc_traditional'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_pattern="Autoconf.*'x'" cat > conftest.$ac_ext < Autoconf TIOCGETP EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "$ac_pattern" >/dev/null 2>&1; then rm -rf conftest* ac_cv_prog_gcc_traditional=yes else rm -rf conftest* ac_cv_prog_gcc_traditional=no fi rm -f conftest* if test $ac_cv_prog_gcc_traditional = no; then cat > conftest.$ac_ext < Autoconf TCGETA EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "$ac_pattern" >/dev/null 2>&1; then rm -rf conftest* ac_cv_prog_gcc_traditional=yes fi rm -f conftest* fi fi echo "$ac_t""$ac_cv_prog_gcc_traditional" 1>&6 if test $ac_cv_prog_gcc_traditional = yes; then CC="$CC -traditional" fi fi # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 echo "configure:1073: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="${IFS}:" for ac_dir in $PATH; do # Account for people who put trailing slashes in PATH elements. case "$ac_dir/" in /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. for ac_prog in ginstall installbsd scoinst install; do if test -f $ac_dir/$ac_prog; then if test $ac_prog = install && grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. # OSF/1 installbsd also uses dspmsg, but is usable. : else ac_cv_path_install="$ac_dir/$ac_prog -c" break 2 fi fi done ;; esac done IFS="$ac_save_IFS" fi if test "${ac_cv_path_install+set}" = set; then INSTALL="$ac_cv_path_install" else # As a last resort, use the slow shell script. We don't cache a # path for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the path is relative. INSTALL="$ac_install_sh" fi fi echo "$ac_t""$INSTALL" 1>&6 # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:1125: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_RANLIB="ranlib" break fi done IFS="$ac_save_ifs" test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" fi fi RANLIB="$ac_cv_prog_RANLIB" if test -n "$RANLIB"; then echo "$ac_t""$RANLIB" 1>&6 else echo "$ac_t""no" 1>&6 fi # We do this for the sake of a more helpful warning in doc/Makefile. TEXMF='$(datadir)/texmf' # Extract the first word of "texconfig", so it can be a program name with args. set dummy texconfig; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:1157: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_TEXCONFIG'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$TEXCONFIG"; then ac_cv_prog_TEXCONFIG="$TEXCONFIG" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_TEXCONFIG="true" break fi done IFS="$ac_save_ifs" test -z "$ac_cv_prog_TEXCONFIG" && ac_cv_prog_TEXCONFIG="false" fi fi TEXCONFIG="$ac_cv_prog_TEXCONFIG" if test -n "$TEXCONFIG"; then echo "$ac_t""$TEXCONFIG" 1>&6 else echo "$ac_t""no" 1>&6 fi $TEXCONFIG && eval `texconfig conf &6 echo "configure:1209: checking for minix/config.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1219: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 MINIX=yes else echo "$ac_t""no" 1>&6 MINIX= fi if test "$MINIX" = yes; then cat >> confdefs.h <<\EOF #define _POSIX_SOURCE 1 EOF cat >> confdefs.h <<\EOF #define _POSIX_1_SOURCE 2 EOF cat >> confdefs.h <<\EOF #define _MINIX 1 EOF fi echo $ac_n "checking for gzdopen in -lz""... $ac_c" 1>&6 echo "configure:1258: checking for gzdopen in -lz" >&5 ac_lib_var=`echo z'_'gzdopen | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lz $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_lib=HAVE_LIB`echo z | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` cat >> confdefs.h <&6 fi # Needed on sysV68 for sigblock, sigsetmask. But check for it in libc first. echo $ac_n "checking for sigblock""... $ac_c" 1>&6 echo "configure:1307: checking for sigblock" >&5 if eval "test \"`echo '$''{'ac_cv_func_sigblock'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char sigblock(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_sigblock) || defined (__stub___sigblock) choke me #else sigblock(); #endif ; return 0; } EOF if { (eval echo configure:1335: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_sigblock=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_sigblock=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'sigblock`\" = yes"; then echo "$ac_t""yes" 1>&6 : else echo "$ac_t""no" 1>&6 echo $ac_n "checking for sigblock in -lbsd""... $ac_c" 1>&6 echo "configure:1353: checking for sigblock in -lbsd" >&5 ac_lib_var=`echo bsd'_'sigblock | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lbsd $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_lib=HAVE_LIB`echo bsd | sed -e 's/^a-zA-Z0-9_/_/g' \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` cat >> confdefs.h <&6 fi fi # Some GNU/Linux systems (e.g., SuSE 4.3, 1996) don't have curses, but # rather ncurses. So we check for it. TERMLIBS= for termlib in ncurses curses termcap terminfo termlib ; do echo $ac_n "checking for tputs in -l${termlib}""... $ac_c" 1>&6 echo "configure:1407: checking for tputs in -l${termlib}" >&5 ac_lib_var=`echo ${termlib}'_'tputs | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-l${termlib} $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 TERMLIBS="${TERMLIBS} -l${termlib}"; break else echo "$ac_t""no" 1>&6 fi done if test "x$termlib" = xncurses; then for ac_hdr in ncurses/termcap.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo "configure:1454: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1464: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` cat >> confdefs.h <&6 fi done fi echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 echo "configure:1492: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include #include #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1505: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* ac_cv_header_stdc=yes else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "memchr" >/dev/null 2>&1; then : else rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "free" >/dev/null 2>&1; then : else rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') #define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF if { (eval echo configure:1572: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then : else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_header_stdc=no fi rm -fr conftest* fi fi fi echo "$ac_t""$ac_cv_header_stdc" 1>&6 if test $ac_cv_header_stdc = yes; then cat >> confdefs.h <<\EOF #define STDC_HEADERS 1 EOF fi for ac_hdr in fcntl.h pwd.h string.h strings.h termcap.h termio.h \ termios.h unistd.h \ sys/fcntl.h sys/file.h sys/ptem.h sys/time.h sys/ttold.h sys/wait.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo "configure:1601: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1611: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` cat >> confdefs.h <&6 fi done echo $ac_n "checking for off_t""... $ac_c" 1>&6 echo "configure:1639: checking for off_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS #include #include #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "off_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_off_t=yes else rm -rf conftest* ac_cv_type_off_t=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_off_t" 1>&6 if test $ac_cv_type_off_t = no; then cat >> confdefs.h <<\EOF #define off_t long EOF fi echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6 echo "configure:1672: checking return type of signal handlers" >&5 if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include #ifdef signal #undef signal #endif #ifdef __cplusplus extern "C" void (*signal (int, void (*)(int)))(int); #else void (*signal ()) (); #endif int main() { int i; ; return 0; } EOF if { (eval echo configure:1694: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_type_signal=void else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_type_signal=int fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_signal" 1>&6 cat >> confdefs.h <&6 echo "configure:1713: checking for working const" >&5 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; } ; return 0; } EOF if { (eval echo configure:1767: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_const=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_c_const=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_c_const" 1>&6 if test $ac_cv_c_const = no; then cat >> confdefs.h <<\EOF #define const EOF fi echo $ac_n "checking whether struct tm is in sys/time.h or time.h""... $ac_c" 1>&6 echo "configure:1788: checking whether struct tm is in sys/time.h or time.h" >&5 if eval "test \"`echo '$''{'ac_cv_struct_tm'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include int main() { struct tm *tp; tp->tm_sec; ; return 0; } EOF if { (eval echo configure:1801: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_struct_tm=time.h else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_struct_tm=sys/time.h fi rm -f conftest* fi echo "$ac_t""$ac_cv_struct_tm" 1>&6 if test $ac_cv_struct_tm = sys/time.h; then cat >> confdefs.h <<\EOF #define TM_IN_SYS_TIME 1 EOF fi # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6 echo "configure:1825: checking for working alloca.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { char *p = alloca(2 * sizeof(int)); ; return 0; } EOF if { (eval echo configure:1837: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* ac_cv_header_alloca_h=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_header_alloca_h=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_header_alloca_h" 1>&6 if test $ac_cv_header_alloca_h = yes; then cat >> confdefs.h <<\EOF #define HAVE_ALLOCA_H 1 EOF fi echo $ac_n "checking for alloca""... $ac_c" 1>&6 echo "configure:1858: checking for alloca" >&5 if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < # else # ifdef _AIX #pragma alloca # else # ifndef alloca /* predefined by HP cc +Olibcalls */ char *alloca (); # endif # endif # endif #endif int main() { char *p = (char *) alloca(1); ; return 0; } EOF if { (eval echo configure:1886: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* ac_cv_func_alloca_works=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_func_alloca_works=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_func_alloca_works" 1>&6 if test $ac_cv_func_alloca_works = yes; then cat >> confdefs.h <<\EOF #define HAVE_ALLOCA 1 EOF fi if test $ac_cv_func_alloca_works = no; then # The SVR3 libPW and SVR4 libucb both contain incompatible functions # that cause trouble. Some versions do not even contain alloca or # contain a buggy version. If you still want to use their alloca, # use ar to extract alloca.o from them instead of compiling alloca.c. ALLOCA=alloca.o cat >> confdefs.h <<\EOF #define C_ALLOCA 1 EOF echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6 echo "configure:1918: checking whether alloca needs Cray hooks" >&5 if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5 | egrep "webecray" >/dev/null 2>&1; then rm -rf conftest* ac_cv_os_cray=yes else rm -rf conftest* ac_cv_os_cray=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_os_cray" 1>&6 if test $ac_cv_os_cray = yes; then for ac_func in _getb67 GETB67 getb67; do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:1948: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:1976: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <&6 fi done fi echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6 echo "configure:2003: checking stack direction for C alloca" >&5 if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then ac_cv_c_stack_direction=0 else cat > conftest.$ac_ext < addr) ? 1 : -1; } main () { exit (find_stack_direction() < 0); } EOF if { (eval echo configure:2030: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then ac_cv_c_stack_direction=1 else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_c_stack_direction=-1 fi rm -fr conftest* fi fi echo "$ac_t""$ac_cv_c_stack_direction" 1>&6 cat >> confdefs.h <&6 echo "configure:2052: checking for vprintf" >&5 if eval "test \"`echo '$''{'ac_cv_func_vprintf'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char vprintf(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_vprintf) || defined (__stub___vprintf) choke me #else vprintf(); #endif ; return 0; } EOF if { (eval echo configure:2080: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_vprintf=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_vprintf=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'vprintf`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_VPRINTF 1 EOF else echo "$ac_t""no" 1>&6 fi if test "$ac_cv_func_vprintf" != yes; then echo $ac_n "checking for _doprnt""... $ac_c" 1>&6 echo "configure:2104: checking for _doprnt" >&5 if eval "test \"`echo '$''{'ac_cv_func__doprnt'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char _doprnt(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub__doprnt) || defined (__stub____doprnt) choke me #else _doprnt(); #endif ; return 0; } EOF if { (eval echo configure:2132: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func__doprnt=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func__doprnt=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'_doprnt`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_DOPRNT 1 EOF else echo "$ac_t""no" 1>&6 fi fi echo $ac_n "checking whether setvbuf arguments are reversed""... $ac_c" 1>&6 echo "configure:2157: checking whether setvbuf arguments are reversed" >&5 if eval "test \"`echo '$''{'ac_cv_func_setvbuf_reversed'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } else cat > conftest.$ac_ext < /* If setvbuf has the reversed format, exit 0. */ main () { /* This call has the arguments reversed. A reversed system may check and see that the address of main is not _IOLBF, _IONBF, or _IOFBF, and return nonzero. */ if (setvbuf(stdout, _IOLBF, (char *) main, BUFSIZ) != 0) exit(1); putc('\r', stdout); exit(0); /* Non-reversed systems segv here. */ } EOF if { (eval echo configure:2179: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then ac_cv_func_setvbuf_reversed=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_func_setvbuf_reversed=no fi rm -fr conftest* fi rm -f core core.* *.core fi echo "$ac_t""$ac_cv_func_setvbuf_reversed" 1>&6 if test $ac_cv_func_setvbuf_reversed = yes; then cat >> confdefs.h <<\EOF #define SETVBUF_REVERSED 1 EOF fi for ac_func in setvbuf getcwd memset bzero strchr strcasecmp \ sigprocmask sigsetmask do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:2206: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:2234: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <&6 fi done for ac_func in memcpy memmove strdup strerror do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:2261: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:2289: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <&6 LIBOBJS="$LIBOBJS ${ac_func}.o" fi done ALL_LINGUAS="de fr" echo $ac_n "checking for inline""... $ac_c" 1>&6 echo "configure:2318: checking for inline" >&5 if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_inline=$ac_kw; break else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -f conftest* done fi echo "$ac_t""$ac_cv_c_inline" 1>&6 case "$ac_cv_c_inline" in inline | yes) ;; no) cat >> confdefs.h <<\EOF #define inline EOF ;; *) cat >> confdefs.h <&6 echo "configure:2358: checking for size_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS #include #include #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_size_t=yes else rm -rf conftest* ac_cv_type_size_t=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_size_t" 1>&6 if test $ac_cv_type_size_t = no; then cat >> confdefs.h <<\EOF #define size_t unsigned EOF fi for ac_hdr in unistd.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo "configure:2394: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:2404: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` cat >> confdefs.h <&6 fi done for ac_func in getpagesize do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:2433: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:2461: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <&6 fi done echo $ac_n "checking for working mmap""... $ac_c" 1>&6 echo "configure:2486: checking for working mmap" >&5 if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then ac_cv_func_mmap_fixed_mapped=no else cat > conftest.$ac_ext < #include #include /* This mess was copied from the GNU getpagesize.h. */ #ifndef HAVE_GETPAGESIZE # ifdef HAVE_UNISTD_H # include # endif /* Assume that all systems that can run configure have sys/param.h. */ # ifndef HAVE_SYS_PARAM_H # define HAVE_SYS_PARAM_H 1 # endif # ifdef _SC_PAGESIZE # define getpagesize() sysconf(_SC_PAGESIZE) # else /* no _SC_PAGESIZE */ # ifdef HAVE_SYS_PARAM_H # include # ifdef EXEC_PAGESIZE # define getpagesize() EXEC_PAGESIZE # else /* no EXEC_PAGESIZE */ # ifdef NBPG # define getpagesize() NBPG * CLSIZE # ifndef CLSIZE # define CLSIZE 1 # endif /* no CLSIZE */ # else /* no NBPG */ # ifdef NBPC # define getpagesize() NBPC # else /* no NBPC */ # ifdef PAGESIZE # define getpagesize() PAGESIZE # endif /* PAGESIZE */ # endif /* no NBPC */ # endif /* no NBPG */ # endif /* no EXEC_PAGESIZE */ # else /* no HAVE_SYS_PARAM_H */ # define getpagesize() 8192 /* punt totally */ # endif /* no HAVE_SYS_PARAM_H */ # endif /* no _SC_PAGESIZE */ #endif /* no HAVE_GETPAGESIZE */ #ifdef __cplusplus extern "C" { void *malloc(unsigned); } #else char *malloc(); #endif int main() { char *data, *data2, *data3; int i, pagesize; int fd; pagesize = getpagesize(); /* * First, make a file with some known garbage in it. */ data = malloc(pagesize); if (!data) exit(1); for (i = 0; i < pagesize; ++i) *(data + i) = rand(); umask(0); fd = creat("conftestmmap", 0600); if (fd < 0) exit(1); if (write(fd, data, pagesize) != pagesize) exit(1); close(fd); /* * Next, try to mmap the file at a fixed address which * already has something else allocated at it. If we can, * also make sure that we see the same garbage. */ fd = open("conftestmmap", O_RDWR); if (fd < 0) exit(1); data2 = malloc(2 * pagesize); if (!data2) exit(1); data2 += (pagesize - ((int) data2 & (pagesize - 1))) & (pagesize - 1); if (data2 != mmap(data2, pagesize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, fd, 0L)) exit(1); for (i = 0; i < pagesize; ++i) if (*(data + i) != *(data2 + i)) exit(1); /* * Finally, make sure that changes to the mapped area * do not percolate back to the file as seen by read(). * (This is a bug on some variants of i386 svr4.0.) */ for (i = 0; i < pagesize; ++i) *(data2 + i) = *(data2 + i) + 1; data3 = malloc(pagesize); if (!data3) exit(1); if (read(fd, data3, pagesize) != pagesize) exit(1); for (i = 0; i < pagesize; ++i) if (*(data + i) != *(data3 + i)) exit(1); close(fd); unlink("conftestmmap"); exit(0); } EOF if { (eval echo configure:2634: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then ac_cv_func_mmap_fixed_mapped=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_func_mmap_fixed_mapped=no fi rm -fr conftest* fi fi echo "$ac_t""$ac_cv_func_mmap_fixed_mapped" 1>&6 if test $ac_cv_func_mmap_fixed_mapped = yes; then cat >> confdefs.h <<\EOF #define HAVE_MMAP 1 EOF fi for ac_hdr in argz.h limits.h locale.h nl_types.h malloc.h string.h \ unistd.h values.h sys/param.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo "configure:2662: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:2672: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` cat >> confdefs.h <&6 fi done for ac_func in getcwd munmap putenv setenv setlocale strchr strcasecmp \ __argz_count __argz_stringify __argz_next do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:2702: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:2730: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <&6 fi done if test "${ac_cv_func_stpcpy+set}" != "set"; then for ac_func in stpcpy do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:2759: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:2787: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <&6 fi done fi if test "${ac_cv_func_stpcpy}" = "yes"; then cat >> confdefs.h <<\EOF #define HAVE_STPCPY 1 EOF fi if test $ac_cv_header_locale_h = yes; then echo $ac_n "checking for LC_MESSAGES""... $ac_c" 1>&6 echo "configure:2821: checking for LC_MESSAGES" >&5 if eval "test \"`echo '$''{'am_cv_val_LC_MESSAGES'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { return LC_MESSAGES ; return 0; } EOF if { (eval echo configure:2833: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* am_cv_val_LC_MESSAGES=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* am_cv_val_LC_MESSAGES=no fi rm -f conftest* fi echo "$ac_t""$am_cv_val_LC_MESSAGES" 1>&6 if test $am_cv_val_LC_MESSAGES = yes; then cat >> confdefs.h <<\EOF #define HAVE_LC_MESSAGES 1 EOF fi fi echo $ac_n "checking whether NLS is requested""... $ac_c" 1>&6 echo "configure:2854: checking whether NLS is requested" >&5 # Check whether --enable-nls or --disable-nls was given. if test "${enable_nls+set}" = set; then enableval="$enable_nls" USE_NLS=$enableval else USE_NLS=yes fi echo "$ac_t""$USE_NLS" 1>&6 USE_INCLUDED_LIBINTL=no if test "$USE_NLS" = "yes"; then cat >> confdefs.h <<\EOF #define ENABLE_NLS 1 EOF echo $ac_n "checking whether included gettext is requested""... $ac_c" 1>&6 echo "configure:2874: checking whether included gettext is requested" >&5 # Check whether --with-included-gettext or --without-included-gettext was given. if test "${with_included_gettext+set}" = set; then withval="$with_included_gettext" nls_cv_force_use_gnu_gettext=$withval else nls_cv_force_use_gnu_gettext=no fi echo "$ac_t""$nls_cv_force_use_gnu_gettext" 1>&6 nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext" if test "$nls_cv_force_use_gnu_gettext" != "yes"; then nls_cv_header_intl= nls_cv_header_libgt= CATOBJEXT=NONE ac_safe=`echo "libintl.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for libintl.h""... $ac_c" 1>&6 echo "configure:2893: checking for libintl.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:2903: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 echo $ac_n "checking for gettext in libc""... $ac_c" 1>&6 echo "configure:2920: checking for gettext in libc" >&5 if eval "test \"`echo '$''{'gt_cv_func_gettext_libc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { return (int) gettext ("") ; return 0; } EOF if { (eval echo configure:2932: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* gt_cv_func_gettext_libc=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* gt_cv_func_gettext_libc=no fi rm -f conftest* fi echo "$ac_t""$gt_cv_func_gettext_libc" 1>&6 if test "$gt_cv_func_gettext_libc" != "yes"; then echo $ac_n "checking for bindtextdomain in -lintl""... $ac_c" 1>&6 echo "configure:2948: checking for bindtextdomain in -lintl" >&5 ac_lib_var=`echo intl'_'bindtextdomain | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lintl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 echo $ac_n "checking for gettext in libintl""... $ac_c" 1>&6 echo "configure:2983: checking for gettext in libintl" >&5 if eval "test \"`echo '$''{'gt_cv_func_gettext_libintl'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* gt_cv_func_gettext_libintl=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* gt_cv_func_gettext_libintl=no fi rm -f conftest* fi echo "$ac_t""$gt_cv_func_gettext_libintl" 1>&6 else echo "$ac_t""no" 1>&6 fi fi if test "$gt_cv_func_gettext_libc" = "yes" \ || test "$gt_cv_func_gettext_libintl" = "yes"; then cat >> confdefs.h <<\EOF #define HAVE_GETTEXT 1 EOF # Extract the first word of "msgfmt", so it can be a program name with args. set dummy msgfmt; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:3023: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else case "$MSGFMT" in /*) ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path. ;; *) IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then ac_cv_path_MSGFMT="$ac_dir/$ac_word" break fi fi done IFS="$ac_save_ifs" test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="no" ;; esac fi MSGFMT="$ac_cv_path_MSGFMT" if test -n "$MSGFMT"; then echo "$ac_t""$MSGFMT" 1>&6 else echo "$ac_t""no" 1>&6 fi if test "$MSGFMT" != "no"; then for ac_func in dcgettext do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:3057: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:3085: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <&6 fi done # Extract the first word of "gmsgfmt", so it can be a program name with args. set dummy gmsgfmt; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:3112: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else case "$GMSGFMT" in /*) ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path. ;; *) IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_path_GMSGFMT="$ac_dir/$ac_word" break fi done IFS="$ac_save_ifs" test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT" ;; esac fi GMSGFMT="$ac_cv_path_GMSGFMT" if test -n "$GMSGFMT"; then echo "$ac_t""$GMSGFMT" 1>&6 else echo "$ac_t""no" 1>&6 fi # Extract the first word of "xgettext", so it can be a program name with args. set dummy xgettext; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:3144: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else case "$XGETTEXT" in /*) ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path. ;; *) IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then ac_cv_path_XGETTEXT="$ac_dir/$ac_word" break fi fi done IFS="$ac_save_ifs" test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":" ;; esac fi XGETTEXT="$ac_cv_path_XGETTEXT" if test -n "$XGETTEXT"; then echo "$ac_t""$XGETTEXT" 1>&6 else echo "$ac_t""no" 1>&6 fi cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* CATOBJEXT=.gmo DATADIRNAME=share else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CATOBJEXT=.mo DATADIRNAME=lib fi rm -f conftest* INSTOBJEXT=.mo fi fi else echo "$ac_t""no" 1>&6 fi if test "$CATOBJEXT" = "NONE"; then echo $ac_n "checking whether catgets can be used""... $ac_c" 1>&6 echo "configure:3207: checking whether catgets can be used" >&5 # Check whether --with-catgets or --without-catgets was given. if test "${with_catgets+set}" = set; then withval="$with_catgets" nls_cv_use_catgets=$withval else nls_cv_use_catgets=no fi echo "$ac_t""$nls_cv_use_catgets" 1>&6 if test "$nls_cv_use_catgets" = "yes"; then echo $ac_n "checking for main in -li""... $ac_c" 1>&6 echo "configure:3220: checking for main in -li" >&5 ac_lib_var=`echo i'_'main | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-li $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_lib=HAVE_LIB`echo i | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` cat >> confdefs.h <&6 fi echo $ac_n "checking for catgets""... $ac_c" 1>&6 echo "configure:3263: checking for catgets" >&5 if eval "test \"`echo '$''{'ac_cv_func_catgets'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char catgets(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_catgets) || defined (__stub___catgets) choke me #else catgets(); #endif ; return 0; } EOF if { (eval echo configure:3291: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_catgets=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_catgets=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'catgets`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_CATGETS 1 EOF INTLOBJS="\$(CATOBJS)" # Extract the first word of "gencat", so it can be a program name with args. set dummy gencat; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:3313: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_GENCAT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else case "$GENCAT" in /*) ac_cv_path_GENCAT="$GENCAT" # Let the user override the test with a path. ;; *) IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_path_GENCAT="$ac_dir/$ac_word" break fi done IFS="$ac_save_ifs" test -z "$ac_cv_path_GENCAT" && ac_cv_path_GENCAT="no" ;; esac fi GENCAT="$ac_cv_path_GENCAT" if test -n "$GENCAT"; then echo "$ac_t""$GENCAT" 1>&6 else echo "$ac_t""no" 1>&6 fi if test "$GENCAT" != "no"; then # Extract the first word of "gmsgfmt", so it can be a program name with args. set dummy gmsgfmt; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:3345: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else case "$GMSGFMT" in /*) ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path. ;; *) IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_path_GMSGFMT="$ac_dir/$ac_word" break fi done IFS="$ac_save_ifs" test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="no" ;; esac fi GMSGFMT="$ac_cv_path_GMSGFMT" if test -n "$GMSGFMT"; then echo "$ac_t""$GMSGFMT" 1>&6 else echo "$ac_t""no" 1>&6 fi if test "$GMSGFMT" = "no"; then # Extract the first word of "msgfmt", so it can be a program name with args. set dummy msgfmt; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:3378: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else case "$GMSGFMT" in /*) ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path. ;; *) IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then ac_cv_path_GMSGFMT="$ac_dir/$ac_word" break fi fi done IFS="$ac_save_ifs" test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="no" ;; esac fi GMSGFMT="$ac_cv_path_GMSGFMT" if test -n "$GMSGFMT"; then echo "$ac_t""$GMSGFMT" 1>&6 else echo "$ac_t""no" 1>&6 fi fi # Extract the first word of "xgettext", so it can be a program name with args. set dummy xgettext; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:3413: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else case "$XGETTEXT" in /*) ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path. ;; *) IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then ac_cv_path_XGETTEXT="$ac_dir/$ac_word" break fi fi done IFS="$ac_save_ifs" test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":" ;; esac fi XGETTEXT="$ac_cv_path_XGETTEXT" if test -n "$XGETTEXT"; then echo "$ac_t""$XGETTEXT" 1>&6 else echo "$ac_t""no" 1>&6 fi USE_INCLUDED_LIBINTL=yes CATOBJEXT=.cat INSTOBJEXT=.cat DATADIRNAME=lib INTLDEPS='$(top_builddir)/intl/libintl.a' INTLLIBS=$INTLDEPS LIBS=`echo $LIBS | sed -e 's/-lintl//'` nls_cv_header_intl=intl/libintl.h nls_cv_header_libgt=intl/libgettext.h fi else echo "$ac_t""no" 1>&6 fi fi fi if test "$CATOBJEXT" = "NONE"; then nls_cv_use_gnu_gettext=yes fi fi if test "$nls_cv_use_gnu_gettext" = "yes"; then INTLOBJS="\$(GETTOBJS)" # Extract the first word of "msgfmt", so it can be a program name with args. set dummy msgfmt; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:3471: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else case "$MSGFMT" in /*) ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path. ;; *) IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then ac_cv_path_MSGFMT="$ac_dir/$ac_word" break fi fi done IFS="$ac_save_ifs" test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="msgfmt" ;; esac fi MSGFMT="$ac_cv_path_MSGFMT" if test -n "$MSGFMT"; then echo "$ac_t""$MSGFMT" 1>&6 else echo "$ac_t""no" 1>&6 fi # Extract the first word of "gmsgfmt", so it can be a program name with args. set dummy gmsgfmt; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:3505: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else case "$GMSGFMT" in /*) ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path. ;; *) IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_path_GMSGFMT="$ac_dir/$ac_word" break fi done IFS="$ac_save_ifs" test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT" ;; esac fi GMSGFMT="$ac_cv_path_GMSGFMT" if test -n "$GMSGFMT"; then echo "$ac_t""$GMSGFMT" 1>&6 else echo "$ac_t""no" 1>&6 fi # Extract the first word of "xgettext", so it can be a program name with args. set dummy xgettext; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:3537: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else case "$XGETTEXT" in /*) ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path. ;; *) IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then ac_cv_path_XGETTEXT="$ac_dir/$ac_word" break fi fi done IFS="$ac_save_ifs" test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":" ;; esac fi XGETTEXT="$ac_cv_path_XGETTEXT" if test -n "$XGETTEXT"; then echo "$ac_t""$XGETTEXT" 1>&6 else echo "$ac_t""no" 1>&6 fi USE_INCLUDED_LIBINTL=yes CATOBJEXT=.gmo INSTOBJEXT=.mo DATADIRNAME=share INTLDEPS='$(top_builddir)/intl/libintl.a' INTLLIBS=$INTLDEPS LIBS=`echo $LIBS | sed -e 's/-lintl//'` nls_cv_header_intl=intl/libintl.h nls_cv_header_libgt=intl/libgettext.h fi if test "$XGETTEXT" != ":"; then if $XGETTEXT --omit-header /dev/null 2> /dev/null; then : ; else echo "$ac_t""found xgettext programs is not GNU xgettext; ignore it" 1>&6 XGETTEXT=":" fi fi # We need to process the po/ directory. POSUB=po else DATADIRNAME=share nls_cv_header_intl=intl/libintl.h nls_cv_header_libgt=intl/libgettext.h fi # If this is used in GNU gettext we have to set USE_NLS to `yes' # because some of the sources are only built for this goal. if test "$PACKAGE" = gettext; then USE_NLS=yes USE_INCLUDED_LIBINTL=yes fi for lang in $ALL_LINGUAS; do GMOFILES="$GMOFILES $lang.gmo" POFILES="$POFILES $lang.po" done if test "x$CATOBJEXT" != "x"; then if test "x$ALL_LINGUAS" = "x"; then LINGUAS= else echo $ac_n "checking for catalogs to be installed""... $ac_c" 1>&6 echo "configure:3627: checking for catalogs to be installed" >&5 NEW_LINGUAS= for lang in ${LINGUAS=$ALL_LINGUAS}; do case "$ALL_LINGUAS" in *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;; esac done LINGUAS=$NEW_LINGUAS echo "$ac_t""$LINGUAS" 1>&6 fi if test -n "$LINGUAS"; then for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done fi fi if test $ac_cv_header_locale_h = yes; then INCLUDE_LOCALE_H="#include " else INCLUDE_LOCALE_H="\ /* The system does not provide the header . Take care yourself. */" fi test -d intl || mkdir intl if test "$CATOBJEXT" = ".cat"; then ac_safe=`echo "linux/version.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for linux/version.h""... $ac_c" 1>&6 echo "configure:3655: checking for linux/version.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:3665: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 msgformat=linux else echo "$ac_t""no" 1>&6 msgformat=xopen fi sed -e '/^#/d' $srcdir/intl/$msgformat-msg.sed > intl/po2msg.sed fi sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \ $srcdir/intl/po2tbl.sed.in > intl/po2tbl.sed if test "$PACKAGE" = "gettext"; then GT_NO="#NO#" GT_YES= else GT_NO= GT_YES="#YES#" fi MKINSTALLDIRS= if test -n "$ac_aux_dir"; then MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" fi if test -z "$MKINSTALLDIRS"; then MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" fi l= test -d po || mkdir po if test "x$srcdir" != "x."; then if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then posrcprefix="$srcdir/" else posrcprefix="../$srcdir/" fi else posrcprefix="../" fi rm -f po/POTFILES sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \ < $srcdir/po/POTFILES.in > po/POTFILES trap '' 1 2 15 cat > confcache <<\EOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs. It is not useful on other systems. # If it contains results you don't want to keep, you may remove or edit it. # # By default, configure uses ./config.cache as the cache file, # creating it if it does not exist already. You can give configure # the --cache-file=FILE option to use a different cache file; that is # what configure does when it calls configure scripts in # subdirectories, so they share the cache. # Giving --cache-file=/dev/null disables caching, for debugging configure. # config.status only pays attention to the cache file if you give it the # --recheck option to rerun configure. # EOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, don't put newlines in cache variables' values. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. (set) 2>&1 | case `(ac_space=' '; set) 2>&1` in *ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote substitution # turns \\\\ into \\, and sed turns \\ into \). sed -n \ -e "s/'/'\\\\''/g" \ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" ;; *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' ;; esac >> confcache if cmp -s $cache_file confcache; then : else if test -w $cache_file; then echo "updating cache $cache_file" cat confcache > $cache_file else echo "not updating unwritable cache $cache_file" fi fi rm -f confcache trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # Any assignment to VPATH causes Sun make to only execute # the first set of double-colon rules, so remove it if not needed. # If there is a colon in the path, we need to keep it. if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' fi trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 DEFS=-DHAVE_CONFIG_H # Without the "./", some shells look in PATH for config.status. : ${CONFIG_STATUS=./config.status} echo creating $CONFIG_STATUS rm -f $CONFIG_STATUS cat > $CONFIG_STATUS </dev/null | sed 1q`: # # $0 $ac_configure_args # # Compiler output produced by configure, useful for debugging # configure, is in ./config.log if it exists. ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" for ac_option do case "\$ac_option" in -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; -version | --version | --versio | --versi | --vers | --ver | --ve | --v) echo "$CONFIG_STATUS generated by autoconf version 2.12" exit 0 ;; -help | --help | --hel | --he | --h) echo "\$ac_cs_usage"; exit 0 ;; *) echo "\$ac_cs_usage"; exit 1 ;; esac done ac_given_srcdir=$srcdir ac_given_INSTALL="$INSTALL" trap 'rm -fr `echo "Makefile \ doc/Makefile \ info/Makefile \ intl/Makefile \ lib/Makefile \ makeinfo/Makefile \ po/Makefile.in \ util/Makefile \ config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 EOF cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF $ac_vpsub $extrasub s%@CFLAGS@%$CFLAGS%g s%@CPPFLAGS@%$CPPFLAGS%g s%@CXXFLAGS@%$CXXFLAGS%g s%@DEFS@%$DEFS%g s%@LDFLAGS@%$LDFLAGS%g s%@LIBS@%$LIBS%g s%@exec_prefix@%$exec_prefix%g s%@prefix@%$prefix%g s%@program_transform_name@%$program_transform_name%g s%@bindir@%$bindir%g s%@sbindir@%$sbindir%g s%@libexecdir@%$libexecdir%g s%@datadir@%$datadir%g s%@sysconfdir@%$sysconfdir%g s%@sharedstatedir@%$sharedstatedir%g s%@localstatedir@%$localstatedir%g s%@libdir@%$libdir%g s%@includedir@%$includedir%g s%@oldincludedir@%$oldincludedir%g s%@infodir@%$infodir%g s%@mandir@%$mandir%g s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g s%@INSTALL_DATA@%$INSTALL_DATA%g s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g s%@PACKAGE@%$PACKAGE%g s%@VERSION@%$VERSION%g s%@ACLOCAL@%$ACLOCAL%g s%@AUTOCONF@%$AUTOCONF%g s%@AUTOMAKE@%$AUTOMAKE%g s%@AUTOHEADER@%$AUTOHEADER%g s%@MAKEINFO@%$MAKEINFO%g s%@SET_MAKE@%$SET_MAKE%g s%@CC@%$CC%g s%@CPP@%$CPP%g s%@RANLIB@%$RANLIB%g s%@TEXCONFIG@%$TEXCONFIG%g s%@TEXMF@%$TEXMF%g s%@TERMLIBS@%$TERMLIBS%g s%@ALLOCA@%$ALLOCA%g s%@LIBOBJS@%$LIBOBJS%g s%@USE_NLS@%$USE_NLS%g s%@MSGFMT@%$MSGFMT%g s%@GMSGFMT@%$GMSGFMT%g s%@XGETTEXT@%$XGETTEXT%g s%@GENCAT@%$GENCAT%g s%@USE_INCLUDED_LIBINTL@%$USE_INCLUDED_LIBINTL%g s%@CATALOGS@%$CATALOGS%g s%@CATOBJEXT@%$CATOBJEXT%g s%@DATADIRNAME@%$DATADIRNAME%g s%@GMOFILES@%$GMOFILES%g s%@INSTOBJEXT@%$INSTOBJEXT%g s%@INTLDEPS@%$INTLDEPS%g s%@INTLLIBS@%$INTLLIBS%g s%@INTLOBJS@%$INTLOBJS%g s%@POFILES@%$POFILES%g s%@POSUB@%$POSUB%g s%@INCLUDE_LOCALE_H@%$INCLUDE_LOCALE_H%g s%@GT_NO@%$GT_NO%g s%@GT_YES@%$GT_YES%g s%@MKINSTALLDIRS@%$MKINSTALLDIRS%g s%@l@%$l%g CEOF EOF cat >> $CONFIG_STATUS <<\EOF # Split the substitutions into bite-sized pieces for seds with # small command number limits, like on Digital OSF/1 and HP-UX. ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. ac_file=1 # Number of current file. ac_beg=1 # First line for current file. ac_end=$ac_max_sed_cmds # Line after last line for current file. ac_more_lines=: ac_sed_cmds="" while $ac_more_lines; do if test $ac_beg -gt 1; then sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file else sed "${ac_end}q" conftest.subs > conftest.s$ac_file fi if test ! -s conftest.s$ac_file; then ac_more_lines=false rm -f conftest.s$ac_file else if test -z "$ac_sed_cmds"; then ac_sed_cmds="sed -f conftest.s$ac_file" else ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" fi ac_file=`expr $ac_file + 1` ac_beg=$ac_end ac_end=`expr $ac_end + $ac_max_sed_cmds` fi done if test -z "$ac_sed_cmds"; then ac_sed_cmds=cat fi EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. # Remove last slash and all that follows it. Not all systems have dirname. ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then # The file is in a subdirectory. test ! -d "$ac_dir" && mkdir "$ac_dir" ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" # A "../" for each directory in $ac_dir_suffix. ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` else ac_dir_suffix= ac_dots= fi case "$ac_given_srcdir" in .) srcdir=. if test -z "$ac_dots"; then top_srcdir=. else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; *) # Relative path. srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" top_srcdir="$ac_dots$ac_given_srcdir" ;; esac case "$ac_given_INSTALL" in [/$]*) INSTALL="$ac_given_INSTALL" ;; *) INSTALL="$ac_dots$ac_given_INSTALL" ;; esac echo creating "$ac_file" rm -f "$ac_file" configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." case "$ac_file" in *Makefile*) ac_comsub="1i\\ # $configure_input" ;; *) ac_comsub= ;; esac ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` sed -e "$ac_comsub s%@configure_input@%$configure_input%g s%@srcdir@%$srcdir%g s%@top_srcdir@%$top_srcdir%g s%@INSTALL@%$INSTALL%g " $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file fi; done rm -f conftest.s* # These sed commands are passed to sed as "A NAME B NAME C VALUE D", where # NAME is the cpp macro being defined and VALUE is the value it is being given. # # ac_d sets the value in "#define NAME VALUE" lines. ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' ac_dC='\3' ac_dD='%g' # ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_uB='\([ ]\)%\1#\2define\3' ac_uC=' ' ac_uD='\4%g' # ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_eB='$%\1#\2define\3' ac_eC=' ' ac_eD='%g' if test "${CONFIG_HEADERS+set}" != set; then EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF fi for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac echo creating $ac_file rm -f conftest.frag conftest.in conftest.out ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` cat $ac_file_inputs > conftest.in EOF # Transform confdefs.h into a sed script conftest.vals that substitutes # the proper values into config.h.in to produce config.h. And first: # Protect against being on the right side of a sed subst in config.status. # Protect against being in an unquoted here document in config.status. rm -f conftest.vals cat > conftest.hdr <<\EOF s/[\\&%]/\\&/g s%[\\$`]%\\&%g s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp s%ac_d%ac_u%gp s%ac_u%ac_e%gp EOF sed -n -f conftest.hdr confdefs.h > conftest.vals rm -f conftest.hdr # This sed command replaces #undef with comments. This is necessary, for # example, in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. cat >> conftest.vals <<\EOF s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% EOF # Break up conftest.vals because some shells have a limit on # the size of here documents, and old seds have small limits too. rm -f conftest.tail while : do ac_lines=`grep -c . conftest.vals` # grep -c gives empty output for an empty file on some AIX systems. if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi # Write a limited-size here document to conftest.frag. echo ' cat > conftest.frag <> $CONFIG_STATUS sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS echo 'CEOF sed -f conftest.frag conftest.in > conftest.out rm -f conftest.in mv conftest.out conftest.in ' >> $CONFIG_STATUS sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail rm -f conftest.vals mv conftest.tail conftest.vals done rm -f conftest.vals cat >> $CONFIG_STATUS <<\EOF rm -f conftest.frag conftest.h echo "/* $ac_file. Generated automatically by configure. */" > conftest.h cat conftest.in >> conftest.h rm -f conftest.in if cmp -s $ac_file conftest.h 2>/dev/null; then echo "$ac_file is unchanged" rm -f conftest.h else # Remove last slash and all that follows it. Not all systems have dirname. ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then # The file is in a subdirectory. test ! -d "$ac_dir" && mkdir "$ac_dir" fi rm -f $ac_file mv conftest.h $ac_file fi fi; done EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF srcdir=$ac_given_srcdir while test -n "$ac_sources"; do set $ac_dests; ac_dest=$1; shift; ac_dests=$* set $ac_sources; ac_source=$1; shift; ac_sources=$* echo "linking $srcdir/$ac_source to $ac_dest" if test ! -r $srcdir/$ac_source; then { echo "configure: error: $srcdir/$ac_source: File not found" 1>&2; exit 1; } fi rm -f $ac_dest # Make relative symlinks. # Remove last slash and all that follows it. Not all systems have dirname. ac_dest_dir=`echo $ac_dest|sed 's%/[^/][^/]*$%%'` if test "$ac_dest_dir" != "$ac_dest" && test "$ac_dest_dir" != .; then # The dest file is in a subdirectory. test ! -d "$ac_dest_dir" && mkdir "$ac_dest_dir" ac_dest_dir_suffix="/`echo $ac_dest_dir|sed 's%^\./%%'`" # A "../" for each directory in $ac_dest_dir_suffix. ac_dots=`echo $ac_dest_dir_suffix|sed 's%/[^/]*%../%g'` else ac_dest_dir_suffix= ac_dots= fi case "$srcdir" in [/$]*) ac_rel_source="$srcdir/$ac_source" ;; *) ac_rel_source="$ac_dots$srcdir/$ac_source" ;; esac # Make a symlink if possible; otherwise try a hard link. if ln -s $ac_rel_source $ac_dest 2>/dev/null || ln $srcdir/$ac_source $ac_dest; then : else { echo "configure: error: can not link $ac_dest to $srcdir/$ac_source" 1>&2; exit 1; } fi done EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in >po/Makefile exit 0 EOF chmod +x $CONFIG_STATUS rm -fr confdefs* $ac_clean_files test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 texinfo-3.12/intl/0000775000175000017500000000000006477056742011342 5ustar ggtexinfo-3.12/intl/Makefile.in0000664000175000017500000001450106475640103013374 0ustar gg# Makefile for directory with message catalog handling in GNU NLS Utilities. # Copyright (C) 1995, 1996, 1997 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, USA. PACKAGE = @PACKAGE@ VERSION = @VERSION@ SHELL = /bin/sh srcdir = @srcdir@ top_srcdir = @top_srcdir@ top_builddir = .. VPATH = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ transform = @program_transform_name@ libdir = $(exec_prefix)/lib includedir = $(prefix)/include datadir = $(prefix)/@DATADIRNAME@ localedir = $(datadir)/locale gnulocaledir = $(prefix)/share/locale gettextsrcdir = @datadir@/gettext/intl aliaspath = $(localedir):. subdir = intl INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ MKINSTALLDIRS = @MKINSTALLDIRS@ l = @l@ AR = ar CC = @CC@ LIBTOOL = @LIBTOOL@ RANLIB = @RANLIB@ DEFS = -DLOCALEDIR=\"$(localedir)\" -DGNULOCALEDIR=\"$(gnulocaledir)\" \ -DLOCALE_ALIAS_PATH=\"$(aliaspath)\" @DEFS@ CPPFLAGS = @CPPFLAGS@ CFLAGS = @CFLAGS@ LDFLAGS = @LDFLAGS@ COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS) HEADERS = $(COMHDRS) libgettext.h loadinfo.h COMHDRS = gettext.h gettextP.h hash-string.h SOURCES = $(COMSRCS) intl-compat.c cat-compat.c COMSRCS = bindtextdom.c dcgettext.c dgettext.c gettext.c \ finddomain.c loadmsgcat.c localealias.c textdomain.c l10nflist.c \ explodename.c OBJECTS = @INTLOBJS@ bindtextdom.$lo dcgettext.$lo dgettext.$lo gettext.$lo \ finddomain.$lo loadmsgcat.$lo localealias.$lo textdomain.$lo l10nflist.$lo \ explodename.$lo CATOBJS = cat-compat.$lo ../po/cat-id-tbl.$lo GETTOBJS = intl-compat.$lo DISTFILES.common = ChangeLog Makefile.in linux-msg.sed po2tbl.sed.in \ xopen-msg.sed $(HEADERS) $(SOURCES) DISTFILES.normal = VERSION DISTFILES.gettext = libintl.glibc intlh.inst.in .SUFFIXES: .SUFFIXES: .c .o .lo .c.o: $(COMPILE) $< .c.lo: $(LIBTOOL) --mode=compile $(COMPILE) $< INCLUDES = -I.. -I. -I$(top_srcdir)/intl -I$(top_srcdir)/lib all: all-@USE_INCLUDED_LIBINTL@ all-yes: libintl.$la intlh.inst all-no: libintl.a: $(OBJECTS) rm -f $@ $(AR) cru $@ $(OBJECTS) $(RANLIB) $@ libintl.la: $(OBJECTS) $(LIBTOOL) --mode=link $(CC) $(LDFLAGS) -o $@ $(OBJECTS) \ -version-info 1:0 -rpath $(libdir) ../po/cat-id-tbl.$lo: ../po/cat-id-tbl.c $(top_srcdir)/po/$(PACKAGE).pot cd ../po && $(MAKE) cat-id-tbl.$lo check: all # This installation goal is only used in GNU gettext. Packages which # only use the library should use install instead. # We must not install the libintl.h/libintl.a files if we are on a # system which has the gettext() function in its C library or in a # separate library or use the catgets interface. A special case is # where configure found a previously installed GNU gettext library. # If you want to use the one which comes with this version of the # package, you have to use `configure --with-included-gettext'. install: install-exec install-data install-exec: all if test "$(PACKAGE)" = "gettext" \ && test '@INTLOBJS@' = '$(GETTOBJS)'; then \ if test -r $(MKINSTALLDIRS); then \ $(MKINSTALLDIRS) $(libdir) $(includedir); \ else \ $(top_srcdir)/mkinstalldirs $(libdir) $(includedir); \ fi; \ $(INSTALL_DATA) intlh.inst $(includedir)/libintl.h; \ $(INSTALL_DATA) libintl.a $(libdir)/libintl.a; \ else \ : ; \ fi install-data: all if test "$(PACKAGE)" = "gettext"; then \ if test -r $(MKINSTALLDIRS); then \ $(MKINSTALLDIRS) $(gettextsrcdir); \ else \ $(top_srcdir)/mkinstalldirs $(gettextsrcdir); \ fi; \ $(INSTALL_DATA) VERSION $(gettextsrcdir)/VERSION; \ dists="$(DISTFILES.common)"; \ for file in $$dists; do \ $(INSTALL_DATA) $(srcdir)/$$file $(gettextsrcdir)/$$file; \ done; \ else \ : ; \ fi # Define this as empty until I found a useful application. installcheck: uninstall: dists="$(DISTFILES.common)"; \ for file in $$dists; do \ rm -f $(gettextsrcdir)/$$file; \ done info dvi: $(OBJECTS): ../config.h libgettext.h bindtextdom.$lo finddomain.$lo loadmsgcat.$lo: gettextP.h gettext.h loadinfo.h dcgettext.$lo: gettextP.h gettext.h hash-string.h loadinfo.h tags: TAGS TAGS: $(HEADERS) $(SOURCES) here=`pwd`; cd $(srcdir) && etags -o $$here/TAGS $(HEADERS) $(SOURCES) id: ID ID: $(HEADERS) $(SOURCES) here=`pwd`; cd $(srcdir) && mkid -f$$here/ID $(HEADERS) $(SOURCES) mostlyclean: rm -f *.a *.o *.lo core core.* clean: mostlyclean distclean: clean rm -f Makefile ID TAGS po2msg.sed po2tbl.sed libintl.h maintainer-clean: distclean @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." # GNU gettext needs not contain the file `VERSION' but contains some # other files which should not be distributed in other packages. distdir = ../$(PACKAGE)-$(VERSION)/$(subdir) dist distdir: Makefile $(DISTFILES) if test "$(PACKAGE)" = gettext; then \ additional="$(DISTFILES.gettext)"; \ else \ additional="$(DISTFILES.normal)"; \ fi; \ for file in $(DISTFILES.common) $$additional; do \ ln $(srcdir)/$$file $(distdir) 2> /dev/null \ || cp -p $(srcdir)/$$file $(distdir); \ done dist-libc: tar zcvf intl-glibc.tar.gz $(COMSRCS) $(COMHDRS) libintl.h.glibc Makefile: Makefile.in ../config.status cd .. \ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status # The dependency for intlh.inst is different in gettext and all other # packages. Because we cannot you GNU make features we have to solve # the problem while rewriting Makefile.in. @GT_YES@intlh.inst: intlh.inst.in ../config.status @GT_YES@ cd .. \ @GT_YES@ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= \ @GT_YES@ $(SHELL) ./config.status @GT_NO@.PHONY: intlh.inst @GT_NO@intlh.inst: # Tell versions [3.59,3.63) of GNU make not to export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: texinfo-3.12/intl/ChangeLog0000664000175000017500000010040106475640103013074 0ustar gg1997-09-06 02:10 Ulrich Drepper * intlh.inst.in: Reformat copyright. 1997-08-19 15:22 Ulrich Drepper * dcgettext.c (DCGETTEXT): Remove wrong comment. 1997-08-16 00:13 Ulrich Drepper * Makefile.in (install-data): Don't change directory to install. 1997-08-01 14:30 Ulrich Drepper * cat-compat.c: Fix copyright. * localealias.c: Don't define strchr unless !HAVE_STRCHR. * loadmsgcat.c: Update copyright. Fix typos. * l10nflist.c: Don't define strchr unless !HAVE_STRCHR. (_nl_make_l10nflist): Handle sponsor and revision correctly. * gettext.c: Update copyright. * gettext.h: Likewise. * hash-string.h: Likewise. * finddomain.c: Remoave dead code. Define strchr only if !HAVE_STRCHR. * explodename.c: Include . * explodename.c: Reformat copyright text. (_nl_explode_name): Fix typo. * dcgettext.c: Define and use __set_errno. (guess_category_value): Don't use setlocale if HAVE_LC_MESSAGES is not defined. * bindtextdom.c: Pretty printing. 1997-05-01 02:25 Ulrich Drepper * dcgettext.c (guess_category_value): Don't depend on HAVE_LC_MESSAGES. We don't need the macro here. Patch by Bruno Haible . * cat-compat.c (textdomain): DoN't refer to HAVE_SETLOCALE_NULL macro. Instead use HAVE_LOCALE_NULL and define it when using glibc, as in dcgettext.c. Patch by Bruno Haible . * Makefile.in (CPPFLAGS): New variable. Reported by Franc,ois Pinard. Mon Mar 10 06:51:17 1997 Ulrich Drepper * Makefile.in: Implement handling of libtool. * gettextP.h: Change data structures for use of generic lowlevel i18n file handling. Wed Dec 4 20:21:18 1996 Ulrich Drepper * textdomain.c: Put parentheses around arguments of memcpy macro definition. * localealias.c: Likewise. * l10nflist.c: Likewise. * finddomain.c: Likewise. * bindtextdom.c: Likewise. Reported by Thomas Esken. Mon Nov 25 22:57:51 1996 Ulrich Drepper * textdomain.c: Move definition of `memcpy` macro to right position. Fri Nov 22 04:01:58 1996 Ulrich Drepper * finddomain.c [!HAVE_STRING_H && !_LIBC]: Define memcpy using bcopy if not already defined. Reported by Thomas Esken. * bindtextdom.c: Likewise. * l10nflist.c: Likewise. * localealias.c: Likewise. * textdomain.c: Likewise. Tue Oct 29 11:10:27 1996 Ulrich Drepper * Makefile.in (libdir): Change to use exec_prefix instead of prefix. Reported by Knut-HåvardAksnes . Sat Aug 31 03:07:09 1996 Ulrich Drepper * l10nflist.c (_nl_normalize_codeset): We convert to lower case, so don't prepend uppercase `ISO' for only numeric arg. Fri Jul 19 00:15:46 1996 Ulrich Drepper * l10nflist.c: Move inclusion of argz.h, ctype.h, stdlib.h after definition of _GNU_SOURCE. Patch by Roland McGrath. * Makefile.in (uninstall): Fix another bug with `for' loop and empty arguments. Patch by Jim Meyering. Correct name os uninstalled files: no intl- prefix anymore. * Makefile.in (install-data): Again work around shells which cannot handle mpty for list. Reported by Jim Meyering. Sat Jul 13 18:11:35 1996 Ulrich Drepper * Makefile.in (install): Split goal. Now depend on install-exec and install-data. (install-exec, install-data): New goals. Created from former install goal. Reported by Karl Berry. Sat Jun 22 04:58:14 1996 Ulrich Drepper * Makefile.in (MKINSTALLDIRS): New variable. Path to mkinstalldirs script. (install): use MKINSTALLDIRS variable or if the script is not present try to find it in the $top_scrdir). Wed Jun 19 02:56:56 1996 Ulrich Drepper * l10nflist.c: Linux libc *partly* includes the argz_* functions. Grr. Work around by renaming the static version and use macros for renaming. Tue Jun 18 20:11:17 1996 Ulrich Drepper * l10nflist.c: Correct presence test macros of __argz_* functions. * l10nflist.c: Include based on test of it instead when __argz_* functions are available. Reported by Andreas Schwab. Thu Jun 13 15:17:44 1996 Ulrich Drepper * explodename.c, l10nflist.c: Define NULL for dumb systems. Tue Jun 11 17:05:13 1996 Ulrich Drepper * intlh.inst.in, libgettext.h (dcgettext): Rename local variable result to __result to prevent name clash. * l10nflist.c, localealias.c, dcgettext.c: Define _GNU_SOURCE to get prototype for stpcpy and strcasecmp. * intlh.inst.in, libgettext.h: Move declaration of `_nl_msg_cat_cntr' outside __extension__ block to prevent warning from gcc's -Wnested-extern option. Fri Jun 7 01:58:00 1996 Ulrich Drepper * Makefile.in (install): Remove comment. Thu Jun 6 17:28:17 1996 Ulrich Drepper * Makefile.in (install): Work around for another Buglix stupidity. Always use an `else' close for `if's. Reported by Nelson Beebe. * Makefile.in (intlh.inst): Correct typo in phony rule. Reported by Nelson Beebe. Thu Jun 6 01:49:52 1996 Ulrich Drepper * dcgettext.c (read_alias_file): Rename variable alloca_list to block_list as the macro calls assume. Patch by Eric Backus. * localealias.c [!HAVE_ALLOCA]: Define alloca as macro using malloc. (read_alias_file): Rename varriabe alloca_list to block_list as the macro calls assume. Patch by Eric Backus. * l10nflist.c: Correct conditional for inclusion. Reported by Roland McGrath. * Makefile.in (all): Depend on all-@USE_INCLUDED_LIBINTL@, not all-@USE_NLS@. * Makefile.in (install): intlh.inst comes from local dir, not $(srcdir). * Makefile.in (intlh.inst): Special handling of this goal. If used in gettext, this is really a rul to construct this file. If used in any other package it is defined as a .PHONY rule with empty body. * finddomain.c: Extract locale file information handling into l10nfile.c. Rename local stpcpy__ function to stpcpy. * dcgettext.c (stpcpy): Add local definition. * l10nflist.c: Solve some portability problems. Patches partly by Thomas Esken. Add local definition of stpcpy. Tue Jun 4 02:47:49 1996 Ulrich Drepper * intlh.inst.in: Don't depend including on HAVE_LOCALE_H. Instead configure must rewrite this fiile depending on the result of the configure run. * Makefile.in (install): libintl.inst is now called intlh.inst. Add rules for updating intlh.inst from intlh.inst.in. * libintl.inst: Renamed to intlh.inst.in. * localealias.c, dcgettext.c [__GNUC__]: Define HAVE_ALLOCA to 1 because gcc has __buitlin_alloca. Reported by Roland McGrath. Mon Jun 3 00:32:16 1996 Ulrich Drepper * Makefile.in (installcheck): New goal to fulfill needs of automake's distcheck. * Makefile.in (install): Reorder commands so that VERSION is found. * Makefile.in (gettextsrcdir): Now use subdirectory intl/ in @datadir@/gettext. (COMSRCS): Add l10nfile.c. (OBJECTS): Add l10nfile.o. (DISTFILES): Rename to DISTFILE.normal. Remove $(DISTFILES.common). (DISTFILE.gettext): Remove $(DISTFILES.common). (all-gettext): Remove goal. (install): If $(PACKAGE) = gettext install, otherwose do nothing. No package but gettext itself should install libintl.h + headers. (dist): Extend goal to work for gettext, too. (dist-gettext): Remove goal. * dcgettext.c [!HAVE_ALLOCA]: Define macro alloca by using malloc. Sun Jun 2 17:33:06 1996 Ulrich Drepper * loadmsgcat.c (_nl_load_domain): Parameter is now comes from find_l10nfile. Sat Jun 1 02:23:03 1996 Ulrich Drepper * l10nflist.c (__argz_next): Add definition. * dcgettext.c [!HAVE_ALLOCA]: Add code for handling missing alloca code. Use new l10nfile handling. * localealias.c [!HAVE_ALLOCA]: Add code for handling missing alloca code. * l10nflist.c: Initial revision. Tue Apr 2 18:51:18 1996 Ulrich Drepper * Makefile.in (all-gettext): New goal. Same as all-yes. Thu Mar 28 23:01:22 1996 Karl Eichwalder * Makefile.in (gettextsrcdir): Define using @datadir@. Tue Mar 26 12:39:14 1996 Ulrich Drepper * finddomain.c: Include . Reported by Roland McGrath. Sat Mar 23 02:00:35 1996 Ulrich Drepper * finddomain.c (stpcpy): Rename to stpcpy__ to prevent clashing with external declaration. Sat Mar 2 00:47:09 1996 Ulrich Drepper * Makefile.in (all-no): Rename from all_no. Sat Feb 17 00:25:59 1996 Ulrich Drepper * gettextP.h [loaded_domain]: Array `successor' must now contain up to 63 elements (because of codeset name normalization). * finddomain.c: Implement codeset name normalization. Thu Feb 15 04:39:09 1996 Ulrich Drepper * Makefile.in (all): Define to `all-@USE_NLS@'. (all-yes, all_no): New goals. `all-no' is noop, `all-yes' is former all. Mon Jan 15 21:46:01 1996 Howard Gayle * localealias.c (alias_compare): Increment string pointers in loop of strcasecmp replacement. Fri Dec 29 21:16:34 1995 Ulrich Drepper * Makefile.in (install-src): Who commented this goal out ? :-) Fri Dec 29 15:08:16 1995 Ulrich Drepper * dcgettext.c (DCGETTEXT): Save `errno'. Failing system calls should not effect it because a missing catalog is no error. Reported by Harald Knig . Tue Dec 19 22:09:13 1995 Ulrich Drepper * Makefile.in (Makefile): Explicitly use $(SHELL) for running shell scripts. Fri Dec 15 17:34:59 1995 Andreas Schwab * Makefile.in (install-src): Only install library and header when we use the own implementation. Don't do it when using the system's gettext or catgets functions. * dcgettext.c (find_msg): Must not swap domain->hash_size here. Sat Dec 9 16:24:37 1995 Ulrich Drepper * localealias.c, libintl.inst, libgettext.h, hash-string.h, gettextP.h, finddomain.c, dcgettext.c, cat-compat.c: Use PARAMS instead of __P. Suggested by Roland McGrath. Tue Dec 5 11:39:14 1995 Larry Schwimmer * libgettext.h: Use `#if !defined (_LIBINTL_H)' instead of `#if !_LIBINTL_H' because Solaris defines _LIBINTL_H as empty. Mon Dec 4 15:42:07 1995 Ulrich Drepper * Makefile.in (install-src): Install libintl.inst instead of libintl.h.install. Sat Dec 2 22:51:38 1995 Marcus Daniels * cat-compat.c (textdomain): Reverse order in which files are tried you load. First try local file, when this failed absolute path. Wed Nov 29 02:03:53 1995 Nelson H. F. Beebe * cat-compat.c (bindtextdomain): Add missing { }. Sun Nov 26 18:21:41 1995 Ulrich Drepper * libintl.inst: Add missing __P definition. Reported by Nelson Beebe. * Makefile.in: Add dummy `all' and `dvi' goals. Reported by Tom Tromey. Sat Nov 25 16:12:01 1995 Franc,ois Pinard * hash-string.h: Capitalize arguments of macros. Sat Nov 25 12:01:36 1995 Ulrich Drepper * Makefile.in (DISTFILES): Prevent files names longer than 13 characters. libintl.h.glibc->libintl.glibc, libintl.h.install->libintl.inst. Reported by Joshua R. Poulson. Sat Nov 25 11:31:12 1995 Eric Backus * dcgettext.c: Fix bug in preprocessor conditionals. Sat Nov 25 02:35:27 1995 Nelson H. F. Beebe * libgettext.h: Solaris cc does not understand #if !SYMBOL1 && !SYMBOL2. Sad but true. Thu Nov 23 16:22:14 1995 Ulrich Drepper * hash-string.h (hash_string): Fix for machine with >32 bit `unsigned long's. * dcgettext.c (DCGETTEXT): Fix horrible bug in loop for alternative translation. Thu Nov 23 01:45:29 1995 Ulrich Drepper * po2tbl.sed.in, linux-msg.sed, xopen-msg.sed: Some further simplifications in message number generation. Mon Nov 20 21:08:43 1995 Ulrich Drepper * libintl.h.glibc: Use __const instead of const in prototypes. * Makefile.in (install-src): Install libintl.h.install instead of libintl.h. This is a stripped-down version. Suggested by Peter Miller. * libintl.h.install, libintl.h.glibc: Initial revision. * localealias.c (_nl_expand_alias, read_alias_file): Protect prototypes in type casts by __P. Tue Nov 14 16:43:58 1995 Ulrich Drepper * hash-string.h: Correct prototype for hash_string. Sun Nov 12 12:42:30 1995 Ulrich Drepper * hash-string.h (hash_string): Add prototype. * gettextP.h: Fix copyright. (SWAP): Add prototype. Wed Nov 8 22:56:33 1995 Ulrich Drepper * localealias.c (read_alias_file): Forgot sizeof. Avoid calling *printf function. This introduces a big overhead. Patch by Roland McGrath. Tue Nov 7 14:21:08 1995 Ulrich Drepper * finddomain.c, cat-compat.c: Wrong indentation in #if for stpcpy. * finddomain.c (stpcpy): Define substitution function local. The macro was to flaky. * cat-compat.c: Fix typo. * xopen-msg.sed, linux-msg.sed: While bringing message number to right place only accept digits. * linux-msg.sed, xopen-msg.sed: Now that the counter does not have leading 0s we don't need to remove them. Reported by Marcus Daniels. * Makefile.in (../po/cat-id-tbl.o): Use $(top_srdir) in dependency. Reported by Marcus Daniels. * cat-compat.c: (stpcpy) [!_LIBC && !HAVE_STPCPY]: Define replacement. Generally cleanup using #if instead of #ifndef. * Makefile.in: Correct typos in comment. By Franc,ois Pinard. Mon Nov 6 00:27:02 1995 Ulrich Drepper * Makefile.in (install-src): Don't install libintl.h and libintl.a if we use an available gettext implementation. Sun Nov 5 22:02:08 1995 Ulrich Drepper * libgettext.h: Fix typo: HAVE_CATGETTS -> HAVE_CATGETS. Reported by Franc,ois Pinard. * libgettext.h: Use #if instead of #ifdef/#ifndef. * finddomain.c: Comments describing what has to be done should start with FIXME. Sun Nov 5 19:38:01 1995 Ulrich Drepper * Makefile.in (DISTFILES): Split. Use DISTFILES with normal meaning. DISTFILES.common names the files common to both dist goals. DISTFILES.gettext are the files only distributed in GNU gettext. Sun Nov 5 17:32:54 1995 Ulrich Drepper * dcgettext.c (DCGETTEXT): Correct searching in derived locales. This was necessary since a change in _nl_find_msg several weeks ago. I really don't know this is still not fixed. Sun Nov 5 12:43:12 1995 Ulrich Drepper * loadmsgcat.c (_nl_load_domain): Test for FILENAME == NULL. This might mark a special condition. * finddomain.c (make_entry_rec): Don't make illegal entry as decided. * Makefile.in (dist): Suppress error message when ln failed. Get files from $(srcdir) explicitly. * libgettext.h (gettext_const): Rename to gettext_noop. Fri Nov 3 07:36:50 1995 Ulrich Drepper * finddomain.c (make_entry_rec): Protect against wrong locale names by testing mask. * libgettext.h (gettext_const): Add macro definition. Capitalize macro arguments. Thu Nov 2 23:15:51 1995 Ulrich Drepper * finddomain.c (_nl_find_domain): Test for pointer != NULL before accessing value. Reported by Tom Tromey. * gettext.c (NULL): Define as (void*)0 instad of 0. Reported by Franc,ois Pinard. Mon Oct 30 21:28:52 1995 Ulrich Drepper * po2tbl.sed.in: Serious typo bug fixed by Jim Meyering. Sat Oct 28 23:20:47 1995 Ulrich Drepper * libgettext.h: Disable dcgettext optimization for Solaris 2.3. * localealias.c (alias_compare): Peter Miller reported that tolower in some systems is even dumber than I thought. Protect call by `isupper'. Fri Oct 27 22:22:51 1995 Ulrich Drepper * Makefile.in (libdir, includedir): New variables. (install-src): Install libintl.a and libintl.h in correct dirs. Fri Oct 27 22:07:29 1995 Ulrich Drepper * Makefile.in (SOURCES): Fix typo: intrl.compat.c -> intl-compat.c. * po2tbl.sed.in: Patch for buggy SEDs by Christian von Roques. * localealias.c: Fix typo and superflous test. Reported by Christian von Roques. Fri Oct 6 11:52:05 1995 Ulrich Drepper * finddomain.c (_nl_find_domain): Correct some remainder from the pre-CEN syntax. Now we don't have a constant number of successors anymore. Wed Sep 27 21:41:13 1995 Ulrich Drepper * Makefile.in (DISTFILES): Add libintl.h.glibc. * Makefile.in (dist-libc): Add goal for packing sources for glibc. (COMSRCS, COMHDRS): Splitted to separate sources shared with glibc. * loadmsgcat.c: Forget to continue #if line. * localealias.c: [_LIBC]: Rename strcasecmp to __strcasecmp to keep ANSI C name space clean. * dcgettext.c, finddomain.c: Better comment to last change. * loadmsgcat.c: [_LIBC]: Rename fstat, open, close, read, mmap, and munmap to __fstat, __open, __close, __read, __mmap, and __munmap resp to keep ANSI C name space clean. * finddomain.c: [_LIBC]: Rename stpcpy to __stpcpy to keep ANSI C name space clean. * dcgettext.c: [_LIBC]: Rename getced and stpcpy to __getcwd and __stpcpy resp to keep ANSI C name space clean. * libgettext.h: Include sys/types.h for those old SysV systems out there. Reported by Francesco Potorti`. * loadmsgcat.c (use_mmap): Define if compiled for glibc. * bindtextdom.c: Include all those standard headers unconditionally if _LIBC is defined. * finddomain.c: Fix 2 times defiend -> defined. * textdomain.c: Include libintl.h instead of libgettext.h when compiling for glibc. Include all those standard headers unconditionally if _LIBC is defined. * localealias.c, loadmsgcat.c: Prepare to be compiled in glibc. * gettext.c: Include libintl.h instead of libgettext.h when compiling for glibc. Get NULL from stddef.h if we compile for glibc. * finddomain.c: Include libintl.h instead of libgettext.h when compiling for glibc. Include all those standard headers unconditionally if _LIBC is defined. * dcgettext.c: Include all those standard headers unconditionally if _LIBC is defined. * dgettext.c: If compiled in glibc include libintl.h instead of libgettext.h. (locale.h): Don't rely on HAVE_LOCALE_H when compiling for glibc. * dcgettext.c: If compiled in glibc include libintl.h instead of libgettext.h. (getcwd): Don't rely on HAVE_GETCWD when compiling for glibc. * bindtextdom.c: If compiled in glibc include libintl.h instead of libgettext.h. Mon Sep 25 22:23:06 1995 Ulrich Drepper * localealias.c (_nl_expand_alias): Don't call bsearch if NMAP <= 0. Reported by Marcus Daniels. * cat-compat.c (bindtextdomain): String used in putenv must not be recycled. Reported by Marcus Daniels. * libgettext.h (__USE_GNU_GETTEXT): Additional symbol to signal that we use GNU gettext library. * cat-compat.c (bindtextdomain): Fix bug with the strange stpcpy replacement. Reported by Nelson Beebe. Sat Sep 23 08:23:51 1995 Ulrich Drepper * cat-compat.c: Include for stpcpy prototype. * localealias.c (read_alias_file): While expand strdup code temporary variable `cp' hided higher level variable with same name. Rename to `tp'. * textdomain.c (textdomain): Avoid warning by using temporary variable in strdup code. * finddomain.c (_nl_find_domain): Remove unused variable `application'. Thu Sep 21 15:51:44 1995 Ulrich Drepper * localealias.c (alias_compare): Use strcasecmp() only if available. Else use implementation in place. * intl-compat.c: Wrapper functions now call *__ functions instead of __*. * libgettext.h: Declare prototypes for *__ functions instead for __*. * cat-compat.c, loadmsgcat.c: Don't use xmalloc, xstrdup, and stpcpy. These functions are not part of the standard libc and so prevent libintl.a from being used standalone. * bindtextdom.c: Don't use xmalloc, xstrdup, and stpcpy. These functions are not part of the standard libc and so prevent libintl.a from being used standalone. Rename to bindtextdomain__ if not used in GNU C Library. * dgettext.c: Rename function to dgettext__ if not used in GNU C Library. * gettext.c: Don't use xmalloc, xstrdup, and stpcpy. These functions are not part of the standard libc and so prevent libintl.a from being used standalone. Functions now called gettext__ if not used in GNU C Library. * dcgettext.c, localealias.c, textdomain.c, finddomain.c: Don't use xmalloc, xstrdup, and stpcpy. These functions are not part of the standard libc and so prevent libintl.a from being used standalone. Sun Sep 17 23:14:49 1995 Ulrich Drepper * finddomain.c: Correct some bugs in handling of CEN standard locale definitions. Thu Sep 7 01:49:28 1995 Ulrich Drepper * finddomain.c: Implement CEN syntax. * gettextP.h (loaded_domain): Extend number of successors to 31. Sat Aug 19 19:25:29 1995 Ulrich Drepper * Makefile.in (aliaspath): Remove path to X11 locale dir. * Makefile.in: Make install-src depend on install. This helps gettext to install the sources and other packages can use the install goal. Sat Aug 19 15:19:33 1995 Ulrich Drepper * Makefile.in (uninstall): Remove stuff installed by install-src. Tue Aug 15 13:13:53 1995 Ulrich Drepper * VERSION.in: Initial revision. * Makefile.in (DISTFILES): Add VERSION file. This is not necessary for gettext, but for other packages using this library. Tue Aug 15 06:16:44 1995 Ulrich Drepper * gettextP.h (_nl_find_domain): New prototype after changing search strategy. * finddomain.c (_nl_find_domain): We now try only to find a specified catalog. Fall back to other catalogs listed in the locale list is now done in __dcgettext. * dcgettext.c (__dcgettext): Now we provide message fall back even to different languages. I.e. if a message is not available in one language all the other in the locale list a tried. Formerly fall back was only possible within one language. Implemented by moving one loop from _nl_find_domain to here. Mon Aug 14 23:45:50 1995 Ulrich Drepper * Makefile.in (gettextsrcdir): Directory where source of GNU gettext library are made available. (INSTALL, INSTALL_DATA): Programs used for installing sources. (gettext-src): New. Rule to install GNU gettext sources for use in gettextize shell script. Sun Aug 13 14:40:48 1995 Ulrich Drepper * loadmsgcat.c (_nl_load_domain): Use mmap for loading only when munmap function is also available. * Makefile.in (install): Depend on `all' goal. Wed Aug 9 11:04:33 1995 Ulrich Drepper * localealias.c (read_alias_file): Do not overwrite '\n' when terminating alias value string. * localealias.c (read_alias_file): Handle long lines. Ignore the rest not fitting in the buffer after the initial `fgets' call. Wed Aug 9 00:54:29 1995 Ulrich Drepper * gettextP.h (_nl_load_domain): Add prototype, replacing prototype for _nl_load_msg_cat. * finddomain.c (_nl_find_domain): Remove unneeded variable filename and filename_len. (expand_alias): Remove prototype because functions does not exist anymore. * localealias.c (read_alias_file): Change type of fname_len parameter to int. (xmalloc): Add prototype. * loadmsgcat.c: Better prototypes for xmalloc. Tue Aug 8 22:30:39 1995 Ulrich Drepper * finddomain.c (_nl_find_domain): Allow alias name to be constructed from the four components. * Makefile.in (aliaspath): New variable. Set to preliminary value. (SOURCES): Add localealias.c. (OBJECTS): Add localealias.o. * gettextP.h: Add prototype for _nl_expand_alias. * finddomain.c: Aliasing handled in intl/localealias.c. * localealias.c: Aliasing for locale names. * bindtextdom.c: Better prototypes for xmalloc and xstrdup. Mon Aug 7 23:47:42 1995 Ulrich Drepper * Makefile.in (DISTFILES): gettext.perl is now found in misc/. * cat-compat.c (bindtextdomain): Correct implementation. dirname parameter was not used. Reported by Marcus Daniels. * gettextP.h (loaded_domain): New fields `successor' and `decided' for oo, lazy message handling implementation. * dcgettext.c: Adopt for oo, lazy message handliing. Now we can inherit translations from less specific locales. (find_msg): New function. * loadmsgcat.c, finddomain.c: Complete rewrite. Implement oo, lazy message handling :-). We now have an additional environment variable `LANGUAGE' with a higher priority than LC_ALL for the LC_MESSAGE locale. Here we can set a colon separated list of specifications each of the form `language[_territory[.codeset]][@modifier]'. Sat Aug 5 09:55:42 1995 Ulrich Drepper * finddomain.c (unistd.h): Include to get _PC_PATH_MAX defined on system having it. Fri Aug 4 22:42:00 1995 Ulrich Drepper * finddomain.c (stpcpy): Include prototype. * Makefile.in (dist): Remove `copying instead' message. Wed Aug 2 18:52:03 1995 Ulrich Drepper * Makefile.in (ID, TAGS): Do not use $^. Tue Aug 1 20:07:11 1995 Ulrich Drepper * Makefile.in (TAGS, ID): Use $^ as command argument. (TAGS): Give etags -o option t write to current directory, not $(srcdir). (ID): Use $(srcdir) instead os $(top_srcdir)/src. (distclean): Remove ID. Sun Jul 30 11:51:46 1995 Ulrich Drepper * Makefile.in (gnulocaledir): New variable, always using share/ for data directory. (DEFS): Add GNULOCALEDIR, used in finddomain.c. * finddomain.c (_nl_default_dirname): Set to GNULOCALEDIR, because it always has to point to the directory where GNU gettext Library writes it to. * intl-compat.c (textdomain, bindtextdomain): Undefine macros before function definition. Sat Jul 22 01:10:02 1995 Ulrich Drepper * libgettext.h (_LIBINTL_H): Protect definition in case where this file is included as libgettext.h on Solaris machines. Add comment about this. Wed Jul 19 02:36:42 1995 Ulrich Drepper * intl-compat.c (textdomain): Correct typo. Wed Jul 19 01:51:35 1995 Ulrich Drepper * dcgettext.c (dcgettext): Function now called __dcgettext. * dgettext.c (dgettext): Now called __dgettext and calls __dcgettext. * gettext.c (gettext): Function now called __gettext and calls __dgettext. * textdomain.c (textdomain): Function now called __textdomain. * bindtextdom.c (bindtextdomain): Function now called __bindtextdomain. * intl-compat.c: Initial revision. * Makefile.in (SOURCES): Add intl-compat.c. (OBJECTS): We always compile the GNU gettext library functions. OBJECTS contains all objects but cat-compat.o, ../po/cat-if-tbl.o, and intl-compat.o. (GETTOBJS): Contains now only intl-compat.o. * libgettext.h: Re-include protection matches dualistic character of libgettext.h. For all functions in GNU gettext library define __ counter part. * finddomain.c (strchr): Define as index if not found in C library. (_nl_find_domain): For relative paths paste / in between. Tue Jul 18 16:37:45 1995 Ulrich Drepper * loadmsgcat.c, finddomain.c: Add inclusion of sys/types.h. * xopen-msg.sed: Fix bug with `msgstr ""' lines. A little bit better comments. Tue Jul 18 01:18:27 1995 Ulrich Drepper * Makefile.in: po-mode.el, makelinks, combine-sh are now found in ../misc. * po-mode.el, makelinks, combine-sh, elisp-comp: Moved to ../misc/. * libgettext.h, gettextP.h, gettext.h: Uniform test for __STDC__. Sun Jul 16 22:33:02 1995 Ulrich Drepper * Makefile.in (INSTALL, INSTALL_DATA): New variables. (install-data, uninstall): Install/uninstall .elc file. * po-mode.el (Installation comment): Add .pox as possible extension of .po files. Sun Jul 16 13:23:27 1995 Ulrich Drepper * elisp-comp: Complete new version by Franc,ois: This does not fail when not compiling in the source directory. Sun Jul 16 00:12:17 1995 Ulrich Drepper * Makefile.in (../po/cat-id-tbl.o): Use $(MAKE) instead of make for recursive make. * Makefile.in (.el.elc): Use $(SHELL) instead of /bin/sh. (install-exec): Add missing dummy goal. (install-data, uninstall): @ in multi-line shell command at beginning, not in front of echo. Reported by Eric Backus. Sat Jul 15 00:21:28 1995 Ulrich Drepper * Makefile.in (DISTFILES): Rename libgettext.perl to gettext.perl to fit in 14 chars file systems. * gettext.perl: Rename to gettext.perl to fit in 14 chars file systems. Thu Jul 13 23:17:20 1995 Ulrich Drepper * cat-compat.c: If !STDC_HEADERS try to include malloc.h. Thu Jul 13 20:55:02 1995 Ulrich Drepper * po2tbl.sed.in: Pretty printing. * linux-msg.sed, xopen-msg.sed: Correct bugs with handling substitute flags in branches. * hash-string.h (hash_string): Old K&R compilers don't under stand `unsigned char'. * gettext.h (nls_uint32): Some old K&R compilers (eg HP) don't understand `unsigned int'. * cat-compat.c (msg_to_cat_id): De-ANSI-fy prototypes. Thu Jul 13 01:34:33 1995 Ulrich Drepper * Makefile.in (ELCFILES): New variable. (DISTFILES): Add elisp-comp. Add implicit rule for .el -> .elc compilation. (install-data): install $ELCFILES (clean): renamed po-to-tbl and po-to-msg to po2tbl and po2msg resp. * elisp-comp: Initial revision Wed Jul 12 16:14:52 1995 Ulrich Drepper * Makefile.in: cat-id-tbl.c is now found in po/. This enables us to use an identical intl/ directory in all packages. * dcgettext.c (dcgettext): hashing does not work for table size <= 2. * textdomain.c: fix typo (#if def -> #if defined) Tue Jul 11 18:44:43 1995 Ulrich Drepper * Makefile.in (stamp-cat-id): use top_srcdir to address source files (DISTFILES,distclean): move tupdate.perl to src/ * po-to-tbl.sed.in: add additional jump to clear change flag to recognize multiline strings Tue Jul 11 01:32:50 1995 Ulrich Drepper * textdomain.c: Protect inclusion of stdlib.h and string.h. * loadmsgcat.c: Protect inclusion of stdlib.h. * libgettext.h: Protect inclusion of locale.h. Allow use in C++ programs. Define NULL is not happened already. * Makefile.in (DISTFILES): ship po-to-tbl.sed.in instead of po-to-tbl.sed. (distclean): remove po-to-tbl.sed and tupdate.perl. * tupdate.perl.in: Substitute Perl path even in exec line. Don't include entries without translation from old .po file. Tue Jul 4 00:41:51 1995 Ulrich Drepper * tupdate.perl.in: use "Updated: " in msgid "". * cat-compat.c: Fix typo (LOCALDIR -> LOCALEDIR). Define getenv if !__STDC__. * bindtextdom.c: Protect stdlib.h and string.h inclusion. Define free if !__STDC__. * finddomain.c: Change DEF_MSG_DOM_DIR to LOCALEDIR. Define free if !__STDC__. * cat-compat.c: Change DEF_MSG_DOM_DIR to LOCALEDIR. Mon Jul 3 23:56:30 1995 Ulrich Drepper * Makefile.in: Use LOCALEDIR instead of DEF_MSG_DOM_DIR. Remove unneeded $(srcdir) from Makefile.in dependency. * makelinks: Add copyright and short description. * po-mode.el: Last version for 0.7. * tupdate.perl.in: Fix die message. * dcgettext.c: Protect include of string.h. * gettext.c: Protect include of stdlib.h and further tries to get NULL. * finddomain.c: Some corrections in includes. * Makefile.in (INCLUDES): Prune list correct path to Makefile.in. * po-to-tbl.sed: Adopt for new .po file format. * linux-msg.sed, xopen-msg.sed: Adopt for new .po file format. Sun Jul 2 23:55:03 1995 Ulrich Drepper * tupdate.perl.in: Complete rewrite for new .po file format. Sun Jul 2 02:06:50 1995 Ulrich Drepper * First official release. This directory contains all the code needed to internationalize own packages. It provides functions which allow to use the X/Open catgets function with an interface like the Uniforum gettext function. For system which does not have neither of those a complete implementation is provided. texinfo-3.12/intl/hash-string.h0000664000175000017500000000345506475640104013736 0ustar gg/* Implements a string hashing function. Copyright (C) 1995, 1997 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 Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_VALUES_H # include #endif /* @@ end of prolog @@ */ #ifndef PARAMS # if __STDC__ # define PARAMS(Args) Args # else # define PARAMS(Args) () # endif #endif /* We assume to have `unsigned long int' value with at least 32 bits. */ #define HASHWORDBITS 32 /* Defines the so called `hashpjw' function by P.J. Weinberger [see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools, 1986, 1987 Bell Telephone Laboratories, Inc.] */ static unsigned long hash_string PARAMS ((const char *__str_param)); static inline unsigned long hash_string (str_param) const char *str_param; { unsigned long int hval, g; const char *str = str_param; /* Compute the hash value for the given string. */ hval = 0; while (*str != '\0') { hval <<= 4; hval += (unsigned long) *str++; g = hval & ((unsigned long) 0xf << (HASHWORDBITS - 4)); if (g != 0) { hval ^= g >> (HASHWORDBITS - 8); hval ^= g; } } return hval; } texinfo-3.12/intl/bindtextdom.c0000664000175000017500000001220206475640104014011 0ustar gg/* Implementation of the bindtextdomain(3) function Copyright (C) 1995, 1996, 1997 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, USA. */ #ifdef HAVE_CONFIG_H # include #endif #if defined STDC_HEADERS || defined _LIBC # include #else # ifdef HAVE_MALLOC_H # include # else void free (); # endif #endif #if defined HAVE_STRING_H || defined _LIBC # include #else # include # ifndef memcpy # define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num) # endif #endif #ifdef _LIBC # include #else # include "libgettext.h" #endif #include "gettext.h" #include "gettextP.h" /* @@ end of prolog @@ */ /* Contains the default location of the message catalogs. */ extern const char _nl_default_dirname[]; /* List with bindings of specific domains. */ extern struct binding *_nl_domain_bindings; /* Names for the libintl functions are a problem. They must not clash with existing names and they should follow ANSI C. But this source code is also used in GNU C Library where the names have a __ prefix. So we have to make a difference here. */ #ifdef _LIBC # define BINDTEXTDOMAIN __bindtextdomain # define strdup(str) __strdup (str) #else # define BINDTEXTDOMAIN bindtextdomain__ #endif /* Specify that the DOMAINNAME message catalog will be found in DIRNAME rather than in the system locale data base. */ char * BINDTEXTDOMAIN (domainname, dirname) const char *domainname; const char *dirname; { struct binding *binding; /* Some sanity checks. */ if (domainname == NULL || domainname[0] == '\0') return NULL; for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next) { int compare = strcmp (domainname, binding->domainname); if (compare == 0) /* We found it! */ break; if (compare < 0) { /* It is not in the list. */ binding = NULL; break; } } if (dirname == NULL) /* The current binding has be to returned. */ return binding == NULL ? (char *) _nl_default_dirname : binding->dirname; if (binding != NULL) { /* The domain is already bound. If the new value and the old one are equal we simply do nothing. Otherwise replace the old binding. */ if (strcmp (dirname, binding->dirname) != 0) { char *new_dirname; if (strcmp (dirname, _nl_default_dirname) == 0) new_dirname = (char *) _nl_default_dirname; else { #if defined _LIBC || defined HAVE_STRDUP new_dirname = strdup (dirname); if (new_dirname == NULL) return NULL; #else size_t len = strlen (dirname) + 1; new_dirname = (char *) malloc (len); if (new_dirname == NULL) return NULL; memcpy (new_dirname, dirname, len); #endif } if (binding->dirname != _nl_default_dirname) free (binding->dirname); binding->dirname = new_dirname; } } else { /* We have to create a new binding. */ size_t len; struct binding *new_binding = (struct binding *) malloc (sizeof (*new_binding)); if (new_binding == NULL) return NULL; #if defined _LIBC || defined HAVE_STRDUP new_binding->domainname = strdup (domainname); if (new_binding->domainname == NULL) return NULL; #else len = strlen (domainname) + 1; new_binding->domainname = (char *) malloc (len); if (new_binding->domainname == NULL) return NULL; memcpy (new_binding->domainname, domainname, len); #endif if (strcmp (dirname, _nl_default_dirname) == 0) new_binding->dirname = (char *) _nl_default_dirname; else { #if defined _LIBC || defined HAVE_STRDUP new_binding->dirname = strdup (dirname); if (new_binding->dirname == NULL) return NULL; #else len = strlen (dirname) + 1; new_binding->dirname = (char *) malloc (len); if (new_binding->dirname == NULL) return NULL; memcpy (new_binding->dirname, dirname, len); #endif } /* Now enqueue it. */ if (_nl_domain_bindings == NULL || strcmp (domainname, _nl_domain_bindings->domainname) < 0) { new_binding->next = _nl_domain_bindings; _nl_domain_bindings = new_binding; } else { binding = _nl_domain_bindings; while (binding->next != NULL && strcmp (domainname, binding->next->domainname) > 0) binding = binding->next; new_binding->next = binding->next; binding->next = new_binding; } binding = new_binding; } return binding->dirname; } #ifdef _LIBC /* Alias for function name in GNU C Library. */ weak_alias (__bindtextdomain, bindtextdomain); #endif texinfo-3.12/intl/libgettext.h0000664000175000017500000001313206475640104013653 0ustar gg/* Message catalogs for internationalization. Copyright (C) 1995, 1996, 1997 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, USA. */ /* Because on some systems (e.g. Solaris) we sometimes have to include the systems libintl.h as well as this file we have more complex include protection above. But the systems header might perhaps also define _LIBINTL_H and therefore we have to protect the definition here. */ #if !defined (_LIBINTL_H) || !defined (_LIBGETTEXT_H) #if !defined (_LIBINTL_H) # define _LIBINTL_H 1 #endif #define _LIBGETTEXT_H 1 /* We define an additional symbol to signal that we use the GNU implementation of gettext. */ #define __USE_GNU_GETTEXT 1 #include #if HAVE_LOCALE_H # include #endif #ifdef __cplusplus extern "C" { #endif /* @@ end of prolog @@ */ #ifndef PARAMS # if __STDC__ # define PARAMS(args) args # else # define PARAMS(args) () # endif #endif #ifndef NULL # if !defined __cplusplus || defined __GNUC__ # define NULL ((void *) 0) # else # define NULL (0) # endif #endif #if !HAVE_LC_MESSAGES /* This value determines the behaviour of the gettext() and dgettext() function. But some system does not have this defined. Define it to a default value. */ # define LC_MESSAGES (-1) #endif /* Declarations for gettext-using-catgets interface. Derived from Jim Meyering's libintl.h. */ struct _msg_ent { const char *_msg; int _msg_number; }; #if HAVE_CATGETS /* These two variables are defined in the automatically by po-to-tbl.sed generated file `cat-id-tbl.c'. */ extern const struct _msg_ent _msg_tbl[]; extern int _msg_tbl_length; #endif /* For automatical extraction of messages sometimes no real translation is needed. Instead the string itself is the result. */ #define gettext_noop(Str) (Str) /* Look up MSGID in the current default message catalog for the current LC_MESSAGES locale. If not found, returns MSGID itself (the default text). */ extern char *gettext PARAMS ((const char *__msgid)); extern char *gettext__ PARAMS ((const char *__msgid)); /* Look up MSGID in the DOMAINNAME message catalog for the current LC_MESSAGES locale. */ extern char *dgettext PARAMS ((const char *__domainname, const char *__msgid)); extern char *dgettext__ PARAMS ((const char *__domainname, const char *__msgid)); /* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY locale. */ extern char *dcgettext PARAMS ((const char *__domainname, const char *__msgid, int __category)); extern char *dcgettext__ PARAMS ((const char *__domainname, const char *__msgid, int __category)); /* Set the current default message catalog to DOMAINNAME. If DOMAINNAME is null, return the current default. If DOMAINNAME is "", reset to the default of "messages". */ extern char *textdomain PARAMS ((const char *__domainname)); extern char *textdomain__ PARAMS ((const char *__domainname)); /* Specify that the DOMAINNAME message catalog will be found in DIRNAME rather than in the system locale data base. */ extern char *bindtextdomain PARAMS ((const char *__domainname, const char *__dirname)); extern char *bindtextdomain__ PARAMS ((const char *__domainname, const char *__dirname)); #if ENABLE_NLS /* Solaris 2.3 has the gettext function but dcgettext is missing. So we omit this optimization for Solaris 2.3. BTW, Solaris 2.4 has dcgettext. */ # if !HAVE_CATGETS && (!HAVE_GETTEXT || HAVE_DCGETTEXT) # define gettext(Msgid) \ dgettext (NULL, Msgid) # define dgettext(Domainname, Msgid) \ dcgettext (Domainname, Msgid, LC_MESSAGES) # if defined __GNUC__ && __GNUC__ == 2 && __GNUC_MINOR__ >= 7 /* This global variable is defined in loadmsgcat.c. We need a sign, whether a new catalog was loaded, which can be associated with all translations. */ extern int _nl_msg_cat_cntr; # define dcgettext(Domainname, Msgid, Category) \ (__extension__ \ ({ \ char *__result; \ if (__builtin_constant_p (Msgid)) \ { \ static char *__translation__; \ static int __catalog_counter__; \ if (! __translation__ || __catalog_counter__ != _nl_msg_cat_cntr) \ { \ __translation__ = \ dcgettext__ (Domainname, Msgid, Category); \ __catalog_counter__ = _nl_msg_cat_cntr; \ } \ __result = __translation__; \ } \ else \ __result = dcgettext__ (Domainname, Msgid, Category); \ __result; \ })) # endif # endif #else # define gettext(Msgid) (Msgid) # define dgettext(Domainname, Msgid) (Msgid) # define dcgettext(Domainname, Msgid, Category) (Msgid) # define textdomain(Domainname) while (0) /* nothing */ # define bindtextdomain(Domainname, Dirname) while (0) /* nothing */ #endif /* @@ begin of epilog @@ */ #ifdef __cplusplus } #endif #endif texinfo-3.12/intl/loadmsgcat.c0000664000175000017500000001306006475640105013612 0ustar gg/* Load needed message catalogs Copyright (C) 1995, 1996, 1997 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, USA. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #if defined STDC_HEADERS || defined _LIBC # include #endif #if defined HAVE_UNISTD_H || defined _LIBC # include #endif #if (defined HAVE_MMAP && defined HAVE_MUNMAP) || defined _LIBC # include #endif #include "gettext.h" #include "gettextP.h" /* @@ end of prolog @@ */ #ifdef _LIBC /* Rename the non ISO C functions. This is required by the standard because some ISO C functions will require linking with this object file and the name space must not be polluted. */ # define fstat __fstat # define open __open # define close __close # define read __read # define mmap __mmap # define munmap __munmap #endif /* We need a sign, whether a new catalog was loaded, which can be associated with all translations. This is important if the translations are cached by one of GCC's features. */ int _nl_msg_cat_cntr = 0; /* Load the message catalogs specified by FILENAME. If it is no valid message catalog do nothing. */ void _nl_load_domain (domain_file) struct loaded_l10nfile *domain_file; { int fd; struct stat st; struct mo_file_header *data = (struct mo_file_header *) -1; #if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \ || defined _LIBC int use_mmap = 0; #endif struct loaded_domain *domain; domain_file->decided = 1; domain_file->data = NULL; /* If the record does not represent a valid locale the FILENAME might be NULL. This can happen when according to the given specification the locale file name is different for XPG and CEN syntax. */ if (domain_file->filename == NULL) return; /* Try to open the addressed file. */ fd = open (domain_file->filename, O_RDONLY); if (fd == -1) return; /* We must know about the size of the file. */ if (fstat (fd, &st) != 0 && st.st_size < (off_t) sizeof (struct mo_file_header)) { /* Something went wrong. */ close (fd); return; } #if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \ || defined _LIBC /* Now we are ready to load the file. If mmap() is available we try this first. If not available or it failed we try to load it. */ data = (struct mo_file_header *) mmap (NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); if (data != (struct mo_file_header *) -1) { /* mmap() call was successful. */ close (fd); use_mmap = 1; } #endif /* If the data is not yet available (i.e. mmap'ed) we try to load it manually. */ if (data == (struct mo_file_header *) -1) { off_t to_read; char *read_ptr; data = (struct mo_file_header *) malloc (st.st_size); if (data == NULL) return; to_read = st.st_size; read_ptr = (char *) data; do { long int nb = (long int) read (fd, read_ptr, to_read); if (nb == -1) { close (fd); return; } read_ptr += nb; to_read -= nb; } while (to_read > 0); close (fd); } /* Using the magic number we can test whether it really is a message catalog file. */ if (data->magic != _MAGIC && data->magic != _MAGIC_SWAPPED) { /* The magic number is wrong: not a message catalog file. */ #if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \ || defined _LIBC if (use_mmap) munmap ((caddr_t) data, st.st_size); else #endif free (data); return; } domain_file->data = (struct loaded_domain *) malloc (sizeof (struct loaded_domain)); if (domain_file->data == NULL) return; domain = (struct loaded_domain *) domain_file->data; domain->data = (char *) data; domain->must_swap = data->magic != _MAGIC; /* Fill in the information about the available tables. */ switch (W (domain->must_swap, data->revision)) { case 0: domain->nstrings = W (domain->must_swap, data->nstrings); domain->orig_tab = (struct string_desc *) ((char *) data + W (domain->must_swap, data->orig_tab_offset)); domain->trans_tab = (struct string_desc *) ((char *) data + W (domain->must_swap, data->trans_tab_offset)); domain->hash_size = W (domain->must_swap, data->hash_tab_size); domain->hash_tab = (nls_uint32 *) ((char *) data + W (domain->must_swap, data->hash_tab_offset)); break; default: /* This is an illegal revision. */ #if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \ || defined _LIBC if (use_mmap) munmap ((caddr_t) data, st.st_size); else #endif free (data); free (domain); domain_file->data = NULL; return; } /* Show that one domain is changed. This might make some cached translations invalid. */ ++_nl_msg_cat_cntr; } texinfo-3.12/intl/l10nflist.c0000664000175000017500000002417606475640105013322 0ustar gg/* Handle list of needed message catalogs Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. Written by Ulrich Drepper , 1995. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 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, USA. */ #ifdef HAVE_CONFIG_H # include #endif #if defined HAVE_STRING_H || defined _LIBC # ifndef _GNU_SOURCE # define _GNU_SOURCE 1 # endif # include #else # include # ifndef memcpy # define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num) # endif #endif #if !HAVE_STRCHR && !defined _LIBC # ifndef strchr # define strchr index # endif #endif #if defined _LIBC || defined HAVE_ARGZ_H # include #endif #include #include #if defined STDC_HEADERS || defined _LIBC # include #endif #include "loadinfo.h" /* On some strange systems still no definition of NULL is found. Sigh! */ #ifndef NULL # if defined __STDC__ && __STDC__ # define NULL ((void *) 0) # else # define NULL 0 # endif #endif /* @@ end of prolog @@ */ #ifdef _LIBC /* Rename the non ANSI C functions. This is required by the standard because some ANSI C functions will require linking with this object file and the name space must not be polluted. */ # define stpcpy(dest, src) __stpcpy(dest, src) #else # ifndef HAVE_STPCPY static char *stpcpy PARAMS ((char *dest, const char *src)); # endif #endif /* Define function which are usually not available. */ #if !defined _LIBC && !defined HAVE___ARGZ_COUNT /* Returns the number of strings in ARGZ. */ static size_t argz_count__ PARAMS ((const char *argz, size_t len)); static size_t argz_count__ (argz, len) const char *argz; size_t len; { size_t count = 0; while (len > 0) { size_t part_len = strlen (argz); argz += part_len + 1; len -= part_len + 1; count++; } return count; } # undef __argz_count # define __argz_count(argz, len) argz_count__ (argz, len) #endif /* !_LIBC && !HAVE___ARGZ_COUNT */ #if !defined _LIBC && !defined HAVE___ARGZ_STRINGIFY /* Make '\0' separated arg vector ARGZ printable by converting all the '\0's except the last into the character SEP. */ static void argz_stringify__ PARAMS ((char *argz, size_t len, int sep)); static void argz_stringify__ (argz, len, sep) char *argz; size_t len; int sep; { while (len > 0) { size_t part_len = strlen (argz); argz += part_len; len -= part_len + 1; if (len > 0) *argz++ = sep; } } # undef __argz_stringify # define __argz_stringify(argz, len, sep) argz_stringify__ (argz, len, sep) #endif /* !_LIBC && !HAVE___ARGZ_STRINGIFY */ #if !defined _LIBC && !defined HAVE___ARGZ_NEXT static char *argz_next__ PARAMS ((char *argz, size_t argz_len, const char *entry)); static char * argz_next__ (argz, argz_len, entry) char *argz; size_t argz_len; const char *entry; { if (entry) { if (entry < argz + argz_len) entry = strchr (entry, '\0') + 1; return entry >= argz + argz_len ? NULL : (char *) entry; } else if (argz_len > 0) return argz; else return 0; } # undef __argz_next # define __argz_next(argz, len, entry) argz_next__ (argz, len, entry) #endif /* !_LIBC && !HAVE___ARGZ_NEXT */ /* Return number of bits set in X. */ static int pop PARAMS ((int x)); static inline int pop (x) int x; { /* We assume that no more than 16 bits are used. */ x = ((x & ~0x5555) >> 1) + (x & 0x5555); x = ((x & ~0x3333) >> 2) + (x & 0x3333); x = ((x >> 4) + x) & 0x0f0f; x = ((x >> 8) + x) & 0xff; return x; } struct loaded_l10nfile * _nl_make_l10nflist (l10nfile_list, dirlist, dirlist_len, mask, language, territory, codeset, normalized_codeset, modifier, special, sponsor, revision, filename, do_allocate) struct loaded_l10nfile **l10nfile_list; const char *dirlist; size_t dirlist_len; int mask; const char *language; const char *territory; const char *codeset; const char *normalized_codeset; const char *modifier; const char *special; const char *sponsor; const char *revision; const char *filename; int do_allocate; { char *abs_filename; struct loaded_l10nfile *last = NULL; struct loaded_l10nfile *retval; char *cp; size_t entries; int cnt; /* Allocate room for the full file name. */ abs_filename = (char *) malloc (dirlist_len + strlen (language) + ((mask & TERRITORY) != 0 ? strlen (territory) + 1 : 0) + ((mask & XPG_CODESET) != 0 ? strlen (codeset) + 1 : 0) + ((mask & XPG_NORM_CODESET) != 0 ? strlen (normalized_codeset) + 1 : 0) + (((mask & XPG_MODIFIER) != 0 || (mask & CEN_AUDIENCE) != 0) ? strlen (modifier) + 1 : 0) + ((mask & CEN_SPECIAL) != 0 ? strlen (special) + 1 : 0) + (((mask & CEN_SPONSOR) != 0 || (mask & CEN_REVISION) != 0) ? (1 + ((mask & CEN_SPONSOR) != 0 ? strlen (sponsor) + 1 : 0) + ((mask & CEN_REVISION) != 0 ? strlen (revision) + 1 : 0)) : 0) + 1 + strlen (filename) + 1); if (abs_filename == NULL) return NULL; retval = NULL; last = NULL; /* Construct file name. */ memcpy (abs_filename, dirlist, dirlist_len); __argz_stringify (abs_filename, dirlist_len, ':'); cp = abs_filename + (dirlist_len - 1); *cp++ = '/'; cp = stpcpy (cp, language); if ((mask & TERRITORY) != 0) { *cp++ = '_'; cp = stpcpy (cp, territory); } if ((mask & XPG_CODESET) != 0) { *cp++ = '.'; cp = stpcpy (cp, codeset); } if ((mask & XPG_NORM_CODESET) != 0) { *cp++ = '.'; cp = stpcpy (cp, normalized_codeset); } if ((mask & (XPG_MODIFIER | CEN_AUDIENCE)) != 0) { /* This component can be part of both syntaces but has different leading characters. For CEN we use `+', else `@'. */ *cp++ = (mask & CEN_AUDIENCE) != 0 ? '+' : '@'; cp = stpcpy (cp, modifier); } if ((mask & CEN_SPECIAL) != 0) { *cp++ = '+'; cp = stpcpy (cp, special); } if ((mask & (CEN_SPONSOR | CEN_REVISION)) != 0) { *cp++ = ','; if ((mask & CEN_SPONSOR) != 0) cp = stpcpy (cp, sponsor); if ((mask & CEN_REVISION) != 0) { *cp++ = '_'; cp = stpcpy (cp, revision); } } *cp++ = '/'; stpcpy (cp, filename); /* Look in list of already loaded domains whether it is already available. */ last = NULL; for (retval = *l10nfile_list; retval != NULL; retval = retval->next) if (retval->filename != NULL) { int compare = strcmp (retval->filename, abs_filename); if (compare == 0) /* We found it! */ break; if (compare < 0) { /* It's not in the list. */ retval = NULL; break; } last = retval; } if (retval != NULL || do_allocate == 0) { free (abs_filename); return retval; } retval = (struct loaded_l10nfile *) malloc (sizeof (*retval) + (__argz_count (dirlist, dirlist_len) * (1 << pop (mask)) * sizeof (struct loaded_l10nfile *))); if (retval == NULL) return NULL; retval->filename = abs_filename; retval->decided = (__argz_count (dirlist, dirlist_len) != 1 || ((mask & XPG_CODESET) != 0 && (mask & XPG_NORM_CODESET) != 0)); retval->data = NULL; if (last == NULL) { retval->next = *l10nfile_list; *l10nfile_list = retval; } else { retval->next = last->next; last->next = retval; } entries = 0; /* If the DIRLIST is a real list the RETVAL entry corresponds not to a real file. So we have to use the DIRLIST separation mechanism of the inner loop. */ cnt = __argz_count (dirlist, dirlist_len) == 1 ? mask - 1 : mask; for (; cnt >= 0; --cnt) if ((cnt & ~mask) == 0 && ((cnt & CEN_SPECIFIC) == 0 || (cnt & XPG_SPECIFIC) == 0) && ((cnt & XPG_CODESET) == 0 || (cnt & XPG_NORM_CODESET) == 0)) { /* Iterate over all elements of the DIRLIST. */ char *dir = NULL; while ((dir = __argz_next ((char *) dirlist, dirlist_len, dir)) != NULL) retval->successor[entries++] = _nl_make_l10nflist (l10nfile_list, dir, strlen (dir) + 1, cnt, language, territory, codeset, normalized_codeset, modifier, special, sponsor, revision, filename, 1); } retval->successor[entries] = NULL; return retval; } /* Normalize codeset name. There is no standard for the codeset names. Normalization allows the user to use any of the common names. */ const char * _nl_normalize_codeset (codeset, name_len) const char *codeset; size_t name_len; { int len = 0; int only_digit = 1; char *retval; char *wp; size_t cnt; for (cnt = 0; cnt < name_len; ++cnt) if (isalnum (codeset[cnt])) { ++len; if (isalpha (codeset[cnt])) only_digit = 0; } retval = (char *) malloc ((only_digit ? 3 : 0) + len + 1); if (retval != NULL) { if (only_digit) wp = stpcpy (retval, "iso"); else wp = retval; for (cnt = 0; cnt < name_len; ++cnt) if (isalpha (codeset[cnt])) *wp++ = tolower (codeset[cnt]); else if (isdigit (codeset[cnt])) *wp++ = codeset[cnt]; *wp = '\0'; } return (const char *) retval; } /* @@ begin of epilog @@ */ /* We don't want libintl.a to depend on any other library. So we avoid the non-standard function stpcpy. In GNU C Library this function is available, though. Also allow the symbol HAVE_STPCPY to be defined. */ #if !_LIBC && !HAVE_STPCPY static char * stpcpy (dest, src) char *dest; const char *src; { while ((*dest++ = *src++) != '\0') /* Do nothing. */ ; return dest - 1; } #endif texinfo-3.12/intl/gettext.h0000664000175000017500000000620406475640104013166 0ustar gg/* Internal header for GNU gettext internationalization functions Copyright (C) 1995, 1997 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 Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _GETTEXT_H #define _GETTEXT_H 1 #include #if HAVE_LIMITS_H || _LIBC # include #endif /* @@ end of prolog @@ */ /* The magic number of the GNU message catalog format. */ #define _MAGIC 0x950412de #define _MAGIC_SWAPPED 0xde120495 /* Revision number of the currently used .mo (binary) file format. */ #define MO_REVISION_NUMBER 0 /* The following contortions are an attempt to use the C preprocessor to determine an unsigned integral type that is 32 bits wide. An alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but doing that would require that the configure script compile and *run* the resulting executable. Locally running cross-compiled executables is usually not possible. */ #if __STDC__ # define UINT_MAX_32_BITS 4294967295U #else # define UINT_MAX_32_BITS 0xFFFFFFFF #endif /* If UINT_MAX isn't defined, assume it's a 32-bit type. This should be valid for all systems GNU cares about because that doesn't include 16-bit systems, and only modern systems (that certainly have ) have 64+-bit integral types. */ #ifndef UINT_MAX # define UINT_MAX UINT_MAX_32_BITS #endif #if UINT_MAX == UINT_MAX_32_BITS typedef unsigned nls_uint32; #else # if USHRT_MAX == UINT_MAX_32_BITS typedef unsigned short nls_uint32; # else # if ULONG_MAX == UINT_MAX_32_BITS typedef unsigned long nls_uint32; # else /* The following line is intended to throw an error. Using #error is not portable enough. */ "Cannot determine unsigned 32-bit data type." # endif # endif #endif /* Header for binary .mo file format. */ struct mo_file_header { /* The magic number. */ nls_uint32 magic; /* The revision number of the file format. */ nls_uint32 revision; /* The number of strings pairs. */ nls_uint32 nstrings; /* Offset of table with start offsets of original strings. */ nls_uint32 orig_tab_offset; /* Offset of table with start offsets of translation strings. */ nls_uint32 trans_tab_offset; /* Size of hashing table. */ nls_uint32 hash_tab_size; /* Offset of first hashing entry. */ nls_uint32 hash_tab_offset; }; struct string_desc { /* Length of addressed string. */ nls_uint32 length; /* Offset of string in file. */ nls_uint32 offset; }; /* @@ begin of epilog @@ */ #endif /* gettext.h */ texinfo-3.12/intl/dgettext.c0000664000175000017500000000332606475640105013330 0ustar gg/* dgettext.c -- implementation of the dgettext(3) function Copyright (C) 1995 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, USA. */ #ifdef HAVE_CONFIG_H # include #endif #if defined HAVE_LOCALE_H || defined _LIBC # include #endif #ifdef _LIBC # include #else # include "libgettext.h" #endif /* @@ end of prolog @@ */ /* Names for the libintl functions are a problem. They must not clash with existing names and they should follow ANSI C. But this source code is also used in GNU C Library where the names have a __ prefix. So we have to make a difference here. */ #ifdef _LIBC # define DGETTEXT __dgettext # define DCGETTEXT __dcgettext #else # define DGETTEXT dgettext__ # define DCGETTEXT dcgettext__ #endif /* Look up MSGID in the DOMAINNAME message catalog of the current LC_MESSAGES locale. */ char * DGETTEXT (domainname, msgid) const char *domainname; const char *msgid; { return DCGETTEXT (domainname, msgid, LC_MESSAGES); } #ifdef _LIBC /* Alias for function name in GNU C Library. */ weak_alias (__dgettext, dgettext); #endif texinfo-3.12/intl/dcgettext.c0000664000175000017500000003660306475640104013476 0ustar gg/* Implementation of the dcgettext(3) function Copyright (C) 1995, 1996, 1997 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, USA. */ #ifdef HAVE_CONFIG_H # include #endif #include #ifdef __GNUC__ # define alloca __builtin_alloca # define HAVE_ALLOCA 1 #else # if defined HAVE_ALLOCA_H || defined _LIBC # include # else # ifdef _AIX #pragma alloca # else # ifndef alloca char *alloca (); # endif # endif # endif #endif #include #ifndef errno extern int errno; #endif #ifndef __set_errno # define __set_errno(val) errno = (val) #endif #if defined STDC_HEADERS || defined _LIBC # include #else char *getenv (); # ifdef HAVE_MALLOC_H # include # else void free (); # endif #endif #if defined HAVE_STRING_H || defined _LIBC # ifndef _GNU_SOURCE # define _GNU_SOURCE 1 # endif # include #else # include #endif #if !HAVE_STRCHR && !defined _LIBC # ifndef strchr # define strchr index # endif #endif #if defined HAVE_UNISTD_H || defined _LIBC # include #endif #include "gettext.h" #include "gettextP.h" #ifdef _LIBC # include #else # include "libgettext.h" #endif #include "hash-string.h" /* @@ end of prolog @@ */ #ifdef _LIBC /* Rename the non ANSI C functions. This is required by the standard because some ANSI C functions will require linking with this object file and the name space must not be polluted. */ # define getcwd __getcwd # define stpcpy __stpcpy #else # if !defined HAVE_GETCWD char *getwd (); # define getcwd(buf, max) getwd (buf) # else char *getcwd (); # endif # ifndef HAVE_STPCPY static char *stpcpy PARAMS ((char *dest, const char *src)); # endif #endif /* Amount to increase buffer size by in each try. */ #define PATH_INCR 32 /* The following is from pathmax.h. */ /* Non-POSIX BSD systems might have gcc's limits.h, which doesn't define PATH_MAX but might cause redefinition warnings when sys/param.h is later included (as on MORE/BSD 4.3). */ #if defined(_POSIX_VERSION) || (defined(HAVE_LIMITS_H) && !defined(__GNUC__)) # include #endif #ifndef _POSIX_PATH_MAX # define _POSIX_PATH_MAX 255 #endif #if !defined(PATH_MAX) && defined(_PC_PATH_MAX) # define PATH_MAX (pathconf ("/", _PC_PATH_MAX) < 1 ? 1024 : pathconf ("/", _PC_PATH_MAX)) #endif /* Don't include sys/param.h if it already has been. */ #if defined(HAVE_SYS_PARAM_H) && !defined(PATH_MAX) && !defined(MAXPATHLEN) # include #endif #if !defined(PATH_MAX) && defined(MAXPATHLEN) # define PATH_MAX MAXPATHLEN #endif #ifndef PATH_MAX # define PATH_MAX _POSIX_PATH_MAX #endif /* XPG3 defines the result of `setlocale (category, NULL)' as: ``Directs `setlocale()' to query `category' and return the current setting of `local'.'' However it does not specify the exact format. And even worse: POSIX defines this not at all. So we can use this feature only on selected system (e.g. those using GNU C Library). */ #ifdef _LIBC # define HAVE_LOCALE_NULL #endif /* Name of the default domain used for gettext(3) prior any call to textdomain(3). The default value for this is "messages". */ const char _nl_default_default_domain[] = "messages"; /* Value used as the default domain for gettext(3). */ const char *_nl_current_default_domain = _nl_default_default_domain; /* Contains the default location of the message catalogs. */ const char _nl_default_dirname[] = GNULOCALEDIR; /* List with bindings of specific domains created by bindtextdomain() calls. */ struct binding *_nl_domain_bindings; /* Prototypes for local functions. */ static char *find_msg PARAMS ((struct loaded_l10nfile *domain_file, const char *msgid)); static const char *category_to_name PARAMS ((int category)); static const char *guess_category_value PARAMS ((int category, const char *categoryname)); /* For those loosing systems which don't have `alloca' we have to add some additional code emulating it. */ #ifdef HAVE_ALLOCA /* Nothing has to be done. */ # define ADD_BLOCK(list, address) /* nothing */ # define FREE_BLOCKS(list) /* nothing */ #else struct block_list { void *address; struct block_list *next; }; # define ADD_BLOCK(list, addr) \ do { \ struct block_list *newp = (struct block_list *) malloc (sizeof (*newp)); \ /* If we cannot get a free block we cannot add the new element to \ the list. */ \ if (newp != NULL) { \ newp->address = (addr); \ newp->next = (list); \ (list) = newp; \ } \ } while (0) # define FREE_BLOCKS(list) \ do { \ while (list != NULL) { \ struct block_list *old = list; \ list = list->next; \ free (old); \ } \ } while (0) # undef alloca # define alloca(size) (malloc (size)) #endif /* have alloca */ /* Names for the libintl functions are a problem. They must not clash with existing names and they should follow ANSI C. But this source code is also used in GNU C Library where the names have a __ prefix. So we have to make a difference here. */ #ifdef _LIBC # define DCGETTEXT __dcgettext #else # define DCGETTEXT dcgettext__ #endif /* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY locale. */ char * DCGETTEXT (domainname, msgid, category) const char *domainname; const char *msgid; int category; { #ifndef HAVE_ALLOCA struct block_list *block_list = NULL; #endif struct loaded_l10nfile *domain; struct binding *binding; const char *categoryname; const char *categoryvalue; char *dirname, *xdomainname; char *single_locale; char *retval; int saved_errno = errno; /* If no real MSGID is given return NULL. */ if (msgid == NULL) return NULL; /* If DOMAINNAME is NULL, we are interested in the default domain. If CATEGORY is not LC_MESSAGES this might not make much sense but the defintion left this undefined. */ if (domainname == NULL) domainname = _nl_current_default_domain; /* First find matching binding. */ for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next) { int compare = strcmp (domainname, binding->domainname); if (compare == 0) /* We found it! */ break; if (compare < 0) { /* It is not in the list. */ binding = NULL; break; } } if (binding == NULL) dirname = (char *) _nl_default_dirname; else if (binding->dirname[0] == '/') dirname = binding->dirname; else { /* We have a relative path. Make it absolute now. */ size_t dirname_len = strlen (binding->dirname) + 1; size_t path_max; char *ret; path_max = (unsigned) PATH_MAX; path_max += 2; /* The getcwd docs say to do this. */ dirname = (char *) alloca (path_max + dirname_len); ADD_BLOCK (block_list, dirname); __set_errno (0); while ((ret = getcwd (dirname, path_max)) == NULL && errno == ERANGE) { path_max += PATH_INCR; dirname = (char *) alloca (path_max + dirname_len); ADD_BLOCK (block_list, dirname); __set_errno (0); } if (ret == NULL) { /* We cannot get the current working directory. Don't signal an error but simply return the default string. */ FREE_BLOCKS (block_list); __set_errno (saved_errno); return (char *) msgid; } stpcpy (stpcpy (strchr (dirname, '\0'), "/"), binding->dirname); } /* Now determine the symbolic name of CATEGORY and its value. */ categoryname = category_to_name (category); categoryvalue = guess_category_value (category, categoryname); xdomainname = (char *) alloca (strlen (categoryname) + strlen (domainname) + 5); ADD_BLOCK (block_list, xdomainname); stpcpy (stpcpy (stpcpy (stpcpy (xdomainname, categoryname), "/"), domainname), ".mo"); /* Creating working area. */ single_locale = (char *) alloca (strlen (categoryvalue) + 1); ADD_BLOCK (block_list, single_locale); /* Search for the given string. This is a loop because we perhaps got an ordered list of languages to consider for th translation. */ while (1) { /* Make CATEGORYVALUE point to the next element of the list. */ while (categoryvalue[0] != '\0' && categoryvalue[0] == ':') ++categoryvalue; if (categoryvalue[0] == '\0') { /* The whole contents of CATEGORYVALUE has been searched but no valid entry has been found. We solve this situation by implicitly appending a "C" entry, i.e. no translation will take place. */ single_locale[0] = 'C'; single_locale[1] = '\0'; } else { char *cp = single_locale; while (categoryvalue[0] != '\0' && categoryvalue[0] != ':') *cp++ = *categoryvalue++; *cp = '\0'; } /* If the current locale value is C (or POSIX) we don't load a domain. Return the MSGID. */ if (strcmp (single_locale, "C") == 0 || strcmp (single_locale, "POSIX") == 0) { FREE_BLOCKS (block_list); __set_errno (saved_errno); return (char *) msgid; } /* Find structure describing the message catalog matching the DOMAINNAME and CATEGORY. */ domain = _nl_find_domain (dirname, single_locale, xdomainname); if (domain != NULL) { retval = find_msg (domain, msgid); if (retval == NULL) { int cnt; for (cnt = 0; domain->successor[cnt] != NULL; ++cnt) { retval = find_msg (domain->successor[cnt], msgid); if (retval != NULL) break; } } if (retval != NULL) { FREE_BLOCKS (block_list); __set_errno (saved_errno); return retval; } } } /* NOTREACHED */ } #ifdef _LIBC /* Alias for function name in GNU C Library. */ weak_alias (__dcgettext, dcgettext); #endif static char * find_msg (domain_file, msgid) struct loaded_l10nfile *domain_file; const char *msgid; { size_t top, act, bottom; struct loaded_domain *domain; if (domain_file->decided == 0) _nl_load_domain (domain_file); if (domain_file->data == NULL) return NULL; domain = (struct loaded_domain *) domain_file->data; /* Locate the MSGID and its translation. */ if (domain->hash_size > 2 && domain->hash_tab != NULL) { /* Use the hashing table. */ nls_uint32 len = strlen (msgid); nls_uint32 hash_val = hash_string (msgid); nls_uint32 idx = hash_val % domain->hash_size; nls_uint32 incr = 1 + (hash_val % (domain->hash_size - 2)); nls_uint32 nstr = W (domain->must_swap, domain->hash_tab[idx]); if (nstr == 0) /* Hash table entry is empty. */ return NULL; if (W (domain->must_swap, domain->orig_tab[nstr - 1].length) == len && strcmp (msgid, domain->data + W (domain->must_swap, domain->orig_tab[nstr - 1].offset)) == 0) return (char *) domain->data + W (domain->must_swap, domain->trans_tab[nstr - 1].offset); while (1) { if (idx >= domain->hash_size - incr) idx -= domain->hash_size - incr; else idx += incr; nstr = W (domain->must_swap, domain->hash_tab[idx]); if (nstr == 0) /* Hash table entry is empty. */ return NULL; if (W (domain->must_swap, domain->orig_tab[nstr - 1].length) == len && strcmp (msgid, domain->data + W (domain->must_swap, domain->orig_tab[nstr - 1].offset)) == 0) return (char *) domain->data + W (domain->must_swap, domain->trans_tab[nstr - 1].offset); } /* NOTREACHED */ } /* Now we try the default method: binary search in the sorted array of messages. */ bottom = 0; top = domain->nstrings; while (bottom < top) { int cmp_val; act = (bottom + top) / 2; cmp_val = strcmp (msgid, domain->data + W (domain->must_swap, domain->orig_tab[act].offset)); if (cmp_val < 0) top = act; else if (cmp_val > 0) bottom = act + 1; else break; } /* If an translation is found return this. */ return bottom >= top ? NULL : (char *) domain->data + W (domain->must_swap, domain->trans_tab[act].offset); } /* Return string representation of locale CATEGORY. */ static const char * category_to_name (category) int category; { const char *retval; switch (category) { #ifdef LC_COLLATE case LC_COLLATE: retval = "LC_COLLATE"; break; #endif #ifdef LC_CTYPE case LC_CTYPE: retval = "LC_CTYPE"; break; #endif #ifdef LC_MONETARY case LC_MONETARY: retval = "LC_MONETARY"; break; #endif #ifdef LC_NUMERIC case LC_NUMERIC: retval = "LC_NUMERIC"; break; #endif #ifdef LC_TIME case LC_TIME: retval = "LC_TIME"; break; #endif #ifdef LC_MESSAGES case LC_MESSAGES: retval = "LC_MESSAGES"; break; #endif #ifdef LC_RESPONSE case LC_RESPONSE: retval = "LC_RESPONSE"; break; #endif #ifdef LC_ALL case LC_ALL: /* This might not make sense but is perhaps better than any other value. */ retval = "LC_ALL"; break; #endif default: /* If you have a better idea for a default value let me know. */ retval = "LC_XXX"; } return retval; } /* Guess value of current locale from value of the environment variables. */ static const char * guess_category_value (category, categoryname) int category; const char *categoryname; { const char *retval; /* The highest priority value is the `LANGUAGE' environment variable. This is a GNU extension. */ retval = getenv ("LANGUAGE"); if (retval != NULL && retval[0] != '\0') return retval; /* `LANGUAGE' is not set. So we have to proceed with the POSIX methods of looking to `LC_ALL', `LC_xxx', and `LANG'. On some systems this can be done by the `setlocale' function itself. */ #if defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES && defined HAVE_LOCALE_NULL return setlocale (category, NULL); #else /* Setting of LC_ALL overwrites all other. */ retval = getenv ("LC_ALL"); if (retval != NULL && retval[0] != '\0') return retval; /* Next comes the name of the desired category. */ retval = getenv (categoryname); if (retval != NULL && retval[0] != '\0') return retval; /* Last possibility is the LANG environment variable. */ retval = getenv ("LANG"); if (retval != NULL && retval[0] != '\0') return retval; /* We use C as the default domain. POSIX says this is implementation defined. */ return "C"; #endif } /* @@ begin of epilog @@ */ /* We don't want libintl.a to depend on any other library. So we avoid the non-standard function stpcpy. In GNU C Library this function is available, though. Also allow the symbol HAVE_STPCPY to be defined. */ #if !_LIBC && !HAVE_STPCPY static char * stpcpy (dest, src) char *dest; const char *src; { while ((*dest++ = *src++) != '\0') /* Do nothing. */ ; return dest - 1; } #endif texinfo-3.12/intl/xopen-msg.sed0000664000175000017500000000537606475640104013754 0ustar gg# po2msg.sed - Convert Uniforum style .po file to X/Open style .msg file # Copyright (C) 1995 Free Software Foundation, Inc. # Ulrich Drepper , 1995. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 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, USA. # # # The first directive in the .msg should be the definition of the # message set number. We use always set number 1. # 1 { i\ $set 1 # Automatically created by po2msg.sed h s/.*/0/ x } # # We copy all comments into the .msg file. Perhaps they can help. # /^#/ s/^#[ ]*/$ /p # # We copy the original message as a comment into the .msg file. # /^msgid/ { # Does not work now # /"$/! { # s/\\$// # s/$/ ... (more lines following)"/ # } s/^msgid[ ]*"\(.*\)"$/$ Original Message: \1/ p } # # The .msg file contains, other then the .po file, only the translations # but each given a unique ID. Starting from 1 and incrementing by 1 for # each message we assign them to the messages. # It is important that the .po file used to generate the cat-id-tbl.c file # (with po-to-tbl) is the same as the one used here. (At least the order # of declarations must not be changed.) # /^msgstr/ { s/msgstr[ ]*"\(.*\)"/\1/ x # The following nice solution is by # Bruno td # Increment a decimal number in pattern space. # First hide trailing `9' digits. :d s/9\(_*\)$/_\1/ td # Assure at least one digit is available. s/^\(_*\)$/0\1/ # Increment the last digit. s/8\(_*\)$/9\1/ s/7\(_*\)$/8\1/ s/6\(_*\)$/7\1/ s/5\(_*\)$/6\1/ s/4\(_*\)$/5\1/ s/3\(_*\)$/4\1/ s/2\(_*\)$/3\1/ s/1\(_*\)$/2\1/ s/0\(_*\)$/1\1/ # Convert the hidden `9' digits to `0's. s/_/0/g x # Bring the line in the format ` ' G s/^[^\n]*$/& / s/\(.*\)\n\([0-9]*\)/\2 \1/ # Clear flag from last substitution. tb # Append the next line. :b N # Look whether second part is a continuation line. s/\(.*\n\)"\(.*\)"/\1\2/ # Yes, then branch. ta P D # Note that `D' includes a jump to the start!! # We found a continuation line. But before printing insert '\'. :a s/\(.*\)\(\n.*\)/\1\\\2/ P # We cannot use the sed command `D' here s/.*\n\(.*\)/\1/ tb } d texinfo-3.12/intl/cat-compat.c0000664000175000017500000001474106475640106013534 0ustar gg/* Compatibility code for gettext-using-catgets interface. Copyright (C) 1995, 1997 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, USA. */ #ifdef HAVE_CONFIG_H # include #endif #include #ifdef STDC_HEADERS # include # include #else char *getenv (); # ifdef HAVE_MALLOC_H # include # endif #endif #ifdef HAVE_NL_TYPES_H # include #endif #include "libgettext.h" /* @@ end of prolog @@ */ /* XPG3 defines the result of `setlocale (category, NULL)' as: ``Directs `setlocale()' to query `category' and return the current setting of `local'.'' However it does not specify the exact format. And even worse: POSIX defines this not at all. So we can use this feature only on selected system (e.g. those using GNU C Library). */ #ifdef _LIBC # define HAVE_LOCALE_NULL #endif /* The catalog descriptor. */ static nl_catd catalog = (nl_catd) -1; /* Name of the default catalog. */ static const char default_catalog_name[] = "messages"; /* Name of currently used catalog. */ static const char *catalog_name = default_catalog_name; /* Get ID for given string. If not found return -1. */ static int msg_to_cat_id PARAMS ((const char *msg)); /* Substitution for systems lacking this function in their C library. */ #if !_LIBC && !HAVE_STPCPY static char *stpcpy PARAMS ((char *dest, const char *src)); #endif /* Set currently used domain/catalog. */ char * textdomain (domainname) const char *domainname; { nl_catd new_catalog; char *new_name; size_t new_name_len; char *lang; #if defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES \ && defined HAVE_LOCALE_NULL lang = setlocale (LC_MESSAGES, NULL); #else lang = getenv ("LC_ALL"); if (lang == NULL || lang[0] == '\0') { lang = getenv ("LC_MESSAGES"); if (lang == NULL || lang[0] == '\0') lang = getenv ("LANG"); } #endif if (lang == NULL || lang[0] == '\0') lang = "C"; /* See whether name of currently used domain is asked. */ if (domainname == NULL) return (char *) catalog_name; if (domainname[0] == '\0') domainname = default_catalog_name; /* Compute length of added path element. */ new_name_len = sizeof (LOCALEDIR) - 1 + 1 + strlen (lang) + sizeof ("/LC_MESSAGES/") - 1 + sizeof (PACKAGE) - 1 + sizeof (".cat"); new_name = (char *) malloc (new_name_len); if (new_name == NULL) return NULL; strcpy (new_name, PACKAGE); new_catalog = catopen (new_name, 0); if (new_catalog == (nl_catd) -1) { /* NLSPATH search didn't work, try absolute path */ sprintf (new_name, "%s/%s/LC_MESSAGES/%s.cat", LOCALEDIR, lang, PACKAGE); new_catalog = catopen (new_name, 0); if (new_catalog == (nl_catd) -1) { free (new_name); return (char *) catalog_name; } } /* Close old catalog. */ if (catalog != (nl_catd) -1) catclose (catalog); if (catalog_name != default_catalog_name) free ((char *) catalog_name); catalog = new_catalog; catalog_name = new_name; return (char *) catalog_name; } char * bindtextdomain (domainname, dirname) const char *domainname; const char *dirname; { #if HAVE_SETENV || HAVE_PUTENV char *old_val, *new_val, *cp; size_t new_val_len; /* This does not make much sense here but to be compatible do it. */ if (domainname == NULL) return NULL; /* Compute length of added path element. If we use setenv we don't need the first byts for NLSPATH=, but why complicate the code for this peanuts. */ new_val_len = sizeof ("NLSPATH=") - 1 + strlen (dirname) + sizeof ("/%L/LC_MESSAGES/%N.cat"); old_val = getenv ("NLSPATH"); if (old_val == NULL || old_val[0] == '\0') { old_val = NULL; new_val_len += 1 + sizeof (LOCALEDIR) - 1 + sizeof ("/%L/LC_MESSAGES/%N.cat"); } else new_val_len += strlen (old_val); new_val = (char *) malloc (new_val_len); if (new_val == NULL) return NULL; # if HAVE_SETENV cp = new_val; # else cp = stpcpy (new_val, "NLSPATH="); # endif cp = stpcpy (cp, dirname); cp = stpcpy (cp, "/%L/LC_MESSAGES/%N.cat:"); if (old_val == NULL) { # if __STDC__ stpcpy (cp, LOCALEDIR "/%L/LC_MESSAGES/%N.cat"); # else cp = stpcpy (cp, LOCALEDIR); stpcpy (cp, "/%L/LC_MESSAGES/%N.cat"); # endif } else stpcpy (cp, old_val); # if HAVE_SETENV setenv ("NLSPATH", new_val, 1); free (new_val); # else putenv (new_val); /* Do *not* free the environment entry we just entered. It is used from now on. */ # endif #endif return (char *) domainname; } #undef gettext char * gettext (msg) const char *msg; { int msgid; if (msg == NULL || catalog == (nl_catd) -1) return (char *) msg; /* Get the message from the catalog. We always use set number 1. The message ID is computed by the function `msg_to_cat_id' which works on the table generated by `po-to-tbl'. */ msgid = msg_to_cat_id (msg); if (msgid == -1) return (char *) msg; return catgets (catalog, 1, msgid, (char *) msg); } /* Look through the table `_msg_tbl' which has `_msg_tbl_length' entries for the one equal to msg. If it is found return the ID. In case when the string is not found return -1. */ static int msg_to_cat_id (msg) const char *msg; { int cnt; for (cnt = 0; cnt < _msg_tbl_length; ++cnt) if (strcmp (msg, _msg_tbl[cnt]._msg) == 0) return _msg_tbl[cnt]._msg_number; return -1; } /* @@ begin of epilog @@ */ /* We don't want libintl.a to depend on any other library. So we avoid the non-standard function stpcpy. In GNU C Library this function is available, though. Also allow the symbol HAVE_STPCPY to be defined. */ #if !_LIBC && !HAVE_STPCPY static char * stpcpy (dest, src) char *dest; const char *src; { while ((*dest++ = *src++) != '\0') /* Do nothing. */ ; return dest - 1; } #endif texinfo-3.12/intl/gettext.c0000664000175000017500000000362206475640105013163 0ustar gg/* Implementation of gettext(3) function Copyright (C) 1995, 1997 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, USA. */ #ifdef HAVE_CONFIG_H # include #endif #ifdef _LIBC # define __need_NULL # include #else # ifdef STDC_HEADERS # include /* Just for NULL. */ # else # ifdef HAVE_STRING_H # include # else # define NULL ((void *) 0) # endif # endif #endif #ifdef _LIBC # include #else # include "libgettext.h" #endif /* @@ end of prolog @@ */ /* Names for the libintl functions are a problem. They must not clash with existing names and they should follow ANSI C. But this source code is also used in GNU C Library where the names have a __ prefix. So we have to make a difference here. */ #ifdef _LIBC # define GETTEXT __gettext # define DGETTEXT __dgettext #else # define GETTEXT gettext__ # define DGETTEXT dgettext__ #endif /* Look up MSGID in the current default message catalog for the current LC_MESSAGES locale. If not found, returns MSGID itself (the default text). */ char * GETTEXT (msgid) const char *msgid; { return DGETTEXT (NULL, msgid); } #ifdef _LIBC /* Alias for function name in GNU C Library. */ weak_alias (__gettext, gettext); #endif texinfo-3.12/intl/localealias.c0000664000175000017500000002131506475640105013747 0ustar gg/* Handle aliases for locale names Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. Written by Ulrich Drepper , 1995. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 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, USA. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #ifdef __GNUC__ # define alloca __builtin_alloca # define HAVE_ALLOCA 1 #else # if defined HAVE_ALLOCA_H || defined _LIBC # include # else # ifdef _AIX #pragma alloca # else # ifndef alloca char *alloca (); # endif # endif # endif #endif #if defined STDC_HEADERS || defined _LIBC # include #else char *getenv (); # ifdef HAVE_MALLOC_H # include # else void free (); # endif #endif #if defined HAVE_STRING_H || defined _LIBC # ifndef _GNU_SOURCE # define _GNU_SOURCE 1 # endif # include #else # include # ifndef memcpy # define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num) # endif #endif #if !HAVE_STRCHR && !defined _LIBC # ifndef strchr # define strchr index # endif #endif #include "gettext.h" #include "gettextP.h" /* @@ end of prolog @@ */ #ifdef _LIBC /* Rename the non ANSI C functions. This is required by the standard because some ANSI C functions will require linking with this object file and the name space must not be polluted. */ # define strcasecmp __strcasecmp #endif /* For those loosing systems which don't have `alloca' we have to add some additional code emulating it. */ #ifdef HAVE_ALLOCA /* Nothing has to be done. */ # define ADD_BLOCK(list, address) /* nothing */ # define FREE_BLOCKS(list) /* nothing */ #else struct block_list { void *address; struct block_list *next; }; # define ADD_BLOCK(list, addr) \ do { \ struct block_list *newp = (struct block_list *) malloc (sizeof (*newp)); \ /* If we cannot get a free block we cannot add the new element to \ the list. */ \ if (newp != NULL) { \ newp->address = (addr); \ newp->next = (list); \ (list) = newp; \ } \ } while (0) # define FREE_BLOCKS(list) \ do { \ while (list != NULL) { \ struct block_list *old = list; \ list = list->next; \ free (old); \ } \ } while (0) # undef alloca # define alloca(size) (malloc (size)) #endif /* have alloca */ struct alias_map { const char *alias; const char *value; }; static struct alias_map *map; static size_t nmap = 0; static size_t maxmap = 0; /* Prototypes for local functions. */ static size_t read_alias_file PARAMS ((const char *fname, int fname_len)); static void extend_alias_table PARAMS ((void)); static int alias_compare PARAMS ((const struct alias_map *map1, const struct alias_map *map2)); const char * _nl_expand_alias (name) const char *name; { static const char *locale_alias_path = LOCALE_ALIAS_PATH; struct alias_map *retval; size_t added; do { struct alias_map item; item.alias = name; if (nmap > 0) retval = (struct alias_map *) bsearch (&item, map, nmap, sizeof (struct alias_map), (int (*) PARAMS ((const void *, const void *)) ) alias_compare); else retval = NULL; /* We really found an alias. Return the value. */ if (retval != NULL) return retval->value; /* Perhaps we can find another alias file. */ added = 0; while (added == 0 && locale_alias_path[0] != '\0') { const char *start; while (locale_alias_path[0] == ':') ++locale_alias_path; start = locale_alias_path; while (locale_alias_path[0] != '\0' && locale_alias_path[0] != ':') ++locale_alias_path; if (start < locale_alias_path) added = read_alias_file (start, locale_alias_path - start); } } while (added != 0); return NULL; } static size_t read_alias_file (fname, fname_len) const char *fname; int fname_len; { #ifndef HAVE_ALLOCA struct block_list *block_list = NULL; #endif FILE *fp; char *full_fname; size_t added; static const char aliasfile[] = "/locale.alias"; full_fname = (char *) alloca (fname_len + sizeof aliasfile); ADD_BLOCK (block_list, full_fname); memcpy (full_fname, fname, fname_len); memcpy (&full_fname[fname_len], aliasfile, sizeof aliasfile); fp = fopen (full_fname, "r"); if (fp == NULL) { FREE_BLOCKS (block_list); return 0; } added = 0; while (!feof (fp)) { /* It is a reasonable approach to use a fix buffer here because a) we are only interested in the first two fields b) these fields must be usable as file names and so must not be that long */ char buf[BUFSIZ]; char *alias; char *value; char *cp; if (fgets (buf, BUFSIZ, fp) == NULL) /* EOF reached. */ break; cp = buf; /* Ignore leading white space. */ while (isspace (cp[0])) ++cp; /* A leading '#' signals a comment line. */ if (cp[0] != '\0' && cp[0] != '#') { alias = cp++; while (cp[0] != '\0' && !isspace (cp[0])) ++cp; /* Terminate alias name. */ if (cp[0] != '\0') *cp++ = '\0'; /* Now look for the beginning of the value. */ while (isspace (cp[0])) ++cp; if (cp[0] != '\0') { char *tp; size_t len; value = cp++; while (cp[0] != '\0' && !isspace (cp[0])) ++cp; /* Terminate value. */ if (cp[0] == '\n') { /* This has to be done to make the following test for the end of line possible. We are looking for the terminating '\n' which do not overwrite here. */ *cp++ = '\0'; *cp = '\n'; } else if (cp[0] != '\0') *cp++ = '\0'; if (nmap >= maxmap) extend_alias_table (); /* We cannot depend on strdup available in the libc. Sigh! */ len = strlen (alias) + 1; tp = (char *) malloc (len); if (tp == NULL) { FREE_BLOCKS (block_list); return added; } memcpy (tp, alias, len); map[nmap].alias = tp; len = strlen (value) + 1; tp = (char *) malloc (len); if (tp == NULL) { FREE_BLOCKS (block_list); return added; } memcpy (tp, value, len); map[nmap].value = tp; ++nmap; ++added; } } /* Possibly not the whole line fits into the buffer. Ignore the rest of the line. */ while (strchr (cp, '\n') == NULL) { cp = buf; if (fgets (buf, BUFSIZ, fp) == NULL) /* Make sure the inner loop will be left. The outer loop will exit at the `feof' test. */ *cp = '\n'; } } /* Should we test for ferror()? I think we have to silently ignore errors. --drepper */ fclose (fp); if (added > 0) qsort (map, nmap, sizeof (struct alias_map), (int (*) PARAMS ((const void *, const void *))) alias_compare); FREE_BLOCKS (block_list); return added; } static void extend_alias_table () { size_t new_size; struct alias_map *new_map; new_size = maxmap == 0 ? 100 : 2 * maxmap; new_map = (struct alias_map *) malloc (new_size * sizeof (struct alias_map)); if (new_map == NULL) /* Simply don't extend: we don't have any more core. */ return; memcpy (new_map, map, nmap * sizeof (struct alias_map)); if (maxmap != 0) free (map); map = new_map; maxmap = new_size; } static int alias_compare (map1, map2) const struct alias_map *map1; const struct alias_map *map2; { #if defined _LIBC || defined HAVE_STRCASECMP return strcasecmp (map1->alias, map2->alias); #else const unsigned char *p1 = (const unsigned char *) map1->alias; const unsigned char *p2 = (const unsigned char *) map2->alias; unsigned char c1, c2; if (p1 == p2) return 0; do { /* I know this seems to be odd but the tolower() function in some systems libc cannot handle nonalpha characters. */ c1 = isupper (*p1) ? tolower (*p1) : *p1; c2 = isupper (*p2) ? tolower (*p2) : *p2; if (c1 == '\0') break; ++p1; ++p2; } while (c1 == c2); return c1 - c2; #endif } texinfo-3.12/intl/gettextP.h0000664000175000017500000000341406475640104013306 0ustar gg/* Header describing internals of gettext library Copyright (C) 1995, 1996, 1997 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, USA. */ #ifndef _GETTEXTP_H #define _GETTEXTP_H #include "loadinfo.h" /* @@ end of prolog @@ */ #ifndef PARAMS # if __STDC__ # define PARAMS(args) args # else # define PARAMS(args) () # endif #endif #ifndef W # define W(flag, data) ((flag) ? SWAP (data) : (data)) #endif static nls_uint32 SWAP PARAMS ((nls_uint32 i)); static inline nls_uint32 SWAP (i) nls_uint32 i; { return (i << 24) | ((i & 0xff00) << 8) | ((i >> 8) & 0xff00) | (i >> 24); } struct loaded_domain { const char *data; int must_swap; nls_uint32 nstrings; struct string_desc *orig_tab; struct string_desc *trans_tab; nls_uint32 hash_size; nls_uint32 *hash_tab; }; struct binding { struct binding *next; char *domainname; char *dirname; }; struct loaded_l10nfile *_nl_find_domain PARAMS ((const char *__dirname, char *__locale, const char *__domainname)); void _nl_load_domain PARAMS ((struct loaded_l10nfile *__domain)); /* @@ begin of epilog @@ */ #endif /* gettextP.h */ texinfo-3.12/intl/finddomain.c0000664000175000017500000001226206475640105013607 0ustar gg/* Handle list of needed message catalogs Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. Written by Ulrich Drepper , 1995. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 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, USA. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #if defined STDC_HEADERS || defined _LIBC # include #else # ifdef HAVE_MALLOC_H # include # else void free (); # endif #endif #if defined HAVE_STRING_H || defined _LIBC # include #else # include # ifndef memcpy # define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num) # endif #endif #if !HAVE_STRCHR && !defined _LIBC # ifndef strchr # define strchr index # endif #endif #if defined HAVE_UNISTD_H || defined _LIBC # include #endif #include "gettext.h" #include "gettextP.h" #ifdef _LIBC # include #else # include "libgettext.h" #endif /* @@ end of prolog @@ */ /* List of already loaded domains. */ static struct loaded_l10nfile *_nl_loaded_domains; /* Return a data structure describing the message catalog described by the DOMAINNAME and CATEGORY parameters with respect to the currently established bindings. */ struct loaded_l10nfile * _nl_find_domain (dirname, locale, domainname) const char *dirname; char *locale; const char *domainname; { struct loaded_l10nfile *retval; const char *language; const char *modifier; const char *territory; const char *codeset; const char *normalized_codeset; const char *special; const char *sponsor; const char *revision; const char *alias_value; int mask; /* LOCALE can consist of up to four recognized parts for the XPG syntax: language[_territory[.codeset]][@modifier] and six parts for the CEN syntax: language[_territory][+audience][+special][,[sponsor][_revision]] Beside the first all of them are allowed to be missing. If the full specified locale is not found, the less specific one are looked for. The various part will be stripped of according to the following order: (1) revision (2) sponsor (3) special (4) codeset (5) normalized codeset (6) territory (7) audience/modifier */ /* If we have already tested for this locale entry there has to be one data set in the list of loaded domains. */ retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname, strlen (dirname) + 1, 0, locale, NULL, NULL, NULL, NULL, NULL, NULL, NULL, domainname, 0); if (retval != NULL) { /* We know something about this locale. */ int cnt; if (retval->decided == 0) _nl_load_domain (retval); if (retval->data != NULL) return retval; for (cnt = 0; retval->successor[cnt] != NULL; ++cnt) { if (retval->successor[cnt]->decided == 0) _nl_load_domain (retval->successor[cnt]); if (retval->successor[cnt]->data != NULL) break; } return cnt >= 0 ? retval : NULL; /* NOTREACHED */ } /* See whether the locale value is an alias. If yes its value *overwrites* the alias name. No test for the original value is done. */ alias_value = _nl_expand_alias (locale); if (alias_value != NULL) { size_t len = strlen (alias_value) + 1; locale = (char *) malloc (len); if (locale == NULL) return NULL; memcpy (locale, alias_value, len); } /* Now we determine the single parts of the locale name. First look for the language. Termination symbols are `_' and `@' if we use XPG4 style, and `_', `+', and `,' if we use CEN syntax. */ mask = _nl_explode_name (locale, &language, &modifier, &territory, &codeset, &normalized_codeset, &special, &sponsor, &revision); /* Create all possible locale entries which might be interested in generalization. */ retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname, strlen (dirname) + 1, mask, language, territory, codeset, normalized_codeset, modifier, special, sponsor, revision, domainname, 1); if (retval == NULL) /* This means we are out of core. */ return NULL; if (retval->decided == 0) _nl_load_domain (retval); if (retval->data == NULL) { int cnt; for (cnt = 0; retval->successor[cnt] != NULL; ++cnt) { if (retval->successor[cnt]->decided == 0) _nl_load_domain (retval->successor[cnt]); if (retval->successor[cnt]->data != NULL) break; } } /* The room for an alias was dynamically allocated. Free it now. */ if (alias_value != NULL) free (locale); return retval; } texinfo-3.12/intl/intl-compat.c0000664000175000017500000000315606475640106013731 0ustar gg/* intl-compat.c - Stub functions to call gettext functions from GNU gettext Library. Copyright (C) 1995 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, USA. */ #ifdef HAVE_CONFIG_H # include #endif #include "libgettext.h" /* @@ end of prolog @@ */ #undef gettext #undef dgettext #undef dcgettext #undef textdomain #undef bindtextdomain char * bindtextdomain (domainname, dirname) const char *domainname; const char *dirname; { return bindtextdomain__ (domainname, dirname); } char * dcgettext (domainname, msgid, category) const char *domainname; const char *msgid; int category; { return dcgettext__ (domainname, msgid, category); } char * dgettext (domainname, msgid) const char *domainname; const char *msgid; { return dgettext__ (domainname, msgid); } char * gettext (msgid) const char *msgid; { return gettext__ (msgid); } char * textdomain (domainname) const char *domainname; { return textdomain__ (domainname); } texinfo-3.12/intl/explodename.c0000664000175000017500000001060006475640105013772 0ustar gg/* Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. Contributed by Ulrich Drepper , 1995. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 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, USA. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include "loadinfo.h" /* On some strange systems still no definition of NULL is found. Sigh! */ #ifndef NULL # if defined __STDC__ && __STDC__ # define NULL ((void *) 0) # else # define NULL 0 # endif #endif /* @@ end of prolog @@ */ int _nl_explode_name (name, language, modifier, territory, codeset, normalized_codeset, special, sponsor, revision) char *name; const char **language; const char **modifier; const char **territory; const char **codeset; const char **normalized_codeset; const char **special; const char **sponsor; const char **revision; { enum { undecided, xpg, cen } syntax; char *cp; int mask; *modifier = NULL; *territory = NULL; *codeset = NULL; *normalized_codeset = NULL; *special = NULL; *sponsor = NULL; *revision = NULL; /* Now we determine the single parts of the locale name. First look for the language. Termination symbols are `_' and `@' if we use XPG4 style, and `_', `+', and `,' if we use CEN syntax. */ mask = 0; syntax = undecided; *language = cp = name; while (cp[0] != '\0' && cp[0] != '_' && cp[0] != '@' && cp[0] != '+' && cp[0] != ',') ++cp; if (*language == cp) /* This does not make sense: language has to be specified. Use this entry as it is without exploding. Perhaps it is an alias. */ cp = strchr (*language, '\0'); else if (cp[0] == '_') { /* Next is the territory. */ cp[0] = '\0'; *territory = ++cp; while (cp[0] != '\0' && cp[0] != '.' && cp[0] != '@' && cp[0] != '+' && cp[0] != ',' && cp[0] != '_') ++cp; mask |= TERRITORY; if (cp[0] == '.') { /* Next is the codeset. */ syntax = xpg; cp[0] = '\0'; *codeset = ++cp; while (cp[0] != '\0' && cp[0] != '@') ++cp; mask |= XPG_CODESET; if (*codeset != cp && (*codeset)[0] != '\0') { *normalized_codeset = _nl_normalize_codeset (*codeset, cp - *codeset); if (strcmp (*codeset, *normalized_codeset) == 0) free ((char *) *normalized_codeset); else mask |= XPG_NORM_CODESET; } } } if (cp[0] == '@' || (syntax != xpg && cp[0] == '+')) { /* Next is the modifier. */ syntax = cp[0] == '@' ? xpg : cen; cp[0] = '\0'; *modifier = ++cp; while (syntax == cen && cp[0] != '\0' && cp[0] != '+' && cp[0] != ',' && cp[0] != '_') ++cp; mask |= XPG_MODIFIER | CEN_AUDIENCE; } if (syntax != xpg && (cp[0] == '+' || cp[0] == ',' || cp[0] == '_')) { syntax = cen; if (cp[0] == '+') { /* Next is special application (CEN syntax). */ cp[0] = '\0'; *special = ++cp; while (cp[0] != '\0' && cp[0] != ',' && cp[0] != '_') ++cp; mask |= CEN_SPECIAL; } if (cp[0] == ',') { /* Next is sponsor (CEN syntax). */ cp[0] = '\0'; *sponsor = ++cp; while (cp[0] != '\0' && cp[0] != '_') ++cp; mask |= CEN_SPONSOR; } if (cp[0] == '_') { /* Next is revision (CEN syntax). */ cp[0] = '\0'; *revision = ++cp; mask |= CEN_REVISION; } } /* For CEN syntax values it might be important to have the separator character in the file name, not for XPG syntax. */ if (syntax == xpg) { if (*territory != NULL && (*territory)[0] == '\0') mask &= ~TERRITORY; if (*codeset != NULL && (*codeset)[0] == '\0') mask &= ~XPG_CODESET; if (*modifier != NULL && (*modifier)[0] == '\0') mask &= ~XPG_MODIFIER; } return mask; } texinfo-3.12/intl/textdomain.c0000664000175000017500000000624106475640105013653 0ustar gg/* Implementation of the textdomain(3) function Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. Written by Ulrich Drepper , 1995. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 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, USA. */ #ifdef HAVE_CONFIG_H # include #endif #if defined STDC_HEADERS || defined _LIBC # include #endif #if defined STDC_HEADERS || defined HAVE_STRING_H || defined _LIBC # include #else # include # ifndef memcpy # define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num) # endif #endif #ifdef _LIBC # include #else # include "libgettext.h" #endif /* @@ end of prolog @@ */ /* Name of the default text domain. */ extern const char _nl_default_default_domain[]; /* Default text domain in which entries for gettext(3) are to be found. */ extern const char *_nl_current_default_domain; /* Names for the libintl functions are a problem. They must not clash with existing names and they should follow ANSI C. But this source code is also used in GNU C Library where the names have a __ prefix. So we have to make a difference here. */ #ifdef _LIBC # define TEXTDOMAIN __textdomain # define strdup(str) __strdup (str) #else # define TEXTDOMAIN textdomain__ #endif /* Set the current default message catalog to DOMAINNAME. If DOMAINNAME is null, return the current default. If DOMAINNAME is "", reset to the default of "messages". */ char * TEXTDOMAIN (domainname) const char *domainname; { char *old; /* A NULL pointer requests the current setting. */ if (domainname == NULL) return (char *) _nl_current_default_domain; old = (char *) _nl_current_default_domain; /* If domain name is the null string set to default domain "messages". */ if (domainname[0] == '\0' || strcmp (domainname, _nl_default_default_domain) == 0) _nl_current_default_domain = _nl_default_default_domain; else { /* If the following malloc fails `_nl_current_default_domain' will be NULL. This value will be returned and so signals we are out of core. */ #if defined _LIBC || defined HAVE_STRDUP _nl_current_default_domain = strdup (domainname); #else size_t len = strlen (domainname) + 1; char *cp = (char *) malloc (len); if (cp != NULL) memcpy (cp, domainname, len); _nl_current_default_domain = cp; #endif } if (old != _nl_default_default_domain) free (old); return (char *) _nl_current_default_domain; } #ifdef _LIBC /* Alias for function name in GNU C Library. */ weak_alias (__textdomain, textdomain); #endif texinfo-3.12/intl/VERSION0000664000175000017500000000005106475640103012372 0ustar ggGNU gettext library from gettext-0.10.32 texinfo-3.12/intl/linux-msg.sed0000664000175000017500000000520506475640104013751 0ustar gg# po2msg.sed - Convert Uniforum style .po file to Linux style .msg file # Copyright (C) 1995 Free Software Foundation, Inc. # Ulrich Drepper , 1995. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 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, USA. # # # The first directive in the .msg should be the definition of the # message set number. We use always set number 1. # 1 { i\ $set 1 # Automatically created by po2msg.sed h s/.*/0/ x } # # Mitch's old catalog format does not allow comments. # # We copy the original message as a comment into the .msg file. # /^msgid/ { s/msgid[ ]*"// # # This does not work now with the new format. # /"$/! { # s/\\$// # s/$/ ... (more lines following)"/ # } x # The following nice solution is by # Bruno td # Increment a decimal number in pattern space. # First hide trailing `9' digits. :d s/9\(_*\)$/_\1/ td # Assure at least one digit is available. s/^\(_*\)$/0\1/ # Increment the last digit. s/8\(_*\)$/9\1/ s/7\(_*\)$/8\1/ s/6\(_*\)$/7\1/ s/5\(_*\)$/6\1/ s/4\(_*\)$/5\1/ s/3\(_*\)$/4\1/ s/2\(_*\)$/3\1/ s/1\(_*\)$/2\1/ s/0\(_*\)$/1\1/ # Convert the hidden `9' digits to `0's. s/_/0/g x G s/\(.*\)"\n\([0-9]*\)/$ #\2 Original Message:(\1)/p } # # The .msg file contains, other then the .po file, only the translations # but each given a unique ID. Starting from 1 and incrementing by 1 for # each message we assign them to the messages. # It is important that the .po file used to generate the cat-id-tbl.c file # (with po-to-tbl) is the same as the one used here. (At least the order # of declarations must not be changed.) # /^msgstr/ { s/msgstr[ ]*"\(.*\)"/# \1/ # Clear substitution flag. tb # Append the next line. :b N # Look whether second part is continuation line. s/\(.*\n\)"\(.*\)"/\1\2/ # Yes, then branch. ta P D # Note that D includes a jump to the start!! # We found a continuation line. But before printing insert '\'. :a s/\(.*\)\(\n.*\)/\1\\\2/ P # We cannot use D here. s/.*\n\(.*\)/\1/ tb } d texinfo-3.12/intl/loadinfo.h0000664000175000017500000000300406475640104013270 0ustar gg#ifndef PARAMS # if __STDC__ # define PARAMS(args) args # else # define PARAMS(args) () # endif #endif /* Encoding of locale name parts. */ #define CEN_REVISION 1 #define CEN_SPONSOR 2 #define CEN_SPECIAL 4 #define XPG_NORM_CODESET 8 #define XPG_CODESET 16 #define TERRITORY 32 #define CEN_AUDIENCE 64 #define XPG_MODIFIER 128 #define CEN_SPECIFIC (CEN_REVISION|CEN_SPONSOR|CEN_SPECIAL|CEN_AUDIENCE) #define XPG_SPECIFIC (XPG_CODESET|XPG_NORM_CODESET|XPG_MODIFIER) struct loaded_l10nfile { const char *filename; int decided; const void *data; struct loaded_l10nfile *next; struct loaded_l10nfile *successor[1]; }; extern const char *_nl_normalize_codeset PARAMS ((const char *codeset, size_t name_len)); extern struct loaded_l10nfile * _nl_make_l10nflist PARAMS ((struct loaded_l10nfile **l10nfile_list, const char *dirlist, size_t dirlist_len, int mask, const char *language, const char *territory, const char *codeset, const char *normalized_codeset, const char *modifier, const char *special, const char *sponsor, const char *revision, const char *filename, int do_allocate)); extern const char *_nl_expand_alias PARAMS ((const char *name)); extern int _nl_explode_name PARAMS ((char *name, const char **language, const char **modifier, const char **territory, const char **codeset, const char **normalized_codeset, const char **special, const char **sponsor, const char **revision)); texinfo-3.12/intl/po2tbl.sed.in0000664000175000017500000000456506475640104013645 0ustar gg# po2tbl.sed - Convert Uniforum style .po file to lookup table for catgets # Copyright (C) 1995 Free Software Foundation, Inc. # Ulrich Drepper , 1995. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 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, USA. # 1 { i\ /* Automatically generated by po2tbl.sed from @PACKAGE NAME@.pot. */\ \ #if HAVE_CONFIG_H\ # include \ #endif\ \ #include "libgettext.h"\ \ const struct _msg_ent _msg_tbl[] = { h s/.*/0/ x } # # Write msgid entries in C array form. # /^msgid/ { s/msgid[ ]*\(".*"\)/ {\1/ tb # Append the next line :b N # Look whether second part is continuation line. s/\(.*\)"\(\n\)"\(.*"\)/\1\2\3/ # Yes, then branch. ta # Because we assume that the input file correctly formed the line # just read cannot be again be a msgid line. So it's safe to ignore # it. s/\(.*\)\n.*/\1/ bc # We found a continuation line. But before printing insert '\'. :a s/\(.*\)\(\n.*\)/\1\\\2/ P # We cannot use D here. s/.*\n\(.*\)/\1/ # Some buggy seds do not clear the `successful substitution since last ``t''' # flag on `N', so we do a `t' here to clear it. tb # Not reached :c x # The following nice solution is by # Bruno td # Increment a decimal number in pattern space. # First hide trailing `9' digits. :d s/9\(_*\)$/_\1/ td # Assure at least one digit is available. s/^\(_*\)$/0\1/ # Increment the last digit. s/8\(_*\)$/9\1/ s/7\(_*\)$/8\1/ s/6\(_*\)$/7\1/ s/5\(_*\)$/6\1/ s/4\(_*\)$/5\1/ s/3\(_*\)$/4\1/ s/2\(_*\)$/3\1/ s/1\(_*\)$/2\1/ s/0\(_*\)$/1\1/ # Convert the hidden `9' digits to `0's. s/_/0/g x G s/\(.*\)\n\([0-9]*\)/\1, \2},/ s/\(.*\)"$/\1/ p } # # Last line. # $ { i\ };\ g s/0*\(.*\)/int _msg_tbl_length = \1;/p } d texinfo-3.12/lib/0000775000175000017500000000000006477056744011144 5ustar ggtexinfo-3.12/lib/getopt1.c0000444000175000017500000001072006334130750012645 0ustar gg/* getopt_long and getopt_long_only entry points for GNU getopt. Copyright (C) 1987,88,89,90,91,92,93,94,96,97 Free Software Foundation, Inc. NOTE: The canonical source of this file is maintained with the GNU C Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu. 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, USA. */ #ifdef HAVE_CONFIG_H #include #endif #include "getopt.h" #if !defined (__STDC__) || !__STDC__ /* This is a separate conditional since some stdc systems reject `defined (const)'. */ #ifndef const #define const #endif #endif #include /* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C Library, but also included in many other GNU distributions. Compiling and linking in this code is a waste when using the GNU C library (especially if it is a shared library). Rather than having every GNU program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */ #define GETOPT_INTERFACE_VERSION 2 #if !defined (_LIBC) && defined (__GLIBC__) && __GLIBC__ >= 2 #include #if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION #define ELIDE_CODE #endif #endif #ifndef ELIDE_CODE /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ #ifdef __GNU_LIBRARY__ #include #endif #ifndef NULL #define NULL 0 #endif int getopt_long (argc, argv, options, long_options, opt_index) int argc; char *const *argv; const char *options; const struct option *long_options; int *opt_index; { return _getopt_internal (argc, argv, options, long_options, opt_index, 0); } /* Like getopt_long, but '-' as well as '--' can indicate a long option. If an option that starts with '-' (not '--') doesn't match a long option, but does match a short option, it is parsed as a short option instead. */ int getopt_long_only (argc, argv, options, long_options, opt_index) int argc; char *const *argv; const char *options; const struct option *long_options; int *opt_index; { return _getopt_internal (argc, argv, options, long_options, opt_index, 1); } #endif /* Not ELIDE_CODE. */ #ifdef TEST #include int main (argc, argv) int argc; char **argv; { int c; int digit_optind = 0; while (1) { int this_option_optind = optind ? optind : 1; int option_index = 0; static struct option long_options[] = { {"add", 1, 0, 0}, {"append", 0, 0, 0}, {"delete", 1, 0, 0}, {"verbose", 0, 0, 0}, {"create", 0, 0, 0}, {"file", 1, 0, 0}, {0, 0, 0, 0} }; c = getopt_long (argc, argv, "abc:d:0123456789", long_options, &option_index); if (c == -1) break; switch (c) { case 0: printf ("option %s", long_options[option_index].name); if (optarg) printf (" with arg %s", optarg); printf ("\n"); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (digit_optind != 0 && digit_optind != this_option_optind) printf ("digits occur in two different argv-elements.\n"); digit_optind = this_option_optind; printf ("option %c\n", c); break; case 'a': printf ("option a\n"); break; case 'b': printf ("option b\n"); break; case 'c': printf ("option c with value `%s'\n", optarg); break; case 'd': printf ("option d with value `%s'\n", optarg); break; case '?': break; default: printf ("?? getopt returned character code 0%o ??\n", c); } } if (optind < argc) { printf ("non-option ARGV-elements: "); while (optind < argc) printf ("%s ", argv[optind++]); printf ("\n"); } exit (0); } #endif /* TEST */ texinfo-3.12/lib/Makefile.in0000664000175000017500000001544206477056743013216 0ustar gg# Makefile.in generated automatically by automake 1.2f from Makefile.am # Copyright (C) 1994, 1995, 1996, 1997, 1998 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. SHELL = /bin/sh srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ bindir = @bindir@ sbindir = @sbindir@ libexecdir = @libexecdir@ datadir = @datadir@ sysconfdir = @sysconfdir@ sharedstatedir = @sharedstatedir@ localstatedir = @localstatedir@ libdir = @libdir@ infodir = @infodir@ mandir = @mandir@ includedir = @includedir@ oldincludedir = /usr/include pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. ACLOCAL = @ACLOCAL@ AUTOCONF = @AUTOCONF@ AUTOMAKE = @AUTOMAKE@ AUTOHEADER = @AUTOHEADER@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ transform = @program_transform_name@ NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : CATALOGS = @CATALOGS@ CATOBJEXT = @CATOBJEXT@ CC = @CC@ DATADIRNAME = @DATADIRNAME@ GENCAT = @GENCAT@ GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ GT_NO = @GT_NO@ GT_YES = @GT_YES@ INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@ INSTOBJEXT = @INSTOBJEXT@ INTLDEPS = @INTLDEPS@ INTLLIBS = @INTLLIBS@ INTLOBJS = @INTLOBJS@ MAKEINFO = @MAKEINFO@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ PACKAGE = @PACKAGE@ POFILES = @POFILES@ POSUB = @POSUB@ RANLIB = @RANLIB@ TERMLIBS = @TERMLIBS@ TEXCONFIG = @TEXCONFIG@ TEXMF = @TEXMF@ USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ l = @l@ noinst_LIBRARIES = libtxi.a INCLUDES = -I../intl # Don't need to list alloca.c, etc., Automake includes them. libtxi_a_SOURCES = getopt.c getopt.h getopt1.c system.h xmalloc.c xstrdup.c libtxi_a_LIBADD = @LIBOBJS@ @ALLOCA@ libtxi_a_DEPENDENCIES = $(libtxi_a_LIBADD) EXTRA_DIST = README mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = ../config.h CONFIG_CLEAN_FILES = LIBRARIES = $(noinst_LIBRARIES) DEFS = @DEFS@ -I. -I$(srcdir) -I.. CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ libtxi_a_OBJECTS = getopt.o getopt1.o xmalloc.o xstrdup.o AR = ar CFLAGS = @CFLAGS@ COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) LINK = $(CC) $(CFLAGS) $(LDFLAGS) -o $@ DIST_COMMON = README Makefile.am Makefile.in alloca.c memcpy.c \ memmove.c strdup.c strerror.c DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) TAR = tar GZIP = --best SOURCES = $(libtxi_a_SOURCES) OBJECTS = $(libtxi_a_OBJECTS) default: all .SUFFIXES: .SUFFIXES: .S .c .o .s $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps lib/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) \ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status mostlyclean-noinstLIBRARIES: clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) distclean-noinstLIBRARIES: maintainer-clean-noinstLIBRARIES: .c.o: $(COMPILE) -c $< .s.o: $(COMPILE) -c $< .S.o: $(COMPILE) -c $< mostlyclean-compile: -rm -f *.o core *.core clean-compile: distclean-compile: -rm -f *.tab.c maintainer-clean-compile: libtxi.a: $(libtxi_a_OBJECTS) $(libtxi_a_DEPENDENCIES) -rm -f libtxi.a $(AR) cru libtxi.a $(libtxi_a_OBJECTS) $(libtxi_a_LIBADD) $(RANLIB) libtxi.a tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) here=`pwd` && cd $(srcdir) \ && mkid -f$$here/ID $(SOURCES) $(HEADERS) $(LISP) TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS)'; \ unique=`for i in $$list; do echo $$i; done | \ awk ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) mostlyclean-tags: clean-tags: distclean-tags: -rm -f TAGS ID maintainer-clean-tags: distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) subdir = lib distdir: $(DISTFILES) @for file in $(DISTFILES); do \ d=$(srcdir); \ test -f $(distdir)/$$file \ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ || cp -p $$d/$$file $(distdir)/$$file; \ done getopt.o: getopt.c ../config.h getopt1.o: getopt1.c ../config.h getopt.h xmalloc.o: xmalloc.c xstrdup.o: xstrdup.c ../config.h info: dvi: check: all $(MAKE) installcheck: install-exec: @$(NORMAL_INSTALL) install-data: @$(NORMAL_INSTALL) install: install-exec install-data all @: uninstall: all: Makefile $(LIBRARIES) install-strip: $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install installdirs: mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -rm -f Makefile $(DISTCLEANFILES) -rm -f config.cache config.log stamp-h stamp-h[0-9]* -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) mostlyclean: mostlyclean-noinstLIBRARIES mostlyclean-compile \ mostlyclean-tags mostlyclean-generic clean: clean-noinstLIBRARIES clean-compile clean-tags clean-generic \ mostlyclean distclean: distclean-noinstLIBRARIES distclean-compile distclean-tags \ distclean-generic clean -rm -f config.status maintainer-clean: maintainer-clean-noinstLIBRARIES \ maintainer-clean-compile maintainer-clean-tags \ maintainer-clean-generic distclean @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." .PHONY: default mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \ clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \ mostlyclean-compile distclean-compile clean-compile \ maintainer-clean-compile tags mostlyclean-tags distclean-tags \ clean-tags maintainer-clean-tags distdir info dvi installcheck \ install-exec install-data install uninstall all installdirs \ mostlyclean-generic distclean-generic clean-generic \ maintainer-clean-generic clean mostlyclean distclean maintainer-clean # 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: texinfo-3.12/lib/memcpy.c0000444000175000017500000000060106225252345012555 0ustar gg/* Copy LEN bytes starting at SRCADDR to DESTADDR. Result undefined if the source overlaps with the destination. Return DESTADDR. */ #ifdef HAVE_CONFIG_H #include #endif char * memcpy (destaddr, srcaddr, len) char *destaddr; const char *srcaddr; int len; { char *dest = destaddr; while (len-- > 0) *destaddr++ = *srcaddr++; return dest; } texinfo-3.12/lib/memmove.c0000444000175000017500000000117205757623632012746 0ustar gg/* memmove.c -- copy memory. Copy LENGTH bytes from SOURCE to DEST. Does not null-terminate. In the public domain. By David MacKenzie . */ #ifdef HAVE_CONFIG_H #include #endif void memmove (dest, source, length) char *dest; const char *source; unsigned length; { if (source < dest) /* Moving from low mem to hi mem; start at end. */ for (source += length, dest += length; length; --length) *--dest = *--source; else if (source != dest) /* Moving from hi mem to low mem; start at beginning. */ for (; length; --length) *dest++ = *source++; } texinfo-3.12/lib/alloca.c0000664000175000017500000003363606166576654012560 0ustar gg/* alloca.c -- allocate automatically reclaimed memory (Mostly) portable public-domain implementation -- D A Gwyn This implementation of the PWB library alloca function, which is used to allocate space off the run-time stack so that it is automatically reclaimed upon procedure exit, was inspired by discussions with J. Q. Johnson of Cornell. J.Otto Tennant contributed the Cray support. There are some preprocessor constants that can be defined when compiling for your specific system, for improved efficiency; however, the defaults should be okay. The general concept of this implementation is to keep track of all alloca-allocated blocks, and reclaim any that are found to be deeper in the stack than the current invocation. This heuristic does not reclaim storage as soon as it becomes invalid, but it will do so eventually. As a special case, alloca(0) reclaims storage without allocating any. It is a good idea to use alloca(0) in your main control loop, etc. to force garbage collection. */ #ifdef HAVE_CONFIG_H #include #endif #ifdef HAVE_STRING_H #include #endif #ifdef HAVE_STDLIB_H #include #endif #ifdef emacs #include "blockinput.h" #endif /* If compiling with GCC 2, this file's not needed. */ #if !defined (__GNUC__) || __GNUC__ < 2 /* If someone has defined alloca as a macro, there must be some other way alloca is supposed to work. */ #ifndef alloca #ifdef emacs #ifdef static /* actually, only want this if static is defined as "" -- this is for usg, in which emacs must undefine static in order to make unexec workable */ #ifndef STACK_DIRECTION you lose -- must know STACK_DIRECTION at compile-time #endif /* STACK_DIRECTION undefined */ #endif /* static */ #endif /* emacs */ /* If your stack is a linked list of frames, you have to provide an "address metric" ADDRESS_FUNCTION macro. */ #if defined (CRAY) && defined (CRAY_STACKSEG_END) long i00afunc (); #define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg)) #else #define ADDRESS_FUNCTION(arg) &(arg) #endif #if __STDC__ typedef void *pointer; #else typedef char *pointer; #endif #ifndef NULL #define NULL 0 #endif /* Different portions of Emacs need to call different versions of malloc. The Emacs executable needs alloca to call xmalloc, because ordinary malloc isn't protected from input signals. On the other hand, the utilities in lib-src need alloca to call malloc; some of them are very simple, and don't have an xmalloc routine. Non-Emacs programs expect this to call use xmalloc. Callers below should use malloc. */ #ifndef emacs #define malloc xmalloc #endif extern pointer malloc (); /* Define STACK_DIRECTION if you know the direction of stack growth for your system; otherwise it will be automatically deduced at run-time. STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ #ifndef STACK_DIRECTION #define STACK_DIRECTION 0 /* Direction unknown. */ #endif #if STACK_DIRECTION != 0 #define STACK_DIR STACK_DIRECTION /* Known at compile-time. */ #else /* STACK_DIRECTION == 0; need run-time code. */ static int stack_dir; /* 1 or -1 once known. */ #define STACK_DIR stack_dir static void find_stack_direction () { static char *addr = NULL; /* Address of first `dummy', once known. */ auto char dummy; /* To get stack address. */ if (addr == NULL) { /* Initial entry. */ addr = ADDRESS_FUNCTION (dummy); find_stack_direction (); /* Recurse once. */ } else { /* Second entry. */ if (ADDRESS_FUNCTION (dummy) > addr) stack_dir = 1; /* Stack grew upward. */ else stack_dir = -1; /* Stack grew downward. */ } } #endif /* STACK_DIRECTION == 0 */ /* An "alloca header" is used to: (a) chain together all alloca'ed blocks; (b) keep track of stack depth. It is very important that sizeof(header) agree with malloc alignment chunk size. The following default should work okay. */ #ifndef ALIGN_SIZE #define ALIGN_SIZE sizeof(double) #endif typedef union hdr { char align[ALIGN_SIZE]; /* To force sizeof(header). */ struct { union hdr *next; /* For chaining headers. */ char *deep; /* For stack depth measure. */ } h; } header; static header *last_alloca_header = NULL; /* -> last alloca header. */ /* Return a pointer to at least SIZE bytes of storage, which will be automatically reclaimed upon exit from the procedure that called alloca. Originally, this space was supposed to be taken from the current stack frame of the caller, but that method cannot be made to work for some implementations of C, for example under Gould's UTX/32. */ pointer alloca (size) unsigned size; { auto char probe; /* Probes stack depth: */ register char *depth = ADDRESS_FUNCTION (probe); #if STACK_DIRECTION == 0 if (STACK_DIR == 0) /* Unknown growth direction. */ find_stack_direction (); #endif /* Reclaim garbage, defined as all alloca'd storage that was allocated from deeper in the stack than currently. */ { register header *hp; /* Traverses linked list. */ #ifdef emacs BLOCK_INPUT; #endif for (hp = last_alloca_header; hp != NULL;) if ((STACK_DIR > 0 && hp->h.deep > depth) || (STACK_DIR < 0 && hp->h.deep < depth)) { register header *np = hp->h.next; free ((pointer) hp); /* Collect garbage. */ hp = np; /* -> next header. */ } else break; /* Rest are not deeper. */ last_alloca_header = hp; /* -> last valid storage. */ #ifdef emacs UNBLOCK_INPUT; #endif } if (size == 0) return NULL; /* No allocation required. */ /* Allocate combined header + user data storage. */ { register pointer new = malloc (sizeof (header) + size); /* Address of header. */ if (new == 0) abort(); ((header *) new)->h.next = last_alloca_header; ((header *) new)->h.deep = depth; last_alloca_header = (header *) new; /* User storage begins just after header. */ return (pointer) ((char *) new + sizeof (header)); } } #if defined (CRAY) && defined (CRAY_STACKSEG_END) #ifdef DEBUG_I00AFUNC #include #endif #ifndef CRAY_STACK #define CRAY_STACK #ifndef CRAY2 /* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */ struct stack_control_header { long shgrow:32; /* Number of times stack has grown. */ long shaseg:32; /* Size of increments to stack. */ long shhwm:32; /* High water mark of stack. */ long shsize:32; /* Current size of stack (all segments). */ }; /* The stack segment linkage control information occurs at the high-address end of a stack segment. (The stack grows from low addresses to high addresses.) The initial part of the stack segment linkage control information is 0200 (octal) words. This provides for register storage for the routine which overflows the stack. */ struct stack_segment_linkage { long ss[0200]; /* 0200 overflow words. */ long sssize:32; /* Number of words in this segment. */ long ssbase:32; /* Offset to stack base. */ long:32; long sspseg:32; /* Offset to linkage control of previous segment of stack. */ long:32; long sstcpt:32; /* Pointer to task common address block. */ long sscsnm; /* Private control structure number for microtasking. */ long ssusr1; /* Reserved for user. */ long ssusr2; /* Reserved for user. */ long sstpid; /* Process ID for pid based multi-tasking. */ long ssgvup; /* Pointer to multitasking thread giveup. */ long sscray[7]; /* Reserved for Cray Research. */ long ssa0; long ssa1; long ssa2; long ssa3; long ssa4; long ssa5; long ssa6; long ssa7; long sss0; long sss1; long sss2; long sss3; long sss4; long sss5; long sss6; long sss7; }; #else /* CRAY2 */ /* The following structure defines the vector of words returned by the STKSTAT library routine. */ struct stk_stat { long now; /* Current total stack size. */ long maxc; /* Amount of contiguous space which would be required to satisfy the maximum stack demand to date. */ long high_water; /* Stack high-water mark. */ long overflows; /* Number of stack overflow ($STKOFEN) calls. */ long hits; /* Number of internal buffer hits. */ long extends; /* Number of block extensions. */ long stko_mallocs; /* Block allocations by $STKOFEN. */ long underflows; /* Number of stack underflow calls ($STKRETN). */ long stko_free; /* Number of deallocations by $STKRETN. */ long stkm_free; /* Number of deallocations by $STKMRET. */ long segments; /* Current number of stack segments. */ long maxs; /* Maximum number of stack segments so far. */ long pad_size; /* Stack pad size. */ long current_address; /* Current stack segment address. */ long current_size; /* Current stack segment size. This number is actually corrupted by STKSTAT to include the fifteen word trailer area. */ long initial_address; /* Address of initial segment. */ long initial_size; /* Size of initial segment. */ }; /* The following structure describes the data structure which trails any stack segment. I think that the description in 'asdef' is out of date. I only describe the parts that I am sure about. */ struct stk_trailer { long this_address; /* Address of this block. */ long this_size; /* Size of this block (does not include this trailer). */ long unknown2; long unknown3; long link; /* Address of trailer block of previous segment. */ long unknown5; long unknown6; long unknown7; long unknown8; long unknown9; long unknown10; long unknown11; long unknown12; long unknown13; long unknown14; }; #endif /* CRAY2 */ #endif /* not CRAY_STACK */ #ifdef CRAY2 /* Determine a "stack measure" for an arbitrary ADDRESS. I doubt that "lint" will like this much. */ static long i00afunc (long *address) { struct stk_stat status; struct stk_trailer *trailer; long *block, size; long result = 0; /* We want to iterate through all of the segments. The first step is to get the stack status structure. We could do this more quickly and more directly, perhaps, by referencing the $LM00 common block, but I know that this works. */ STKSTAT (&status); /* Set up the iteration. */ trailer = (struct stk_trailer *) (status.current_address + status.current_size - 15); /* There must be at least one stack segment. Therefore it is a fatal error if "trailer" is null. */ if (trailer == 0) abort (); /* Discard segments that do not contain our argument address. */ while (trailer != 0) { block = (long *) trailer->this_address; size = trailer->this_size; if (block == 0 || size == 0) abort (); trailer = (struct stk_trailer *) trailer->link; if ((block <= address) && (address < (block + size))) break; } /* Set the result to the offset in this segment and add the sizes of all predecessor segments. */ result = address - block; if (trailer == 0) { return result; } do { if (trailer->this_size <= 0) abort (); result += trailer->this_size; trailer = (struct stk_trailer *) trailer->link; } while (trailer != 0); /* We are done. Note that if you present a bogus address (one not in any segment), you will get a different number back, formed from subtracting the address of the first block. This is probably not what you want. */ return (result); } #else /* not CRAY2 */ /* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP. Determine the number of the cell within the stack, given the address of the cell. The purpose of this routine is to linearize, in some sense, stack addresses for alloca. */ static long i00afunc (long address) { long stkl = 0; long size, pseg, this_segment, stack; long result = 0; struct stack_segment_linkage *ssptr; /* Register B67 contains the address of the end of the current stack segment. If you (as a subprogram) store your registers on the stack and find that you are past the contents of B67, you have overflowed the segment. B67 also points to the stack segment linkage control area, which is what we are really interested in. */ stkl = CRAY_STACKSEG_END (); ssptr = (struct stack_segment_linkage *) stkl; /* If one subtracts 'size' from the end of the segment, one has the address of the first word of the segment. If this is not the first segment, 'pseg' will be nonzero. */ pseg = ssptr->sspseg; size = ssptr->sssize; this_segment = stkl - size; /* It is possible that calling this routine itself caused a stack overflow. Discard stack segments which do not contain the target address. */ while (!(this_segment <= address && address <= stkl)) { #ifdef DEBUG_I00AFUNC fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl); #endif if (pseg == 0) break; stkl = stkl - pseg; ssptr = (struct stack_segment_linkage *) stkl; size = ssptr->sssize; pseg = ssptr->sspseg; this_segment = stkl - size; } result = address - this_segment; /* If you subtract pseg from the current end of the stack, you get the address of the previous stack segment's end. This seems a little convoluted to me, but I'll bet you save a cycle somewhere. */ while (pseg != 0) { #ifdef DEBUG_I00AFUNC fprintf (stderr, "%011o %011o\n", pseg, size); #endif stkl = stkl - pseg; ssptr = (struct stack_segment_linkage *) stkl; size = ssptr->sssize; pseg = ssptr->sspseg; result += size; } return (result); } #endif /* not CRAY2 */ #endif /* CRAY */ #endif /* no alloca */ #endif /* not GCC version 2 */ texinfo-3.12/lib/strdup.c0000444000175000017500000000224505643443271012615 0ustar gg/* strdup.c -- return a newly allocated copy of a string Copyright (C) 1990 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifdef HAVE_CONFIG_H #include #endif #ifdef STDC_HEADERS #include #include #else char *malloc (); char *strcpy (); #endif /* Return a newly allocated copy of STR, or 0 if out of memory. */ char * strdup (str) const char *str; { char *newstr; newstr = (char *) malloc (strlen (str) + 1); if (newstr) strcpy (newstr, str); return newstr; } texinfo-3.12/lib/xmalloc.c0000444000175000017500000000430705771354307012737 0ustar gg/* xmalloc.c -- safe versions of malloc and realloc */ /* This file is part of GNU Info, a program for reading online documentation stored in Info format. This file has appeared in prior works by the Free Software Foundation; thus it carries copyright dates from 1988 through 1993. Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ #if !defined (ALREADY_HAVE_XMALLOC) #include #include extern void *malloc (), *realloc (); static void memory_error_and_abort (); /* **************************************************************** */ /* */ /* Memory Allocation and Deallocation. */ /* */ /* **************************************************************** */ /* Return a pointer to free()able block of memory large enough to hold BYTES number of bytes. If the memory cannot be allocated, print an error message and abort. */ void * xmalloc (bytes) int bytes; { void *temp = malloc (bytes); if (!temp) memory_error_and_abort ("xmalloc"); return (temp); } void * xrealloc (pointer, bytes) void *pointer; int bytes; { void *temp; if (!pointer) temp = malloc (bytes); else temp = realloc (pointer, bytes); if (!temp) memory_error_and_abort ("xrealloc"); return (temp); } static void memory_error_and_abort (fname) char *fname; { fprintf (stderr, "%s: Out of virtual memory!\n", fname); abort (); } #endif /* !ALREADY_HAVE_XMALLOC */ texinfo-3.12/lib/getopt.h0000444000175000017500000001076706352654426012617 0ustar gg/* Declarations for getopt. Copyright (C) 1989,90,91,92,93,94,96,97 Free Software Foundation, Inc. NOTE: The canonical source of this file is maintained with the GNU C Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu. 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, USA. */ #ifndef _GETOPT_H #define _GETOPT_H 1 #ifdef __cplusplus extern "C" { #endif /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ extern char *optarg; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns -1, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ extern int optind; /* Callers store zero here to inhibit the error message `getopt' prints for unrecognized options. */ extern int opterr; /* Set to an option character which was unrecognized. */ extern int optopt; /* Describe the long-named options requested by the application. The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector of `struct option' terminated by an element containing a name which is zero. The field `has_arg' is: no_argument (or 0) if the option does not take an argument, required_argument (or 1) if the option requires an argument, optional_argument (or 2) if the option takes an optional argument. If the field `flag' is not NULL, it points to a variable that is set to the value given in the field `val' when the option is found, but left unchanged if the option is not found. To have a long-named option do something other than set an `int' to a compiled-in constant, such as set a value from `optarg', set the option's `flag' field to zero and its `val' field to a nonzero value (the equivalent single-letter option character, if there is one). For long options that have a zero `flag' field, `getopt' returns the contents of the `val' field. */ struct option { #if defined (__STDC__) && __STDC__ const char *name; #else char *name; #endif /* has_arg can't be an enum because some compilers complain about type mismatches in all the code that assumes it is an int. */ int has_arg; int *flag; int val; }; /* Names for the values of the `has_arg' field of `struct option'. */ #define no_argument 0 #define required_argument 1 #define optional_argument 2 #if defined (__STDC__) && __STDC__ #ifdef __GNU_LIBRARY__ /* Many other libraries have conflicting prototypes for getopt, with differences in the consts, in stdlib.h. To avoid compilation errors, only prototype getopt for the GNU C library. */ extern int getopt (int argc, char *const *argv, const char *shortopts); #else /* not __GNU_LIBRARY__ */ extern int getopt (); #endif /* __GNU_LIBRARY__ */ extern int getopt_long (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind); extern int getopt_long_only (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind); /* Internal only. Users should not call this directly. */ extern int _getopt_internal (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind, int long_only); #else /* not __STDC__ */ extern int getopt (); extern int getopt_long (); extern int getopt_long_only (); extern int _getopt_internal (); #endif /* __STDC__ */ #ifdef __cplusplus } #endif #endif /* getopt.h */ texinfo-3.12/lib/getopt.c0000444000175000017500000007242706441402204012573 0ustar gg/* Getopt for GNU. NOTE: getopt is now part of the C library, so if you don't know what "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu before changing it! Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97 Free Software Foundation, Inc. NOTE: The canonical source of this file is maintained with the GNU C Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu. 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, USA. */ /* This tells Alpha OSF/1 not to define a getopt prototype in . Ditto for AIX 3.2 and . */ #ifndef _NO_PROTO #define _NO_PROTO #endif #ifdef HAVE_CONFIG_H #include #endif #if !defined (__STDC__) || !__STDC__ /* This is a separate conditional since some stdc systems reject `defined (const)'. */ #ifndef const #define const #endif #endif #include /* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C Library, but also included in many other GNU distributions. Compiling and linking in this code is a waste when using the GNU C library (especially if it is a shared library). Rather than having every GNU program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */ #define GETOPT_INTERFACE_VERSION 2 #if !defined (_LIBC) && defined (__GLIBC__) && __GLIBC__ >= 2 #include #if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION #define ELIDE_CODE #endif #endif #ifndef ELIDE_CODE /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ #ifdef __GNU_LIBRARY__ /* Don't include stdlib.h for non-GNU C libraries because some of them contain conflicting prototypes for getopt. */ #include #include #endif /* GNU C library. */ #ifdef VMS #include #if HAVE_STRING_H - 0 #include #endif #endif #ifndef _ /* This is for other GNU distributions with internationalized messages. When compiling libc, the _ macro is predefined. */ #ifdef HAVE_LIBINTL_H # include # define _(msgid) gettext (msgid) #else # define _(msgid) (msgid) #endif #endif /* This version of `getopt' appears to the caller like standard Unix `getopt' but it behaves differently for the user, since it allows the user to intersperse the options with the other arguments. As `getopt' works, it permutes the elements of ARGV so that, when it is done, all the options precede everything else. Thus all application programs are extended to handle flexible argument order. Setting the environment variable POSIXLY_CORRECT disables permutation. Then the behavior is completely standard. GNU application programs can use a third alternative mode in which they can distinguish the relative order of options and other arguments. */ #include "getopt.h" /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ char *optarg = NULL; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns -1, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ /* 1003.2 says this must be 1 before any call. */ int optind = 1; /* Formerly, initialization of getopt depended on optind==0, which causes problems with re-calling getopt as programs generally don't know that. */ int __getopt_initialized = 0; /* The next char to be scanned in the option-element in which the last option character we returned was found. This allows us to pick up the scan where we left off. If this is zero, or a null string, it means resume the scan by advancing to the next ARGV-element. */ static char *nextchar; /* Callers store zero here to inhibit the error message for unrecognized options. */ int opterr = 1; /* Set to an option character which was unrecognized. This must be initialized on some systems to avoid linking in the system's own getopt implementation. */ int optopt = '?'; /* Describe how to deal with options that follow non-option ARGV-elements. If the caller did not specify anything, the default is REQUIRE_ORDER if the environment variable POSIXLY_CORRECT is defined, PERMUTE otherwise. REQUIRE_ORDER means don't recognize them as options; stop option processing when the first non-option is seen. This is what Unix does. This mode of operation is selected by either setting the environment variable POSIXLY_CORRECT, or using `+' as the first character of the list of option characters. PERMUTE is the default. We permute the contents of ARGV as we scan, so that eventually all the non-options are at the end. This allows options to be given in any order, even with programs that were not written to expect this. RETURN_IN_ORDER is an option available to programs that were written to expect options and other ARGV-elements in any order and that care about the ordering of the two. We describe each non-option ARGV-element as if it were the argument of an option with character code 1. Using `-' as the first character of the list of option characters selects this mode of operation. The special argument `--' forces an end of option-scanning regardless of the value of `ordering'. In the case of RETURN_IN_ORDER, only `--' can cause `getopt' to return -1 with `optind' != ARGC. */ static enum { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER } ordering; /* Value of POSIXLY_CORRECT environment variable. */ static char *posixly_correct; #ifdef __GNU_LIBRARY__ /* We want to avoid inclusion of string.h with non-GNU libraries because there are many ways it can cause trouble. On some systems, it contains special magic macros that don't work in GCC. */ #include #define my_index strchr #else /* Avoid depending on library functions or files whose names are inconsistent. */ char *getenv (); static char * my_index (str, chr) const char *str; int chr; { while (*str) { if (*str == chr) return (char *) str; str++; } return 0; } /* If using GCC, we can safely declare strlen this way. If not using GCC, it is ok not to declare it. */ #ifdef __GNUC__ /* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. That was relevant to code that was here before. */ #if !defined (__STDC__) || !__STDC__ /* gcc with -traditional declares the built-in strlen to return int, and has done so at least since version 2.4.5. -- rms. */ extern int strlen (const char *); #endif /* not __STDC__ */ #endif /* __GNUC__ */ #endif /* not __GNU_LIBRARY__ */ /* Handle permutation of arguments. */ /* Describe the part of ARGV that contains non-options that have been skipped. `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is the index after the last of them. */ static int first_nonopt; static int last_nonopt; #ifdef _LIBC /* Bash 2.0 gives us an environment variable containing flags indicating ARGV elements that should not be considered arguments. */ /* Defined in getopt_init.c */ extern char *__getopt_nonoption_flags; static int nonoption_flags_max_len; static int nonoption_flags_len; static int original_argc; static char *const *original_argv; /* Make sure the environment variable bash 2.0 puts in the environment is valid for the getopt call we must make sure that the ARGV passed to getopt is that one passed to the process. */ static void __attribute__ ((unused)) store_args_and_env (int argc, char *const *argv) { /* XXX This is no good solution. We should rather copy the args so that we can compare them later. But we must not use malloc(3). */ original_argc = argc; original_argv = argv; } # ifdef text_set_element text_set_element (__libc_subinit, store_args_and_env); # endif /* text_set_element */ # define SWAP_FLAGS(ch1, ch2) \ if (nonoption_flags_len > 0) \ { \ char __tmp = __getopt_nonoption_flags[ch1]; \ __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ __getopt_nonoption_flags[ch2] = __tmp; \ } #else /* !_LIBC */ # define SWAP_FLAGS(ch1, ch2) #endif /* _LIBC */ /* Exchange two adjacent subsequences of ARGV. One subsequence is elements [first_nonopt,last_nonopt) which contains all the non-options that have been skipped so far. The other is elements [last_nonopt,optind), which contains all the options processed since those non-options were skipped. `first_nonopt' and `last_nonopt' are relocated so that they describe the new indices of the non-options in ARGV after they are moved. */ #if defined (__STDC__) && __STDC__ static void exchange (char **); #endif static void exchange (argv) char **argv; { int bottom = first_nonopt; int middle = last_nonopt; int top = optind; char *tem; /* Exchange the shorter segment with the far end of the longer segment. That puts the shorter segment into the right place. It leaves the longer segment in the right place overall, but it consists of two parts that need to be swapped next. */ #ifdef _LIBC /* First make sure the handling of the `__getopt_nonoption_flags' string can work normally. Our top argument must be in the range of the string. */ if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) { /* We must extend the array. The user plays games with us and presents new arguments. */ char *new_str = malloc (top + 1); if (new_str == NULL) nonoption_flags_len = nonoption_flags_max_len = 0; else { memset (__mempcpy (new_str, __getopt_nonoption_flags, nonoption_flags_max_len), '\0', top + 1 - nonoption_flags_max_len); nonoption_flags_max_len = top + 1; __getopt_nonoption_flags = new_str; } } #endif while (top > middle && middle > bottom) { if (top - middle > middle - bottom) { /* Bottom segment is the short one. */ int len = middle - bottom; register int i; /* Swap it with the top part of the top segment. */ for (i = 0; i < len; i++) { tem = argv[bottom + i]; argv[bottom + i] = argv[top - (middle - bottom) + i]; argv[top - (middle - bottom) + i] = tem; SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); } /* Exclude the moved bottom segment from further swapping. */ top -= len; } else { /* Top segment is the short one. */ int len = top - middle; register int i; /* Swap it with the bottom part of the bottom segment. */ for (i = 0; i < len; i++) { tem = argv[bottom + i]; argv[bottom + i] = argv[middle + i]; argv[middle + i] = tem; SWAP_FLAGS (bottom + i, middle + i); } /* Exclude the moved top segment from further swapping. */ bottom += len; } } /* Update records for the slots the non-options now occupy. */ first_nonopt += (optind - last_nonopt); last_nonopt = optind; } /* Initialize the internal data when the first call is made. */ #if defined (__STDC__) && __STDC__ static const char *_getopt_initialize (int, char *const *, const char *); #endif static const char * _getopt_initialize (argc, argv, optstring) int argc; char *const *argv; const char *optstring; { /* Start processing options with ARGV-element 1 (since ARGV-element 0 is the program name); the sequence of previously skipped non-option ARGV-elements is empty. */ first_nonopt = last_nonopt = optind; nextchar = NULL; posixly_correct = getenv ("POSIXLY_CORRECT"); /* Determine how to handle the ordering of options and nonoptions. */ if (optstring[0] == '-') { ordering = RETURN_IN_ORDER; ++optstring; } else if (optstring[0] == '+') { ordering = REQUIRE_ORDER; ++optstring; } else if (posixly_correct != NULL) ordering = REQUIRE_ORDER; else ordering = PERMUTE; #ifdef _LIBC if (posixly_correct == NULL && argc == original_argc && argv == original_argv) { if (nonoption_flags_max_len == 0) { if (__getopt_nonoption_flags == NULL || __getopt_nonoption_flags[0] == '\0') nonoption_flags_max_len = -1; else { const char *orig_str = __getopt_nonoption_flags; int len = nonoption_flags_max_len = strlen (orig_str); if (nonoption_flags_max_len < argc) nonoption_flags_max_len = argc; __getopt_nonoption_flags = (char *) malloc (nonoption_flags_max_len); if (__getopt_nonoption_flags == NULL) nonoption_flags_max_len = -1; else memset (__mempcpy (__getopt_nonoption_flags, orig_str, len), '\0', nonoption_flags_max_len - len); } } nonoption_flags_len = nonoption_flags_max_len; } else nonoption_flags_len = 0; #endif return optstring; } /* Scan elements of ARGV (whose length is ARGC) for option characters given in OPTSTRING. If an element of ARGV starts with '-', and is not exactly "-" or "--", then it is an option element. The characters of this element (aside from the initial '-') are option characters. If `getopt' is called repeatedly, it returns successively each of the option characters from each of the option elements. If `getopt' finds another option character, it returns that character, updating `optind' and `nextchar' so that the next call to `getopt' can resume the scan with the following option character or ARGV-element. If there are no more option characters, `getopt' returns -1. Then `optind' is the index in ARGV of the first ARGV-element that is not an option. (The ARGV-elements have been permuted so that those that are not options now come last.) OPTSTRING is a string containing the legitimate option characters. If an option character is seen that is not listed in OPTSTRING, return '?' after printing an error message. If you set `opterr' to zero, the error message is suppressed but we still return '?'. If a char in OPTSTRING is followed by a colon, that means it wants an arg, so the following text in the same ARGV-element, or the text of the following ARGV-element, is returned in `optarg'. Two colons mean an option that wants an optional arg; if there is text in the current ARGV-element, it is returned in `optarg', otherwise `optarg' is set to zero. If OPTSTRING starts with `-' or `+', it requests different methods of handling the non-option ARGV-elements. See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. Long-named options begin with `--' instead of `-'. Their names may be abbreviated as long as the abbreviation is unique or is an exact match for some defined option. If they have an argument, it follows the option name in the same ARGV-element, separated from the option name by a `=', or else the in next ARGV-element. When `getopt' finds a long-named option, it returns 0 if that option's `flag' field is nonzero, the value of the option's `val' field if the `flag' field is zero. The elements of ARGV aren't really const, because we permute them. But we pretend they're const in the prototype to be compatible with other systems. LONGOPTS is a vector of `struct option' terminated by an element containing a name which is zero. LONGIND returns the index in LONGOPT of the long-named option found. It is only valid when a long-named option has been found by the most recent call. If LONG_ONLY is nonzero, '-' as well as '--' can introduce long-named options. */ int _getopt_internal (argc, argv, optstring, longopts, longind, long_only) int argc; char *const *argv; const char *optstring; const struct option *longopts; int *longind; int long_only; { optarg = NULL; if (optind == 0 || !__getopt_initialized) { if (optind == 0) optind = 1; /* Don't scan ARGV[0], the program name. */ optstring = _getopt_initialize (argc, argv, optstring); __getopt_initialized = 1; } /* Test whether ARGV[optind] points to a non-option argument. Either it does not have option syntax, or there is an environment flag from the shell indicating it is not an option. The later information is only used when the used in the GNU libc. */ #ifdef _LIBC #define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ || (optind < nonoption_flags_len \ && __getopt_nonoption_flags[optind] == '1')) #else #define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') #endif if (nextchar == NULL || *nextchar == '\0') { /* Advance to the next ARGV-element. */ /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been moved back by the user (who may also have changed the arguments). */ if (last_nonopt > optind) last_nonopt = optind; if (first_nonopt > optind) first_nonopt = optind; if (ordering == PERMUTE) { /* If we have just processed some options following some non-options, exchange them so that the options come first. */ if (first_nonopt != last_nonopt && last_nonopt != optind) exchange ((char **) argv); else if (last_nonopt != optind) first_nonopt = optind; /* Skip any additional non-options and extend the range of non-options previously skipped. */ while (optind < argc && NONOPTION_P) optind++; last_nonopt = optind; } /* The special ARGV-element `--' means premature end of options. Skip it like a null option, then exchange with previous non-options as if it were an option, then skip everything else like a non-option. */ if (optind != argc && !strcmp (argv[optind], "--")) { optind++; if (first_nonopt != last_nonopt && last_nonopt != optind) exchange ((char **) argv); else if (first_nonopt == last_nonopt) first_nonopt = optind; last_nonopt = argc; optind = argc; } /* If we have done all the ARGV-elements, stop the scan and back over any non-options that we skipped and permuted. */ if (optind == argc) { /* Set the next-arg-index to point at the non-options that we previously skipped, so the caller will digest them. */ if (first_nonopt != last_nonopt) optind = first_nonopt; return -1; } /* If we have come to a non-option and did not permute it, either stop the scan or describe it to the caller and pass it by. */ if (NONOPTION_P) { if (ordering == REQUIRE_ORDER) return -1; optarg = argv[optind++]; return 1; } /* We have found another option-ARGV-element. Skip the initial punctuation. */ nextchar = (argv[optind] + 1 + (longopts != NULL && argv[optind][1] == '-')); } /* Decode the current option-ARGV-element. */ /* Check whether the ARGV-element is a long option. If long_only and the ARGV-element has the form "-f", where f is a valid short option, don't consider it an abbreviated form of a long option that starts with f. Otherwise there would be no way to give the -f short option. On the other hand, if there's a long option "fubar" and the ARGV-element is "-fu", do consider that an abbreviation of the long option, just like "--fu", and not "-f" with arg "u". This distinction seems to be the most useful approach. */ if (longopts != NULL && (argv[optind][1] == '-' || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) { char *nameend; const struct option *p; const struct option *pfound = NULL; int exact = 0; int ambig = 0; int indfound = -1; int option_index; for (nameend = nextchar; *nameend && *nameend != '='; nameend++) /* Do nothing. */ ; /* Test all long options for either exact match or abbreviated matches. */ for (p = longopts, option_index = 0; p->name; p++, option_index++) if (!strncmp (p->name, nextchar, nameend - nextchar)) { if ((unsigned int) (nameend - nextchar) == (unsigned int) strlen (p->name)) { /* Exact match found. */ pfound = p; indfound = option_index; exact = 1; break; } else if (pfound == NULL) { /* First nonexact match found. */ pfound = p; indfound = option_index; } else /* Second or later nonexact match found. */ ambig = 1; } if (ambig && !exact) { if (opterr) fprintf (stderr, _("%s: option `%s' is ambiguous\n"), argv[0], argv[optind]); nextchar += strlen (nextchar); optind++; optopt = 0; return '?'; } if (pfound != NULL) { option_index = indfound; optind++; if (*nameend) { /* Don't test has_arg with >, because some C compilers don't allow it to be used on enums. */ if (pfound->has_arg) optarg = nameend + 1; else { if (opterr) if (argv[optind - 1][1] == '-') /* --option */ fprintf (stderr, _("%s: option `--%s' doesn't allow an argument\n"), argv[0], pfound->name); else /* +option or -option */ fprintf (stderr, _("%s: option `%c%s' doesn't allow an argument\n"), argv[0], argv[optind - 1][0], pfound->name); nextchar += strlen (nextchar); optopt = pfound->val; return '?'; } } else if (pfound->has_arg == 1) { if (optind < argc) optarg = argv[optind++]; else { if (opterr) fprintf (stderr, _("%s: option `%s' requires an argument\n"), argv[0], argv[optind - 1]); nextchar += strlen (nextchar); optopt = pfound->val; return optstring[0] == ':' ? ':' : '?'; } } nextchar += strlen (nextchar); if (longind != NULL) *longind = option_index; if (pfound->flag) { *(pfound->flag) = pfound->val; return 0; } return pfound->val; } /* Can't find it as a long option. If this is not getopt_long_only, or the option starts with '--' or is not a valid short option, then it's an error. Otherwise interpret it as a short option. */ if (!long_only || argv[optind][1] == '-' || my_index (optstring, *nextchar) == NULL) { if (opterr) { if (argv[optind][1] == '-') /* --option */ fprintf (stderr, _("%s: unrecognized option `--%s'\n"), argv[0], nextchar); else /* +option or -option */ fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), argv[0], argv[optind][0], nextchar); } nextchar = (char *) ""; optind++; optopt = 0; return '?'; } } /* Look at and handle the next short option-character. */ { char c = *nextchar++; char *temp = my_index (optstring, c); /* Increment `optind' when we start to process its last character. */ if (*nextchar == '\0') ++optind; if (temp == NULL || c == ':') { if (opterr) { if (posixly_correct) /* 1003.2 specifies the format of this message. */ fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c); else fprintf (stderr, _("%s: invalid option -- %c\n"), argv[0], c); } optopt = c; return '?'; } /* Convenience. Treat POSIX -W foo same as long option --foo */ if (temp[0] == 'W' && temp[1] == ';') { char *nameend; const struct option *p; const struct option *pfound = NULL; int exact = 0; int ambig = 0; int indfound = 0; int option_index; /* This is an option that requires an argument. */ if (*nextchar != '\0') { optarg = nextchar; /* If we end this ARGV-element by taking the rest as an arg, we must advance to the next element now. */ optind++; } else if (optind == argc) { if (opterr) { /* 1003.2 specifies the format of this message. */ fprintf (stderr, _("%s: option requires an argument -- %c\n"), argv[0], c); } optopt = c; if (optstring[0] == ':') c = ':'; else c = '?'; return c; } else /* We already incremented `optind' once; increment it again when taking next ARGV-elt as argument. */ optarg = argv[optind++]; /* optarg is now the argument, see if it's in the table of longopts. */ for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) /* Do nothing. */ ; /* Test all long options for either exact match or abbreviated matches. */ for (p = longopts, option_index = 0; p->name; p++, option_index++) if (!strncmp (p->name, nextchar, nameend - nextchar)) { if ((unsigned int) (nameend - nextchar) == strlen (p->name)) { /* Exact match found. */ pfound = p; indfound = option_index; exact = 1; break; } else if (pfound == NULL) { /* First nonexact match found. */ pfound = p; indfound = option_index; } else /* Second or later nonexact match found. */ ambig = 1; } if (ambig && !exact) { if (opterr) fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), argv[0], argv[optind]); nextchar += strlen (nextchar); optind++; return '?'; } if (pfound != NULL) { option_index = indfound; if (*nameend) { /* Don't test has_arg with >, because some C compilers don't allow it to be used on enums. */ if (pfound->has_arg) optarg = nameend + 1; else { if (opterr) fprintf (stderr, _("\ %s: option `-W %s' doesn't allow an argument\n"), argv[0], pfound->name); nextchar += strlen (nextchar); return '?'; } } else if (pfound->has_arg == 1) { if (optind < argc) optarg = argv[optind++]; else { if (opterr) fprintf (stderr, _("%s: option `%s' requires an argument\n"), argv[0], argv[optind - 1]); nextchar += strlen (nextchar); return optstring[0] == ':' ? ':' : '?'; } } nextchar += strlen (nextchar); if (longind != NULL) *longind = option_index; if (pfound->flag) { *(pfound->flag) = pfound->val; return 0; } return pfound->val; } nextchar = NULL; return 'W'; /* Let the application handle it. */ } if (temp[1] == ':') { if (temp[2] == ':') { /* This is an option that accepts an argument optionally. */ if (*nextchar != '\0') { optarg = nextchar; optind++; } else optarg = NULL; nextchar = NULL; } else { /* This is an option that requires an argument. */ if (*nextchar != '\0') { optarg = nextchar; /* If we end this ARGV-element by taking the rest as an arg, we must advance to the next element now. */ optind++; } else if (optind == argc) { if (opterr) { /* 1003.2 specifies the format of this message. */ fprintf (stderr, _("%s: option requires an argument -- %c\n"), argv[0], c); } optopt = c; if (optstring[0] == ':') c = ':'; else c = '?'; } else /* We already incremented `optind' once; increment it again when taking next ARGV-elt as argument. */ optarg = argv[optind++]; nextchar = NULL; } } return c; } } int getopt (argc, argv, optstring) int argc; char *const *argv; const char *optstring; { return _getopt_internal (argc, argv, optstring, (const struct option *) 0, (int *) 0, 0); } #endif /* Not ELIDE_CODE. */ #ifdef TEST /* Compile with -DTEST to make an executable for use in testing the above definition of `getopt'. */ int main (argc, argv) int argc; char **argv; { int c; int digit_optind = 0; while (1) { int this_option_optind = optind ? optind : 1; c = getopt (argc, argv, "abc:d:0123456789"); if (c == -1) break; switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (digit_optind != 0 && digit_optind != this_option_optind) printf ("digits occur in two different argv-elements.\n"); digit_optind = this_option_optind; printf ("option %c\n", c); break; case 'a': printf ("option a\n"); break; case 'b': printf ("option b\n"); break; case 'c': printf ("option c with value `%s'\n", optarg); break; case '?': break; default: printf ("?? getopt returned character code 0%o ??\n", c); } } if (optind < argc) { printf ("non-option ARGV-elements: "); while (optind < argc) printf ("%s ", argv[optind++]); printf ("\n"); } exit (0); } #endif /* TEST */ texinfo-3.12/lib/Makefile.am0000444000175000017500000000075006357261517013167 0ustar gg## Makefile.am for texinfo/lib. ## $Id: Makefile.am,v 1.4 1997/07/04 20:55:42 karl Exp $ ## Run automake in .. to produce Makefile.in from this. noinst_LIBRARIES = libtxi.a INCLUDES = -I../intl # Don't need to list alloca.c, etc., Automake includes them. libtxi_a_SOURCES = getopt.c getopt.h getopt1.c system.h xmalloc.c xstrdup.c libtxi_a_LIBADD = @LIBOBJS@ @ALLOCA@ libtxi_a_DEPENDENCIES = $(libtxi_a_LIBADD) ## xx configure for bzero?, clib, other common stuff EXTRA_DIST = README texinfo-3.12/lib/strerror.c0000644000175000017500000000214706317273674013170 0ustar gg/* * strerror.c --- ANSI C compatible system error routine */ /* * Copyright (C) 1986, 1988, 1989, 1991 the Free Software Foundation, Inc. * From gawk. * * 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, USA. * */ #if 0 #include #endif extern int sys_nerr; extern char *sys_errlist[]; char * strerror(n) int n; { static char mesg[30]; if (n < 0 || n >= sys_nerr) { sprintf(mesg, "Unknown error (%d)", n); return mesg; } else return sys_errlist[n]; } texinfo-3.12/lib/system.h0000444000175000017500000000473206370173334012626 0ustar gg/* system.h: System-dependent declarations. Include this first. $Id: system.h,v 1.5 1997/07/31 20:34:36 karl Exp $ Copyright (C) 1997 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, USA. */ #ifndef TEXINFO_SYSTEM_H #define TEXINFO_SYSTEM_H #define _GNU_SOURCE #include /* should be included before any preprocessor test of _POSIX_VERSION. */ #ifdef HAVE_UNISTD_H #include #endif /* HAVE_UNISTD_H */ #include #include #include #ifdef HAVE_LOCALE_H #include #endif #include /* Don't use bcopy! Use memmove if source and destination may overlap, memcpy otherwise. */ #ifdef HAVE_STRING_H # if !STDC_HEADERS && HAVE_MEMORY_H # include # endif # include #else # include char *memchr (); #endif #ifdef STDC_HEADERS #define getopt system_getopt #include #undef getopt #else extern char *getenv (); #endif #ifndef HAVE_STRERROR extern char *strerror (); #endif #include #ifndef errno extern int errno; #endif #ifdef VMS #include #endif #include #ifdef HAVE_SYS_FILE_H #include #endif /* HAVE_SYS_FILE_H */ #ifndef O_RDONLY /* Since is POSIX, prefer that to . This also avoids some useless warnings on (at least) Linux. */ #ifdef HAVE_FCNTL_H #include #else /* not HAVE_FCNTL_H */ #ifdef HAVE_SYS_FCNTL_H #include #endif /* not HAVE_SYS_FCNTL_H */ #endif /* not HAVE_FCNTL_H */ #endif /* not O_RDONLY */ #ifdef HAVE_PWD_H #include #endif /* Some systems don't declare this function in pwd.h. */ struct passwd *getpwnam (); /* Our library routines not included in any system library. */ extern void *xmalloc (), *xrealloc (); extern char *xstrdup (); #endif /* TEXINFO_SYSTEM_H */ texinfo-3.12/lib/xstrdup.c0000444000175000017500000000234006446626006013002 0ustar gg/* xstrdup.c -- copy a string with out of memory checking Copyright (C) 1990, 1996 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, USA. */ #if HAVE_CONFIG_H # include #endif #if defined(STDC_HEADERS) || defined(HAVE_STRING_H) # include #else # include #endif #if defined (__STDC__) && __STDC__ char *xmalloc (size_t); char *xstrdup (char *string); #else char *xmalloc (); #endif /* Return a newly allocated copy of STRING. */ char * xstrdup (string) char *string; { return strcpy (xmalloc (strlen (string) + 1), string); } texinfo-3.12/lib/README0000664000175000017500000000022706475365612012020 0ustar ggCommon routines for the Texinfo package. Many are common to other GNU packages as well. (On the FSF machines, check /home/gd/gnu/lib for the latest.) texinfo-3.12/po/0000775000175000017500000000000006477056756011017 5ustar ggtexinfo-3.12/po/Makefile.in.in0000664000175000017500000001516506475640120013457 0ustar gg# Makefile for program source directory in GNU NLS utilities package. # Copyright (C) 1995, 1996, 1997 by Ulrich Drepper # # This file file be copied and used freely without restrictions. It can # be used in projects which are not available under the GNU Public License # but which still want to provide support for the GNU gettext functionality. # Please note that the actual code is *not* freely available. PACKAGE = @PACKAGE@ VERSION = @VERSION@ SHELL = /bin/sh @SET_MAKE@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ datadir = $(prefix)/@DATADIRNAME@ localedir = $(datadir)/locale gnulocaledir = $(prefix)/share/locale gettextsrcdir = $(prefix)/share/gettext/po subdir = po INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ MKINSTALLDIRS = $(top_srcdir)/@MKINSTALLDIRS@ CC = @CC@ GENCAT = @GENCAT@ GMSGFMT = PATH=../src:$$PATH @GMSGFMT@ MSGFMT = @MSGFMT@ XGETTEXT = PATH=../src:$$PATH @XGETTEXT@ MSGMERGE = PATH=../src:$$PATH msgmerge DEFS = @DEFS@ CFLAGS = @CFLAGS@ CPPFLAGS = @CPPFLAGS@ INCLUDES = -I.. -I$(top_srcdir)/intl COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS) SOURCES = cat-id-tbl.c POFILES = @POFILES@ GMOFILES = @GMOFILES@ DISTFILES = ChangeLog Makefile.in.in POTFILES.in $(PACKAGE).pot \ stamp-cat-id $(POFILES) $(GMOFILES) $(SOURCES) POTFILES = \ CATALOGS = @CATALOGS@ CATOBJEXT = @CATOBJEXT@ INSTOBJEXT = @INSTOBJEXT@ .SUFFIXES: .SUFFIXES: .c .o .po .pox .gmo .mo .msg .cat .c.o: $(COMPILE) $< .po.pox: $(MAKE) $(PACKAGE).pot $(MSGMERGE) $< $(srcdir)/$(PACKAGE).pot -o $*.pox .po.mo: $(MSGFMT) -o $@ $< .po.gmo: file=$(srcdir)/`echo $* | sed 's,.*/,,'`.gmo \ && rm -f $$file && $(GMSGFMT) -o $$file $< .po.cat: sed -f ../intl/po2msg.sed < $< > $*.msg \ && rm -f $@ && $(GENCAT) $@ $*.msg all: all-@USE_NLS@ all-yes: cat-id-tbl.c $(CATALOGS) all-no: $(srcdir)/$(PACKAGE).pot: $(POTFILES) $(XGETTEXT) --default-domain=$(PACKAGE) --directory=$(top_srcdir) \ --add-comments --keyword=_ --keyword=N_ \ --files-from=$(srcdir)/POTFILES.in rm -f $(srcdir)/$(PACKAGE).pot mv $(PACKAGE).po $(srcdir)/$(PACKAGE).pot $(srcdir)/cat-id-tbl.c: stamp-cat-id; @: $(srcdir)/stamp-cat-id: $(PACKAGE).pot rm -f cat-id-tbl.tmp sed -f ../intl/po2tbl.sed $(srcdir)/$(PACKAGE).pot \ | sed -e "s/@PACKAGE NAME@/$(PACKAGE)/" > cat-id-tbl.tmp if cmp -s cat-id-tbl.tmp $(srcdir)/cat-id-tbl.c; then \ rm cat-id-tbl.tmp; \ else \ echo cat-id-tbl.c changed; \ rm -f $(srcdir)/cat-id-tbl.c; \ mv cat-id-tbl.tmp $(srcdir)/cat-id-tbl.c; \ fi cd $(srcdir) && rm -f stamp-cat-id && echo timestamp > stamp-cat-id install: install-exec install-data install-exec: install-data: install-data-@USE_NLS@ install-data-no: all install-data-yes: all if test -r $(MKINSTALLDIRS); then \ $(MKINSTALLDIRS) $(datadir); \ else \ $(top_srcdir)/mkinstalldirs $(datadir); \ fi @catalogs='$(CATALOGS)'; \ for cat in $$catalogs; do \ cat=`basename $$cat`; \ case "$$cat" in \ *.gmo) destdir=$(gnulocaledir);; \ *) destdir=$(localedir);; \ esac; \ lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \ dir=$$destdir/$$lang/LC_MESSAGES; \ if test -r $(MKINSTALLDIRS); then \ $(MKINSTALLDIRS) $$dir; \ else \ $(top_srcdir)/mkinstalldirs $$dir; \ fi; \ if test -r $$cat; then \ $(INSTALL_DATA) $$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \ echo "installing $$cat as $$dir/$(PACKAGE)$(INSTOBJEXT)"; \ else \ $(INSTALL_DATA) $(srcdir)/$$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \ echo "installing $(srcdir)/$$cat as" \ "$$dir/$(PACKAGE)$(INSTOBJEXT)"; \ fi; \ if test -r $$cat.m; then \ $(INSTALL_DATA) $$cat.m $$dir/$(PACKAGE)$(INSTOBJEXT).m; \ echo "installing $$cat.m as $$dir/$(PACKAGE)$(INSTOBJEXT).m"; \ else \ if test -r $(srcdir)/$$cat.m ; then \ $(INSTALL_DATA) $(srcdir)/$$cat.m \ $$dir/$(PACKAGE)$(INSTOBJEXT).m; \ echo "installing $(srcdir)/$$cat as" \ "$$dir/$(PACKAGE)$(INSTOBJEXT).m"; \ else \ true; \ fi; \ fi; \ done if test "$(PACKAGE)" = "gettext"; then \ if test -r $(MKINSTALLDIRS); then \ $(MKINSTALLDIRS) $(gettextsrcdir); \ else \ $(top_srcdir)/mkinstalldirs $(gettextsrcdir); \ fi; \ $(INSTALL_DATA) $(srcdir)/Makefile.in.in \ $(gettextsrcdir)/Makefile.in.in; \ else \ : ; \ fi # Define this as empty until I found a useful application. installcheck: uninstall: catalogs='$(CATALOGS)'; \ for cat in $$catalogs; do \ cat=`basename $$cat`; \ lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \ rm -f $(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \ rm -f $(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \ rm -f $(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \ rm -f $(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \ done rm -f $(gettextsrcdir)/po-Makefile.in.in check: all cat-id-tbl.o: ../intl/libgettext.h dvi info tags TAGS ID: mostlyclean: rm -f core core.* *.pox $(PACKAGE).po *.old.po cat-id-tbl.tmp rm -fr *.o clean: mostlyclean distclean: clean rm -f Makefile Makefile.in POTFILES *.mo *.msg *.cat *.cat.m maintainer-clean: distclean @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." rm -f $(GMOFILES) distdir = ../$(PACKAGE)-$(VERSION)/$(subdir) dist distdir: update-po $(DISTFILES) dists="$(DISTFILES)"; \ for file in $$dists; do \ ln $(srcdir)/$$file $(distdir) 2> /dev/null \ || cp -p $(srcdir)/$$file $(distdir); \ done update-po: Makefile $(MAKE) $(PACKAGE).pot PATH=`pwd`/../src:$$PATH; \ cd $(srcdir); \ catalogs='$(CATALOGS)'; \ for cat in $$catalogs; do \ cat=`basename $$cat`; \ lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \ mv $$lang.po $$lang.old.po; \ echo "$$lang:"; \ if $(MSGMERGE) $$lang.old.po $(PACKAGE).pot -o $$lang.po; then \ rm -f $$lang.old.po; \ else \ echo "msgmerge for $$cat failed!"; \ rm -f $$lang.po; \ mv $$lang.old.po $$lang.po; \ fi; \ done POTFILES: POTFILES.in ( if test 'x$(srcdir)' != 'x.'; then \ posrcprefix='$(top_srcdir)/'; \ else \ posrcprefix="../"; \ fi; \ rm -f $@-t $@ \ && (sed -e '/^#/d' -e '/^[ ]*$$/d' \ -e "s@.*@ $$posrcprefix& \\\\@" < $(srcdir)/$@.in \ | sed -e '$$s/\\$$//') > $@-t \ && chmod a-w $@-t \ && mv $@-t $@ ) Makefile: Makefile.in.in ../config.status POTFILES cd .. \ && CONFIG_FILES=$(subdir)/$@.in CONFIG_HEADERS= \ $(SHELL) ./config.status # Tell versions [3.59,3.63) of GNU make not to export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: texinfo-3.12/po/ChangeLog0000644000175000017500000000000006350456024012533 0ustar ggtexinfo-3.12/po/stamp-cat-id0000664000175000017500000000001206477046266013211 0ustar ggtimestamp texinfo-3.12/po/fr.po0000664000175000017500000017373106477056754012000 0ustar gg# Version française du progiciel Texinfo-3.11. # Copyright © 1996, 1997 Free Software Foundation, Inc. # Laurent Bourbeau , 1997. # msgid "" msgstr "" "Project-Id-Version: texinfo 3.11\n" "POT-Creation-Date: 1998-03-03 13:32-0500\n" "PO-Revision-Date: 1997-09-16 12:28-04:00\n" "Last-Translator: Laurent Bourbeau \n" "Language-Team: French \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=8859-1\n" "Content-Transfer-Encoding: 8-bit\n" #. **************************************************************** #. #. Echo Area Movement Commands #. #. **************************************************************** #: info/echo-area.c:283 info/session.c:698 msgid "Move forward a character" msgstr "Avancer d'un caractère" #. Move point backward in the node. #: info/echo-area.c:295 info/session.c:714 msgid "Move backward a character" msgstr "Reculer d'un caractère" #: info/echo-area.c:307 msgid "Move to the start of this line" msgstr "Se déplacer au début de cette ligne" #: info/echo-area.c:312 msgid "Move to the end of this line" msgstr "Se déplacer à la fin de cette ligne" #. Move forward a word in the input line. #: info/echo-area.c:320 info/session.c:732 msgid "Move forward a word" msgstr "Avancer d'un mot" #: info/echo-area.c:360 info/session.c:781 msgid "Move backward a word" msgstr "Reculer d'un mot" #: info/echo-area.c:400 msgid "Delete the character under the cursor" msgstr "Éliminer le caractère sous le curseur" #: info/echo-area.c:430 msgid "Delete the character behind the cursor" msgstr "Éliminer le caractère précédent le curseur" #: info/echo-area.c:451 msgid "Cancel or quit operation" msgstr "Annuler ou opération de quitter" #: info/echo-area.c:466 msgid "Accept (or force completion of) this line" msgstr "Accepter cette ligne (ou en forcer la complétion)" #: info/echo-area.c:471 msgid "Insert next character verbatim" msgstr "Insérer le prochain caractère textuellement" #: info/echo-area.c:479 msgid "Insert this character" msgstr "Insérer ce caractère" #: info/echo-area.c:497 msgid "Insert a TAB character" msgstr "Insérer un caractère de tabulation" #. Transpose the characters at point. If point is at the end of the line, #. then transpose the characters before point. #: info/echo-area.c:504 msgid "Transpose characters at point" msgstr "Transposer les caractères en position du point courant" #: info/echo-area.c:555 msgid "Yank back the contents of the last kill" msgstr "Recoller le contenu du dernier effacement" #: info/echo-area.c:562 msgid "Kill ring is empty" msgstr "L'anneau des effacements temporaires est vide" #. If the last command was yank, or yank_pop, and the text just before #. point is identical to the current kill item, then delete that text #. from the line, rotate the index down, and yank back some other text. #: info/echo-area.c:575 msgid "Yank back a previous kill" msgstr "Recoller un effacement antérieur" #. Delete the text from point to end of line. #: info/echo-area.c:608 msgid "Kill to the end of the line" msgstr "Effacer du point courant jusqu'à la fin de la ligne" #: info/echo-area.c:621 msgid "Kill to the beginning of the line" msgstr "Effacer du point courant jusqu'au début de la ligne" #. Delete from point to the end of the current word. #: info/echo-area.c:633 msgid "Kill the word following the cursor" msgstr "Effacer le mot suivant le curseur" #: info/echo-area.c:652 msgid "Kill the word preceding the cursor" msgstr "Effacer le mot précédent le curseur" #: info/echo-area.c:871 msgid "Not complete" msgstr "Non complet" #: info/echo-area.c:916 msgid "List possible completions" msgstr "Énumérer les complétions possibles" #: info/echo-area.c:929 msgid "No completions" msgstr "Aucune complétion" #: info/echo-area.c:933 msgid "Sole completion" msgstr "Une seule complétion" #: info/echo-area.c:942 #, fuzzy msgid "One completion:\n" msgstr "la complétion %s:\n" #: info/echo-area.c:943 #, fuzzy, c-format msgid "%d completions:\n" msgstr "la complétion %s:\n" #: info/echo-area.c:1088 msgid "Insert completion" msgstr "Insérer la complétion" #: info/echo-area.c:1221 msgid "Building completions..." msgstr "Construction des complétions..." #. Scroll the "other" window. If there is a window showing completions, scroll #. that one, otherwise scroll the window which was active on entering the read #. function. #: info/echo-area.c:1319 msgid "Scroll the completions window" msgstr "Dérouler la fenêtre des complétions" #: info/footnotes.c:206 msgid "Footnotes could not be displayed" msgstr "Les notes en bas de page ne peuvent pas être affichées" #: info/footnotes.c:232 msgid "Show the footnotes associated with this node in another window" msgstr "" "Montrer les notes en bas de page associées à ce noeud dans une autre fenêtre" #: info/indices.c:175 msgid "Look up a string in the index for this file" msgstr "Rechercher une chaîne dans l'index pour ce fichier" #: info/indices.c:205 msgid "Finding index entries..." msgstr "Recherche des entrées d'index..." #: info/indices.c:212 msgid "No indices found." msgstr "Aucun indice retrouvé." #: info/indices.c:222 msgid "Index entry: " msgstr "Entrée d'index: " #: info/indices.c:332 msgid "" "Go to the next matching index item from the last `\\[index-search]' command" msgstr "" "Passer à la référence suivante de la dernière commande «\\[index-search]»" #: info/indices.c:342 msgid "No previous index search string." msgstr "Aucune autre chaîne de fouille d'index." #: info/indices.c:349 msgid "No index entries." msgstr "Aucune entrée d'index." #: info/indices.c:382 #, c-format msgid "No %sindex entries containing \"%s\"." msgstr "Aucune entrée %sindex contenant «%s»." #: info/indices.c:383 msgid "more " msgstr "plus " #: info/indices.c:393 msgid "CAN'T SEE THIS" msgstr "NE PEUT PAS VOIR CECI" #: info/indices.c:429 #, c-format msgid "Found \"%s\" in %s. (`\\[next-index-match]' tries to find next.)" msgstr "Trouver «%s» dans %s. («\\[next-index-match]» cherchera le prochain.)" #: info/indices.c:533 #, c-format msgid "Scanning indices of \"%s\"..." msgstr "Fouille des indices de «%s»..." #: info/indices.c:616 msgid "Grovel all known info file's indices for a string and build a menu" msgstr "" "Aplatir tous les indices de fichier info connus pour une chaîne et " "construire un menu" #: info/indices.c:620 msgid "Index apropos: " msgstr "Index à-propos: " #: info/indices.c:650 #, c-format msgid "" "\n" "* Menu: Nodes whoses indices contain \"%s\":\n" msgstr "" "\n" "* Menu: Noeuds dont les indices contiennent «%s»:\n" #: info/info.c:212 #, fuzzy msgid "Try --help for more information." msgstr "Pour en savoir davantage, faites: «%s --help».\n" #: info/info.c:231 makeinfo/makeinfo.c:1089 util/install-info.c:530 #: util/texindex.c:338 #, fuzzy, c-format msgid "" "Copyright (C) %s Free Software Foundation, Inc.\n" "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" msgstr "" "Copyright © 1996 Free Software Foundation, Inc.\n" "AUCUNE garantie n'est donnée; tant pour des raisons COMMERCIALES que\n" "pour RÉPONDRE À UN BESOIN PARTICULIER. Vous pouvez redistribuer des copies\n" "de ce logiciel selon les termes de la licence GNU General Public License.\n" "Pour plus d'informations, consultez le fichier COPYING." #: info/info.c:363 msgid "no entries found\n" msgstr "aucune entrée retrouvée\n" #: info/info.c:406 msgid "There is no menu in this node." msgstr "Il n'y a pas de menu dans ce noeud." #: info/info.c:437 #, c-format msgid "There is no menu item \"%s\" in this node." msgstr "Il n'y a pas d'item menu «%s» dans ce noeud." #: info/info.c:501 #, c-format msgid "Unable to find the node referenced by \"%s\"." msgstr "Incappable de trouver le noeud référencé par «%s»." #: info/info.c:602 #, fuzzy, c-format msgid "" "Usage: %s [OPTION]... [INFO-FILE [MENU-ITEM...]]\n" "\n" "Read documentation in Info format.\n" "For more complete documentation on how to use Info, run `info info " "options'.\n" "\n" "Options:\n" "--directory DIR add DIR to INFOPATH.\n" "--dribble FILENAME remember user keystrokes in FILENAME.\n" "--file FILENAME specify Info file to visit.\n" "--node NODENAME specify nodes in first visited Info file.\n" "--output FILENAME output selected nodes to FILENAME.\n" "--restore FILENAME read initial keystrokes from FILENAME.\n" "--subnodes recursively output menu items.\n" "--help display this help and exit.\n" "--version display version information and exit.\n" "\n" "The first argument, if present, is the name of the Info file to read.\n" "Any remaining arguments are treated as the names of menu\n" "items in the initial node visited. For example, `info emacs buffers'\n" "moves to the node `buffers' in the info file `emacs'.\n" "\n" "Email bug reports to bug-texinfo@gnu.org." msgstr "" "Voici une brève description des options en mode Info.\n" "Pour une description plus détaillée sur le comment utiliser le mode Info,\n" "tapper «info info options».\n" "\n" " --directory RÉP Ajouter le RÉPertoire à INFOPATH.\n" " --dribble FICHIER Mémoriser les touches de l'usager dans FICHIER.\n" " --file FICHIER Spécifier le FICHIER Info à visiter.\n" " --node NOEUD Spécifier les noms de NOEUD à visiter en premier.\n" " --output FICHIER Sortir les noeuds sélectionnés dans FICHIER.\n" " --restore FICHIER Lire les touches initiales à partir de FICHIER.\n" " --subnodes Sortir récursivement les items menu.\n" " --help Afficher cet aide-mémoire.\n" " --version Afficher le nom et la version du logiciel.\n" "\n" "Les arguments résiduels à Info sont traités comme étant les noms des items\n" "menu dans le noeud initial visité. Vous pouvez aisément rejoindre le\n" "noeud de votre choix en spécifiant les noms de menu lesquels décrivent\n" "le chemin de ce noeud. Par exemple, «info emacs buffers».\n" "\n" "Rapporter toute anomalie à bug-texinfo@prep.ai.mit.edu." #: info/infodoc.c:50 msgid "Basic Commands in Info Windows" msgstr "Commandes de base en Info Windows" #: info/infodoc.c:211 msgid "" "The following commands can only be invoked via M-x:\n" "\n" msgstr "" "Les commandes suivantes peuvent être invoquées seulement via M-x:\n" "\n" #: info/infodoc.c:228 msgid "--- Use `\\[history-node]' or `\\[kill-node]' to exit ---\n" msgstr "--- Utiliser «\\[history-node]» ou «\\[kill-node]» pour sortir ---\n" #. Create or move to the help window. #: info/infodoc.c:328 msgid "Display help message" msgstr "Afficher le message d'aide" #. Show the Info help node. This means that the "info" file is installed #. where it can easily be found on your system. #: info/infodoc.c:346 msgid "Visit Info node `(info)Help'" msgstr "Visiter le noeud Info «(info)Aide»" #: info/infodoc.c:470 msgid "Print documentation for KEY" msgstr "Imprimer la documentation relative à KEY" #: info/infodoc.c:483 #, c-format msgid "Describe key: %s" msgstr "Décrire la clé: %s" #: info/infodoc.c:492 #, c-format msgid "ESC %s is undefined." msgstr "ESC %s est non défini." #: info/infodoc.c:509 #, c-format msgid "%s is undefined." msgstr "%s est non défini." #: info/infodoc.c:535 #, c-format msgid "%s is defined to %s." msgstr "%s est défini à %s." #: info/infodoc.c:731 msgid "Where is command: " msgstr "Où se trouve la commande: " #: info/infodoc.c:753 #, c-format msgid "`%s' is not on any keys" msgstr "«%s» ne se trouve pas sur une quelconque clé" #: info/infodoc.c:759 #, c-format msgid "%s can only be invoked via %s." msgstr "%s peut être invoqué seulement via %s." #: info/infodoc.c:762 #, c-format msgid "%s can be invoked via %s." msgstr "%s peut être invoqué via %s." #: info/infodoc.c:766 #, c-format msgid "There is no function named `%s'" msgstr "Il n'y a pas de fonction nommée «%s»" #: info/m-x.c:69 msgid "Read the name of an Info command and describe it" msgstr "Lire le nom d'une commande Info et la décrire" #: info/m-x.c:73 msgid "Describe command: " msgstr "Décrire la commande: " #: info/m-x.c:96 msgid "Read a command name in the echo area and execute it" msgstr "Lire le nom d'une commande dans la zone écho et l'exécuter" #: info/m-x.c:134 msgid "Cannot execute an `echo-area' command here." msgstr "Ne peut pas exécuter une commande «echo-area» en cet endroit." #: info/m-x.c:150 msgid "Set the height of the displayed window" msgstr "Ajuster la hauteur de la fenêtre affichée" #: info/m-x.c:163 #, c-format msgid "Set screen height to (%d): " msgstr "Ajuster la hauteur de l'écran à (%d): " #: info/makedoc.c:126 msgid "" " Source files groveled to make this file include:\n" "\n" msgstr "" " Les fichiers sources aplatis pour faire ce fichier incluent:\n" "\n" #: info/makedoc.c:450 #, c-format msgid "Couldn't manipulate the file %s.\n" msgstr "Ne peut pas manipuler le fichier %s.\n" #: info/nodemenu.c:28 msgid "" "\n" "* Menu:\n" " (File)Node Lines Size Containing File\n" " ---------- ----- ---- ---------------" msgstr "" "\n" "* Menu:\n" " (Fichier)Noeud Lignes Taille Contenant Fichier(s)\n" " -------------- ------ ------ --------------------" #: info/nodemenu.c:197 msgid "" "Here is the menu of nodes you have recently visited.\n" "Select one from this menu, or use `\\[history-node]' in another window.\n" msgstr "" "Voici le menu de noeuds que vous avez visité récemment.\n" "Sélectionner un noeud de ce menu, ou utiliser «\\[history-node]» dans une\n" "autre fenêtre.\n" #: info/nodemenu.c:217 msgid "Make a window containing a menu of all of the currently visited nodes" msgstr "" "Faire une fenêtre contenant un menu de tous les noeuds actuellement visités" #: info/nodemenu.c:297 msgid "Select a node which has been previously visited in a visible window" msgstr "Sélectionner un noeud qui a déjà été visité dans une fenêtre visible" #: info/nodemenu.c:309 msgid "Select visited node: " msgstr "Sélectionner un noeud visité: " #: info/nodemenu.c:329 info/session.c:1996 #, c-format msgid "The reference disappeared! (%s)." msgstr "La référence est disparue! (%s)." #: info/session.c:162 #, c-format msgid "" "Welcome to Info version %s. \"\\[get-help-window]\" for help, " "\"\\[menu-item]\" for menu item." msgstr "" "Bienvenue au mode Info version %s.\n" " «\\[get-help-window]» pour obtenir de l'aide,\n" " «\\[menu-item]» pour obtenir l'item menu." #. Move WINDOW's point down to the next line if possible. #: info/session.c:629 msgid "Move down to the next line" msgstr "Descendre à la ligne suivante" #. Move WINDOW's point up to the previous line if possible. #: info/session.c:644 msgid "Move up to the previous line" msgstr "Monter à la ligne précédente" #. Move WINDOW's point to the end of the true line. #: info/session.c:659 msgid "Move to the end of the line" msgstr "Aller à la fin de la ligne" #. Move WINDOW's point to the beginning of the true line. #: info/session.c:679 msgid "Move to the start of the line" msgstr "Aller au début de la ligne" #: info/session.c:855 msgid " times" msgstr " fois" #: info/session.c:857 #, c-format msgid "%d times" msgstr "%d fois" #: info/session.c:895 msgid "No \"Next\" pointer for this node." msgstr "Aucun pointeur «Next» pour ce noeud." #: info/session.c:898 msgid "Following \"Next\" node..." msgstr "En suivant le noeud «Next»..." #: info/session.c:899 info/session.c:927 info/session.c:999 #: info/session.c:1717 msgid "Next" msgstr "Noeud «Next»" #: info/session.c:915 msgid "Selecting first menu item..." msgstr "Sélection du premier item menu..." #: info/session.c:926 msgid "Selecting \"Next\" node..." msgstr "Sélection du noeud «Next»..." # Est-ce vraiment un message à traduire? #: info/session.c:950 info/session.c:1063 info/session.c:1733 msgid "Up" msgstr "Noeud «Up»" #: info/session.c:1020 msgid "No more nodes." msgstr "Aucun autre noeud." #: info/session.c:1044 msgid "No \"Prev\" for this node." msgstr "Aucun noeud «Prev» pour ce noeud." #. Move to the previous node. If this node now contains a menu, #. and we have not inhibited movement to it, move to the node #. corresponding to the last menu item. #: info/session.c:1047 info/session.c:1100 msgid "Moving \"Prev\" in this window." msgstr "Monter au noeud «Prev» dans cette fenêtre." # Est-ce vraiment un message à traduire? #: info/session.c:1048 info/session.c:1101 info/session.c:1725 msgid "Prev" msgstr "Noeud «Prev»" #: info/session.c:1059 msgid "No \"Prev\" or \"Up\" for this node." msgstr "Aucun noeud «Prev» ou «Up» pour ce noeud." #: info/session.c:1062 msgid "Moving \"Up\" in this window." msgstr "Aller au noeud «Up» dans cette fenêtre." #: info/session.c:1110 msgid "Moving to \"Prev\"'s last menu item." msgstr "Aller au dernier item menu du noeud «Prev»." #: info/session.c:1121 msgid "Move forwards or down through node structure" msgstr "Avancer ou descendre à travers la structure de noeuds" #: info/session.c:1137 msgid "Move backwards or up through node structure" msgstr "Reculer ou monter à travers la structure de noeuds" #. Show the next screen of WINDOW's node. #: info/session.c:1152 msgid "Scroll forward in this window" msgstr "Défiler vers l'avant dans cette fenêtre" #. Show the previous screen of WINDOW's node. #: info/session.c:1197 msgid "Scroll backward in this window" msgstr "Défiler vers l'arrière dans cette fenêtre" #. Move to the beginning of the node. #: info/session.c:1237 msgid "Move to the start of this node" msgstr "Aller au point de départ de ce noeud" #. Move to the end of the node. #: info/session.c:1244 msgid "Move to the end of this node" msgstr "Aller au point terminal de ce noeud" #. **************************************************************** #. #. Commands for Manipulating Windows #. #. **************************************************************** #. Make the next window in the chain be the active window. #: info/session.c:1257 msgid "Select the next window" msgstr "Sélectionner la fenêtre suivante" #. Make the previous window in the chain be the active window. #: info/session.c:1296 msgid "Select the previous window" msgstr "Sélectionner la fenêtre précédente" #. Split WINDOW into two windows, both showing the same node. If we #. are automatically tiling windows, re-tile after the split. #: info/session.c:1347 msgid "Split the current window" msgstr "Diviser en deux la fenêtre courante" #. Delete WINDOW, forgetting the list of last visited nodes. If we are #. automatically displaying footnotes, show or remove the footnotes #. window. If we are automatically tiling windows, re-tile after the #. deletion. #: info/session.c:1428 msgid "Delete the current window" msgstr "Éliminer la fenêtre courante" #: info/session.c:1436 msgid "Cannot delete a permanent window" msgstr "Ne peut pas éliminer une fenêtre permanente" #. Just keep WINDOW, deleting all others. #: info/session.c:1469 msgid "Delete all other windows" msgstr "Éliminer toutes les autres fenêtres" #. Scroll the "other" window of WINDOW. #: info/session.c:1515 msgid "Scroll the other window" msgstr "Défiler l'autre fenêtre" #. Change the size of WINDOW by AMOUNT. #: info/session.c:1535 msgid "Grow (or shrink) this window" msgstr "Agrandir (ou réduire) cette fenêtre" #: info/session.c:1546 msgid "Divide the available screen space among the visible windows" msgstr "Répartir l'espace écran disponible parmi les fenêtres visibles" #: info/session.c:1553 msgid "Toggle the state of line wrapping in the current window" msgstr "Basculer l'état du remplissage de ligne dans la fenêtre courante" #. Make WINDOW display the "Next:" node of the node currently being #. displayed. #: info/session.c:1714 msgid "Select the `Next' node" msgstr "Sélectionner le noeud «Next»" #. Make WINDOW display the "Prev:" node of the node currently being #. displayed. #: info/session.c:1722 msgid "Select the `Prev' node" msgstr "Sélectionner le noeud «Prev»" #. Make WINDOW display the "Up:" node of the node currently being #. displayed. #: info/session.c:1730 msgid "Select the `Up' node" msgstr "Sélectionner le noeud «Up»" #. Make WINDOW display the last node of this info file. #: info/session.c:1737 msgid "Select the last node in this file" msgstr "Sélectionner le dernier noeud dans ce fichier" #: info/session.c:1750 info/session.c:1768 msgid "This window has no additional nodes" msgstr "Cette fenêtre a aucun noeud additionnel" #. Make WINDOW display the first node of this info file. #: info/session.c:1759 msgid "Select the first node in this file" msgstr "Sélectionner le premier noeud dans ce fichier" #: info/session.c:1778 msgid "Select the last item in this node's menu" msgstr "Sélectionner le dernier item dans ce menu de noeuds" #. Use KEY (a digit) to select the Nth menu item in WINDOW->node. #: info/session.c:1784 msgid "Select this menu item" msgstr "Sélectionner cet item menu" #: info/session.c:1813 #, c-format msgid "There aren't %d items in this menu." msgstr "Il n'y a pas %d items dans ce menu." #: info/session.c:1944 #, c-format msgid "Menu item (%s): " msgstr "Item menu (%s): " #: info/session.c:1946 msgid "Menu item: " msgstr "Item menu: " #: info/session.c:1951 #, c-format msgid "Follow xref (%s): " msgstr "Suivre xref (%s): " #: info/session.c:1953 msgid "Follow xref: " msgstr "Suivre xref: " #. Read a line (with completion) which is the name of a menu item, #. and select that item. #: info/session.c:2042 msgid "Read a menu item and select its node" msgstr "Lire un item menu et sélectionner son noeud" #: info/session.c:2050 msgid "Read a footnote or cross reference and select its node" msgstr "" "Lire une note en bas de page ou une référence croisée et sélectionner son " "noeud" #. Position the cursor at the start of this node's menu. #: info/session.c:2056 msgid "Move to the start of this node's menu" msgstr "Aller au point de départ de ce menu de noeud" #: info/session.c:2080 msgid "Visit as many menu items at once as possible" msgstr "Visiter d'un seul coup autant d'items menu que possible" #. Read a line of input which is a node name, and go to that node. #: info/session.c:2108 msgid "Read a node name and select it" msgstr "Lire un nom de noeud et sélectionner ce noeud" #: info/session.c:2169 info/session.c:2173 msgid "Goto Node: " msgstr "Aller au Noeud: " #: info/session.c:2194 msgid "Read a manpage reference and select it" msgstr "Lire une référence de page-manuel et la sélectionner" #: info/session.c:2198 msgid "Get Manpage: " msgstr "Obtenir la Page-manuel: " #. Move to the "Top" node in this file. #: info/session.c:2228 msgid "Select the node `Top' in this file" msgstr "Sélectionner le noeud «Top» dans ce fichier" #. Notice that the node "Top" is special, and doesn't have to #. be referenced. #: info/session.c:2230 makeinfo/makeinfo.c:5145 makeinfo/makeinfo.c:5228 msgid "Top" msgstr "Noeud «Top»" #. Move to the node "(dir)Top". #: info/session.c:2234 msgid "Select the node `(dir)'" msgstr "Sélectionner le noeud «(dir)»" #: info/session.c:2254 #, c-format msgid "Kill node (%s): " msgstr "Effacer le noeud (%s): " #: info/session.c:2307 #, c-format msgid "Cannot kill node `%s'" msgstr "Ne peut pas effacer le noeud «%s»" #: info/session.c:2317 msgid "Cannot kill the last node" msgstr "Ne peut pas effacer le dernier noeud" #: info/session.c:2401 msgid "Select the most recently selected node" msgstr "Choisir le noeud qui a été le plus récemment sélectionné" #. Kill named node. #: info/session.c:2407 msgid "Kill this node" msgstr "Effacer ce noeud" #. Read the name of a file and select the entire file. #: info/session.c:2415 msgid "Read the name of a file and select it" msgstr "Lire le nom d'un fichier et le sélectionner" #: info/session.c:2419 msgid "Find file: " msgstr "Trouver le fichier: " #: info/session.c:2436 #, c-format msgid "Cannot find \"%s\"." msgstr "Ne peut pas trouver «%s»." #: info/session.c:2483 info/session.c:2608 #, c-format msgid "Could not create output file \"%s\"." msgstr "Ne peut pas créer le fichier de sortie «%s»." #: info/session.c:2496 info/session.c:2625 info/session.c:2671 msgid "Done." msgstr "Terminé." #: info/session.c:2553 #, c-format msgid "Writing node \"(%s)%s\"..." msgstr "Écriture du noeud «(%s)%s»..." #: info/session.c:2556 #, c-format msgid "Writing node \"%s\"..." msgstr "Écriture du noeud «%s»..." #: info/session.c:2634 msgid "Pipe the contents of this node through INFO_PRINT_COMMAND" msgstr "Acheminer les contenus de ce noeud à travers INFO_PRINT_COMMAND" #: info/session.c:2654 #, c-format msgid "Cannot open pipe to \"%s\"." msgstr "Ne peut pas ouvrir un tube de communication à «%s»." #: info/session.c:2661 #, c-format msgid "Printing node \"(%s)%s\"..." msgstr "Impression du noeud «(%s)%s»..." #: info/session.c:2664 #, c-format msgid "Printing node \"%s\"..." msgstr "Impression du noeud «%s»..." #: info/session.c:2896 #, c-format msgid "Searching subfile \"%s\"..." msgstr "Fouille du sous-fichier «%s»..." #: info/session.c:2946 msgid "Read a string and search for it" msgstr "Lire une chaîne et en faire la fouille" #: info/session.c:2966 #, c-format msgid "%s for string [%s]: " msgstr "%s pour la chaîne [%s]: " #: info/session.c:2967 msgid "Search backward" msgstr "Fouiller vers l'arrière" #: info/session.c:2967 msgid "Search" msgstr "Fouiller" #: info/session.c:2994 msgid "Search failed." msgstr "Fouille infructueuse." #: info/session.c:3020 info/session.c:3026 msgid "Search interactively for a string as you type it" msgstr "Fouiller interactivement pour une chaîne telle que vous la tapez" #: info/session.c:3120 msgid "I-search backward: " msgstr "Fouille I-search vers l'arrière: " #: info/session.c:3122 msgid "I-search: " msgstr "Fouille I-search: " #: info/session.c:3147 msgid "Failing " msgstr "Échec " #: info/session.c:3512 msgid "No cross references in this node." msgstr "Aucune référence croisée dans ce noeud." #: info/session.c:3579 msgid "Move to the previous cross reference" msgstr "Aller à la référence croisée précédente" #: info/session.c:3588 msgid "Move to the next cross reference" msgstr "Aller à la prochaine référence croisée" #: info/session.c:3598 msgid "Select reference or menu item appearing on this line" msgstr "Sélectionner la référence ou l'item menu apparaissant sur cette ligne" #. **************************************************************** #. #. Miscellaneous Info Commands #. #. **************************************************************** #. What to do when C-g is pressed in a window. #: info/session.c:3620 msgid "Cancel current operation" msgstr "Annuler l'opération courante" #: info/session.c:3627 msgid "Quit" msgstr "Quitter" #: info/session.c:3636 msgid "Move to the cursor to a specific line of the window" msgstr "Déplacer le curseur sur une ligne spécifique de la fenêtre" #. Clear the screen and redraw its contents. Given a numeric argument, #. move the line the cursor is on to the COUNT'th line of the window. #: info/session.c:3668 msgid "Redraw the display" msgstr "Redessiner l'affichage écran" #. This command does nothing. It is the fact that a key is bound to it #. that has meaning. See the code at the top of info_session (). #: info/session.c:3705 msgid "Quit using Info" msgstr "Quitter en utilisant Info" #: info/session.c:3728 #, c-format msgid "Unknown command (%s)." msgstr "Commande inconnue (%s)." # Est-ce que c'est " " ou « » comme caractères? #: info/session.c:3733 msgid "\"\" is invalid" msgstr "\"\" est invalide" #: info/session.c:3735 #, c-format msgid "\"%s\" is invalid" msgstr "«%s» est invalide" #: info/session.c:3958 msgid "Add this digit to the current numeric argument" msgstr "Ajouter ce chiffre à l'argument numérique courant" #: info/session.c:3967 msgid "Start (or multiply by 4) the current numeric argument" msgstr "Enclencher (ou multipler par 4) l'argument numérique courant" #: info/session.c:3982 msgid "Internally used by \\[universal-argument]" msgstr "Utilisé internement par \\[universal-argument]" #: info/tilde.c:362 msgid "readline: Out of virtual memory!\n" msgstr "" #: info/variables.c:40 msgid "When \"On\", footnotes appear and disappear automatically" msgstr "" "Lorsque «On» est en fonction, les notes en bas de page apparaissent\n" "et disparaissent automatiquement" #: info/variables.c:44 msgid "When \"On\", creating or deleting a window resizes other windows" msgstr "" "Lorsque «On» est en fonction, la création ou l'effacement d'une fenêtre\n" "réajuste la dimension des autres fenêtres" #: info/variables.c:48 msgid "When \"On\", flash the screen instead of ringing the bell" msgstr "" "Lorsque «On» est en fonction, un clignotement d'écran est utilisé plutôt\n" "qu'un bruit de cloche" #: info/variables.c:52 msgid "When \"On\", errors cause the bell to ring" msgstr "" "Lorsque «On» est en fonction, les erreurs sont signalées par un\n" "bruit de cloche" #: info/variables.c:56 msgid "When \"On\", Info garbage collects files which had to be uncompressed" msgstr "" "Lorsque «On» est en fonction, le ramasse-miette Info récolte les fichiers\n" "qui devaient être décomprimés" #: info/variables.c:59 msgid "When \"On\", the portion of the matched search string is highlighted" msgstr "" "Lorsque «On» est en fonction, la portion de la chaîne de fouille appariée\n" "est mise en surbrillance" #: info/variables.c:63 msgid "Controls what happens when scrolling is requested at the end of a node" msgstr "" "Contrôler ce qui arrive lorsqu'un défilement est requis à la fin d'un noeud" #: info/variables.c:67 msgid "The number lines to scroll when the cursor moves out of the window" msgstr "Le nombre de lignes à défiler quand le curseur va hors de la fenêtre" #: info/variables.c:71 msgid "When \"On\", Info accepts and displays ISO Latin characters" msgstr "" "Lorsque «On» est en fonction, Info accepte et affiche les caractères ISO " "Latin" #: info/variables.c:77 msgid "Explain the use of a variable" msgstr "Expliquer l'usage d'une variable" #. Get the variable's name. #: info/variables.c:83 msgid "Describe variable: " msgstr "Décrire la variable: " #: info/variables.c:102 msgid "Set the value of an Info variable" msgstr "Fixer la valeur d'une variable Info" #. Get the variable's name and value. #: info/variables.c:108 msgid "Set variable: " msgstr "Fixer la variable: " #: info/variables.c:126 #, c-format msgid "Set %s to value (%d): " msgstr "Fixer %s à la valeur (%d): " #: info/variables.c:167 #, c-format msgid "Set %s to value (%s): " msgstr "Fixer %s à la valeur (%s): " # Est-ce vraiment un message à traduire? #: info/window.c:1102 msgid "--*** Tags out of Date ***" msgstr "--*** Étiquettes passées Date ***" #. strlen (location_indicator). #. 10 for the decimal representation of the number of lines in this #. node, and the remainder of the text that can appear in the line. #: info/window.c:1113 msgid "-----Info: (), lines ----, " msgstr "-----Info: (), lignes ----, " #: info/window.c:1120 #, c-format msgid "-%s---Info: %s, %d lines --%s--" msgstr "-%s---Info: %s, %d lignes --%s--" #: info/window.c:1124 #, c-format msgid "-%s%s-Info: (%s)%s, %d lines --%s--" msgstr "-%s%s-Info: (%s)%s, %d lignes --%s--" #: info/window.c:1131 #, c-format msgid " Subfile: %s" msgstr " Sous-fichier: %s" #: lib/getopt.c:672 #, c-format msgid "%s: option `%s' is ambiguous\n" msgstr "" #: lib/getopt.c:696 #, c-format msgid "%s: option `--%s' doesn't allow an argument\n" msgstr "" #: lib/getopt.c:701 #, c-format msgid "%s: option `%c%s' doesn't allow an argument\n" msgstr "" #: lib/getopt.c:718 lib/getopt.c:891 #, fuzzy, c-format msgid "%s: option `%s' requires an argument\n" msgstr "%c%s nécessite un nom" #. --option #: lib/getopt.c:747 #, c-format msgid "%s: unrecognized option `--%s'\n" msgstr "" #. +option or -option #: lib/getopt.c:751 #, c-format msgid "%s: unrecognized option `%c%s'\n" msgstr "" #. 1003.2 specifies the format of this message. #: lib/getopt.c:777 #, c-format msgid "%s: illegal option -- %c\n" msgstr "" #: lib/getopt.c:780 #, c-format msgid "%s: invalid option -- %c\n" msgstr "" #. 1003.2 specifies the format of this message. #: lib/getopt.c:810 lib/getopt.c:940 #, fuzzy, c-format msgid "%s: option requires an argument -- %c\n" msgstr "%s exige un argument: le formateur pour %citem" #: lib/getopt.c:857 #, c-format msgid "%s: option `-W %s' is ambiguous\n" msgstr "" #: lib/getopt.c:875 #, c-format msgid "%s: option `-W %s' doesn't allow an argument\n" msgstr "" #: makeinfo/makeinfo.c:893 #, c-format msgid "%s:%d: warning: " msgstr "%s:%d: AVERTISSEMENT: " #: makeinfo/makeinfo.c:916 msgid "Too many errors! Gave up.\n" msgstr "Beaucoup trop d'erreurs! Abandon.\n" #: makeinfo/makeinfo.c:975 makeinfo/makeinfo.c:1000 makeinfo/makeinfo.c:1068 #, c-format msgid "%s: %s arg must be numeric, not `%s'.\n" msgstr "%s: l'argument %s doit être numérique, non pas «%s».\n" #: makeinfo/makeinfo.c:989 #, c-format msgid "Couldn't open macro expansion output `%s'" msgstr "Ne peut ouvrir la sortie d'expansion de macro «%s»" #: makeinfo/makeinfo.c:992 msgid "Cannot specify more than one macro expansion output" msgstr "Ne peut spécifier plus d'une sortie d'expansion de macro" #: makeinfo/makeinfo.c:1036 #, c-format msgid "%s: --paragraph-indent arg must be numeric/`none'/`asis', not `%s'.\n" msgstr "" "%s: l'argument de l'option --paragraph-indent doit être numérique, «none» " "ou\n" "«asis», non pas «%s».\n" #: makeinfo/makeinfo.c:1079 #, c-format msgid "%s: --footnote-style arg must be `separate' or `end', not `%s'.\n" msgstr "" "%s: l'argument de l'option --footnote-style doit être «separate» ou\n" "«end», non pas «%s».\n" #: makeinfo/makeinfo.c:1110 #, c-format msgid "%s: missing file argument.\n" msgstr "%s: absence d'un argument fichier.\n" #: makeinfo/makeinfo.c:1163 #, c-format msgid "Try `%s --help' for more information.\n" msgstr "Pour en savoir davantage, faites: «%s --help».\n" #: makeinfo/makeinfo.c:1165 #, fuzzy, c-format msgid "" "Usage: %s [OPTION]... TEXINFO-FILE...\n" "\n" "Translate Texinfo source documentation to a format suitable for reading\n" "with GNU Info.\n" "\n" "Options:\n" "-D VAR define a variable, as with @set.\n" "-E MACRO-OFILE process macros only, output texinfo source.\n" "-I DIR append DIR to the @include directory search path.\n" "-P DIR prepend DIR to the @include directory search path.\n" "-U VAR undefine a variable, as with @clear.\n" "--error-limit NUM quit after NUM errors (default %d).\n" "--fill-column NUM break lines at NUM characters (default %d).\n" "--footnote-style STYLE output footnotes according to STYLE:\n" " `separate' to place footnotes in their own node,\n" " `end' to place the footnotes at the end of\n" " the node in which they are defined (the default).\n" "--force preserve output even if errors.\n" "--help display this help and exit.\n" "--no-validate suppress node cross-reference validation.\n" "--no-warn suppress warnings (but not errors).\n" "--no-split suppress splitting of large files.\n" "--no-headers suppress node separators and Node: Foo headers.\n" "--output FILE, -o FILE output to FILE, and ignore any @setfilename.\n" "--paragraph-indent VAL indent paragraphs with VAL spaces (default %d).\n" " if VAL is `none', do not indent; if VAL is `asis',\n" " preserve any existing indentation.\n" "--reference-limit NUM complain about at most NUM references (default %d).\n" "--verbose report about what is being done.\n" "--version display version information and exit.\n" "\n" "Email bug reports to bug-texinfo@gnu.org.\n" msgstr "" "Usage: %s [OPTION]... FICHIER-TEXINFO...\n" "\n" "Traduire une documentation source en format Texinfo vers un format " "approprié\n" "pour une lecture avec GNU Info.\n" "\n" "Options:\n" "-D VAR Définir une variable, comme avec @set.\n" "-E MACRO-OFILE Exécuter les macros seulement, sortir un source " "texinfo.\n" "-I DIR Ajouter à la fin DIR dans la fouille de répertoires\n" " pour @include.\n" "-P DIR Ajouter au début DIR dans la fouille de répertoires\n" " pour @include.\n" "-U VAR Rendre indéfinie une variable, comme avec @clear.\n" "--error-limit NUM Quitter après NUM erreurs (par défaut %d).\n" "--fill-column NUM Tronquer les lignes à NUM caractères (par défaut " "%d).\n" "--footnote-style STYLE Sortir les notes en bas de page selon l'option " "STYLE:\n" " «separate» pour placer les notes dans leur propre " "noeud,\n" " «end» pour les placer à la fin du noeud dans lequel\n" " elles ont été définies (valeur par défaut).\n" "--force Conserver la sortie même s'il y a des erreurs.\n" "--help Afficher l'aide-mémoire.\n" "--no-validate Supprimer la validation de la table de référence\n" " des noeuds.\n" "--no-warn Supprimer les avertissements (mais pas les erreurs).\n" "--no-split Supprimer la troncation de fichiers volumineux.\n" "--no-headers Supprimer les séparateurs de noeud et Node: Foo " "headers.\n" "--output FICHIER, -o FICHIER Écrire dans le FICHIER, et ignorer tous\n" " les @setfilename.\n" "--paragraph-indent VAL Indenter les paragraphes de VAL espaces (%d par " "défaut).\n" " Si VAL est «none», ne pas indenter; si VAL est " "«asis»,\n" " conserver toute valeur d'indentation existante.\n" "--reference-limit NUM Avertir après plus de NUM références (%d par " "défaut).\n" "--verbose Utiliser le mode bavard et indiquer ce qui a été " "fait.\n" "--version Afficher le nom et la version du logiciel.\n" "\n" "Rapporter toute anomalie à bug-texinfo@prep.ai.mit.edu.\n" #: makeinfo/makeinfo.c:1552 #, c-format msgid "%s: getwd: %s, %s\n" msgstr "%s: getwd: %s, %s\n" #: makeinfo/makeinfo.c:1748 #, c-format msgid "Expected `%s'" msgstr "«%s» attendue" #: makeinfo/makeinfo.c:2082 #, c-format msgid "No `%s' found in `%s'" msgstr "Aucun «%s» trouvé dans «%s»" #: makeinfo/makeinfo.c:2132 #, c-format msgid "%s: Skipping macro expansion to stdout as Info output is going there.\n" msgstr "" "%s: Sauter l'expansion de macro qui irait sur stdout comme la sortie Info.\n" #: makeinfo/makeinfo.c:2151 #, c-format msgid "Making %s file `%s' from `%s'.\n" msgstr "Fabrication du fichier %s «%s» à partir de «%s».\n" #: makeinfo/makeinfo.c:2181 #, c-format msgid "This is Info file %s, produced by Makeinfo version %d.%d" msgstr "Ceci est le fichier Info %s, produit par Makeinfo version %d.%d" #: makeinfo/makeinfo.c:2183 #, c-format msgid " from the input file %s.\n" msgstr "à partir du fichier d'entrée «%s».\n" #: makeinfo/makeinfo.c:2202 #, c-format msgid "" "%s: Removing macro output file `%s' due to errors; use --force to preserve.\n" msgstr "" "%s: Enlèvement du fichier de sortie de macro «%s» à cause d'erreurs;\n" "utiliser l'option --force pour préserver.\n" #. If there were errors, and no --force, remove the output. #: makeinfo/makeinfo.c:2234 #, c-format msgid "%s: Removing output file `%s' due to errors; use --force to preserve.\n" msgstr "" "%s: Enlèvement du fichier de sortie «%s» à cause d'erreurs;\n" "utiliser l'option --force pour préserver.\n" #. Special case. I'm not supposed to see this character by itself. #. If I do, it means there is a syntax error in the input text. #. Report the error here, but remember this brace on the stack so #. you can ignore its partner. #: makeinfo/makeinfo.c:2374 makeinfo/makeinfo.c:7629 #, c-format msgid "Misplaced %c" msgstr "%c égarée ou mal placée" #: makeinfo/makeinfo.c:2461 #, c-format msgid "Unknown command `%s'" msgstr "Commande inconnue «%s»." #: makeinfo/makeinfo.c:2481 msgid "NO_NAME!" msgstr "NOM_INCONNU!" #: makeinfo/makeinfo.c:2495 #, c-format msgid "%c%s expected `{...}'" msgstr "%c%s exigeant des accolades «{...}»" #: makeinfo/makeinfo.c:2528 msgid "Unmatched }" msgstr "Accolade «}» non appariée" #: makeinfo/makeinfo.c:2576 #, c-format msgid "%c%s missing close brace" msgstr "%c%s sans accolade fermante" #: makeinfo/makeinfo.c:3372 msgid "Broken-Type in insertion_type_pname" msgstr "Type impossible dans la fonction insertion_type_pname" #: makeinfo/makeinfo.c:3438 msgid "Enumeration stack overflow" msgstr "Débordement de la pile d'énumérations" #: makeinfo/makeinfo.c:3470 #, c-format msgid "lettering overflow, restarting at %c" msgstr "débordement du lettrage, reprise à partir de %c" #: makeinfo/makeinfo.c:3509 msgid "* Menu:\n" msgstr "* Menu:\n" #: makeinfo/makeinfo.c:3593 #, c-format msgid "%s requires an argument: the formatter for %citem" msgstr "%s exige un argument: le formateur pour %citem" #: makeinfo/makeinfo.c:3697 #, c-format msgid "`%cend' expected `%s', but saw `%s'" msgstr "«%cend» attendait «%s», mais a vu «%s»" #: makeinfo/makeinfo.c:3810 #, c-format msgid "No matching `%cend %s'" msgstr "«%cend %s» non apparié" #: makeinfo/makeinfo.c:3949 #, c-format msgid "How did @%s end up in cm_special_char?\n" msgstr "Comment le caractère @%s a-t-il pu aboutir dans cm_special_char?\n" #. This error message isn't perfect if the argument is multiple #. characters, but it doesn't seem worth getting right. #: makeinfo/makeinfo.c:3963 #, c-format msgid "%c%s expects `i' or `j' as argument, not `%c'" msgstr "%c%s s'attend à argument «i» ou «j», non pas «%c»" #: makeinfo/makeinfo.c:3967 #, c-format msgid "%c%s expects a single character `i' or `j' as argument" msgstr "%c%s attend un argument d'un seul caractère «i» ou «j»" #: makeinfo/makeinfo.c:3979 msgid "January" msgstr "janvier" #: makeinfo/makeinfo.c:3979 msgid "February" msgstr "février" #: makeinfo/makeinfo.c:3979 msgid "March" msgstr "mars" #: makeinfo/makeinfo.c:3979 msgid "April" msgstr "avril" #: makeinfo/makeinfo.c:3979 msgid "May" msgstr "mai" #: makeinfo/makeinfo.c:3980 msgid "June" msgstr "juin" #: makeinfo/makeinfo.c:3980 msgid "July" msgstr "juillet" #: makeinfo/makeinfo.c:3980 msgid "August" msgstr "août" #: makeinfo/makeinfo.c:3980 msgid "September" msgstr "septembre" #: makeinfo/makeinfo.c:3980 msgid "October" msgstr "octobre" #: makeinfo/makeinfo.c:3981 msgid "November" msgstr "novembre" #: makeinfo/makeinfo.c:3981 msgid "December" msgstr "décembre" #: makeinfo/makeinfo.c:4039 #, c-format msgid "%c%s expects a single character as an argument" msgstr "%c%s s'attend à un seul caractère comme argument" #: makeinfo/makeinfo.c:4153 #, c-format msgid "%c%s is obsolete" msgstr "%c%s est périmé" #: makeinfo/makeinfo.c:4325 #, c-format msgid "Node with %ctop as a section already exists" msgstr "" #: makeinfo/makeinfo.c:4337 #, c-format msgid "Here is the %ctop node" msgstr "Le noeud %ctop se trouve ici" #: makeinfo/makeinfo.c:4356 #, c-format msgid "%ctop used before %cnode, defaulting to %s" msgstr "noeud %ctop utilisé avant %cnode, %s implicitement" #: makeinfo/makeinfo.c:4431 #, c-format msgid "%c%s is obsolete; use %c%s instead" msgstr "%c%s est périmé; utiliser %c%s à la place" #: makeinfo/makeinfo.c:4680 #, c-format msgid "Node `%s' multiply defined (line %d is first definition at)" msgstr "Noeud «%s» ayant plusieurs définitions (ligne %d étant la première)" #: makeinfo/makeinfo.c:4753 #, c-format msgid "Formatting node %s...\n" msgstr "Écriture du noeud «%s»...\n" #: makeinfo/makeinfo.c:4802 #, c-format msgid "Node `%s' requires a sectioning command (e.g. %c%s)" msgstr "Le noeud «%s» exige une commande de subdivision (e.g. %c%s)" #: makeinfo/makeinfo.c:5085 #, c-format msgid "Node `%s''s Next field not pointed back to" msgstr "Le champ Next du noeud «%s» n'a pas de pointeur de retour en amont" #: makeinfo/makeinfo.c:5090 #, c-format msgid "This node (`%s') is the one with the bad `Prev'" msgstr "Ce noeud («%s») est celui dont le champ «Prev» est erroné" #: makeinfo/makeinfo.c:5130 #, c-format msgid "Node `%s's Prev field not pointed back to" msgstr "Le champ Prev du noeud «%s» n'a pas de pointeur de retour en amont" #: makeinfo/makeinfo.c:5134 #, c-format msgid "This node (`%s') has the bad Next" msgstr "Ce noeud («%s») est celui dont le champ «Next» est erroné" #: makeinfo/makeinfo.c:5146 #, c-format msgid "Node `%s' missing Up field" msgstr "Le noeud «%s» a un champ «Up» manquant" #: makeinfo/makeinfo.c:5186 #, c-format msgid "`%s' has an Up field of `%s', but `%s' has no menu item for `%s'" msgstr "" "Le noeud «%s» a un champ Up de «%s», mais «%s» n'a aucun item menu pour «%s»" #: makeinfo/makeinfo.c:5217 #, c-format msgid "node `%s' has been referenced %d times" msgstr "Le noeud «%s» a été référencé %d fois" #: makeinfo/makeinfo.c:5229 #, c-format msgid "unreferenced node `%s'" msgstr "noeud «%s» non référencé" #: makeinfo/makeinfo.c:5256 #, c-format msgid "%s reference to nonexistent node `%s'" msgstr "%s réfère au noeud «%s» non existant" #: makeinfo/makeinfo.c:5668 makeinfo/makeinfo.c:5680 #, c-format msgid "%cmenu seen before first node" msgstr "%cmenu avant même le premier noeud" #: makeinfo/makeinfo.c:5669 makeinfo/makeinfo.c:5681 msgid "creating `Top' node" msgstr "création du noeud «TOP»" #: makeinfo/makeinfo.c:5794 #, c-format msgid "`.' or `,' must follow cross reference, not %c" msgstr "«.» ou «,» doit suivre une référence croisée, non pas %c" #: makeinfo/makeinfo.c:5962 #, c-format msgid "@image file `%s' unreadable: %s" msgstr "fichier «%s» dans la commande @image est illisible: %s" #: makeinfo/makeinfo.c:5966 msgid "@image missing filename argument" msgstr "absence d'un argument fichier dans la commande @image" #: makeinfo/makeinfo.c:6067 #, c-format msgid "%s requires letter or digit" msgstr "%s exige une lettre ou un chiffre" #: makeinfo/makeinfo.c:6152 #, c-format msgid "Unmatched `%c%s'" msgstr "«%c%s» non apparié" #: makeinfo/makeinfo.c:6159 #, c-format msgid "`%c%s' needs something after it" msgstr "«%c%s» a besoin de quelque chose après lui" #: makeinfo/makeinfo.c:6165 #, c-format msgid "Bad argument to `%s', `%s', using `%s'" msgstr "Mauvais argument à «%s», «%s», utilisant «%s»" #: makeinfo/makeinfo.c:6338 #, c-format msgid "{No Value For \"%s\"}" msgstr "{Aucune Valeur Pour «%s»}" #: makeinfo/makeinfo.c:6388 #, c-format msgid "%c%s requires a name" msgstr "%c%s nécessite un nom" #: makeinfo/makeinfo.c:6496 #, c-format msgid "Reached eof before matching @end %s" msgstr "Fin de fichier rencontré avant l'appariement de @end %s" #: makeinfo/makeinfo.c:6722 #, c-format msgid "The `%c%s' command is meaningless within a `@%s' block" msgstr "La commande «%c%s» est inactive dans un bloc «@%s»" #: makeinfo/makeinfo.c:6731 #, c-format msgid "%citemx is not meaningful inside of a `%s' block" msgstr "%citemx est inactif à l'intérieur d'un bloc «%s»" #: makeinfo/makeinfo.c:6844 #, c-format msgid "%c%s found outside of an insertion block" msgstr "%c%s est trouvé à l'extérieur d'un bloc d'insertion" #: makeinfo/makeinfo.c:6935 #, c-format msgid "Missing `}' in %cdef arg" msgstr "Accolade «}» manquante dans le paramètre %cdef" #: makeinfo/makeinfo.c:7144 makeinfo/makeinfo.c:7164 msgid "Function" msgstr "Fonction" #: makeinfo/makeinfo.c:7148 msgid "Macro" msgstr "Macro" #: makeinfo/makeinfo.c:7152 msgid "Special Form" msgstr "Forme Spéciale" #: makeinfo/makeinfo.c:7156 makeinfo/makeinfo.c:7168 msgid "Variable" msgstr "Variable" #: makeinfo/makeinfo.c:7160 msgid "User Option" msgstr "Option de l'Usager" #: makeinfo/makeinfo.c:7172 msgid "Instance Variable" msgstr "Variable d'Instance" #: makeinfo/makeinfo.c:7176 makeinfo/makeinfo.c:7180 msgid "Method" msgstr "Méthode" #: makeinfo/makeinfo.c:7335 #, c-format msgid "Must be in a `%s' insertion in order to use `%s'x" msgstr "Doit être dans une insertion «%s» afin d'utiliser «%s»x." #: makeinfo/makeinfo.c:7407 #, c-format msgid "%csp requires a positive numeric argument" msgstr "%csp exige un argument numérique positif" #: makeinfo/makeinfo.c:7650 msgid "asis" msgstr "«asis»" #: makeinfo/makeinfo.c:7652 msgid "none" msgstr "«none»" #: makeinfo/makeinfo.c:7674 #, c-format msgid "Bad argument to %c%s" msgstr "Mauvais argument à %c%s" #: makeinfo/makeinfo.c:7966 #, c-format msgid "Unknown index `%s'" msgstr "Nom d'index inconnu «%s»" #: makeinfo/makeinfo.c:8031 #, c-format msgid "Index `%s' already exists" msgstr "L'index «%s» existe toujours" #: makeinfo/makeinfo.c:8062 #, c-format msgid "Unknown index `%s' and/or `%s' in @synindex" msgstr "Nom d'index «%s» inconnu et/ou «%s» dans @synindex" #: makeinfo/makeinfo.c:8251 #, c-format msgid "Unknown index `%s' in @printindex" msgstr "Nom d'index «%s» inconnu dans @printindex" #: makeinfo/makeinfo.c:8266 msgid "" "* Menu:\n" "\n" msgstr "" "* Menu:\n" "\n" #: makeinfo/makeinfo.c:8453 #, c-format msgid "`%c%s' needs an argument `{...}', not just `%s'" msgstr "«%c%s» nécessite un argument «{...}», non pas «%s» seulement" #: makeinfo/makeinfo.c:8468 #, c-format msgid "No closing brace for footnote `%s'" msgstr "Accolade fermante «}» manquante pour la note en bas de page «%s»" #: makeinfo/makeinfo.c:8507 msgid "Footnote defined without parent node" msgstr "La note en bas de page est définie sans noeud parent" # Est-ce vraiement un message à traduire? #: makeinfo/makeinfo.c:8539 msgid "-Footnotes" msgstr "-Footnotes" # Est-ce vraiment un message à traduire? NON. #: makeinfo/makeinfo.c:8594 msgid "" "---------- Footnotes ----------\n" "\n" msgstr "" "--------- Notes en bas de page ---------\n" "\n" #: makeinfo/makeinfo.c:8690 #, c-format msgid "macro `%s' previously defined" msgstr "macro «%s» déjà définie précédemment" #: makeinfo/makeinfo.c:8694 #, c-format msgid "here is the previous definition of `%s'" msgstr "ici se trouve la définition précédente de «%s»" #: makeinfo/makeinfo.c:8908 #, c-format msgid "Macro `%s' called with too many args" msgstr "Macro «%s» appelée avec trop d'arguments" #: makeinfo/makeinfo.c:9060 #, c-format msgid "%cend macro not found" msgstr "macro %cend non trouvée" #: makeinfo/makeinfo.c:9100 #, c-format msgid "%cquote-arg only useful when the macro takes a single argument" msgstr "%cquote-arg utile seulement lorsque la macro prend un seul argument" #: makeinfo/multi.c:206 #, c-format msgid "ignoring stray text `%s' after @multitable" msgstr "abandon du texte orphelin «%s» après la commande @multitable" #: makeinfo/multi.c:277 #, c-format msgid "Too many columns in multitable item (max %d)" msgstr "Trop de colonnes dans un item de multitable (%d max)" #. impossible, I think. #: makeinfo/multi.c:304 msgid "multitable item not in active multitable" msgstr "item de multitable qui n'est pas dans une multitable active" #: makeinfo/multi.c:313 #, c-format msgid "Cannot select column #%d in multitable" msgstr "Ne peut pas sélectionner la colonne #%d dans une multitable." #: makeinfo/multi.c:404 msgid "ignoring @tab outside of multitable" msgstr "inhibition d'une commande @tab à l'extérieur d'une multitable" #: makeinfo/multi.c:428 msgid "** Multicolumn output from last row:\n" msgstr "** Sortie en multicolonnes à partir de la dernière rangée:\n" #: makeinfo/multi.c:431 #, c-format msgid "* column #%d: output = %s\n" msgstr "* colonne #%d: sortie = %s\n" #: util/install-info.c:123 util/install-info.c:136 msgid "virtual memory exhausted" msgstr "mémoire virtuelle épuisée" #: util/install-info.c:192 #, c-format msgid "%s: warning: " msgstr "%s: AVERTISSEMENT: " #: util/install-info.c:213 #, c-format msgid " for %s" msgstr " pour %s" #: util/install-info.c:282 #, c-format msgid "\tTry `%s --help' for a complete list of options.\n" msgstr "Pour avoir la liste complète des options, faites «%s --help».\n" #: util/install-info.c:290 #, fuzzy, c-format msgid "" "Usage: %s [OPTION]... [INFO-FILE [DIR-FILE]]\n" "\n" "Install INFO-FILE in the Info directory file DIR-FILE.\n" "\n" "Options:\n" "--delete Delete existing entries in INFO-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" "\n" "Email bug reports to bug-texinfo@gnu.org.\n" msgstr "" "%s [OPTION]... [INFO-FICHIER [DIR-FICHIER]]\n" " Installer INFO-FICHIER dans le répertoire DIR-FICHIER de fichiers Info.\n" "\n" "Options:\n" "--delete Éliminer les entrées existantes dans INFO-FICHIER;\n" " ne pas insérer une quelconque nouvelle entrée.\n" "--dir-file=NOM Spécifier le NOM du répertoire de fichiers Info.\n" " Ceci équivaut à utiliser l'argument DIR-FICHIER.\n" "--entry=TEXTE Insérer TEXTE comme une entrée du répertoire Info.\n" " TEXTE doit avoir la forme d'une ligne d'item de menu\n" " Info avec zéro ou plusieurs lignes en extra commençant\n" " par un blanc. Si plus d'une entrée est spécifiée,\n" " elles seront toutes ajoutées. Si aucune entrée n'est\n" " spécifiée, elles seront déterminées à partir de\n" " l'information dans le fichier Info lui-même.\n" "--help Afficher l'aide-mémoire.\n" "--info-file=FICHIER Spécifier le FICHIER Info à installer dans le\n" " répertoire de fichiers Info. Ceci équivaut à utiliser\n" " l'argument INFO-FICHIER.\n" "--info-dir=RÉP Identique à l'option --dir-file=RÉP/dir.\n" "--item=TEXTE Identique à l'option --entry=TEXTE\n" " Une entrée de répertoire Info est en fait un item menu.\n" "--quiet Supprimer les avertissements.\n" "--remove Identique à l'option --delete.\n" "--section=SEC Mettre cette entrée de fichier dans la section SEC du\n" " répertoire. Si plus d'une section est spécifiée,\n" " toutes les entrées sont ajoutées dans chacune des\n" " sections. Si aucune section n'est spécifiée, elles\n" " seront déterminées à partir de l'information dans\n" " le fichier Info lui-même.\n" "--version Afficher le nom et la version du logiciel.\n" "\n" "Rapporter toute anomalie à bug-texinfo@prep.ai.mit.edu.\n" #: util/install-info.c:341 #, fuzzy msgid "" "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" "\n" "File: dir,\tNode: Top,\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" "* Menu:\n" msgstr "" "Ceci est le fichier .../info/dir, lequel contient le noeud \n" "le plus haut dans la hiérarchie Info, noeud appelé (dir)Top.\n" "La première fois que Info est invoqué, vous démarrez la recherche \n" "à partir de ce noeud.\n" "\n" "Fichier: dir Noeud: Top Ceci est le haut de l'arborescence INFO\n" "\n" " Ceci (le noeud Répertoire) fournit un menu des sujets majeurs.\n" " Taper «q» pour quitter, «?» pour lister toutes les commandes Info,\n" " «d» pour revenir à cet endroit,\n" " «h» fournit un guide d'initiation pour les nouveaux venus,\n" " «mEmacs» démarre une consultation du manuel Emacs, etc.\n" "\n" " En Emacs, vous pouvez cliquer le bouton 2 de la souris sur un item menu " "ou\n" " sur une référence croisée pour le sélectionner.\n" "\n" "* Menu:\n" #: util/install-info.c:364 #, c-format msgid "%s: could not read (%s) and could not create (%s)\n" msgstr "%s: ne peut pas lire (%s) et ne peut pas créer (%s)\n" #: util/install-info.c:464 util/install-info.c:474 #, c-format msgid "%s: Specify the Info directory only once.\n" msgstr "%s: Spécifier le répertoire Info une seule fois seulement.\n" #: util/install-info.c:502 #, c-format msgid "%s: Specify the Info file only once.\n" msgstr "%s: Spécifier le fichier Info une seule fois seulement.\n" #: util/install-info.c:550 #, c-format msgid "excess command line argument `%s'" msgstr "excédent d'argument de ligne de commande `%s'" #: util/install-info.c:554 msgid "No input file specified; try --help for more information." msgstr "" "Aucun fichier d'entrée spécifié; essayer --help pour plus d'informations." #: util/install-info.c:556 msgid "No dir file specified; try --help for more information." msgstr "Aucun fichier dir spécifié; essayer --help pour plus d'informations." #: util/install-info.c:608 util/install-info.c:631 msgid "START-INFO-DIR-ENTRY without matching END-INFO-DIR-ENTRY" msgstr "START-INFO-DIR-ENTRY non apparié avec END-INFO-DIR-ENTRY" #: util/install-info.c:627 msgid "END-INFO-DIR-ENTRY without matching START-INFO-DIR-ENTRY" msgstr "END-INFO-DIR-ENTRY non apparié avec START-INFO-DIR-ENTRY" #. 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. #: util/install-info.c:641 #, c-format msgid "no info dir entry in `%s'" msgstr "aucune entrée répertoire Info dans «%s»" #: util/install-info.c:852 #, c-format msgid "menu item `%s' already exists, for file `%s'" msgstr "item menu «%s» déjà existant, pour le fichier «%s»" #: util/install-info.c:875 #, c-format msgid "no entries found for `%s'; nothing deleted" msgstr "aucune entrée trouvée pour «%s»; rien n'a été éliminé" #: util/texindex.c:253 msgid "keep temporary files around after processing" msgstr "conserver les fichiers temporaires après le traitement" #: util/texindex.c:255 msgid "do not keep temporary files around after processing (default)" msgstr "ne pas conserver les fichiers temporaires après le traitement (défaut)" #: util/texindex.c:257 msgid "send output to FILE" msgstr "envoyer la sortie dans FICHIER" #: util/texindex.c:259 msgid "display version information and exit" msgstr "afficher la version en usage et quitter" #: util/texindex.c:261 msgid "display this help and exit" msgstr "afficher cet aide-mémoire et quitter" #: util/texindex.c:272 #, c-format msgid "Usage: %s [OPTION]... FILE...\n" msgstr "Usage: %s [OPTION]... FICHIER...\n" #: util/texindex.c:273 msgid "Generate a sorted index for each TeX output FILE.\n" msgstr "Générer un index trié pour chaque FICHIER de sortie TeX.\n" #. Avoid trigraph nonsense. #: util/texindex.c:275 msgid "Usually FILE... is `foo.??' for a document `foo.texi'.\n" msgstr "Habituellement FICHIER... est «foo.??» pour un document «foo.texi».\n" #: util/texindex.c:276 msgid "" "\n" "Options:\n" msgstr "" "\n" "Options:\n" #: util/texindex.c:290 #, fuzzy msgid "" "\n" "Email bug reports to bug-texinfo@gnu.org." msgstr "" "\n" "Rapporter toute anomalie à bug-texinfo@prep.ai.mit.edu." #: util/texindex.c:917 util/texindex.c:951 util/texindex.c:1027 #: util/texindex.c:1055 #, c-format msgid "%s: not a texinfo index file" msgstr "%s: pas un fichier index en format Texinfo" #: util/texindex.c:1012 #, c-format msgid "failure reopening %s" msgstr "échec lors de la réouverture de %s" #: util/texindex.c:1325 #, c-format msgid "entry %s follows an entry with a secondary name" msgstr "l'entrée %s suit une entrée ayant un nom secondaire" #: util/texindex.c:1663 #, c-format msgid "%s; for file `%s'.\n" msgstr "%s; pour le fichier «%s».\n" #: util/texindex.c:1724 #, c-format msgid "Virtual memory exhausted in %s ()! Needed %d bytes." msgstr "Mémoire virtuelle épuisée dans %s ()! Besoin de %d octets." #~ msgid "install-info (GNU %s) %s\n" #~ msgstr "install-info (GNU %s) %s\n" #~ msgid "universal-argument" #~ msgstr "universal-argument" #~ msgid "Show what to type to execute a given command" #~ msgstr "Montrer quoi écrire afin d'exécuter une commande donnée" #~ msgid "There %s %d " #~ msgstr "Comme complétion(s) %s %d " #~ msgid "is" #~ msgstr "il y a" #~ msgid "are" #~ msgstr "il y a" # Est-ce vraiment un message à traduire? NON. #~ msgid "" #~ "Usage: info [-d dir-path] [-f info-file] [-o output-file] [-n node-name]..." #~ msgstr "" #~ "Usage: info [-d dir-path] [-f info-file] [-o output-file] [-n node-name]..." # Est-ce vraiment un message à traduire? NON. #~ msgid "" #~ " [--directory dir-path] [--file info-file] [--node node-name]..." #~ msgstr "" #~ " [--directory dir-path] [--file info-file] [--node node-name]..." # Est-ce vraiment un message à traduire? NON. #~ msgid " [--help] [--output output-file] [--subnodes] [--version]" #~ msgstr "" #~ " [--help] [--output output-file] [--subnodes] [--version]" # Est-ce vraiment un message à traduire? NON. #~ msgid " [--dribble dribble-file] [--restore from-file]" #~ msgstr " [--dribble dribble-file] [--restore from-file]" # Est-ce vraiment un message à traduire? NON. #~ msgid " [menu-selection ...]" #~ msgstr " [menu-selection ...]" #~ msgid "makeinfo (GNU %s %s) %d.%d\n" #~ msgstr "makeinfo (GNU %s %s) %d.%d\n" #~ msgid "%d %s %d" #~ msgstr "%d %s %d" #~ msgid "There already is a node having %ctop as a section" #~ msgstr "Il y a déjà un noeud ayant %ctop en tant que section" #~ msgid "texindex (GNU %s %s) 2.1\n" #~ msgstr "texindex (GNU %s %s) 2.1\n" texinfo-3.12/po/texinfo.pot0000664000175000017500000012000406477046264013205 0ustar gg# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Free Software Foundation, Inc. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 1998-03-03 13:32-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: ENCODING\n" #. **************************************************************** #. #. Echo Area Movement Commands #. #. **************************************************************** #: info/echo-area.c:283 info/session.c:698 msgid "Move forward a character" msgstr "" #. Move point backward in the node. #: info/echo-area.c:295 info/session.c:714 msgid "Move backward a character" msgstr "" #: info/echo-area.c:307 msgid "Move to the start of this line" msgstr "" #: info/echo-area.c:312 msgid "Move to the end of this line" msgstr "" #. Move forward a word in the input line. #: info/echo-area.c:320 info/session.c:732 msgid "Move forward a word" msgstr "" #: info/echo-area.c:360 info/session.c:781 msgid "Move backward a word" msgstr "" #: info/echo-area.c:400 msgid "Delete the character under the cursor" msgstr "" #: info/echo-area.c:430 msgid "Delete the character behind the cursor" msgstr "" #: info/echo-area.c:451 msgid "Cancel or quit operation" msgstr "" #: info/echo-area.c:466 msgid "Accept (or force completion of) this line" msgstr "" #: info/echo-area.c:471 msgid "Insert next character verbatim" msgstr "" #: info/echo-area.c:479 msgid "Insert this character" msgstr "" #: info/echo-area.c:497 msgid "Insert a TAB character" msgstr "" #. Transpose the characters at point. If point is at the end of the line, #. then transpose the characters before point. #: info/echo-area.c:504 msgid "Transpose characters at point" msgstr "" #: info/echo-area.c:555 msgid "Yank back the contents of the last kill" msgstr "" #: info/echo-area.c:562 msgid "Kill ring is empty" msgstr "" #. If the last command was yank, or yank_pop, and the text just before #. point is identical to the current kill item, then delete that text #. from the line, rotate the index down, and yank back some other text. #: info/echo-area.c:575 msgid "Yank back a previous kill" msgstr "" #. Delete the text from point to end of line. #: info/echo-area.c:608 msgid "Kill to the end of the line" msgstr "" #: info/echo-area.c:621 msgid "Kill to the beginning of the line" msgstr "" #. Delete from point to the end of the current word. #: info/echo-area.c:633 msgid "Kill the word following the cursor" msgstr "" #: info/echo-area.c:652 msgid "Kill the word preceding the cursor" msgstr "" #: info/echo-area.c:871 msgid "Not complete" msgstr "" #: info/echo-area.c:916 msgid "List possible completions" msgstr "" #: info/echo-area.c:929 msgid "No completions" msgstr "" #: info/echo-area.c:933 msgid "Sole completion" msgstr "" #: info/echo-area.c:942 msgid "One completion:\n" msgstr "" #: info/echo-area.c:943 #, c-format msgid "%d completions:\n" msgstr "" #: info/echo-area.c:1088 msgid "Insert completion" msgstr "" #: info/echo-area.c:1221 msgid "Building completions..." msgstr "" #. Scroll the "other" window. If there is a window showing completions, scroll #. that one, otherwise scroll the window which was active on entering the read #. function. #: info/echo-area.c:1319 msgid "Scroll the completions window" msgstr "" #: info/footnotes.c:206 msgid "Footnotes could not be displayed" msgstr "" #: info/footnotes.c:232 msgid "Show the footnotes associated with this node in another window" msgstr "" #: info/indices.c:175 msgid "Look up a string in the index for this file" msgstr "" #: info/indices.c:205 msgid "Finding index entries..." msgstr "" #: info/indices.c:212 msgid "No indices found." msgstr "" #: info/indices.c:222 msgid "Index entry: " msgstr "" #: info/indices.c:332 msgid "" "Go to the next matching index item from the last `\\[index-search]' command" msgstr "" #: info/indices.c:342 msgid "No previous index search string." msgstr "" #: info/indices.c:349 msgid "No index entries." msgstr "" #: info/indices.c:382 #, c-format msgid "No %sindex entries containing \"%s\"." msgstr "" #: info/indices.c:383 msgid "more " msgstr "" #: info/indices.c:393 msgid "CAN'T SEE THIS" msgstr "" #: info/indices.c:429 #, c-format msgid "Found \"%s\" in %s. (`\\[next-index-match]' tries to find next.)" msgstr "" #: info/indices.c:533 #, c-format msgid "Scanning indices of \"%s\"..." msgstr "" #: info/indices.c:616 msgid "Grovel all known info file's indices for a string and build a menu" msgstr "" #: info/indices.c:620 msgid "Index apropos: " msgstr "" #: info/indices.c:650 #, c-format msgid "" "\n" "* Menu: Nodes whoses indices contain \"%s\":\n" msgstr "" #: info/info.c:212 msgid "Try --help for more information." msgstr "" #: info/info.c:231 makeinfo/makeinfo.c:1089 util/install-info.c:530 #: util/texindex.c:338 #, c-format msgid "" "Copyright (C) %s Free Software Foundation, Inc.\n" "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" msgstr "" #: info/info.c:363 msgid "no entries found\n" msgstr "" #: info/info.c:406 msgid "There is no menu in this node." msgstr "" #: info/info.c:437 #, c-format msgid "There is no menu item \"%s\" in this node." msgstr "" #: info/info.c:501 #, c-format msgid "Unable to find the node referenced by \"%s\"." msgstr "" #: info/info.c:602 #, c-format msgid "" "Usage: %s [OPTION]... [INFO-FILE [MENU-ITEM...]]\n" "\n" "Read documentation in Info format.\n" "For more complete documentation on how to use Info, run `info info " "options'.\n" "\n" "Options:\n" "--directory DIR add DIR to INFOPATH.\n" "--dribble FILENAME remember user keystrokes in FILENAME.\n" "--file FILENAME specify Info file to visit.\n" "--node NODENAME specify nodes in first visited Info file.\n" "--output FILENAME output selected nodes to FILENAME.\n" "--restore FILENAME read initial keystrokes from FILENAME.\n" "--subnodes recursively output menu items.\n" "--help display this help and exit.\n" "--version display version information and exit.\n" "\n" "The first argument, if present, is the name of the Info file to read.\n" "Any remaining arguments are treated as the names of menu\n" "items in the initial node visited. For example, `info emacs buffers'\n" "moves to the node `buffers' in the info file `emacs'.\n" "\n" "Email bug reports to bug-texinfo@gnu.org." msgstr "" #: info/infodoc.c:50 msgid "Basic Commands in Info Windows" msgstr "" #: info/infodoc.c:211 msgid "" "The following commands can only be invoked via M-x:\n" "\n" msgstr "" #: info/infodoc.c:228 msgid "--- Use `\\[history-node]' or `\\[kill-node]' to exit ---\n" msgstr "" #. Create or move to the help window. #: info/infodoc.c:328 msgid "Display help message" msgstr "" #. Show the Info help node. This means that the "info" file is installed #. where it can easily be found on your system. #: info/infodoc.c:346 msgid "Visit Info node `(info)Help'" msgstr "" #: info/infodoc.c:470 msgid "Print documentation for KEY" msgstr "" #: info/infodoc.c:483 #, c-format msgid "Describe key: %s" msgstr "" #: info/infodoc.c:492 #, c-format msgid "ESC %s is undefined." msgstr "" #: info/infodoc.c:509 #, c-format msgid "%s is undefined." msgstr "" #: info/infodoc.c:535 #, c-format msgid "%s is defined to %s." msgstr "" #: info/infodoc.c:731 msgid "Where is command: " msgstr "" #: info/infodoc.c:753 #, c-format msgid "`%s' is not on any keys" msgstr "" #: info/infodoc.c:759 #, c-format msgid "%s can only be invoked via %s." msgstr "" #: info/infodoc.c:762 #, c-format msgid "%s can be invoked via %s." msgstr "" #: info/infodoc.c:766 #, c-format msgid "There is no function named `%s'" msgstr "" #: info/m-x.c:69 msgid "Read the name of an Info command and describe it" msgstr "" #: info/m-x.c:73 msgid "Describe command: " msgstr "" #: info/m-x.c:96 msgid "Read a command name in the echo area and execute it" msgstr "" #: info/m-x.c:134 msgid "Cannot execute an `echo-area' command here." msgstr "" #: info/m-x.c:150 msgid "Set the height of the displayed window" msgstr "" #: info/m-x.c:163 #, c-format msgid "Set screen height to (%d): " msgstr "" #: info/makedoc.c:126 msgid "" " Source files groveled to make this file include:\n" "\n" msgstr "" #: info/makedoc.c:450 #, c-format msgid "Couldn't manipulate the file %s.\n" msgstr "" #: info/nodemenu.c:28 msgid "" "\n" "* Menu:\n" " (File)Node Lines Size Containing File\n" " ---------- ----- ---- ---------------" msgstr "" #: info/nodemenu.c:197 msgid "" "Here is the menu of nodes you have recently visited.\n" "Select one from this menu, or use `\\[history-node]' in another window.\n" msgstr "" #: info/nodemenu.c:217 msgid "Make a window containing a menu of all of the currently visited nodes" msgstr "" #: info/nodemenu.c:297 msgid "Select a node which has been previously visited in a visible window" msgstr "" #: info/nodemenu.c:309 msgid "Select visited node: " msgstr "" #: info/nodemenu.c:329 info/session.c:1996 #, c-format msgid "The reference disappeared! (%s)." msgstr "" #: info/session.c:162 #, c-format msgid "" "Welcome to Info version %s. \"\\[get-help-window]\" for help, " "\"\\[menu-item]\" for menu item." msgstr "" #. Move WINDOW's point down to the next line if possible. #: info/session.c:629 msgid "Move down to the next line" msgstr "" #. Move WINDOW's point up to the previous line if possible. #: info/session.c:644 msgid "Move up to the previous line" msgstr "" #. Move WINDOW's point to the end of the true line. #: info/session.c:659 msgid "Move to the end of the line" msgstr "" #. Move WINDOW's point to the beginning of the true line. #: info/session.c:679 msgid "Move to the start of the line" msgstr "" #: info/session.c:855 msgid " times" msgstr "" #: info/session.c:857 #, c-format msgid "%d times" msgstr "" #: info/session.c:895 msgid "No \"Next\" pointer for this node." msgstr "" #: info/session.c:898 msgid "Following \"Next\" node..." msgstr "" #: info/session.c:899 info/session.c:927 info/session.c:999 #: info/session.c:1717 msgid "Next" msgstr "" #: info/session.c:915 msgid "Selecting first menu item..." msgstr "" #: info/session.c:926 msgid "Selecting \"Next\" node..." msgstr "" #: info/session.c:950 info/session.c:1063 info/session.c:1733 msgid "Up" msgstr "" #: info/session.c:1020 msgid "No more nodes." msgstr "" #: info/session.c:1044 msgid "No \"Prev\" for this node." msgstr "" #. Move to the previous node. If this node now contains a menu, #. and we have not inhibited movement to it, move to the node #. corresponding to the last menu item. #: info/session.c:1047 info/session.c:1100 msgid "Moving \"Prev\" in this window." msgstr "" #: info/session.c:1048 info/session.c:1101 info/session.c:1725 msgid "Prev" msgstr "" #: info/session.c:1059 msgid "No \"Prev\" or \"Up\" for this node." msgstr "" #: info/session.c:1062 msgid "Moving \"Up\" in this window." msgstr "" #: info/session.c:1110 msgid "Moving to \"Prev\"'s last menu item." msgstr "" #: info/session.c:1121 msgid "Move forwards or down through node structure" msgstr "" #: info/session.c:1137 msgid "Move backwards or up through node structure" msgstr "" #. Show the next screen of WINDOW's node. #: info/session.c:1152 msgid "Scroll forward in this window" msgstr "" #. Show the previous screen of WINDOW's node. #: info/session.c:1197 msgid "Scroll backward in this window" msgstr "" #. Move to the beginning of the node. #: info/session.c:1237 msgid "Move to the start of this node" msgstr "" #. Move to the end of the node. #: info/session.c:1244 msgid "Move to the end of this node" msgstr "" #. **************************************************************** #. #. Commands for Manipulating Windows #. #. **************************************************************** #. Make the next window in the chain be the active window. #: info/session.c:1257 msgid "Select the next window" msgstr "" #. Make the previous window in the chain be the active window. #: info/session.c:1296 msgid "Select the previous window" msgstr "" #. Split WINDOW into two windows, both showing the same node. If we #. are automatically tiling windows, re-tile after the split. #: info/session.c:1347 msgid "Split the current window" msgstr "" #. Delete WINDOW, forgetting the list of last visited nodes. If we are #. automatically displaying footnotes, show or remove the footnotes #. window. If we are automatically tiling windows, re-tile after the #. deletion. #: info/session.c:1428 msgid "Delete the current window" msgstr "" #: info/session.c:1436 msgid "Cannot delete a permanent window" msgstr "" #. Just keep WINDOW, deleting all others. #: info/session.c:1469 msgid "Delete all other windows" msgstr "" #. Scroll the "other" window of WINDOW. #: info/session.c:1515 msgid "Scroll the other window" msgstr "" #. Change the size of WINDOW by AMOUNT. #: info/session.c:1535 msgid "Grow (or shrink) this window" msgstr "" #: info/session.c:1546 msgid "Divide the available screen space among the visible windows" msgstr "" #: info/session.c:1553 msgid "Toggle the state of line wrapping in the current window" msgstr "" #. Make WINDOW display the "Next:" node of the node currently being #. displayed. #: info/session.c:1714 msgid "Select the `Next' node" msgstr "" #. Make WINDOW display the "Prev:" node of the node currently being #. displayed. #: info/session.c:1722 msgid "Select the `Prev' node" msgstr "" #. Make WINDOW display the "Up:" node of the node currently being #. displayed. #: info/session.c:1730 msgid "Select the `Up' node" msgstr "" #. Make WINDOW display the last node of this info file. #: info/session.c:1737 msgid "Select the last node in this file" msgstr "" #: info/session.c:1750 info/session.c:1768 msgid "This window has no additional nodes" msgstr "" #. Make WINDOW display the first node of this info file. #: info/session.c:1759 msgid "Select the first node in this file" msgstr "" #: info/session.c:1778 msgid "Select the last item in this node's menu" msgstr "" #. Use KEY (a digit) to select the Nth menu item in WINDOW->node. #: info/session.c:1784 msgid "Select this menu item" msgstr "" #: info/session.c:1813 #, c-format msgid "There aren't %d items in this menu." msgstr "" #: info/session.c:1944 #, c-format msgid "Menu item (%s): " msgstr "" #: info/session.c:1946 msgid "Menu item: " msgstr "" #: info/session.c:1951 #, c-format msgid "Follow xref (%s): " msgstr "" #: info/session.c:1953 msgid "Follow xref: " msgstr "" #. Read a line (with completion) which is the name of a menu item, #. and select that item. #: info/session.c:2042 msgid "Read a menu item and select its node" msgstr "" #: info/session.c:2050 msgid "Read a footnote or cross reference and select its node" msgstr "" #. Position the cursor at the start of this node's menu. #: info/session.c:2056 msgid "Move to the start of this node's menu" msgstr "" #: info/session.c:2080 msgid "Visit as many menu items at once as possible" msgstr "" #. Read a line of input which is a node name, and go to that node. #: info/session.c:2108 msgid "Read a node name and select it" msgstr "" #: info/session.c:2169 info/session.c:2173 msgid "Goto Node: " msgstr "" #: info/session.c:2194 msgid "Read a manpage reference and select it" msgstr "" #: info/session.c:2198 msgid "Get Manpage: " msgstr "" #. Move to the "Top" node in this file. #: info/session.c:2228 msgid "Select the node `Top' in this file" msgstr "" #. Notice that the node "Top" is special, and doesn't have to #. be referenced. #: info/session.c:2230 makeinfo/makeinfo.c:5145 makeinfo/makeinfo.c:5228 msgid "Top" msgstr "" #. Move to the node "(dir)Top". #: info/session.c:2234 msgid "Select the node `(dir)'" msgstr "" #: info/session.c:2254 #, c-format msgid "Kill node (%s): " msgstr "" #: info/session.c:2307 #, c-format msgid "Cannot kill node `%s'" msgstr "" #: info/session.c:2317 msgid "Cannot kill the last node" msgstr "" #: info/session.c:2401 msgid "Select the most recently selected node" msgstr "" #. Kill named node. #: info/session.c:2407 msgid "Kill this node" msgstr "" #. Read the name of a file and select the entire file. #: info/session.c:2415 msgid "Read the name of a file and select it" msgstr "" #: info/session.c:2419 msgid "Find file: " msgstr "" #: info/session.c:2436 #, c-format msgid "Cannot find \"%s\"." msgstr "" #: info/session.c:2483 info/session.c:2608 #, c-format msgid "Could not create output file \"%s\"." msgstr "" #: info/session.c:2496 info/session.c:2625 info/session.c:2671 msgid "Done." msgstr "" #: info/session.c:2553 #, c-format msgid "Writing node \"(%s)%s\"..." msgstr "" #: info/session.c:2556 #, c-format msgid "Writing node \"%s\"..." msgstr "" #: info/session.c:2634 msgid "Pipe the contents of this node through INFO_PRINT_COMMAND" msgstr "" #: info/session.c:2654 #, c-format msgid "Cannot open pipe to \"%s\"." msgstr "" #: info/session.c:2661 #, c-format msgid "Printing node \"(%s)%s\"..." msgstr "" #: info/session.c:2664 #, c-format msgid "Printing node \"%s\"..." msgstr "" #: info/session.c:2896 #, c-format msgid "Searching subfile \"%s\"..." msgstr "" #: info/session.c:2946 msgid "Read a string and search for it" msgstr "" #: info/session.c:2966 #, c-format msgid "%s for string [%s]: " msgstr "" #: info/session.c:2967 msgid "Search backward" msgstr "" #: info/session.c:2967 msgid "Search" msgstr "" #: info/session.c:2994 msgid "Search failed." msgstr "" #: info/session.c:3020 info/session.c:3026 msgid "Search interactively for a string as you type it" msgstr "" #: info/session.c:3120 msgid "I-search backward: " msgstr "" #: info/session.c:3122 msgid "I-search: " msgstr "" #: info/session.c:3147 msgid "Failing " msgstr "" #: info/session.c:3512 msgid "No cross references in this node." msgstr "" #: info/session.c:3579 msgid "Move to the previous cross reference" msgstr "" #: info/session.c:3588 msgid "Move to the next cross reference" msgstr "" #: info/session.c:3598 msgid "Select reference or menu item appearing on this line" msgstr "" #. **************************************************************** #. #. Miscellaneous Info Commands #. #. **************************************************************** #. What to do when C-g is pressed in a window. #: info/session.c:3620 msgid "Cancel current operation" msgstr "" #: info/session.c:3627 msgid "Quit" msgstr "" #: info/session.c:3636 msgid "Move to the cursor to a specific line of the window" msgstr "" #. Clear the screen and redraw its contents. Given a numeric argument, #. move the line the cursor is on to the COUNT'th line of the window. #: info/session.c:3668 msgid "Redraw the display" msgstr "" #. This command does nothing. It is the fact that a key is bound to it #. that has meaning. See the code at the top of info_session (). #: info/session.c:3705 msgid "Quit using Info" msgstr "" #: info/session.c:3728 #, c-format msgid "Unknown command (%s)." msgstr "" #: info/session.c:3733 msgid "\"\" is invalid" msgstr "" #: info/session.c:3735 #, c-format msgid "\"%s\" is invalid" msgstr "" #: info/session.c:3958 msgid "Add this digit to the current numeric argument" msgstr "" #: info/session.c:3967 msgid "Start (or multiply by 4) the current numeric argument" msgstr "" #: info/session.c:3982 msgid "Internally used by \\[universal-argument]" msgstr "" #: info/tilde.c:362 msgid "readline: Out of virtual memory!\n" msgstr "" #: info/variables.c:40 msgid "When \"On\", footnotes appear and disappear automatically" msgstr "" #: info/variables.c:44 msgid "When \"On\", creating or deleting a window resizes other windows" msgstr "" #: info/variables.c:48 msgid "When \"On\", flash the screen instead of ringing the bell" msgstr "" #: info/variables.c:52 msgid "When \"On\", errors cause the bell to ring" msgstr "" #: info/variables.c:56 msgid "When \"On\", Info garbage collects files which had to be uncompressed" msgstr "" #: info/variables.c:59 msgid "When \"On\", the portion of the matched search string is highlighted" msgstr "" #: info/variables.c:63 msgid "Controls what happens when scrolling is requested at the end of a node" msgstr "" #: info/variables.c:67 msgid "The number lines to scroll when the cursor moves out of the window" msgstr "" #: info/variables.c:71 msgid "When \"On\", Info accepts and displays ISO Latin characters" msgstr "" #: info/variables.c:77 msgid "Explain the use of a variable" msgstr "" #. Get the variable's name. #: info/variables.c:83 msgid "Describe variable: " msgstr "" #: info/variables.c:102 msgid "Set the value of an Info variable" msgstr "" #. Get the variable's name and value. #: info/variables.c:108 msgid "Set variable: " msgstr "" #: info/variables.c:126 #, c-format msgid "Set %s to value (%d): " msgstr "" #: info/variables.c:167 #, c-format msgid "Set %s to value (%s): " msgstr "" #: info/window.c:1102 msgid "--*** Tags out of Date ***" msgstr "" #. strlen (location_indicator). #. 10 for the decimal representation of the number of lines in this #. node, and the remainder of the text that can appear in the line. #: info/window.c:1113 msgid "-----Info: (), lines ----, " msgstr "" #: info/window.c:1120 #, c-format msgid "-%s---Info: %s, %d lines --%s--" msgstr "" #: info/window.c:1124 #, c-format msgid "-%s%s-Info: (%s)%s, %d lines --%s--" msgstr "" #: info/window.c:1131 #, c-format msgid " Subfile: %s" msgstr "" #: lib/getopt.c:672 #, c-format msgid "%s: option `%s' is ambiguous\n" msgstr "" #: lib/getopt.c:696 #, c-format msgid "%s: option `--%s' doesn't allow an argument\n" msgstr "" #: lib/getopt.c:701 #, c-format msgid "%s: option `%c%s' doesn't allow an argument\n" msgstr "" #: lib/getopt.c:718 lib/getopt.c:891 #, c-format msgid "%s: option `%s' requires an argument\n" msgstr "" #. --option #: lib/getopt.c:747 #, c-format msgid "%s: unrecognized option `--%s'\n" msgstr "" #. +option or -option #: lib/getopt.c:751 #, c-format msgid "%s: unrecognized option `%c%s'\n" msgstr "" #. 1003.2 specifies the format of this message. #: lib/getopt.c:777 #, c-format msgid "%s: illegal option -- %c\n" msgstr "" #: lib/getopt.c:780 #, c-format msgid "%s: invalid option -- %c\n" msgstr "" #. 1003.2 specifies the format of this message. #: lib/getopt.c:810 lib/getopt.c:940 #, c-format msgid "%s: option requires an argument -- %c\n" msgstr "" #: lib/getopt.c:857 #, c-format msgid "%s: option `-W %s' is ambiguous\n" msgstr "" #: lib/getopt.c:875 #, c-format msgid "%s: option `-W %s' doesn't allow an argument\n" msgstr "" #: makeinfo/makeinfo.c:893 #, c-format msgid "%s:%d: warning: " msgstr "" #: makeinfo/makeinfo.c:916 msgid "Too many errors! Gave up.\n" msgstr "" #: makeinfo/makeinfo.c:975 makeinfo/makeinfo.c:1000 makeinfo/makeinfo.c:1068 #, c-format msgid "%s: %s arg must be numeric, not `%s'.\n" msgstr "" #: makeinfo/makeinfo.c:989 #, c-format msgid "Couldn't open macro expansion output `%s'" msgstr "" #: makeinfo/makeinfo.c:992 msgid "Cannot specify more than one macro expansion output" msgstr "" #: makeinfo/makeinfo.c:1036 #, c-format msgid "%s: --paragraph-indent arg must be numeric/`none'/`asis', not `%s'.\n" msgstr "" #: makeinfo/makeinfo.c:1079 #, c-format msgid "%s: --footnote-style arg must be `separate' or `end', not `%s'.\n" msgstr "" #: makeinfo/makeinfo.c:1110 #, c-format msgid "%s: missing file argument.\n" msgstr "" #: makeinfo/makeinfo.c:1163 #, c-format msgid "Try `%s --help' for more information.\n" msgstr "" #: makeinfo/makeinfo.c:1165 #, c-format msgid "" "Usage: %s [OPTION]... TEXINFO-FILE...\n" "\n" "Translate Texinfo source documentation to a format suitable for reading\n" "with GNU Info.\n" "\n" "Options:\n" "-D VAR define a variable, as with @set.\n" "-E MACRO-OFILE process macros only, output texinfo source.\n" "-I DIR append DIR to the @include directory search path.\n" "-P DIR prepend DIR to the @include directory search path.\n" "-U VAR undefine a variable, as with @clear.\n" "--error-limit NUM quit after NUM errors (default %d).\n" "--fill-column NUM break lines at NUM characters (default %d).\n" "--footnote-style STYLE output footnotes according to STYLE:\n" " `separate' to place footnotes in their own node,\n" " `end' to place the footnotes at the end of\n" " the node in which they are defined (the default).\n" "--force preserve output even if errors.\n" "--help display this help and exit.\n" "--no-validate suppress node cross-reference validation.\n" "--no-warn suppress warnings (but not errors).\n" "--no-split suppress splitting of large files.\n" "--no-headers suppress node separators and Node: Foo headers.\n" "--output FILE, -o FILE output to FILE, and ignore any @setfilename.\n" "--paragraph-indent VAL indent paragraphs with VAL spaces (default %d).\n" " if VAL is `none', do not indent; if VAL is `asis',\n" " preserve any existing indentation.\n" "--reference-limit NUM complain about at most NUM references (default %d).\n" "--verbose report about what is being done.\n" "--version display version information and exit.\n" "\n" "Email bug reports to bug-texinfo@gnu.org.\n" msgstr "" #: makeinfo/makeinfo.c:1552 #, c-format msgid "%s: getwd: %s, %s\n" msgstr "" #: makeinfo/makeinfo.c:1748 #, c-format msgid "Expected `%s'" msgstr "" #: makeinfo/makeinfo.c:2082 #, c-format msgid "No `%s' found in `%s'" msgstr "" #: makeinfo/makeinfo.c:2132 #, c-format msgid "%s: Skipping macro expansion to stdout as Info output is going there.\n" msgstr "" #: makeinfo/makeinfo.c:2151 #, c-format msgid "Making %s file `%s' from `%s'.\n" msgstr "" #: makeinfo/makeinfo.c:2181 #, c-format msgid "This is Info file %s, produced by Makeinfo version %d.%d" msgstr "" #: makeinfo/makeinfo.c:2183 #, c-format msgid " from the input file %s.\n" msgstr "" #: makeinfo/makeinfo.c:2202 #, c-format msgid "" "%s: Removing macro output file `%s' due to errors; use --force to preserve.\n" msgstr "" #. If there were errors, and no --force, remove the output. #: makeinfo/makeinfo.c:2234 #, c-format msgid "%s: Removing output file `%s' due to errors; use --force to preserve.\n" msgstr "" #. Special case. I'm not supposed to see this character by itself. #. If I do, it means there is a syntax error in the input text. #. Report the error here, but remember this brace on the stack so #. you can ignore its partner. #: makeinfo/makeinfo.c:2374 makeinfo/makeinfo.c:7629 #, c-format msgid "Misplaced %c" msgstr "" #: makeinfo/makeinfo.c:2461 #, c-format msgid "Unknown command `%s'" msgstr "" #: makeinfo/makeinfo.c:2481 msgid "NO_NAME!" msgstr "" #: makeinfo/makeinfo.c:2495 #, c-format msgid "%c%s expected `{...}'" msgstr "" #: makeinfo/makeinfo.c:2528 msgid "Unmatched }" msgstr "" #: makeinfo/makeinfo.c:2576 #, c-format msgid "%c%s missing close brace" msgstr "" #: makeinfo/makeinfo.c:3372 msgid "Broken-Type in insertion_type_pname" msgstr "" #: makeinfo/makeinfo.c:3438 msgid "Enumeration stack overflow" msgstr "" #: makeinfo/makeinfo.c:3470 #, c-format msgid "lettering overflow, restarting at %c" msgstr "" #: makeinfo/makeinfo.c:3509 msgid "* Menu:\n" msgstr "" #: makeinfo/makeinfo.c:3593 #, c-format msgid "%s requires an argument: the formatter for %citem" msgstr "" #: makeinfo/makeinfo.c:3697 #, c-format msgid "`%cend' expected `%s', but saw `%s'" msgstr "" #: makeinfo/makeinfo.c:3810 #, c-format msgid "No matching `%cend %s'" msgstr "" #: makeinfo/makeinfo.c:3949 #, c-format msgid "How did @%s end up in cm_special_char?\n" msgstr "" #. This error message isn't perfect if the argument is multiple #. characters, but it doesn't seem worth getting right. #: makeinfo/makeinfo.c:3963 #, c-format msgid "%c%s expects `i' or `j' as argument, not `%c'" msgstr "" #: makeinfo/makeinfo.c:3967 #, c-format msgid "%c%s expects a single character `i' or `j' as argument" msgstr "" #: makeinfo/makeinfo.c:3979 msgid "January" msgstr "" #: makeinfo/makeinfo.c:3979 msgid "February" msgstr "" #: makeinfo/makeinfo.c:3979 msgid "March" msgstr "" #: makeinfo/makeinfo.c:3979 msgid "April" msgstr "" #: makeinfo/makeinfo.c:3979 msgid "May" msgstr "" #: makeinfo/makeinfo.c:3980 msgid "June" msgstr "" #: makeinfo/makeinfo.c:3980 msgid "July" msgstr "" #: makeinfo/makeinfo.c:3980 msgid "August" msgstr "" #: makeinfo/makeinfo.c:3980 msgid "September" msgstr "" #: makeinfo/makeinfo.c:3980 msgid "October" msgstr "" #: makeinfo/makeinfo.c:3981 msgid "November" msgstr "" #: makeinfo/makeinfo.c:3981 msgid "December" msgstr "" #: makeinfo/makeinfo.c:4039 #, c-format msgid "%c%s expects a single character as an argument" msgstr "" #: makeinfo/makeinfo.c:4153 #, c-format msgid "%c%s is obsolete" msgstr "" #: makeinfo/makeinfo.c:4325 #, c-format msgid "Node with %ctop as a section already exists" msgstr "" #: makeinfo/makeinfo.c:4337 #, c-format msgid "Here is the %ctop node" msgstr "" #: makeinfo/makeinfo.c:4356 #, c-format msgid "%ctop used before %cnode, defaulting to %s" msgstr "" #: makeinfo/makeinfo.c:4431 #, c-format msgid "%c%s is obsolete; use %c%s instead" msgstr "" #: makeinfo/makeinfo.c:4680 #, c-format msgid "Node `%s' multiply defined (line %d is first definition at)" msgstr "" #: makeinfo/makeinfo.c:4753 #, c-format msgid "Formatting node %s...\n" msgstr "" #: makeinfo/makeinfo.c:4802 #, c-format msgid "Node `%s' requires a sectioning command (e.g. %c%s)" msgstr "" #: makeinfo/makeinfo.c:5085 #, c-format msgid "Node `%s''s Next field not pointed back to" msgstr "" #: makeinfo/makeinfo.c:5090 #, c-format msgid "This node (`%s') is the one with the bad `Prev'" msgstr "" #: makeinfo/makeinfo.c:5130 #, c-format msgid "Node `%s's Prev field not pointed back to" msgstr "" #: makeinfo/makeinfo.c:5134 #, c-format msgid "This node (`%s') has the bad Next" msgstr "" #: makeinfo/makeinfo.c:5146 #, c-format msgid "Node `%s' missing Up field" msgstr "" #: makeinfo/makeinfo.c:5186 #, c-format msgid "`%s' has an Up field of `%s', but `%s' has no menu item for `%s'" msgstr "" #: makeinfo/makeinfo.c:5217 #, c-format msgid "node `%s' has been referenced %d times" msgstr "" #: makeinfo/makeinfo.c:5229 #, c-format msgid "unreferenced node `%s'" msgstr "" #: makeinfo/makeinfo.c:5256 #, c-format msgid "%s reference to nonexistent node `%s'" msgstr "" #: makeinfo/makeinfo.c:5668 makeinfo/makeinfo.c:5680 #, c-format msgid "%cmenu seen before first node" msgstr "" #: makeinfo/makeinfo.c:5669 makeinfo/makeinfo.c:5681 msgid "creating `Top' node" msgstr "" #: makeinfo/makeinfo.c:5794 #, c-format msgid "`.' or `,' must follow cross reference, not %c" msgstr "" #: makeinfo/makeinfo.c:5962 #, c-format msgid "@image file `%s' unreadable: %s" msgstr "" #: makeinfo/makeinfo.c:5966 msgid "@image missing filename argument" msgstr "" #: makeinfo/makeinfo.c:6067 #, c-format msgid "%s requires letter or digit" msgstr "" #: makeinfo/makeinfo.c:6152 #, c-format msgid "Unmatched `%c%s'" msgstr "" #: makeinfo/makeinfo.c:6159 #, c-format msgid "`%c%s' needs something after it" msgstr "" #: makeinfo/makeinfo.c:6165 #, c-format msgid "Bad argument to `%s', `%s', using `%s'" msgstr "" #: makeinfo/makeinfo.c:6338 #, c-format msgid "{No Value For \"%s\"}" msgstr "" #: makeinfo/makeinfo.c:6388 #, c-format msgid "%c%s requires a name" msgstr "" #: makeinfo/makeinfo.c:6496 #, c-format msgid "Reached eof before matching @end %s" msgstr "" #: makeinfo/makeinfo.c:6722 #, c-format msgid "The `%c%s' command is meaningless within a `@%s' block" msgstr "" #: makeinfo/makeinfo.c:6731 #, c-format msgid "%citemx is not meaningful inside of a `%s' block" msgstr "" #: makeinfo/makeinfo.c:6844 #, c-format msgid "%c%s found outside of an insertion block" msgstr "" #: makeinfo/makeinfo.c:6935 #, c-format msgid "Missing `}' in %cdef arg" msgstr "" #: makeinfo/makeinfo.c:7144 makeinfo/makeinfo.c:7164 msgid "Function" msgstr "" #: makeinfo/makeinfo.c:7148 msgid "Macro" msgstr "" #: makeinfo/makeinfo.c:7152 msgid "Special Form" msgstr "" #: makeinfo/makeinfo.c:7156 makeinfo/makeinfo.c:7168 msgid "Variable" msgstr "" #: makeinfo/makeinfo.c:7160 msgid "User Option" msgstr "" #: makeinfo/makeinfo.c:7172 msgid "Instance Variable" msgstr "" #: makeinfo/makeinfo.c:7176 makeinfo/makeinfo.c:7180 msgid "Method" msgstr "" #: makeinfo/makeinfo.c:7335 #, c-format msgid "Must be in a `%s' insertion in order to use `%s'x" msgstr "" #: makeinfo/makeinfo.c:7407 #, c-format msgid "%csp requires a positive numeric argument" msgstr "" #: makeinfo/makeinfo.c:7650 msgid "asis" msgstr "" #: makeinfo/makeinfo.c:7652 msgid "none" msgstr "" #: makeinfo/makeinfo.c:7674 #, c-format msgid "Bad argument to %c%s" msgstr "" #: makeinfo/makeinfo.c:7966 #, c-format msgid "Unknown index `%s'" msgstr "" #: makeinfo/makeinfo.c:8031 #, c-format msgid "Index `%s' already exists" msgstr "" #: makeinfo/makeinfo.c:8062 #, c-format msgid "Unknown index `%s' and/or `%s' in @synindex" msgstr "" #: makeinfo/makeinfo.c:8251 #, c-format msgid "Unknown index `%s' in @printindex" msgstr "" #: makeinfo/makeinfo.c:8266 msgid "" "* Menu:\n" "\n" msgstr "" #: makeinfo/makeinfo.c:8453 #, c-format msgid "`%c%s' needs an argument `{...}', not just `%s'" msgstr "" #: makeinfo/makeinfo.c:8468 #, c-format msgid "No closing brace for footnote `%s'" msgstr "" #: makeinfo/makeinfo.c:8507 msgid "Footnote defined without parent node" msgstr "" #: makeinfo/makeinfo.c:8539 msgid "-Footnotes" msgstr "" #: makeinfo/makeinfo.c:8594 msgid "" "---------- Footnotes ----------\n" "\n" msgstr "" #: makeinfo/makeinfo.c:8690 #, c-format msgid "macro `%s' previously defined" msgstr "" #: makeinfo/makeinfo.c:8694 #, c-format msgid "here is the previous definition of `%s'" msgstr "" #: makeinfo/makeinfo.c:8908 #, c-format msgid "Macro `%s' called with too many args" msgstr "" #: makeinfo/makeinfo.c:9060 #, c-format msgid "%cend macro not found" msgstr "" #: makeinfo/makeinfo.c:9100 #, c-format msgid "%cquote-arg only useful when the macro takes a single argument" msgstr "" #: makeinfo/multi.c:206 #, c-format msgid "ignoring stray text `%s' after @multitable" msgstr "" #: makeinfo/multi.c:277 #, c-format msgid "Too many columns in multitable item (max %d)" msgstr "" #. impossible, I think. #: makeinfo/multi.c:304 msgid "multitable item not in active multitable" msgstr "" #: makeinfo/multi.c:313 #, c-format msgid "Cannot select column #%d in multitable" msgstr "" #: makeinfo/multi.c:404 msgid "ignoring @tab outside of multitable" msgstr "" #: makeinfo/multi.c:428 msgid "** Multicolumn output from last row:\n" msgstr "" #: makeinfo/multi.c:431 #, c-format msgid "* column #%d: output = %s\n" msgstr "" #: util/install-info.c:123 util/install-info.c:136 msgid "virtual memory exhausted" msgstr "" #: util/install-info.c:192 #, c-format msgid "%s: warning: " msgstr "" #: util/install-info.c:213 #, c-format msgid " for %s" msgstr "" #: util/install-info.c:282 #, c-format msgid "\tTry `%s --help' for a complete list of options.\n" msgstr "" #: util/install-info.c:290 #, c-format msgid "" "Usage: %s [OPTION]... [INFO-FILE [DIR-FILE]]\n" "\n" "Install INFO-FILE in the Info directory file DIR-FILE.\n" "\n" "Options:\n" "--delete Delete existing entries in INFO-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" "\n" "Email bug reports to bug-texinfo@gnu.org.\n" msgstr "" #: util/install-info.c:341 msgid "" "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" "\n" "File: dir,\tNode: Top,\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" "* Menu:\n" msgstr "" #: util/install-info.c:364 #, c-format msgid "%s: could not read (%s) and could not create (%s)\n" msgstr "" #: util/install-info.c:464 util/install-info.c:474 #, c-format msgid "%s: Specify the Info directory only once.\n" msgstr "" #: util/install-info.c:502 #, c-format msgid "%s: Specify the Info file only once.\n" msgstr "" #: util/install-info.c:550 #, c-format msgid "excess command line argument `%s'" msgstr "" #: util/install-info.c:554 msgid "No input file specified; try --help for more information." msgstr "" #: util/install-info.c:556 msgid "No dir file specified; try --help for more information." msgstr "" #: util/install-info.c:608 util/install-info.c:631 msgid "START-INFO-DIR-ENTRY without matching END-INFO-DIR-ENTRY" msgstr "" #: util/install-info.c:627 msgid "END-INFO-DIR-ENTRY without matching START-INFO-DIR-ENTRY" msgstr "" #. 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. #: util/install-info.c:641 #, c-format msgid "no info dir entry in `%s'" msgstr "" #: util/install-info.c:852 #, c-format msgid "menu item `%s' already exists, for file `%s'" msgstr "" #: util/install-info.c:875 #, c-format msgid "no entries found for `%s'; nothing deleted" msgstr "" #: util/texindex.c:253 msgid "keep temporary files around after processing" msgstr "" #: util/texindex.c:255 msgid "do not keep temporary files around after processing (default)" msgstr "" #: util/texindex.c:257 msgid "send output to FILE" msgstr "" #: util/texindex.c:259 msgid "display version information and exit" msgstr "" #: util/texindex.c:261 msgid "display this help and exit" msgstr "" #: util/texindex.c:272 #, c-format msgid "Usage: %s [OPTION]... FILE...\n" msgstr "" #: util/texindex.c:273 msgid "Generate a sorted index for each TeX output FILE.\n" msgstr "" #. Avoid trigraph nonsense. #: util/texindex.c:275 msgid "Usually FILE... is `foo.??' for a document `foo.texi'.\n" msgstr "" #: util/texindex.c:276 msgid "" "\n" "Options:\n" msgstr "" #: util/texindex.c:290 msgid "" "\n" "Email bug reports to bug-texinfo@gnu.org." msgstr "" #: util/texindex.c:917 util/texindex.c:951 util/texindex.c:1027 #: util/texindex.c:1055 #, c-format msgid "%s: not a texinfo index file" msgstr "" #: util/texindex.c:1012 #, c-format msgid "failure reopening %s" msgstr "" #: util/texindex.c:1325 #, c-format msgid "entry %s follows an entry with a secondary name" msgstr "" #: util/texindex.c:1663 #, c-format msgid "%s; for file `%s'.\n" msgstr "" #: util/texindex.c:1724 #, c-format msgid "Virtual memory exhausted in %s ()! Needed %d bytes." msgstr "" texinfo-3.12/po/de.gmo0000664000175000017500000012267306477056755012125 0ustar ggÞ•UÄ Él1‘ŽÃ,R* ª5µ ëø !/?-U6ƒ.º(é"#F_t0Š»>Ù) *B m ~ ‡ ¡ À Õ ê %û 1!!S!&o!@–!D×!L"Fi"F°"*÷"%"#2H#{#—# ´#Â#Ó#ç# ð#ú#%$#;$_$$8š$!Ó$õ$ %% <%)]%.‡%¶%¼%Ã%&Ø%ÿ%&6&E&^& w&+˜&Ä&Ö&ì&'& '3G'F{'äÂ'"§(!Ê()ì())&8)%_)…)Ÿ)²)Ã)×);ì)(*8.*g*|* —*¥*Ã*Ì* Õ*á*ú* ++$4+ Y+z+=‘+2Ï+ ,J, [,Bg,ª,Ç,|Þ,'[-ƒ- —-¢-¼- Ì-Ú-ñ-.".(8.a.i.n.s.„."—."º.Ý.!ì./*/+D/$p/E•/Û/û/00 0 "0/0H0b0+w0£0¾0×0,ë031L1h1…1 ¢1$Ã1è12%2%D2j2‡2¥2"Á21ä2 373 P3#q3•3"«3Î3!Ý37ÿ374I49[4•4¬4 »4Ü4;÷4335*g5)’5+¼5 è5õ5þ5696Q6m6ƒ66¢6#²63Ö66 7&A7$h77¬7%Ì70ò7#8868o8‹8ª8È8æ8þ8990$9U9Co94³9è9ÿ9:"+:(N:!w:&™:À:×:"ï:;-;C;Y;r; ;™;°;Ç;&ã;! <,<>;<z<Š<5£<6Ù<5=BF= ‰=#ª=Î=î=( >86>o>!Ž@/°@#à@7A,žU(ÝU7V7>VBvV¹VÌVáVúV'W/b,tb1¡bOÓbN#cbrc\ÕcX2d)‹d#µd@Ùde3e Pe^eoe„e e—e.³e$âe f(fF@f"‡fªf Çf"Ñf'ôf=g8Zg“g™g g8½gögh1hIh gh2ˆh.»hêhi+ iLi;hi6¤iQÛiø-j.&k#Uk7yk±kºk%×k$ýk"l‰%Y‰‰‰ ¶‰³׉‹‘^˜ìœAüœ4>s3“qÇD9žI~ž]Èž<&ŸFcŸ@ªŸJëŸ6 J c !z 'œ ?Ä "¡''¡LO¡œ¡2¸¡ë¡ñ¡ ¢!¢E:¢5€¢,¶¢!ã¢-£/3£1c£4•£3Ê£ þ£0¤ P¤6Z¤‘¤1ª¤%ܤ%¥(¥-¥L¥$h¥¥¦¥™ë{<¨/ƒ·UøÍ ”Æ%âI‹$LBF6Œý+Fð5’W+K~—-ÇC¹[h$Žp–ñP ‚oÔ‡6•2ÛU.©}O"­íq¸f«R#H -(>)#×ï,ìÁQ?nÎö»)GÂê'MV3ßTš ˆ1E§Ò ¡A¯ ²@k‘("ù¼Rå¦ç|æz`j1Ъ!„M=Ùwèe/:†÷ÌÖGÏP* S* ¤g2vlÅ047mÿiþrõ›HAN<Õó.Ü @8ua7î¬c]JdCy%BN?Iá>®3X,EÚTJ'Ýô5œü…´Ñ&ÀË!_ãx°t£K˜µDYs³Þ¢&‰ºÓò4ûÊ=ŠÉ8¥Ä à ¾;¿ÃS9bDLZú“¶½:é; QÈO09±\ØŸž^€ä Try `%s --help' for a complete list of options. * Menu: (File)Node Lines Size Containing File ---------- ----- ---- --------------- * Menu: Nodes whoses indices contain "%s": Email bug reports to bug-texinfo@gnu.org. Options: Source files groveled to make this file include: Subfile: %s for %s from the input file %s. times"" is invalid"%s" is invalid%c%s expected `{...}'%c%s expects `i' or `j' as argument, not `%c'%c%s expects a single character `i' or `j' as argument%c%s expects a single character as an argument%c%s found outside of an insertion block%c%s is obsolete%c%s is obsolete; use %c%s instead%c%s missing close brace%c%s requires a name%cend macro not found%citemx is not meaningful inside of a `%s' block%cmenu seen before first node%cquote-arg only useful when the macro takes a single argument%csp requires a positive numeric argument%ctop used before %cnode, defaulting to %s%d completions: %d times%s can be invoked via %s.%s can only be invoked via %s.%s for string [%s]: %s is defined to %s.%s is undefined.%s reference to nonexistent node `%s'%s requires an argument: the formatter for %citem%s requires letter or digit%s: %s arg must be numeric, not `%s'. %s: --footnote-style arg must be `separate' or `end', not `%s'. %s: --paragraph-indent arg must be numeric/`none'/`asis', not `%s'. %s: Removing macro output file `%s' due to errors; use --force to preserve. %s: Removing output file `%s' due to errors; use --force to preserve. %s: Skipping macro expansion to stdout as Info output is going there. %s: Specify the Info directory only once. %s: Specify the Info file only once. %s: could not read (%s) and could not create (%s) %s: missing file argument. %s: not a texinfo index file%s: warning: %s:%d: warning: %s; for file `%s'. * Menu: * Menu: * column #%d: output = %s ** Multicolumn output from last row: -%s%s-Info: (%s)%s, %d lines --%s---%s---Info: %s, %d lines --%s----*** Tags out of Date ***--- Use `\[history-node]' or `\[kill-node]' to exit --- ---------- Footnotes ---------- -----Info: (), lines ----, -Footnotes@image file `%s' unreadable: %s@image missing filename argumentAccept (or force completion of) this lineAdd this digit to the current numeric argumentAprilAugustBad argument to %c%sBad argument to `%s', `%s', using `%s'Basic Commands in Info WindowsBuilding completions...CAN'T SEE THISCancel current operationCancel or quit operationCannot delete a permanent windowCannot execute an `echo-area' command here.Cannot find "%s".Cannot kill node `%s'Cannot kill the last nodeCannot open pipe to "%s".Cannot select column #%d in multitableCannot specify more than one macro expansion outputControls what happens when scrolling is requested at the end of a nodeCopyright (C) %s 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. Could not create output file "%s".Couldn't manipulate the file %s. Couldn't open macro expansion output `%s'DecemberDelete all other windowsDelete the character behind the cursorDelete the character under the cursorDelete the current windowDescribe command: Describe key: %sDescribe variable: Display help messageDivide the available screen space among the visible windowsDone.END-INFO-DIR-ENTRY without matching START-INFO-DIR-ENTRYESC %s is undefined.Enumeration stack overflowExpected `%s'Explain the use of a variableFailing FebruaryFind file: Finding index entries...Follow xref (%s): Follow xref: Following "Next" node...Footnote defined without parent nodeFootnotes could not be displayedFormatting node %s... Found "%s" in %s. (`\[next-index-match]' tries to find next.)Generate a sorted index for each TeX output FILE. Get Manpage: Go to the next matching index item from the last `\[index-search]' commandGoto Node: Grovel all known info file's indices for a string and build a menuGrow (or shrink) this windowHere is the %ctop nodeHere is the menu of nodes you have recently visited. Select one from this menu, or use `\[history-node]' in another window. How did @%s end up in cm_special_char? I-search backward: I-search: Index `%s' already existsIndex apropos: Index entry: Insert a TAB characterInsert completionInsert next character verbatimInsert this characterInternally used by \[universal-argument]JanuaryJulyJuneKill node (%s): Kill ring is emptyKill the word following the cursorKill the word preceding the cursorKill this nodeKill to the beginning of the lineKill to the end of the lineList possible completionsLook up a string in the index for this fileMacro `%s' called with too many argsMake a window containing a menu of all of the currently visited nodesMaking %s file `%s' from `%s'. MarchMayMenu item (%s): Menu item: Misplaced %cMissing `}' in %cdef argMove backward a characterMove backward a wordMove backwards or up through node structureMove down to the next lineMove forward a characterMove forward a wordMove forwards or down through node structureMove to the cursor to a specific line of the windowMove to the end of the lineMove to the end of this lineMove to the end of this nodeMove to the next cross referenceMove to the previous cross referenceMove to the start of the lineMove to the start of this lineMove to the start of this nodeMove to the start of this node's menuMove up to the previous lineMoving "Prev" in this window.Moving "Up" in this window.Moving to "Prev"'s last menu item.Must be in a `%s' insertion in order to use `%s'xNo "Next" pointer for this node.No "Prev" for this node.No "Prev" or "Up" for this node.No %sindex entries containing "%s".No `%s' found in `%s'No closing brace for footnote `%s'No completionsNo cross references in this node.No dir file specified; try --help for more information.No index entries.No indices found.No input file specified; try --help for more information.No matching `%cend %s'No more nodes.No previous index search string.Node `%s' missing Up fieldNode `%s' multiply defined (line %d is first definition at)Node `%s' requires a sectioning command (e.g. %c%s)Node `%s''s Next field not pointed back toNode `%s's Prev field not pointed back toNode with %ctop as a section already existsNot completeNovemberOctoberOne completion: Pipe the contents of this node through INFO_PRINT_COMMANDPrint documentation for KEYPrinting node "%s"...Printing node "(%s)%s"...QuitQuit using InfoReached eof before matching @end %sRead a command name in the echo area and execute itRead a footnote or cross reference and select its nodeRead a manpage reference and select itRead a menu item and select its nodeRead a node name and select itRead a string and search for itRead the name of a file and select itRead the name of an Info command and describe itRedraw the displaySTART-INFO-DIR-ENTRY without matching END-INFO-DIR-ENTRYScanning indices of "%s"...Scroll backward in this windowScroll forward in this windowScroll the completions windowScroll the other windowSearchSearch backwardSearch failed.Search interactively for a string as you type itSearching subfile "%s"...Select a node which has been previously visited in a visible windowSelect reference or menu item appearing on this lineSelect the `Next' nodeSelect the `Prev' nodeSelect the `Up' nodeSelect the first node in this fileSelect the last item in this node's menuSelect the last node in this fileSelect the most recently selected nodeSelect the next windowSelect the node `(dir)'Select the node `Top' in this fileSelect the previous windowSelect this menu itemSelect visited node: Selecting "Next" node...Selecting first menu item...SeptemberSet %s to value (%d): Set %s to value (%s): Set screen height to (%d): Set the height of the displayed windowSet the value of an Info variableSet variable: Show the footnotes associated with this node in another windowSole completionSplit the current windowStart (or multiply by 4) the current numeric argumentThe `%c%s' command is meaningless within a `@%s' blockThe following commands can only be invoked via M-x: The number lines to scroll when the cursor moves out of the windowThe reference disappeared! (%s).There aren't %d items in this menu.There is no function named `%s'There is no menu in this node.There is no menu item "%s" in this node.This is Info file %s, produced by Makeinfo version %d.%dThis is the file .../info/dir, which contains the topmost node of the Info hierarchy, called (dir)Top. The first time you invoke Info you start off looking at this node.  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 manual, etc. In Emacs, you can click mouse button 2 on a menu item or cross reference to select it. * Menu: This node (`%s') has the bad NextThis node (`%s') is the one with the bad `Prev'This window has no additional nodesToggle the state of line wrapping in the current windowToo many columns in multitable item (max %d)Too many errors! Gave up. TopTranspose characters at pointTry --help for more information.Try `%s --help' for more information. Unable to find the node referenced by "%s".Unknown command (%s).Unknown command `%s'Unknown index `%s'Unknown index `%s' and/or `%s' in @synindexUnknown index `%s' in @printindexUnmatched `%c%s'Unmatched }Usage: %s [OPTION]... FILE... Usage: %s [OPTION]... TEXINFO-FILE... Translate Texinfo source documentation to a format suitable for reading with GNU Info. Options: -D VAR define a variable, as with @set. -E MACRO-OFILE process macros only, output texinfo source. -I DIR append DIR to the @include directory search path. -P DIR prepend DIR to the @include directory search path. -U VAR undefine a variable, as with @clear. --error-limit NUM quit after NUM errors (default %d). --fill-column NUM break lines at NUM characters (default %d). --footnote-style STYLE output footnotes according to STYLE: `separate' to place footnotes in their own node, `end' to place the footnotes at the end of the node in which they are defined (the default). --force preserve output even if errors. --help display this help and exit. --no-validate suppress node cross-reference validation. --no-warn suppress warnings (but not errors). --no-split suppress splitting of large files. --no-headers suppress node separators and Node: Foo headers. --output FILE, -o FILE output to FILE, and ignore any @setfilename. --paragraph-indent VAL indent paragraphs with VAL spaces (default %d). if VAL is `none', do not indent; if VAL is `asis', preserve any existing indentation. --reference-limit NUM complain about at most NUM references (default %d). --verbose report about what is being done. --version display version information and exit. Email bug reports to bug-texinfo@gnu.org. Usage: %s [OPTION]... [INFO-FILE [DIR-FILE]] Install INFO-FILE in the Info directory file DIR-FILE. Options: --delete Delete existing entries in INFO-FILE; don't insert any new entries. --dir-file=NAME Specify file name of Info directory file. This is equivalent to using the DIR-FILE argument. --entry=TEXT Insert TEXT as an Info directory entry. TEXT should have the form of an Info menu item line plus zero or more extra lines starting with whitespace. If you specify more than one entry, they are all added. If you don't specify any entries, they are determined from information in the Info file itself. --help Display this help and exit. --info-file=FILE Specify Info file to install in the directory. This is equivalent to using the INFO-FILE argument. --info-dir=DIR Same as --dir-file=DIR/dir. --item=TEXT Same as --entry TEXT. An Info directory entry is actually a menu item. --quiet Suppress warnings. --remove Same as --delete. --section=SEC Put this file's entries in section SEC of the directory. If you specify more than one section, all the entries are added in each of the sections. If you don't specify any sections, they are determined from information in the Info file itself. --version Display version information and exit. Email bug reports to bug-texinfo@gnu.org. Usage: %s [OPTION]... [INFO-FILE [MENU-ITEM...]] Read documentation in Info format. For more complete documentation on how to use Info, run `info info options'. Options: --directory DIR add DIR to INFOPATH. --dribble FILENAME remember user keystrokes in FILENAME. --file FILENAME specify Info file to visit. --node NODENAME specify nodes in first visited Info file. --output FILENAME output selected nodes to FILENAME. --restore FILENAME read initial keystrokes from FILENAME. --subnodes recursively output menu items. --help display this help and exit. --version display version information and exit. The first argument, if present, is the name of the Info file to read. Any remaining arguments are treated as the names of menu items in the initial node visited. For example, `info emacs buffers' moves to the node `buffers' in the info file `emacs'. Email bug reports to bug-texinfo@gnu.org.User OptionUsually FILE... is `foo.??' for a document `foo.texi'. Virtual memory exhausted in %s ()! Needed %d bytes.Visit Info node `(info)Help'Visit as many menu items at once as possibleWelcome to Info version %s. "\[get-help-window]" for help, "\[menu-item]" for menu item.When "On", Info accepts and displays ISO Latin charactersWhen "On", Info garbage collects files which had to be uncompressedWhen "On", creating or deleting a window resizes other windowsWhen "On", errors cause the bell to ringWhen "On", flash the screen instead of ringing the bellWhen "On", footnotes appear and disappear automaticallyWhen "On", the portion of the matched search string is highlightedWhere is command: Writing node "%s"...Writing node "(%s)%s"...Yank back a previous killYank back the contents of the last kill`%c%s' needs an argument `{...}', not just `%s'`%c%s' needs something after it`%cend' expected `%s', but saw `%s'`%s' has an Up field of `%s', but `%s' has no menu item for `%s'`%s' is not on any keys`.' or `,' must follow cross reference, not %casiscreating `Top' nodedisplay this help and exitdisplay version information and exitdo not keep temporary files around after processing (default)entry %s follows an entry with a secondary nameexcess command line argument `%s'failure reopening %shere is the previous definition of `%s'ignoring @tab outside of multitableignoring stray text `%s' after @multitablekeep temporary files around after processinglettering overflow, restarting at %cmacro `%s' previously definedmenu item `%s' already exists, for file `%s'more multitable item not in active multitableno entries found no entries found for `%s'; nothing deletedno info dir entry in `%s'node `%s' has been referenced %d timesnonereadline: Out of virtual memory! send output to FILEunreferenced node `%s'virtual memory exhausted{No Value For "%s"}Project-Id-Version: texinfo 3.11 POT-Creation-Date: 1998-03-03 13:32-0500 PO-Revision-Date: 1998-02-28 14:32+01:00 Last-Translator: Karl Eichwalder Language-Team: German MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8-bit »%s --help« gibt weitere Informationen. * Menü: (Datei)Knoten Zeilen Größe Beinhaltet Datei ------------- ------ ----- ---------------- * Menü: Nodes, deren Indices »%s« beinhalten: Fehler ("bugs") bitte an melden. Für die deutsche Übersetzung ist die Mailingliste zuständig. Optionen: Quelldatei "groveled", damit diese Datei enthält: Unterdatei: %s für %s aus der Eingabe-Datei %s. mal"" ist ungültig"%s" ist ungültig%c%s erwartete »{...}«%c%s erwartet »i« oder »j« als Argument, nicht »%c«%c%s erwartet einen einzigen Buchstaben »i« oder »j« als Argument%c%s erwartet einen einzigen Buchstaben als Argument%c%s außerhalb eines Einfügungsblocks gefunden%c%s ist obsolet%c%s ist obsolet; stattdessen %c%s benutzen%c%s fehlende schließende Klammer%c%s erfordert einen Namen»%cend«-Macro nicht gefunden%citemx ist nicht sinnvoll innerhalb eines »@%s«-Blocks%cmenu festgestellt, bevor der erste Knoten definiert wurde»%cquote«-Argument ist nur sinnvoll, wenn das Macro ein einziges Argument hat»%csp« erfordert ein positives numerisches Argument%ctop vor %cnode gebraucht, als Standard %s genommen%d Vervollständigungen: %d mal%s kann via %s aufgerufen werden.%s kann nur via %s aufgerufen werden.%s nach Zeichenkette [%s]: %s ist definiert als %s.%s ist nicht definiert.Verweis %s auf den nicht existierenden Knoten »%s«%s erfordert ein Argument: der Formatierer für %citem%s erfordert einen Buchstaben oder eine Zahl%s: %s Argument muss numerisch sein, nicht »%s«. %s: Argument für --footnote-style muss »separate« oder »end« sein, nicht »%s«. %s: Arg für --paragraph-indent muss numerisch/»none«/»asis« sein, nicht »%s«. %s: Entferne Macro-Ausgabe-Datei »%s« wegen der Fehler; --force benutzen, um diese beizubehalten. %s: Entferne Ausgabe-Datei »%s« wegen der Fehler; --force benutzen, um diese beizubehalten. %s: Macro-Auflösung nach der Standard-Ausgabe, da auch die Info-Ausgabe nach dort geht. %s: Info-Verzeichnis nur einmal angeben. %s: Info-Datei nur einmal angeben. %s: kann nicht gelesen (%s) und kann nicht angelegt werden (%s) %s: Datei-Angabe fehlt. %s: keine Texinfo-Indexdatei%s: Warnung: %s:%d: Warnung: %s; für Datei »%s«. * Menü: * Menü: * Spalte #%d: Ausgabe = %s ** Mehrspalten-Ausgabe von der letzten Zeile: -%s%s-Info: (%s)%s, %d Zeilen --%s---%s---Info: %s, %d Zeilen --%s----*** Tags veraltet ***--- »\[history-node]« oder »\[kill-node]« benutzen, um zu beenden --- ----------- Fußnoten ----------- -----Info: (), Zeilen ----, -Fußnoten@image-Datei »%s« nicht lesbar: %s@image fehlt als Argument ein DateinameAkzeptiere diese Zeile (oder erzwinge ihre Vervollständigung)Diese Zahl dem aktuellen numerischen Argument hinzufügenAprilAugustFalsches Argument für »%c%s«Falsches Argument für »%s«, »%s«, wenn »%s« benutzt wirdGrundbefehle in Info-FensternBilde Vervollständigungen...DIES IST NICHT ZU SEHENMomentane Operation abbrechenOperation abbrechen oder beendenEin permanentes Fenster kann nicht gelöscht werdenKann hier keinen »echo-area«-Befehl ausführen.Kann »%s« nicht finden.Kann Knoten »%s« nicht killenDer letzte Knoten kann nicht gekillt werdenKann nicht nach »%s« pipen.Spalte #%d kann in der "multitable" nicht ausgewählt werdenMehr als eine Ausgabedatei darf nicht angegeben werdenKontrolliert, was passiert, wenn »scrollen« am Ende eines Knotens veranlasst wirdCopyright © %s Free Software Foundation, Inc. Dies ist freie Software; in den Quellen befindet sich die Lizenz- und Kopierbedingung. Es gibt KEINERLEI Garantie, nicht einmal für die TAUGLICHKEIT oder die VERWENDBARKEIT ZU EINEM ANGEGEBENEN ZWECK. Ausgabe-Datei »%s« kann nicht angelegt werden.Datei »%s« ist nicht zu verändern. Die Macro-Auflösung für »%s« kann nicht geöffnet werdenDezemberAlle anderen Fenster löschenDas Zeichen hinter dem Cursor löschenDas Zeichen unter dem Cursor löschenAktuelles Fenster löschenBeschreibe den Befehl: Beschreibe Taste: %sBeschreibe Variable: Diesen Hilfe-Text anzeigenDen vorhandenen Bildschirmplatz unter allen sichtbaren Fenstern aufteilenFertig.END-INFO-DIR-ENTRY ohne START-INFO-DIR-ENTRYESC %s ist nicht definiert.Nummerierungsstack-ÜberlaufErwartet »%s«Den Zweck einer Variablen erklärenFehlgeschlagen FebruarDatei finden: Suche Index-Einträge...Folge xref (%s): Folge xref: »Next«-Knoten folgend...Fußnote definiert ohne einen Eltern-"node"Fußnoten können nicht angezeigt werdenFormatiere Knoten %s... »%s« in %s gefunden. (»\[next-index-match]« versucht nächsten Eintrag zu finden.)Erzeuge einen sortierten Index für jede TeX-Ausgabedatei. Hole Manpage: Geh zum nächsten übereinstimmenden Index-Eintrag vom letzten »\[index-search]«-BefehlGehe nach Knoten: Durchsuche durch alle bekannten Info-Datei-Indices nach einer Zeichenkette und bilde ein MenüAktuelles Fenster vergrößern (oder verkleinern)Hier ist der Knoten %ctopHier ist das Menü der Knoten, die zuetzt besucht wurden. Einen von diesem Menü auswählen oder »\[history-node]« im anderen Fenster benutzen. Zu was führt @%s in cm_special_char? Interactive Suche rückwarts: Interactive SucheIndex »%s« ist schon vorhandenIndex apropos: Index-Eintrag: Ein TAB-Zeichen eingebenVervollständigung einfügenDas nächste Zeichen wörtlich eingebenDieses Zeichen eingebenIntern gebraucht von \[universal-argument]JanuarJuliJuniKille Knoten (%s): Der Kill-Ring ist leerDas dem Cursor folgende Wort killenDas dem Cursor vorangehende Wort killenDiesen Knoten killenBis zum Anfang der Zeile killenBis zum Ende der Zeile killenMögliche Vervollständigungen listenSieh eine Zeichenkette im Index dieser Datei nachMacro »%s« mit zu vielen Argumenten aufgerufenVeranlassen, dass ein Fenster ein Menü aller aktuell besuchten Knoten enthältErzeuge %s Datei »%s« von »%s«. MärzMaiMenüpunkt (%s): Menüpunkt: Fehlplazierte %cFehlende »}« in »%cdef«-ArgumentEin Zeichen rückwärts bewegenEin Wort rückwärts bewegenZurück oder aufwärts durch die Knotenstruktur bewegenEine Zeile nach unten bewegenEin Zeichen vorwärts bewegenEin Wort vorwärts bewegenVorwärts oder abwärts durch die Knotenstruktur bewegenDen Cursor nach einer bestimmten Zeile des Fensters bewegenZum Ende dieser Zeile bewegenZum Ende dieser Zeile bewegenZum Ende dieses Knotens bewegenZum nächsten Querverweis bewegenZum vorigen Querverweis bewegenZum Anfang der Zeile bewegenZum Anfang dieser Zeile bewegenZum Anfang dieses Knotens bewegenZum Anfang des Menüs dieses Knotens bewegenEine Zeile nach oben bewegenNach »Prev« in diesem Fenster bewegen.Nach »Up« in diesem Fenster bewegen.Nach dem letzten Menüpunkt von »Prev« bewegen.Muss in einer »%s«-Einfügung sein, wenn »%s«x benutzt werden sollKein »Next«-Verweis bei diesem Knoten.Kein »Prev« bei diesem Knoten.Kein »Prev« oder »Up« bei diesem Knoten.Keine %sIndex-Einträge beinhalten »%s«.Kein »%s« in »%s« gefundenKeine schließende Klammer für Fußnote »%s«Keine VervollständigungenKeine Querverweise in diesem Knoten.Keine dir-Datei angegeben; »--help« gibt weitere Informationen.Keine Index-Einträge.Keine Indices gefunden.Keine Eingabe-Datei angegeben; »--help« gibt weitere Informationen.Nicht übereinstimmende »%cend %s«Keine "Nodes" mehrKeine vorangehende zu suchende Index-Zeichenkette.Dem Knoten »%s« fehlt ein "Up field"Knoten »%s« mehrfach definiert (in Zeile %d ist erste Definition)Knoten »%s« erfordert eine Abschnitt-Angabe (z.B. %c%s)"Next field" des Knotens »%s« verweist nicht zurück nachDas "Prev field" des Knotens »%s« verweist nicht zurück nachKonoten mit %ctop als Abschnitt existiert bereitsNicht vollständigNovemberOktoberEine Vervollständigung: Den Inhalt dieses Knotens durch INFO_PRINT_COMMAND pipenDokumentation für KEY ausgebenDrucke Knoten »%s«...Drucke Knoten »(%s)%s«...EndeInfo beendenDas Ende der Datei vor dem erforderlichen @end %s erreichtLies einen Befehlsnamen in der »Echo-Area« und führe ihn ausFußnote oder Querverweis lesen und den Konote auswählenEinen Verweis auf eine Manpage lesen und diese auswählenEinen Menüpunkt lesen und seinen Knoten auswählenDen Namen eines Knotens lesen und diesen auswählenEine Zeichenkette einlesen und danach suchenDen Namen einer Datei lesen und diese auswählenLese den Namen eines Info-Befehls und beschreibe ihnAnzeige erneut darstellenSTART-INFO-DIR-ENTRY ohne END-INFO-DIR-ENTRYIndex von »%s« wird durchsucht...In diesem Fenster rückwärts »scrollen«In diesem Fenster vorwärts »scrollen«Vervollständigungs-Fenster »scrollen«Das andere Fenster »scrollen«SucheSuche rückwärtsSuche fehlgeschlagen.Interaktiv nach einer Zeichenkette während der Eingabe suchenUnterdatei »%s« wird durchsucht...Einen Knoten auswählen, der zuvor in einem sichtbaren Fenster besucht wurdeVerweis oder Menüpunkt auswählen, der auf dieser Zeile erscheintDen »Next«-Knoten auswählenDen »Prev«-Knoten auswählenDen »Up«-Knoten auswählenDen ersten Knoten dieser Datei auswählenDen letzten Punkt des Menüs dieses Knotens auswählenDen letzten Knoten dieser Datei auswählenDen zuletzt gewählten Knoten auswählenDas nächste Fenster auswählenDen Knoten »(dir)« auswählenDen Knoten »Top« dieser Datei auswählenDas vorige Fenster auswählenDiesen Menüpunkt auswählenBesuchten Knoten auswählen: Den Knoten "Next" auswählen...Ersten Menüpunkt auswählen...SeptemberSetze %s auf den Wert (%d): Setze %s auf den Wert (%s): Bildschirm-Höhe auf (%d) setzen: Setze die Höhe des angezeigten FenstersDen Wert einer Info-Variablen setzenSetze Variable: Zeige die mit diesem Node verbundenen Fußnoten im anderen FensterEinzige VervollständigungAktuelles Fenster unterteilenBeginne (oder multipliziere mit 4) das aktuelle nummerische ArgumentDer »%c%s«-Befehl ist sinnlos innerhalb eines »@%s«-BlocksDie folgenden Befehle können nur via M-x aufgerufen werden: Anzahl der Zeilen zu »scrollen«, wenn der Cursor aus dem Fenster bewegt wirdDer Verweispunkt ist verschwunden! (%s).Es sind keine %d Punkte in diesem Menü.Es gibt keine Funktion mit Namen »%s«Es gibt kein Menü in diesem Node.Es gibt keinen Menüpunkt »%s« in diesem Node.Dies ist die Info-Datei %s, hergestellt von Makeinfo Version %d.%dDies ist die Datei .../info/dir, die den obersten Knoten der Info-Hierarchie enthält, genannt (dir)Top. Beim ersten Aufruf von Info geht es bei diesem Knoten los.  Date: dir Knoten: Top Dies ist »top« des INFO-Baums Dieser Verzeichnis-Knoten zeigt ein Menü aller Hauptpunkte an. Beenden mit "q", "?" listet alle Info-Befehle auf, "d" kehrt nach hierher zurück, "h" gibt eine Einsteiger-Hilfe, "mEmacs" besucht das Emacs-Manual, etc. Im Emacs kann man mit mouse-button-2 auf einen Menüpunkt oder einen Querverweis klicken, um einen solchen auswählen. * Menü: Dieser Knoten (»%s«) hat schlechten(?) "Next"-EintragDieser Knoten (»%s«) hat schlechten(?) "Prev"-EintragDies Fenster hat keine weiteren KnotenDen Status des Zeilenumbruchs im aktuellen Fenster umschaltenzu viele Spalten im "multitable"-Eintrag (maximal %d)Zu viele Fehler! Abbruch. TopZeichen am Point umstellen»--help« gibt weitere Informationen.»%s --help« gibt weitere Informationen. Kann keinen von »%s« referenzierten Node finden.Unbekannter Befehl (%s).Unbekannter Befehl »%s«Unbekannter Index »%s«Unbekannter Index »%s« und /oder unbekannter »%s« in @synindexUnbekannter Index »%s« in @printindexNicht übereinstimmende »%c%s«Nicht übereinstimmende }Aufruf: %s [OPTION]... DATEI... Aufruf: %s [OPTION]... TEXINFO-DATEI... Texinfo-Quelltext in ein Format übersetzen, das mit GNU Info gelesen werden kann. Optionen: -D VAR eine Variable definieren, wie mit @set -E MACRO-AUSGABEDATEI nur die Macros auflösen, Texinfo-Quelltext ausgeben -I VERZ VERZ in die Verzeichnis-Suchliste für @include aufnehmen -P DIR VERZ dem @include Verzeichnis-Suchpfad voranstellen -U VAR eine Variable aufheben, wie mit @clear --error-limit ZAHL nach ZAHL Fehlern beenden (Standard %d) --fill-column ZAHL Zeilen nach ZAHL Zeichen umbrechen (Standard %d) --footnote-style STYLE Fußnoten gemäß STYLE ausgeben: »separate«: Fußnoten in einen eigenen Knoten plazieren; »end«: Fußnoten an das Ende des Knoten setzen, in dem sie definiert sind (Standard) --force Ausgabe auch bei Fehlern aufbewahren --help diese Hilfe zeigen --no-validate Überprüfen der "node"-Querverweise unterdrücken --no-warn Warnungen unterdrücken (aber keine Fehler) --no-split Aufteilen langer Dateien unterdrücken --no-headers Knoten-Unterteiler und "Node: Foo" Kopfzeilen unterdrücken --output DATEI, -o DATEI Ausgabe nach DATEI und @setfilename ignorieren --paragraph-indent ZAHL/»none«/»asis« Absätze mit ZAHL Leerräumen einziehen (Standard %d); »none«: keine Leerräume »asis«: keine Veränderung hinsichtlich der Leerräume --reference-limit ZAHL bei wenigstens ZAHL Verweise melden (Standard %d) --verbose ausführlich die Bearbeitungschritte anzeigen --version Programmversion anzeigen Fehlerberichte ("bugs") bitte an schicken. Für die deutsche Übersetzung ist die Mailingliste zuständig. Syntax: %s [OPTION]... [INFO-DATEI [VERZ-DATEI]] Installiere die INFO-DATEI in dem Info-Verzeichnis VERZ-DATEI. Optionen: --delete entferne vorhandene Einträge aus INFO-DATEI; keine neuen Einträge einfügen --dir-file=NAME Namen der Info-Verzeichnis-Datei angeben. Gleichbedeutend mit dem VERZ-DATEI-Argument --entry=TEXT TEXT als einen Info-Verzeichnis-Eintrag einfügen. TEXT soll die Form einer Zeile eines Info-Menüpunkts haben, zuzüglich Null oder mehrerer Extra-Zeilen, die mit Leerraum ("whitespace") beginnen. Wenn mehr als ein Eintrag angegeben wird, werden alle hinzugefügt. Wenn gar kein Eintrag angegeben wird, wird der Eintragstext der Info-Datei selbst entnommen. --help diese Hilfe zeigen --info-file=DATEI Info-Datei angeben, die im Verzeichnis zu installieren ist. Gleichbedeutend mit dem INFO-DATEI-Argument --info-dir=VERZ wie --dir-file=VERZ/dir. --item=TEXT wie --entry TEXT. Ein Info-Verzeichnis-Eintrag ist nämlich ein Menüpunkt --quiet Warnungen unterdrücken --remove wie --delete --section=ABSCHN stelle die Einträge dieser Datei in den Abschnitt ABSCHN des Verzeichnisses. Wenn mehr als ein --section angegeben wird, werden alle Einträge in jedem der Abschnitte hinzugefügt. Wenn gar kein --section angegeben wird, wird der Eintragstext der Info-Datei selbst entnommen. --version Programmversion anzeigen Fehlerberichte ("bugs") bitte an schicken. Für die deutsche Übersetzung ist die Mailingliste zuständig. Syntax: %s [OPTION]... [INFO-DATEI [MENU-EINTRAG...]] Um Dokumentation zu lesen, die im Info-Format vorliegt. Für eine ausführlichere Anleitung, wie Info zu benutzen ist, »info info options« eingeben. Optionen: --directory VERZ VERZ zu INFOPATH hinzufügen --dribble DATEI Tasteneingaben des Benutzers in DATEI merken --file DATEI zu besuchende Info-DATEI angeben --node KNOTEN Knoten in der ersten zu besuchenden Info-Datei angeben --output DATEI ausgewählte Knoten nach DATEI ausgeben --restore DATEI die beginnenden Tasteneingaben von DATEI lesen --subnodes Menüpunkte rekursiv ausgeben --help diese Hilfe anzeigen --version Programmversion anzeigen Verbleibende Parameter werden als Namen von Menüpunkten des zuerst besuchten Knotens angesehen. Man kann sich einfach zum gewünschten Knoten bewegen, indem man die Namen der Menüpunkte angibt, die den Weg dorthin bezeichnen; z. B. »info emacs buffers«. Fehler ("bugs") bitte an melden.< Für die deutsche Übersetzung ist die Mailingliste zuständig.Benutzer-OptionDATEI... ist normalerweise »foo.??« für ein Dokument »foo.texi«. Virtual memory exhausted in %s ()! Needed %d bytes.Info-Node »(info)Help« besuchenSo viele Menüpunkte wie möglich auf einmal besuchenWillkommen bei Info Version %s. "\[get-help-window]" um Hilfe zu bekommen, mit "\[menu-item]" Menüpunkt anzeigen.Wenn »On«, dann akzeptiert Info ISO-Latin-Zeichen und zeigt diese anWenn »On«, Info "garbage collectet" Dateien, die ausgepackt werden müssenWenn »On«, dann werden beim Anlegen oder Löschen eines Fensters die anderen Fenster angepasstWenn »On«, dann lassen Fehler ein akustisches Signal ertönenWenn »On«, dann den Bildschirm blinken lassen, kein akustisches SignalWenn »On«, dann erscheinen und verschwinden Fußnoten automatischWenn »On«, die übereinstimmende gefundene Zeichenkette wird gekennzeichnetWo ist der Befehl: Knoten »%s« schreiben...Schreibe Knoten (%s)%sFüge ein vorangehendes Killen einFüge den Inhalt des letzten Killens ein»%c%s« braucht das Argument in der Form »{...}«, nicht nur »%s«»%c%s« braucht etwas Nachfolgendes»%cend« erwartete »%s«, aber bekam »%s«»%s« hat ein "Up field" von »%s«, aber »%s« hat keinen Menü-Eintrag für »%s«»%s« liegt auf keiner Taste».« or »,« muss einem Querverweis folgen, nicht %cgenau»Top«-Knoten wird angelegtdiese Hilfe anzeigenProgrammversion anzeigenkeine temporäre Dateien bis nach der Verarbeitung aufheben (Standard)Eintrag »%s« folgt einem Eintrag mit einem ZweitnamenKommandozeilen-Argument »%s« wird übergangenFehler beim Wiederöffnen von »%s«Hier ist die vorangehende Definition von »%s«@tab außerhalb der "multitable" wird übergangenirriger Text »%s« nach @multitable wird ignorierttemporäre Dateien bis nach der Verarbeitung aufhebenBuchstaben-Zählungs-Überlauf, beginne wieder bei %cMacro »%s« ist bereits definiertMenüpunkt »%s« bereits vorhanden, für Datei »%s«weiteren "multitable"-Eintrag nicht in der aktiven "multitable"Keine Einträge gefunden keine Einträge für »%s« gefunden; nichts entferntKein Info-Verzeichnis-Eintrag in »%s«auf Knoten »%s« wird %d mal verwiesenkeinreadline: Kein Speicher mehr! Ausgabe nach DATEI schickenauf Knoten »%s« wird nicht verwiesenvirtual memory exhausted{Kein Wert Für »%s«}texinfo-3.12/po/de.po0000664000175000017500000016714706477056754011765 0ustar gg# German messages for GNU Texinfo # Copyright © 1996, 1997, 1998 Free Software Foundation, Inc. # Karl Eichwalder , 1996. # Karl Eichwalder , 1997,1998. # # 1998-02-28 14:29:49 MET # Revised for 3.11b # I refuse to translate getopt.c strings # -ke- # msgid "" msgstr "" "Project-Id-Version: texinfo 3.11\n" "POT-Creation-Date: 1998-03-03 13:32-0500\n" "PO-Revision-Date: 1998-02-28 14:32+01:00\n" "Last-Translator: Karl Eichwalder \n" "Language-Team: German \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-1\n" "Content-Transfer-Encoding: 8-bit\n" #. **************************************************************** #. #. Echo Area Movement Commands #. #. **************************************************************** #: info/echo-area.c:283 info/session.c:698 msgid "Move forward a character" msgstr "Ein Zeichen vorwärts bewegen" #. Move point backward in the node. #: info/echo-area.c:295 info/session.c:714 msgid "Move backward a character" msgstr "Ein Zeichen rückwärts bewegen" #: info/echo-area.c:307 msgid "Move to the start of this line" msgstr "Zum Anfang dieser Zeile bewegen" #: info/echo-area.c:312 msgid "Move to the end of this line" msgstr "Zum Ende dieser Zeile bewegen" #. Move forward a word in the input line. #: info/echo-area.c:320 info/session.c:732 msgid "Move forward a word" msgstr "Ein Wort vorwärts bewegen" #: info/echo-area.c:360 info/session.c:781 msgid "Move backward a word" msgstr "Ein Wort rückwärts bewegen" #: info/echo-area.c:400 msgid "Delete the character under the cursor" msgstr "Das Zeichen unter dem Cursor löschen" # checkit #: info/echo-area.c:430 msgid "Delete the character behind the cursor" msgstr "Das Zeichen hinter dem Cursor löschen" #: info/echo-area.c:451 msgid "Cancel or quit operation" msgstr "Operation abbrechen oder beenden" #: info/echo-area.c:466 msgid "Accept (or force completion of) this line" msgstr "Akzeptiere diese Zeile (oder erzwinge ihre Vervollständigung)" #: info/echo-area.c:471 msgid "Insert next character verbatim" msgstr "Das nächste Zeichen wörtlich eingeben" #: info/echo-area.c:479 msgid "Insert this character" msgstr "Dieses Zeichen eingeben" # checkit #: info/echo-area.c:497 msgid "Insert a TAB character" msgstr "Ein TAB-Zeichen eingeben" #. Transpose the characters at point. If point is at the end of the line, #. then transpose the characters before point. #: info/echo-area.c:504 msgid "Transpose characters at point" msgstr "Zeichen am Point umstellen" #: info/echo-area.c:555 msgid "Yank back the contents of the last kill" msgstr "Füge den Inhalt des letzten Killens ein" # IMO muss "kill" auch im Folgenden wörtlich üs werden -ke- #: info/echo-area.c:562 msgid "Kill ring is empty" msgstr "Der Kill-Ring ist leer" #. If the last command was yank, or yank_pop, and the text just before #. point is identical to the current kill item, then delete that text #. from the line, rotate the index down, and yank back some other text. #: info/echo-area.c:575 msgid "Yank back a previous kill" msgstr "Füge ein vorangehendes Killen ein" #. Delete the text from point to end of line. #: info/echo-area.c:608 msgid "Kill to the end of the line" msgstr "Bis zum Ende der Zeile killen" #: info/echo-area.c:621 msgid "Kill to the beginning of the line" msgstr "Bis zum Anfang der Zeile killen" #. Delete from point to the end of the current word. #: info/echo-area.c:633 msgid "Kill the word following the cursor" msgstr "Das dem Cursor folgende Wort killen" #: info/echo-area.c:652 msgid "Kill the word preceding the cursor" msgstr "Das dem Cursor vorangehende Wort killen" # checkit #: info/echo-area.c:871 msgid "Not complete" msgstr "Nicht vollständig" #: info/echo-area.c:916 msgid "List possible completions" msgstr "Mögliche Vervollständigungen listen" #: info/echo-area.c:929 msgid "No completions" msgstr "Keine Vervollständigungen" #: info/echo-area.c:933 msgid "Sole completion" msgstr "Einzige Vervollständigung" #: info/echo-area.c:942 msgid "One completion:\n" msgstr "Eine Vervollständigung:\n" #: info/echo-area.c:943 #, c-format msgid "%d completions:\n" msgstr "%d Vervollständigungen:\n" #: info/echo-area.c:1088 msgid "Insert completion" msgstr "Vervollständigung einfügen" #: info/echo-area.c:1221 msgid "Building completions..." msgstr "Bilde Vervollständigungen..." # checkit #. Scroll the "other" window. If there is a window showing completions, scroll #. that one, otherwise scroll the window which was active on entering the read #. function. #: info/echo-area.c:1319 msgid "Scroll the completions window" msgstr "Vervollständigungs-Fenster »scrollen«" #: info/footnotes.c:206 msgid "Footnotes could not be displayed" msgstr "Fußnoten können nicht angezeigt werden" #: info/footnotes.c:232 msgid "Show the footnotes associated with this node in another window" msgstr "Zeige die mit diesem Node verbundenen Fußnoten im anderen Fenster" #: info/indices.c:175 msgid "Look up a string in the index for this file" msgstr "Sieh eine Zeichenkette im Index dieser Datei nach" #: info/indices.c:205 msgid "Finding index entries..." msgstr "Suche Index-Einträge..." # checkit # oder sind "Einträge" gemeint? -ke- #: info/indices.c:212 msgid "No indices found." msgstr "Keine Indices gefunden." #: info/indices.c:222 msgid "Index entry: " msgstr "Index-Eintrag: " #: info/indices.c:332 msgid "" "Go to the next matching index item from the last `\\[index-search]' command" msgstr "" "Geh zum nächsten übereinstimmenden Index-Eintrag vom letzten " "»\\[index-search]«-Befehl" #: info/indices.c:342 msgid "No previous index search string." msgstr "Keine vorangehende zu suchende Index-Zeichenkette." #: info/indices.c:349 msgid "No index entries." msgstr "Keine Index-Einträge." # checkit # kann im Deutschen nachgebildet werden, aber... -ke- #: info/indices.c:382 #, c-format msgid "No %sindex entries containing \"%s\"." msgstr "Keine %sIndex-Einträge beinhalten »%s«." #: info/indices.c:383 msgid "more " msgstr "weiteren " #: info/indices.c:393 msgid "CAN'T SEE THIS" msgstr "DIES IST NICHT ZU SEHEN" #: info/indices.c:429 #, c-format msgid "Found \"%s\" in %s. (`\\[next-index-match]' tries to find next.)" msgstr "" "»%s« in %s gefunden. (»\\[next-index-match]« versucht nächsten Eintrag zu " "finden.)" #: info/indices.c:533 #, c-format msgid "Scanning indices of \"%s\"..." msgstr "Index von »%s« wird durchsucht..." #: info/indices.c:616 msgid "Grovel all known info file's indices for a string and build a menu" msgstr "" "Durchsuche durch alle bekannten Info-Datei-Indices nach einer Zeichenkette " "und bilde ein Menü" #: info/indices.c:620 msgid "Index apropos: " msgstr "Index apropos: " #: info/indices.c:650 #, c-format msgid "" "\n" "* Menu: Nodes whoses indices contain \"%s\":\n" msgstr "" "\n" "* Menü: Nodes, deren Indices »%s« beinhalten:\n" #: info/info.c:212 msgid "Try --help for more information." msgstr "»--help« gibt weitere Informationen." # Hier de-Standard-Formulierung einsetzen! #: info/info.c:231 makeinfo/makeinfo.c:1089 util/install-info.c:530 #: util/texindex.c:338 #, c-format msgid "" "Copyright (C) %s Free Software Foundation, Inc.\n" "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" msgstr "" "Copyright © %s Free Software Foundation, Inc.\n" "Dies ist freie Software; in den Quellen befindet sich die Lizenz- und\n" "Kopierbedingung. Es gibt KEINERLEI Garantie, nicht einmal für die\n" "TAUGLICHKEIT oder die VERWENDBARKEIT ZU EINEM ANGEGEBENEN ZWECK.\n" #: info/info.c:363 msgid "no entries found\n" msgstr "Keine Einträge gefunden\n" #: info/info.c:406 msgid "There is no menu in this node." msgstr "Es gibt kein Menü in diesem Node." #: info/info.c:437 #, c-format msgid "There is no menu item \"%s\" in this node." msgstr "Es gibt keinen Menüpunkt »%s« in diesem Node." #: info/info.c:501 #, c-format msgid "Unable to find the node referenced by \"%s\"." msgstr "Kann keinen von »%s« referenzierten Node finden." #: info/info.c:602 #, c-format msgid "" "Usage: %s [OPTION]... [INFO-FILE [MENU-ITEM...]]\n" "\n" "Read documentation in Info format.\n" "For more complete documentation on how to use Info, run `info info " "options'.\n" "\n" "Options:\n" "--directory DIR add DIR to INFOPATH.\n" "--dribble FILENAME remember user keystrokes in FILENAME.\n" "--file FILENAME specify Info file to visit.\n" "--node NODENAME specify nodes in first visited Info file.\n" "--output FILENAME output selected nodes to FILENAME.\n" "--restore FILENAME read initial keystrokes from FILENAME.\n" "--subnodes recursively output menu items.\n" "--help display this help and exit.\n" "--version display version information and exit.\n" "\n" "The first argument, if present, is the name of the Info file to read.\n" "Any remaining arguments are treated as the names of menu\n" "items in the initial node visited. For example, `info emacs buffers'\n" "moves to the node `buffers' in the info file `emacs'.\n" "\n" "Email bug reports to bug-texinfo@gnu.org." msgstr "" "Syntax: %s [OPTION]... [INFO-DATEI [MENU-EINTRAG...]]\n" "\n" "Um Dokumentation zu lesen, die im Info-Format vorliegt.\n" "Für eine ausführlichere Anleitung, wie Info zu benutzen ist, »info info\n" "options« eingeben.\n" "\n" "Optionen:\n" " --directory VERZ VERZ zu INFOPATH hinzufügen\n" " --dribble DATEI Tasteneingaben des Benutzers in DATEI merken\n" " --file DATEI zu besuchende Info-DATEI angeben\n" " --node KNOTEN Knoten in der ersten zu besuchenden Info-Datei " "angeben\n" " --output DATEI ausgewählte Knoten nach DATEI ausgeben\n" " --restore DATEI die beginnenden Tasteneingaben von DATEI lesen\n" " --subnodes Menüpunkte rekursiv ausgeben\n" " --help diese Hilfe anzeigen\n" " --version Programmversion anzeigen\n" "\n" "Verbleibende Parameter werden als Namen von Menüpunkten des zuerst " "besuchten\n" "Knotens angesehen. Man kann sich einfach zum gewünschten Knoten bewegen,\n" "indem man die Namen der Menüpunkte angibt, die den Weg dorthin bezeichnen;\n" "z. B. »info emacs buffers«.\n" "\n" "Fehler (\"bugs\") bitte an melden.<\n" "\n" "Für die deutsche Übersetzung ist die Mailingliste zuständig." #: info/infodoc.c:50 msgid "Basic Commands in Info Windows" msgstr "Grundbefehle in Info-Fenstern" #: info/infodoc.c:211 msgid "" "The following commands can only be invoked via M-x:\n" "\n" msgstr "Die folgenden Befehle können nur via M-x aufgerufen werden:\n" #: info/infodoc.c:228 msgid "--- Use `\\[history-node]' or `\\[kill-node]' to exit ---\n" msgstr "" "--- »\\[history-node]« oder »\\[kill-node]« benutzen, um zu beenden ---\n" #. Create or move to the help window. #: info/infodoc.c:328 msgid "Display help message" msgstr "Diesen Hilfe-Text anzeigen" #. Show the Info help node. This means that the "info" file is installed #. where it can easily be found on your system. #: info/infodoc.c:346 msgid "Visit Info node `(info)Help'" msgstr "Info-Node »(info)Help« besuchen" #: info/infodoc.c:470 msgid "Print documentation for KEY" msgstr "Dokumentation für KEY ausgeben" #: info/infodoc.c:483 #, c-format msgid "Describe key: %s" msgstr "Beschreibe Taste: %s" #: info/infodoc.c:492 #, c-format msgid "ESC %s is undefined." msgstr "ESC %s ist nicht definiert." #: info/infodoc.c:509 #, c-format msgid "%s is undefined." msgstr "%s ist nicht definiert." #: info/infodoc.c:535 #, c-format msgid "%s is defined to %s." msgstr "%s ist definiert als %s." #: info/infodoc.c:731 msgid "Where is command: " msgstr "Wo ist der Befehl: " #: info/infodoc.c:753 #, c-format msgid "`%s' is not on any keys" msgstr "»%s« liegt auf keiner Taste" #: info/infodoc.c:759 #, c-format msgid "%s can only be invoked via %s." msgstr "%s kann nur via %s aufgerufen werden." #: info/infodoc.c:762 #, c-format msgid "%s can be invoked via %s." msgstr "%s kann via %s aufgerufen werden." #: info/infodoc.c:766 #, c-format msgid "There is no function named `%s'" msgstr "Es gibt keine Funktion mit Namen »%s«" #: info/m-x.c:69 msgid "Read the name of an Info command and describe it" msgstr "Lese den Namen eines Info-Befehls und beschreibe ihn" #: info/m-x.c:73 msgid "Describe command: " msgstr "Beschreibe den Befehl: " #: info/m-x.c:96 msgid "Read a command name in the echo area and execute it" msgstr "Lies einen Befehlsnamen in der »Echo-Area« und führe ihn aus" #: info/m-x.c:134 msgid "Cannot execute an `echo-area' command here." msgstr "Kann hier keinen »echo-area«-Befehl ausführen." #: info/m-x.c:150 msgid "Set the height of the displayed window" msgstr "Setze die Höhe des angezeigten Fensters" # checkit #: info/m-x.c:163 #, c-format msgid "Set screen height to (%d): " msgstr "Bildschirm-Höhe auf (%d) setzen: " # checkit #: info/makedoc.c:126 msgid "" " Source files groveled to make this file include:\n" "\n" msgstr "" " Quelldatei \"groveled\", damit diese Datei enthält:\n" "\n" #: info/makedoc.c:450 #, c-format msgid "Couldn't manipulate the file %s.\n" msgstr "Datei »%s« ist nicht zu verändern.\n" #: info/nodemenu.c:28 msgid "" "\n" "* Menu:\n" " (File)Node Lines Size Containing File\n" " ---------- ----- ---- ---------------" msgstr "" "\n" "* Menü:\n" " (Datei)Knoten Zeilen Größe Beinhaltet Datei\n" " ------------- ------ ----- ----------------" #: info/nodemenu.c:197 msgid "" "Here is the menu of nodes you have recently visited.\n" "Select one from this menu, or use `\\[history-node]' in another window.\n" msgstr "" "Hier ist das Menü der Knoten, die zuetzt besucht wurden.\n" "Einen von diesem Menü auswählen oder »\\[history-node]« im anderen Fenster\n" "benutzen.\n" #: info/nodemenu.c:217 msgid "Make a window containing a menu of all of the currently visited nodes" msgstr "" "Veranlassen, dass ein Fenster ein Menü aller aktuell besuchten Knoten enthält" #: info/nodemenu.c:297 msgid "Select a node which has been previously visited in a visible window" msgstr "" "Einen Knoten auswählen, der zuvor in einem sichtbaren Fenster besucht wurde" #: info/nodemenu.c:309 msgid "Select visited node: " msgstr "Besuchten Knoten auswählen: " #: info/nodemenu.c:329 info/session.c:1996 #, c-format msgid "The reference disappeared! (%s)." msgstr "Der Verweispunkt ist verschwunden! (%s)." #: info/session.c:162 #, c-format msgid "" "Welcome to Info version %s. \"\\[get-help-window]\" for help, " "\"\\[menu-item]\" for menu item." msgstr "" "Willkommen bei Info Version %s. \"\\[get-help-window]\" um Hilfe zu " "bekommen,\n" "mit \"\\[menu-item]\" Menüpunkt anzeigen." #. Move WINDOW's point down to the next line if possible. #: info/session.c:629 msgid "Move down to the next line" msgstr "Eine Zeile nach unten bewegen" #. Move WINDOW's point up to the previous line if possible. #: info/session.c:644 msgid "Move up to the previous line" msgstr "Eine Zeile nach oben bewegen" #. Move WINDOW's point to the end of the true line. #: info/session.c:659 msgid "Move to the end of the line" msgstr "Zum Ende dieser Zeile bewegen" #. Move WINDOW's point to the beginning of the true line. #: info/session.c:679 msgid "Move to the start of the line" msgstr "Zum Anfang der Zeile bewegen" #: info/session.c:855 msgid " times" msgstr "mal" #: info/session.c:857 #, c-format msgid "%d times" msgstr "%d mal" #: info/session.c:895 msgid "No \"Next\" pointer for this node." msgstr "Kein »Next«-Verweis bei diesem Knoten." #: info/session.c:898 msgid "Following \"Next\" node..." msgstr "»Next«-Knoten folgend..." # checkit # üs? -ke- #: info/session.c:899 info/session.c:927 info/session.c:999 #: info/session.c:1717 msgid "Next" msgstr "" #: info/session.c:915 msgid "Selecting first menu item..." msgstr "Ersten Menüpunkt auswählen..." # checkit #: info/session.c:926 msgid "Selecting \"Next\" node..." msgstr "Den Knoten \"Next\" auswählen..." # checkit # üs? -ke- #: info/session.c:950 info/session.c:1063 info/session.c:1733 msgid "Up" msgstr "" #: info/session.c:1020 msgid "No more nodes." msgstr "Keine \"Nodes\" mehr" #: info/session.c:1044 msgid "No \"Prev\" for this node." msgstr "Kein »Prev« bei diesem Knoten." # checkit #. Move to the previous node. If this node now contains a menu, #. and we have not inhibited movement to it, move to the node #. corresponding to the last menu item. #: info/session.c:1047 info/session.c:1100 msgid "Moving \"Prev\" in this window." msgstr "Nach »Prev« in diesem Fenster bewegen." # checkit # üs? -ke- #: info/session.c:1048 info/session.c:1101 info/session.c:1725 msgid "Prev" msgstr "" #: info/session.c:1059 msgid "No \"Prev\" or \"Up\" for this node." msgstr "Kein »Prev« oder »Up« bei diesem Knoten." #: info/session.c:1062 msgid "Moving \"Up\" in this window." msgstr "Nach »Up« in diesem Fenster bewegen." #: info/session.c:1110 msgid "Moving to \"Prev\"'s last menu item." msgstr "Nach dem letzten Menüpunkt von »Prev« bewegen." #: info/session.c:1121 msgid "Move forwards or down through node structure" msgstr "Vorwärts oder abwärts durch die Knotenstruktur bewegen" #: info/session.c:1137 msgid "Move backwards or up through node structure" msgstr "Zurück oder aufwärts durch die Knotenstruktur bewegen" #. Show the next screen of WINDOW's node. #: info/session.c:1152 msgid "Scroll forward in this window" msgstr "In diesem Fenster vorwärts »scrollen«" #. Show the previous screen of WINDOW's node. #: info/session.c:1197 msgid "Scroll backward in this window" msgstr "In diesem Fenster rückwärts »scrollen«" #. Move to the beginning of the node. #: info/session.c:1237 msgid "Move to the start of this node" msgstr "Zum Anfang dieses Knotens bewegen" #. Move to the end of the node. #: info/session.c:1244 msgid "Move to the end of this node" msgstr "Zum Ende dieses Knotens bewegen" #. **************************************************************** #. #. Commands for Manipulating Windows #. #. **************************************************************** #. Make the next window in the chain be the active window. #: info/session.c:1257 msgid "Select the next window" msgstr "Das nächste Fenster auswählen" #. Make the previous window in the chain be the active window. #: info/session.c:1296 msgid "Select the previous window" msgstr "Das vorige Fenster auswählen" #. Split WINDOW into two windows, both showing the same node. If we #. are automatically tiling windows, re-tile after the split. #: info/session.c:1347 msgid "Split the current window" msgstr "Aktuelles Fenster unterteilen" #. Delete WINDOW, forgetting the list of last visited nodes. If we are #. automatically displaying footnotes, show or remove the footnotes #. window. If we are automatically tiling windows, re-tile after the #. deletion. #: info/session.c:1428 msgid "Delete the current window" msgstr "Aktuelles Fenster löschen" #: info/session.c:1436 msgid "Cannot delete a permanent window" msgstr "Ein permanentes Fenster kann nicht gelöscht werden" #. Just keep WINDOW, deleting all others. #: info/session.c:1469 msgid "Delete all other windows" msgstr "Alle anderen Fenster löschen" #. Scroll the "other" window of WINDOW. #: info/session.c:1515 msgid "Scroll the other window" msgstr "Das andere Fenster »scrollen«" #. Change the size of WINDOW by AMOUNT. #: info/session.c:1535 msgid "Grow (or shrink) this window" msgstr "Aktuelles Fenster vergrößern (oder verkleinern)" #: info/session.c:1546 msgid "Divide the available screen space among the visible windows" msgstr "" "Den vorhandenen Bildschirmplatz unter allen sichtbaren Fenstern aufteilen" #: info/session.c:1553 msgid "Toggle the state of line wrapping in the current window" msgstr "Den Status des Zeilenumbruchs im aktuellen Fenster umschalten" #. Make WINDOW display the "Next:" node of the node currently being #. displayed. #: info/session.c:1714 msgid "Select the `Next' node" msgstr "Den »Next«-Knoten auswählen" #. Make WINDOW display the "Prev:" node of the node currently being #. displayed. #: info/session.c:1722 msgid "Select the `Prev' node" msgstr "Den »Prev«-Knoten auswählen" #. Make WINDOW display the "Up:" node of the node currently being #. displayed. #: info/session.c:1730 msgid "Select the `Up' node" msgstr "Den »Up«-Knoten auswählen" #. Make WINDOW display the last node of this info file. #: info/session.c:1737 msgid "Select the last node in this file" msgstr "Den letzten Knoten dieser Datei auswählen" # checkit #: info/session.c:1750 info/session.c:1768 msgid "This window has no additional nodes" msgstr "Dies Fenster hat keine weiteren Knoten" #. Make WINDOW display the first node of this info file. #: info/session.c:1759 msgid "Select the first node in this file" msgstr "Den ersten Knoten dieser Datei auswählen" #: info/session.c:1778 msgid "Select the last item in this node's menu" msgstr "Den letzten Punkt des Menüs dieses Knotens auswählen" #. Use KEY (a digit) to select the Nth menu item in WINDOW->node. #: info/session.c:1784 msgid "Select this menu item" msgstr "Diesen Menüpunkt auswählen" #: info/session.c:1813 #, c-format msgid "There aren't %d items in this menu." msgstr "Es sind keine %d Punkte in diesem Menü." #: info/session.c:1944 #, c-format msgid "Menu item (%s): " msgstr "Menüpunkt (%s): " #: info/session.c:1946 msgid "Menu item: " msgstr "Menüpunkt: " #: info/session.c:1951 #, c-format msgid "Follow xref (%s): " msgstr "Folge xref (%s): " #: info/session.c:1953 msgid "Follow xref: " msgstr "Folge xref: " #. Read a line (with completion) which is the name of a menu item, #. and select that item. #: info/session.c:2042 msgid "Read a menu item and select its node" msgstr "Einen Menüpunkt lesen und seinen Knoten auswählen" #: info/session.c:2050 msgid "Read a footnote or cross reference and select its node" msgstr "Fußnote oder Querverweis lesen und den Konote auswählen" #. Position the cursor at the start of this node's menu. #: info/session.c:2056 msgid "Move to the start of this node's menu" msgstr "Zum Anfang des Menüs dieses Knotens bewegen" #: info/session.c:2080 msgid "Visit as many menu items at once as possible" msgstr "So viele Menüpunkte wie möglich auf einmal besuchen" #. Read a line of input which is a node name, and go to that node. #: info/session.c:2108 msgid "Read a node name and select it" msgstr "Den Namen eines Knotens lesen und diesen auswählen" #: info/session.c:2169 info/session.c:2173 msgid "Goto Node: " msgstr "Gehe nach Knoten: " #: info/session.c:2194 msgid "Read a manpage reference and select it" msgstr "Einen Verweis auf eine Manpage lesen und diese auswählen" #: info/session.c:2198 msgid "Get Manpage: " msgstr "Hole Manpage: " #. Move to the "Top" node in this file. #: info/session.c:2228 msgid "Select the node `Top' in this file" msgstr "Den Knoten »Top« dieser Datei auswählen" #. Notice that the node "Top" is special, and doesn't have to #. be referenced. #: info/session.c:2230 makeinfo/makeinfo.c:5145 makeinfo/makeinfo.c:5228 msgid "Top" msgstr "Top" #. Move to the node "(dir)Top". #: info/session.c:2234 msgid "Select the node `(dir)'" msgstr "Den Knoten »(dir)« auswählen" #: info/session.c:2254 #, c-format msgid "Kill node (%s): " msgstr "Kille Knoten (%s): " #: info/session.c:2307 #, c-format msgid "Cannot kill node `%s'" msgstr "Kann Knoten »%s« nicht killen" #: info/session.c:2317 msgid "Cannot kill the last node" msgstr "Der letzte Knoten kann nicht gekillt werden" #: info/session.c:2401 msgid "Select the most recently selected node" msgstr "Den zuletzt gewählten Knoten auswählen" #. Kill named node. #: info/session.c:2407 msgid "Kill this node" msgstr "Diesen Knoten killen" #. Read the name of a file and select the entire file. #: info/session.c:2415 msgid "Read the name of a file and select it" msgstr "Den Namen einer Datei lesen und diese auswählen" #: info/session.c:2419 msgid "Find file: " msgstr "Datei finden: " #: info/session.c:2436 #, c-format msgid "Cannot find \"%s\"." msgstr "Kann »%s« nicht finden." #: info/session.c:2483 info/session.c:2608 #, c-format msgid "Could not create output file \"%s\"." msgstr "Ausgabe-Datei »%s« kann nicht angelegt werden." #: info/session.c:2496 info/session.c:2625 info/session.c:2671 msgid "Done." msgstr "Fertig." #: info/session.c:2553 #, c-format msgid "Writing node \"(%s)%s\"..." msgstr "Schreibe Knoten (%s)%s" #: info/session.c:2556 #, c-format msgid "Writing node \"%s\"..." msgstr "Knoten »%s« schreiben..." #: info/session.c:2634 msgid "Pipe the contents of this node through INFO_PRINT_COMMAND" msgstr "Den Inhalt dieses Knotens durch INFO_PRINT_COMMAND pipen" #: info/session.c:2654 #, c-format msgid "Cannot open pipe to \"%s\"." msgstr "Kann nicht nach »%s« pipen." #: info/session.c:2661 #, c-format msgid "Printing node \"(%s)%s\"..." msgstr "Drucke Knoten »(%s)%s«..." #: info/session.c:2664 #, c-format msgid "Printing node \"%s\"..." msgstr "Drucke Knoten »%s«..." #: info/session.c:2896 #, c-format msgid "Searching subfile \"%s\"..." msgstr "Unterdatei »%s« wird durchsucht..." #: info/session.c:2946 msgid "Read a string and search for it" msgstr "Eine Zeichenkette einlesen und danach suchen" # checkit #: info/session.c:2966 #, c-format msgid "%s for string [%s]: " msgstr "%s nach Zeichenkette [%s]: " #: info/session.c:2967 msgid "Search backward" msgstr "Suche rückwärts" #: info/session.c:2967 msgid "Search" msgstr "Suche" #: info/session.c:2994 msgid "Search failed." msgstr "Suche fehlgeschlagen." #: info/session.c:3020 info/session.c:3026 msgid "Search interactively for a string as you type it" msgstr "Interaktiv nach einer Zeichenkette während der Eingabe suchen" #: info/session.c:3120 msgid "I-search backward: " msgstr "Interactive Suche rückwarts: " #: info/session.c:3122 msgid "I-search: " msgstr "Interactive Suche" # checkit #: info/session.c:3147 msgid "Failing " msgstr "Fehlgeschlagen " #: info/session.c:3512 msgid "No cross references in this node." msgstr "Keine Querverweise in diesem Knoten." #: info/session.c:3579 msgid "Move to the previous cross reference" msgstr "Zum vorigen Querverweis bewegen" #: info/session.c:3588 msgid "Move to the next cross reference" msgstr "Zum nächsten Querverweis bewegen" #: info/session.c:3598 msgid "Select reference or menu item appearing on this line" msgstr "Verweis oder Menüpunkt auswählen, der auf dieser Zeile erscheint" # checkit #. **************************************************************** #. #. Miscellaneous Info Commands #. #. **************************************************************** #. What to do when C-g is pressed in a window. #: info/session.c:3620 msgid "Cancel current operation" msgstr "Momentane Operation abbrechen" #: info/session.c:3627 msgid "Quit" msgstr "Ende" #: info/session.c:3636 msgid "Move to the cursor to a specific line of the window" msgstr "Den Cursor nach einer bestimmten Zeile des Fensters bewegen" #. Clear the screen and redraw its contents. Given a numeric argument, #. move the line the cursor is on to the COUNT'th line of the window. #: info/session.c:3668 msgid "Redraw the display" msgstr "Anzeige erneut darstellen" #. This command does nothing. It is the fact that a key is bound to it #. that has meaning. See the code at the top of info_session (). #: info/session.c:3705 msgid "Quit using Info" msgstr "Info beenden" #: info/session.c:3728 #, c-format msgid "Unknown command (%s)." msgstr "Unbekannter Befehl (%s)." #: info/session.c:3733 msgid "\"\" is invalid" msgstr "\"\" ist ungültig" #: info/session.c:3735 #, c-format msgid "\"%s\" is invalid" msgstr "\"%s\" ist ungültig" #: info/session.c:3958 msgid "Add this digit to the current numeric argument" msgstr "Diese Zahl dem aktuellen numerischen Argument hinzufügen" #: info/session.c:3967 msgid "Start (or multiply by 4) the current numeric argument" msgstr "Beginne (oder multipliziere mit 4) das aktuelle nummerische Argument" #: info/session.c:3982 msgid "Internally used by \\[universal-argument]" msgstr "Intern gebraucht von \\[universal-argument]" #: info/tilde.c:362 msgid "readline: Out of virtual memory!\n" msgstr "readline: Kein Speicher mehr!\n" #: info/variables.c:40 msgid "When \"On\", footnotes appear and disappear automatically" msgstr "Wenn »On«, dann erscheinen und verschwinden Fußnoten automatisch" #: info/variables.c:44 msgid "When \"On\", creating or deleting a window resizes other windows" msgstr "" "Wenn »On«, dann werden beim Anlegen oder Löschen eines Fensters die anderen " "Fenster angepasst" #: info/variables.c:48 msgid "When \"On\", flash the screen instead of ringing the bell" msgstr "Wenn »On«, dann den Bildschirm blinken lassen, kein akustisches Signal" #: info/variables.c:52 msgid "When \"On\", errors cause the bell to ring" msgstr "Wenn »On«, dann lassen Fehler ein akustisches Signal ertönen" # checkit #: info/variables.c:56 msgid "When \"On\", Info garbage collects files which had to be uncompressed" msgstr "" "Wenn »On«, Info \"garbage collectet\" Dateien, die ausgepackt werden müssen" #: info/variables.c:59 msgid "When \"On\", the portion of the matched search string is highlighted" msgstr "" "Wenn »On«, die übereinstimmende gefundene Zeichenkette wird gekennzeichnet" #: info/variables.c:63 msgid "Controls what happens when scrolling is requested at the end of a node" msgstr "" "Kontrolliert, was passiert, wenn »scrollen« am Ende eines Knotens veranlasst " "wird" #: info/variables.c:67 msgid "The number lines to scroll when the cursor moves out of the window" msgstr "" "Anzahl der Zeilen zu »scrollen«, wenn der Cursor aus dem Fenster bewegt wird" #: info/variables.c:71 msgid "When \"On\", Info accepts and displays ISO Latin characters" msgstr "Wenn »On«, dann akzeptiert Info ISO-Latin-Zeichen und zeigt diese an" #: info/variables.c:77 msgid "Explain the use of a variable" msgstr "Den Zweck einer Variablen erklären" #. Get the variable's name. #: info/variables.c:83 msgid "Describe variable: " msgstr "Beschreibe Variable: " #: info/variables.c:102 msgid "Set the value of an Info variable" msgstr "Den Wert einer Info-Variablen setzen" #. Get the variable's name and value. #: info/variables.c:108 msgid "Set variable: " msgstr "Setze Variable: " #: info/variables.c:126 #, c-format msgid "Set %s to value (%d): " msgstr "Setze %s auf den Wert (%d): " #: info/variables.c:167 #, c-format msgid "Set %s to value (%s): " msgstr "Setze %s auf den Wert (%s): " #: info/window.c:1102 msgid "--*** Tags out of Date ***" msgstr "--*** Tags veraltet ***" #. strlen (location_indicator). #. 10 for the decimal representation of the number of lines in this #. node, and the remainder of the text that can appear in the line. #: info/window.c:1113 msgid "-----Info: (), lines ----, " msgstr "-----Info: (), Zeilen ----, " #: info/window.c:1120 #, c-format msgid "-%s---Info: %s, %d lines --%s--" msgstr "-%s---Info: %s, %d Zeilen --%s--" #: info/window.c:1124 #, c-format msgid "-%s%s-Info: (%s)%s, %d lines --%s--" msgstr "-%s%s-Info: (%s)%s, %d Zeilen --%s--" #: info/window.c:1131 #, c-format msgid " Subfile: %s" msgstr " Unterdatei: %s" #: lib/getopt.c:672 #, c-format msgid "%s: option `%s' is ambiguous\n" msgstr "" #: lib/getopt.c:696 #, c-format msgid "%s: option `--%s' doesn't allow an argument\n" msgstr "" #: lib/getopt.c:701 #, c-format msgid "%s: option `%c%s' doesn't allow an argument\n" msgstr "" #: lib/getopt.c:718 lib/getopt.c:891 #, c-format msgid "%s: option `%s' requires an argument\n" msgstr "" #. --option #: lib/getopt.c:747 #, c-format msgid "%s: unrecognized option `--%s'\n" msgstr "" #. +option or -option #: lib/getopt.c:751 #, c-format msgid "%s: unrecognized option `%c%s'\n" msgstr "" #. 1003.2 specifies the format of this message. #: lib/getopt.c:777 #, c-format msgid "%s: illegal option -- %c\n" msgstr "" #: lib/getopt.c:780 #, c-format msgid "%s: invalid option -- %c\n" msgstr "" #. 1003.2 specifies the format of this message. #: lib/getopt.c:810 lib/getopt.c:940 #, c-format msgid "%s: option requires an argument -- %c\n" msgstr "" #: lib/getopt.c:857 #, c-format msgid "%s: option `-W %s' is ambiguous\n" msgstr "" #: lib/getopt.c:875 #, c-format msgid "%s: option `-W %s' doesn't allow an argument\n" msgstr "" #: makeinfo/makeinfo.c:893 #, c-format msgid "%s:%d: warning: " msgstr "%s:%d: Warnung: " #: makeinfo/makeinfo.c:916 msgid "Too many errors! Gave up.\n" msgstr "Zu viele Fehler! Abbruch.\n" #: makeinfo/makeinfo.c:975 makeinfo/makeinfo.c:1000 makeinfo/makeinfo.c:1068 #, c-format msgid "%s: %s arg must be numeric, not `%s'.\n" msgstr "%s: %s Argument muss numerisch sein, nicht »%s«.\n" # checkit #: makeinfo/makeinfo.c:989 #, c-format msgid "Couldn't open macro expansion output `%s'" msgstr "Die Macro-Auflösung für »%s« kann nicht geöffnet werden" #: makeinfo/makeinfo.c:992 msgid "Cannot specify more than one macro expansion output" msgstr "Mehr als eine Ausgabedatei darf nicht angegeben werden" #: makeinfo/makeinfo.c:1036 #, c-format msgid "%s: --paragraph-indent arg must be numeric/`none'/`asis', not `%s'.\n" msgstr "" "%s: Arg für --paragraph-indent muss numerisch/»none«/»asis« sein, nicht " "»%s«.\n" #: makeinfo/makeinfo.c:1079 #, c-format msgid "%s: --footnote-style arg must be `separate' or `end', not `%s'.\n" msgstr "" "%s: Argument für --footnote-style muss »separate« oder »end« sein, nicht " "»%s«.\n" #: makeinfo/makeinfo.c:1110 #, c-format msgid "%s: missing file argument.\n" msgstr "%s: Datei-Angabe fehlt.\n" #: makeinfo/makeinfo.c:1163 #, c-format msgid "Try `%s --help' for more information.\n" msgstr "»%s --help« gibt weitere Informationen.\n" # Die "." am Zeilenende habe ich entfernt. -ke- #: makeinfo/makeinfo.c:1165 #, c-format msgid "" "Usage: %s [OPTION]... TEXINFO-FILE...\n" "\n" "Translate Texinfo source documentation to a format suitable for reading\n" "with GNU Info.\n" "\n" "Options:\n" "-D VAR define a variable, as with @set.\n" "-E MACRO-OFILE process macros only, output texinfo source.\n" "-I DIR append DIR to the @include directory search path.\n" "-P DIR prepend DIR to the @include directory search path.\n" "-U VAR undefine a variable, as with @clear.\n" "--error-limit NUM quit after NUM errors (default %d).\n" "--fill-column NUM break lines at NUM characters (default %d).\n" "--footnote-style STYLE output footnotes according to STYLE:\n" " `separate' to place footnotes in their own node,\n" " `end' to place the footnotes at the end of\n" " the node in which they are defined (the default).\n" "--force preserve output even if errors.\n" "--help display this help and exit.\n" "--no-validate suppress node cross-reference validation.\n" "--no-warn suppress warnings (but not errors).\n" "--no-split suppress splitting of large files.\n" "--no-headers suppress node separators and Node: Foo headers.\n" "--output FILE, -o FILE output to FILE, and ignore any @setfilename.\n" "--paragraph-indent VAL indent paragraphs with VAL spaces (default %d).\n" " if VAL is `none', do not indent; if VAL is `asis',\n" " preserve any existing indentation.\n" "--reference-limit NUM complain about at most NUM references (default %d).\n" "--verbose report about what is being done.\n" "--version display version information and exit.\n" "\n" "Email bug reports to bug-texinfo@gnu.org.\n" msgstr "" "Aufruf: %s [OPTION]... TEXINFO-DATEI...\n" "\n" "Texinfo-Quelltext in ein Format übersetzen, das mit GNU Info gelesen werden\n" "kann.\n" "\n" "Optionen:\n" "-D VAR eine Variable definieren, wie mit @set\n" "-E MACRO-AUSGABEDATEI nur die Macros auflösen, Texinfo-Quelltext ausgeben\n" "-I VERZ VERZ in die Verzeichnis-Suchliste für @include " "aufnehmen\n" "-P DIR VERZ dem @include Verzeichnis-Suchpfad voranstellen\n" "-U VAR eine Variable aufheben, wie mit @clear\n" "--error-limit ZAHL nach ZAHL Fehlern beenden (Standard %d)\n" "--fill-column ZAHL Zeilen nach ZAHL Zeichen umbrechen (Standard %d)\n" "--footnote-style STYLE Fußnoten gemäß STYLE ausgeben:\n" " »separate«: Fußnoten in einen eigenen Knoten " "plazieren;\n" " »end«: Fußnoten an das Ende des Knoten setzen, " "in\n" " dem sie definiert sind (Standard)\n" "--force Ausgabe auch bei Fehlern aufbewahren\n" "--help diese Hilfe zeigen\n" "--no-validate Überprüfen der \"node\"-Querverweise unterdrücken\n" "--no-warn Warnungen unterdrücken (aber keine Fehler)\n" "--no-split Aufteilen langer Dateien unterdrücken\n" "--no-headers Knoten-Unterteiler und \"Node: Foo\" Kopfzeilen\n" " unterdrücken\n" "--output DATEI, -o DATEI\n" " Ausgabe nach DATEI und @setfilename ignorieren\n" "--paragraph-indent ZAHL/»none«/»asis«\n" " Absätze mit ZAHL Leerräumen einziehen (Standard %d);\n" " »none«: keine Leerräume\n" " »asis«: keine Veränderung hinsichtlich der Leerräume\n" "--reference-limit ZAHL bei wenigstens ZAHL Verweise melden (Standard %d)\n" "--verbose ausführlich die Bearbeitungschritte anzeigen\n" "--version Programmversion anzeigen\n" "\n" "Fehlerberichte (\"bugs\") bitte an schicken.\n" "\n" "Für die deutsche Übersetzung ist die Mailingliste zuständig.\n" #: makeinfo/makeinfo.c:1552 #, c-format msgid "%s: getwd: %s, %s\n" msgstr "" #: makeinfo/makeinfo.c:1748 #, c-format msgid "Expected `%s'" msgstr "Erwartet »%s«" #: makeinfo/makeinfo.c:2082 #, c-format msgid "No `%s' found in `%s'" msgstr "Kein »%s« in »%s« gefunden" #: makeinfo/makeinfo.c:2132 #, c-format msgid "%s: Skipping macro expansion to stdout as Info output is going there.\n" msgstr "" "%s: Macro-Auflösung nach der Standard-Ausgabe, da auch die Info-Ausgabe nach " "dort geht.\n" #: makeinfo/makeinfo.c:2151 #, c-format msgid "Making %s file `%s' from `%s'.\n" msgstr "Erzeuge %s Datei »%s« von »%s«.\n" #: makeinfo/makeinfo.c:2181 #, c-format msgid "This is Info file %s, produced by Makeinfo version %d.%d" msgstr "Dies ist die Info-Datei %s, hergestellt von Makeinfo Version %d.%d" #: makeinfo/makeinfo.c:2183 #, c-format msgid " from the input file %s.\n" msgstr " aus der Eingabe-Datei %s.\n" #: makeinfo/makeinfo.c:2202 #, c-format msgid "" "%s: Removing macro output file `%s' due to errors; use --force to preserve.\n" msgstr "" "%s: Entferne Macro-Ausgabe-Datei »%s« wegen der Fehler; --force benutzen, um " "diese beizubehalten.\n" #. If there were errors, and no --force, remove the output. #: makeinfo/makeinfo.c:2234 #, c-format msgid "%s: Removing output file `%s' due to errors; use --force to preserve.\n" msgstr "" "%s: Entferne Ausgabe-Datei »%s« wegen der Fehler; --force benutzen, um diese " "beizubehalten.\n" #. Special case. I'm not supposed to see this character by itself. #. If I do, it means there is a syntax error in the input text. #. Report the error here, but remember this brace on the stack so #. you can ignore its partner. #: makeinfo/makeinfo.c:2374 makeinfo/makeinfo.c:7629 #, c-format msgid "Misplaced %c" msgstr "Fehlplazierte %c" #: makeinfo/makeinfo.c:2461 #, c-format msgid "Unknown command `%s'" msgstr "Unbekannter Befehl »%s«" #: makeinfo/makeinfo.c:2481 msgid "NO_NAME!" msgstr "" #: makeinfo/makeinfo.c:2495 #, c-format msgid "%c%s expected `{...}'" msgstr "%c%s erwartete »{...}«" #: makeinfo/makeinfo.c:2528 msgid "Unmatched }" msgstr "Nicht übereinstimmende }" #: makeinfo/makeinfo.c:2576 #, c-format msgid "%c%s missing close brace" msgstr "%c%s fehlende schließende Klammer" # checkit # üs? -ke- #: makeinfo/makeinfo.c:3372 msgid "Broken-Type in insertion_type_pname" msgstr "" #: makeinfo/makeinfo.c:3438 msgid "Enumeration stack overflow" msgstr "Nummerierungsstack-Überlauf" #: makeinfo/makeinfo.c:3470 #, c-format msgid "lettering overflow, restarting at %c" msgstr "Buchstaben-Zählungs-Überlauf, beginne wieder bei %c" # checkit # übersetzen? -ke- #: makeinfo/makeinfo.c:3509 msgid "* Menu:\n" msgstr "* Menü:\n" # checkit #: makeinfo/makeinfo.c:3593 #, c-format msgid "%s requires an argument: the formatter for %citem" msgstr "%s erfordert ein Argument: der Formatierer für %citem" #: makeinfo/makeinfo.c:3697 #, c-format msgid "`%cend' expected `%s', but saw `%s'" msgstr "»%cend« erwartete »%s«, aber bekam »%s«" # checkit #: makeinfo/makeinfo.c:3810 #, c-format msgid "No matching `%cend %s'" msgstr "Nicht übereinstimmende »%cend %s«" #: makeinfo/makeinfo.c:3949 #, c-format msgid "How did @%s end up in cm_special_char?\n" msgstr "Zu was führt @%s in cm_special_char?\n" #. This error message isn't perfect if the argument is multiple #. characters, but it doesn't seem worth getting right. #: makeinfo/makeinfo.c:3963 #, c-format msgid "%c%s expects `i' or `j' as argument, not `%c'" msgstr "%c%s erwartet »i« oder »j« als Argument, nicht »%c«" #: makeinfo/makeinfo.c:3967 #, c-format msgid "%c%s expects a single character `i' or `j' as argument" msgstr "%c%s erwartet einen einzigen Buchstaben »i« oder »j« als Argument" #: makeinfo/makeinfo.c:3979 msgid "January" msgstr "Januar" #: makeinfo/makeinfo.c:3979 msgid "February" msgstr "Februar" #: makeinfo/makeinfo.c:3979 msgid "March" msgstr "März" #: makeinfo/makeinfo.c:3979 msgid "April" msgstr "April" #: makeinfo/makeinfo.c:3979 msgid "May" msgstr "Mai" #: makeinfo/makeinfo.c:3980 msgid "June" msgstr "Juni" #: makeinfo/makeinfo.c:3980 msgid "July" msgstr "Juli" #: makeinfo/makeinfo.c:3980 msgid "August" msgstr "August" #: makeinfo/makeinfo.c:3980 msgid "September" msgstr "September" #: makeinfo/makeinfo.c:3980 msgid "October" msgstr "Oktober" #: makeinfo/makeinfo.c:3981 msgid "November" msgstr "November" #: makeinfo/makeinfo.c:3981 msgid "December" msgstr "Dezember" #: makeinfo/makeinfo.c:4039 #, c-format msgid "%c%s expects a single character as an argument" msgstr "%c%s erwartet einen einzigen Buchstaben als Argument" #: makeinfo/makeinfo.c:4153 #, c-format msgid "%c%s is obsolete" msgstr "%c%s ist obsolet" #: makeinfo/makeinfo.c:4325 #, c-format msgid "Node with %ctop as a section already exists" msgstr "Konoten mit %ctop als Abschnitt existiert bereits" #: makeinfo/makeinfo.c:4337 #, c-format msgid "Here is the %ctop node" msgstr "Hier ist der Knoten %ctop" #: makeinfo/makeinfo.c:4356 #, c-format msgid "%ctop used before %cnode, defaulting to %s" msgstr "%ctop vor %cnode gebraucht, als Standard %s genommen" #: makeinfo/makeinfo.c:4431 #, c-format msgid "%c%s is obsolete; use %c%s instead" msgstr "%c%s ist obsolet; stattdessen %c%s benutzen" #: makeinfo/makeinfo.c:4680 #, c-format msgid "Node `%s' multiply defined (line %d is first definition at)" msgstr "Knoten »%s« mehrfach definiert (in Zeile %d ist erste Definition)" #: makeinfo/makeinfo.c:4753 #, c-format msgid "Formatting node %s...\n" msgstr "Formatiere Knoten %s...\n" #: makeinfo/makeinfo.c:4802 #, c-format msgid "Node `%s' requires a sectioning command (e.g. %c%s)" msgstr "Knoten »%s« erfordert eine Abschnitt-Angabe (z.B. %c%s)" #: makeinfo/makeinfo.c:5085 #, c-format msgid "Node `%s''s Next field not pointed back to" msgstr "\"Next field\" des Knotens »%s« verweist nicht zurück nach" # checkit #: makeinfo/makeinfo.c:5090 #, c-format msgid "This node (`%s') is the one with the bad `Prev'" msgstr "Dieser Knoten (»%s«) hat schlechten(?) \"Prev\"-Eintrag" #: makeinfo/makeinfo.c:5130 #, c-format msgid "Node `%s's Prev field not pointed back to" msgstr "Das \"Prev field\" des Knotens »%s« verweist nicht zurück nach" # checkit #: makeinfo/makeinfo.c:5134 #, c-format msgid "This node (`%s') has the bad Next" msgstr "Dieser Knoten (»%s«) hat schlechten(?) \"Next\"-Eintrag" #: makeinfo/makeinfo.c:5146 #, c-format msgid "Node `%s' missing Up field" msgstr "Dem Knoten »%s« fehlt ein \"Up field\"" #: makeinfo/makeinfo.c:5186 #, c-format msgid "`%s' has an Up field of `%s', but `%s' has no menu item for `%s'" msgstr "" "»%s« hat ein \"Up field\" von »%s«, aber »%s« hat keinen Menü-Eintrag für " "»%s«" #: makeinfo/makeinfo.c:5217 #, c-format msgid "node `%s' has been referenced %d times" msgstr "auf Knoten »%s« wird %d mal verwiesen" #: makeinfo/makeinfo.c:5229 #, c-format msgid "unreferenced node `%s'" msgstr "auf Knoten »%s« wird nicht verwiesen" # checkit #: makeinfo/makeinfo.c:5256 #, c-format msgid "%s reference to nonexistent node `%s'" msgstr "Verweis %s auf den nicht existierenden Knoten »%s«" #: makeinfo/makeinfo.c:5668 makeinfo/makeinfo.c:5680 #, c-format msgid "%cmenu seen before first node" msgstr "%cmenu festgestellt, bevor der erste Knoten definiert wurde" #: makeinfo/makeinfo.c:5669 makeinfo/makeinfo.c:5681 msgid "creating `Top' node" msgstr "»Top«-Knoten wird angelegt" # checkit #: makeinfo/makeinfo.c:5794 #, c-format msgid "`.' or `,' must follow cross reference, not %c" msgstr "».« or »,« muss einem Querverweis folgen, nicht %c" #: makeinfo/makeinfo.c:5962 #, c-format msgid "@image file `%s' unreadable: %s" msgstr "@image-Datei »%s« nicht lesbar: %s" #: makeinfo/makeinfo.c:5966 msgid "@image missing filename argument" msgstr "@image fehlt als Argument ein Dateiname" #: makeinfo/makeinfo.c:6067 #, c-format msgid "%s requires letter or digit" msgstr "%s erfordert einen Buchstaben oder eine Zahl" #: makeinfo/makeinfo.c:6152 #, c-format msgid "Unmatched `%c%s'" msgstr "Nicht übereinstimmende »%c%s«" #: makeinfo/makeinfo.c:6159 #, c-format msgid "`%c%s' needs something after it" msgstr "»%c%s« braucht etwas Nachfolgendes" # checkit #: makeinfo/makeinfo.c:6165 #, c-format msgid "Bad argument to `%s', `%s', using `%s'" msgstr "Falsches Argument für »%s«, »%s«, wenn »%s« benutzt wird" # checkit #: makeinfo/makeinfo.c:6338 #, c-format msgid "{No Value For \"%s\"}" msgstr "{Kein Wert Für »%s«}" #: makeinfo/makeinfo.c:6388 #, c-format msgid "%c%s requires a name" msgstr "%c%s erfordert einen Namen" #: makeinfo/makeinfo.c:6496 #, c-format msgid "Reached eof before matching @end %s" msgstr "Das Ende der Datei vor dem erforderlichen @end %s erreicht" #: makeinfo/makeinfo.c:6722 #, c-format msgid "The `%c%s' command is meaningless within a `@%s' block" msgstr "Der »%c%s«-Befehl ist sinnlos innerhalb eines »@%s«-Blocks" #: makeinfo/makeinfo.c:6731 #, c-format msgid "%citemx is not meaningful inside of a `%s' block" msgstr "%citemx ist nicht sinnvoll innerhalb eines »@%s«-Blocks" # checkit #: makeinfo/makeinfo.c:6844 #, c-format msgid "%c%s found outside of an insertion block" msgstr "%c%s außerhalb eines Einfügungsblocks gefunden" # checkit #: makeinfo/makeinfo.c:6935 #, c-format msgid "Missing `}' in %cdef arg" msgstr "Fehlende »}« in »%cdef«-Argument" #: makeinfo/makeinfo.c:7144 makeinfo/makeinfo.c:7164 msgid "Function" msgstr "" #: makeinfo/makeinfo.c:7148 msgid "Macro" msgstr "" #: makeinfo/makeinfo.c:7152 msgid "Special Form" msgstr "" #: makeinfo/makeinfo.c:7156 makeinfo/makeinfo.c:7168 msgid "Variable" msgstr "" #: makeinfo/makeinfo.c:7160 msgid "User Option" msgstr "Benutzer-Option" #: makeinfo/makeinfo.c:7172 msgid "Instance Variable" msgstr "" #: makeinfo/makeinfo.c:7176 makeinfo/makeinfo.c:7180 msgid "Method" msgstr "" # checkit #: makeinfo/makeinfo.c:7335 #, c-format msgid "Must be in a `%s' insertion in order to use `%s'x" msgstr "Muss in einer »%s«-Einfügung sein, wenn »%s«x benutzt werden soll" # checkit #: makeinfo/makeinfo.c:7407 #, c-format msgid "%csp requires a positive numeric argument" msgstr "»%csp« erfordert ein positives numerisches Argument" #: makeinfo/makeinfo.c:7650 msgid "asis" msgstr "genau" #: makeinfo/makeinfo.c:7652 msgid "none" msgstr "kein" #: makeinfo/makeinfo.c:7674 #, c-format msgid "Bad argument to %c%s" msgstr "Falsches Argument für »%c%s«" #: makeinfo/makeinfo.c:7966 #, c-format msgid "Unknown index `%s'" msgstr "Unbekannter Index »%s«" #: makeinfo/makeinfo.c:8031 #, c-format msgid "Index `%s' already exists" msgstr "Index »%s« ist schon vorhanden" #: makeinfo/makeinfo.c:8062 #, c-format msgid "Unknown index `%s' and/or `%s' in @synindex" msgstr "Unbekannter Index »%s« und /oder unbekannter »%s« in @synindex" #: makeinfo/makeinfo.c:8251 #, c-format msgid "Unknown index `%s' in @printindex" msgstr "Unbekannter Index »%s« in @printindex" # übersetzen? -ke- #: makeinfo/makeinfo.c:8266 msgid "" "* Menu:\n" "\n" msgstr "" "* Menü:\n" "\n" #: makeinfo/makeinfo.c:8453 #, c-format msgid "`%c%s' needs an argument `{...}', not just `%s'" msgstr "»%c%s« braucht das Argument in der Form »{...}«, nicht nur »%s«" #: makeinfo/makeinfo.c:8468 #, c-format msgid "No closing brace for footnote `%s'" msgstr "Keine schließende Klammer für Fußnote »%s«" # checkit #: makeinfo/makeinfo.c:8507 msgid "Footnote defined without parent node" msgstr "Fußnote definiert ohne einen Eltern-\"node\"" #: makeinfo/makeinfo.c:8539 msgid "-Footnotes" msgstr "-Fußnoten" #: makeinfo/makeinfo.c:8594 msgid "" "---------- Footnotes ----------\n" "\n" msgstr "" "----------- Fußnoten -----------\n" "\n" #: makeinfo/makeinfo.c:8690 #, c-format msgid "macro `%s' previously defined" msgstr "Macro »%s« ist bereits definiert" #: makeinfo/makeinfo.c:8694 #, c-format msgid "here is the previous definition of `%s'" msgstr "Hier ist die vorangehende Definition von »%s«" #: makeinfo/makeinfo.c:8908 #, c-format msgid "Macro `%s' called with too many args" msgstr "Macro »%s« mit zu vielen Argumenten aufgerufen" #: makeinfo/makeinfo.c:9060 #, c-format msgid "%cend macro not found" msgstr "»%cend«-Macro nicht gefunden" # checkit #: makeinfo/makeinfo.c:9100 #, c-format msgid "%cquote-arg only useful when the macro takes a single argument" msgstr "" "»%cquote«-Argument ist nur sinnvoll, wenn das Macro ein einziges Argument hat" #: makeinfo/multi.c:206 #, c-format msgid "ignoring stray text `%s' after @multitable" msgstr "irriger Text »%s« nach @multitable wird ignoriert" #: makeinfo/multi.c:277 #, c-format msgid "Too many columns in multitable item (max %d)" msgstr "zu viele Spalten im \"multitable\"-Eintrag (maximal %d)" # checkit #. impossible, I think. #: makeinfo/multi.c:304 msgid "multitable item not in active multitable" msgstr "\"multitable\"-Eintrag nicht in der aktiven \"multitable\"" #: makeinfo/multi.c:313 #, c-format msgid "Cannot select column #%d in multitable" msgstr "Spalte #%d kann in der \"multitable\" nicht ausgewählt werden" #: makeinfo/multi.c:404 msgid "ignoring @tab outside of multitable" msgstr "@tab außerhalb der \"multitable\" wird übergangen" # checkit #: makeinfo/multi.c:428 msgid "** Multicolumn output from last row:\n" msgstr "** Mehrspalten-Ausgabe von der letzten Zeile:\n" # checkit #: makeinfo/multi.c:431 #, c-format msgid "* column #%d: output = %s\n" msgstr "* Spalte #%d: Ausgabe = %s\n" # checkit #: util/install-info.c:123 util/install-info.c:136 msgid "virtual memory exhausted" msgstr "virtual memory exhausted" #: util/install-info.c:192 #, c-format msgid "%s: warning: " msgstr "%s: Warnung: " #: util/install-info.c:213 #, c-format msgid " for %s" msgstr " für %s" #: util/install-info.c:282 #, c-format msgid "\tTry `%s --help' for a complete list of options.\n" msgstr "»%s --help« gibt weitere Informationen.\n" #: util/install-info.c:290 #, c-format msgid "" "Usage: %s [OPTION]... [INFO-FILE [DIR-FILE]]\n" "\n" "Install INFO-FILE in the Info directory file DIR-FILE.\n" "\n" "Options:\n" "--delete Delete existing entries in INFO-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" "\n" "Email bug reports to bug-texinfo@gnu.org.\n" msgstr "" "Syntax: %s [OPTION]... [INFO-DATEI [VERZ-DATEI]]\n" "\n" "Installiere die INFO-DATEI in dem Info-Verzeichnis VERZ-DATEI.\n" "\n" "Optionen:\n" "--delete entferne vorhandene Einträge aus INFO-DATEI; keine neuen\n" " Einträge einfügen\n" "--dir-file=NAME Namen der Info-Verzeichnis-Datei angeben. " "Gleichbedeutend\n" " mit dem VERZ-DATEI-Argument\n" "--entry=TEXT TEXT als einen Info-Verzeichnis-Eintrag einfügen. TEXT " "soll\n" " die Form einer Zeile eines Info-Menüpunkts haben,\n" " zuzüglich Null oder mehrerer Extra-Zeilen, die mit " "Leerraum\n" " (\"whitespace\") beginnen. Wenn mehr als ein Eintrag " "angegeben\n" " wird, werden alle hinzugefügt. Wenn gar kein Eintrag\n" " angegeben wird, wird der Eintragstext der Info-Datei " "selbst\n" " entnommen.\n" "--help diese Hilfe zeigen\n" "--info-file=DATEI Info-Datei angeben, die im Verzeichnis zu installieren " "ist.\n" " Gleichbedeutend mit dem INFO-DATEI-Argument\n" "--info-dir=VERZ wie --dir-file=VERZ/dir.\n" "--item=TEXT wie --entry TEXT. Ein Info-Verzeichnis-Eintrag ist " "nämlich\n" " ein Menüpunkt\n" "--quiet Warnungen unterdrücken\n" "--remove wie --delete\n" "--section=ABSCHN stelle die Einträge dieser Datei in den Abschnitt ABSCHN\n" " des Verzeichnisses. Wenn mehr als ein --section " "angegeben\n" " wird, werden alle Einträge in jedem der Abschnitte\n" " hinzugefügt. Wenn gar kein --section angegeben wird, " "wird\n" " der Eintragstext der Info-Datei selbst entnommen.\n" "--version Programmversion anzeigen\n" "\n" "Fehlerberichte (\"bugs\") bitte an schicken.\n" "\n" "Für die deutsche Übersetzung ist die Mailingliste zuständig.\n" #: util/install-info.c:341 msgid "" "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" "\n" "File: dir,\tNode: Top,\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" "* Menu:\n" msgstr "" "Dies ist die Datei .../info/dir, die den obersten Knoten der\n" "Info-Hierarchie enthält, genannt (dir)Top.\n" "Beim ersten Aufruf von Info geht es bei diesem Knoten los.\n" "\n" "Date: dir Knoten: Top Dies ist »top« des INFO-Baums\n" "\n" " Dieser Verzeichnis-Knoten zeigt ein Menü aller Hauptpunkte an.\n" " Beenden mit \"q\", \"?\" listet alle Info-Befehle auf, \"d\" kehrt nach " "hierher\n" " zurück, \"h\" gibt eine Einsteiger-Hilfe,\n" " \"mEmacs\" besucht das Emacs-Manual, etc.\n" "\n" " Im Emacs kann man mit mouse-button-2 auf einen Menüpunkt oder einen\n" " Querverweis klicken, um einen solchen auswählen.\n" "\n" "* Menü:\n" #: util/install-info.c:364 #, c-format msgid "%s: could not read (%s) and could not create (%s)\n" msgstr "%s: kann nicht gelesen (%s) und kann nicht angelegt werden (%s)\n" #: util/install-info.c:464 util/install-info.c:474 #, c-format msgid "%s: Specify the Info directory only once.\n" msgstr "%s: Info-Verzeichnis nur einmal angeben.\n" #: util/install-info.c:502 #, c-format msgid "%s: Specify the Info file only once.\n" msgstr "%s: Info-Datei nur einmal angeben.\n" # checkit #: util/install-info.c:550 #, c-format msgid "excess command line argument `%s'" msgstr "Kommandozeilen-Argument »%s« wird übergangen" #: util/install-info.c:554 msgid "No input file specified; try --help for more information." msgstr "Keine Eingabe-Datei angegeben; »--help« gibt weitere Informationen." #: util/install-info.c:556 msgid "No dir file specified; try --help for more information." msgstr "Keine dir-Datei angegeben; »--help« gibt weitere Informationen." #: util/install-info.c:608 util/install-info.c:631 msgid "START-INFO-DIR-ENTRY without matching END-INFO-DIR-ENTRY" msgstr "START-INFO-DIR-ENTRY ohne END-INFO-DIR-ENTRY" #: util/install-info.c:627 msgid "END-INFO-DIR-ENTRY without matching START-INFO-DIR-ENTRY" msgstr "END-INFO-DIR-ENTRY ohne START-INFO-DIR-ENTRY" #. 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. #: util/install-info.c:641 #, c-format msgid "no info dir entry in `%s'" msgstr "Kein Info-Verzeichnis-Eintrag in »%s«" #: util/install-info.c:852 #, c-format msgid "menu item `%s' already exists, for file `%s'" msgstr "Menüpunkt »%s« bereits vorhanden, für Datei »%s«" #: util/install-info.c:875 #, c-format msgid "no entries found for `%s'; nothing deleted" msgstr "keine Einträge für »%s« gefunden; nichts entfernt" #: util/texindex.c:253 msgid "keep temporary files around after processing" msgstr "temporäre Dateien bis nach der Verarbeitung aufheben" #: util/texindex.c:255 msgid "do not keep temporary files around after processing (default)" msgstr "keine temporäre Dateien bis nach der Verarbeitung aufheben (Standard)" #: util/texindex.c:257 msgid "send output to FILE" msgstr "Ausgabe nach DATEI schicken" #: util/texindex.c:259 msgid "display version information and exit" msgstr "Programmversion anzeigen" #: util/texindex.c:261 msgid "display this help and exit" msgstr "diese Hilfe anzeigen" #: util/texindex.c:272 #, c-format msgid "Usage: %s [OPTION]... FILE...\n" msgstr "Aufruf: %s [OPTION]... DATEI...\n" #: util/texindex.c:273 msgid "Generate a sorted index for each TeX output FILE.\n" msgstr "Erzeuge einen sortierten Index für jede TeX-Ausgabedatei.\n" #. Avoid trigraph nonsense. #: util/texindex.c:275 msgid "Usually FILE... is `foo.??' for a document `foo.texi'.\n" msgstr "DATEI... ist normalerweise »foo.??« für ein Dokument »foo.texi«.\n" #: util/texindex.c:276 msgid "" "\n" "Options:\n" msgstr "" "\n" "Optionen:\n" #: util/texindex.c:290 msgid "" "\n" "Email bug reports to bug-texinfo@gnu.org." msgstr "" "\n" "Fehler (\"bugs\") bitte an melden.\n" "\n" "Für die deutsche Übersetzung ist die Mailingliste zuständig." #: util/texindex.c:917 util/texindex.c:951 util/texindex.c:1027 #: util/texindex.c:1055 #, c-format msgid "%s: not a texinfo index file" msgstr "%s: keine Texinfo-Indexdatei" #: util/texindex.c:1012 #, c-format msgid "failure reopening %s" msgstr "Fehler beim Wiederöffnen von »%s«" # checkit #: util/texindex.c:1325 #, c-format msgid "entry %s follows an entry with a secondary name" msgstr "Eintrag »%s« folgt einem Eintrag mit einem Zweitnamen" #: util/texindex.c:1663 #, c-format msgid "%s; for file `%s'.\n" msgstr "%s; für Datei »%s«.\n" # checkit #: util/texindex.c:1724 #, c-format msgid "Virtual memory exhausted in %s ()! Needed %d bytes." msgstr "Virtual memory exhausted in %s ()! Needed %d bytes." texinfo-3.12/po/fr.gmo0000664000175000017500000007657606477056755012156 0ustar ggÞ•VÌ É| 1¡ŽÓ,b 5š ÐÝåÿ $-:6h.Ÿ(Î÷"+DY0o >¾)ý*' R [ u ” © ¾ %Ï 1õ '!&C!@j!D«!Lð!F="F„"*Ë"%ö"2#O#b#~# ›#©#º#Î# ×#á#%ü##"$F$f$8$!º$Ü$ ø$% #%)D%.n%%£%ª%&¿%æ%#&)&A&P&i& ‚&+£&Ï&á&÷&'&+'3R'F†'"Í'!ð')(<(E(&^(%…(«(Å(Ø(é(ý(;)N)8T))¢) ½)Ë)é)ò) û)* * 3*A*$Z* * *=·*õ*2þ* 1+J?+ Š+B–+Ù+ö+| ,'Š,², Æ,Ñ,ë, û, - -2-Q-g-(y-¢-ª-¯-´-Å-"Ø-"û-.!-.O.k.+….±.$·.EÜ."/B/H/L/ ]/i/ p/}/–/°/+Å/ñ/ 0%0,903f0š0¶0Ó0 ð0$161T1s1%’1¸1Õ1ó1"2122d2m2 r2“2 ¬2#Í2ñ2"3*3!937[3“3¥39·3ñ34 484;S434*Ã4)î4 5%5.5965p5u5‘5§5Á5Æ5#Ö53ú56.6&e6$Œ6±6Ð6%ð607G78Z7“7¯7Î7ì7 8"8)8980H8y8C“84×8 9#9:9"O9(r9!›9&½9ä9û9":6:Q:g:}:–: ³:½:Ô:ë:&;!.;P;>_;ž; ®;»;5Ô;6 <5A<Bw< º<#Û<ÿ<=(>=8g=! =/Â=#ò=7>,N>{>—>›>&¹>+à> ?"?7?+J?!v?˜? ©?µ?¸? ×?7ã?@4$@Y@,v@X£@9ü@C6A>zA(¹A7âA7BBRB•B¨B½BÖB'ðB/CHC#hC@ŒCÍC.åCDD-D$HD=mD/«D!ÛDýD'E#:E*^E,‰E$¶EÛE,ùE&F(,FUF*gF’F&¬FÓFØFìFGG00G>aHš H3;I oIAzI¼IÎI#×IûIJJ##J1GJ6yJ0°J3áJK)%KOKkKK0™K"ÊKCíK(1L2ZLL•L&²LÙLòLM$M.>M!mM5MYÅMcNoƒNfóNKZO;¦O8âO4PPP#cP*‡P²PÆPÝPøP Q Q;'Q$cQ ˆQ!©QAËQ* R8R UR6`R5—R1ÍR1ÿR1S7S‰WÈW8ÑW X%!X GX UXvX}X…X šX»X ÎXÜX4úX6/YfYEYÇY9ÐY ZH#ZlZU}Z#ÓZ÷Z[A¥[!ç[ \\9\J\"[\~\+”\À\Õ\-é\]]'],]-D]!r]#”]¸]3É]3ý]"1^2T^‡^(^K¶^1_4_9_=_ N_Z_b_.z_©_À_2Ñ_`"`9`5J`:€`»`#Ö`#ú`&a'Eama#ˆa$¬a,Ñaþa*b'Fb+nb8šb Ób àb$íb!c)4c%^c„c@ các'ócDd`dwdIŽdØdïd'e&*eCQe;•eBÑeBf Wfcflf?tf ´f(Áfêfg&g.g7Hg:€gO»g4 h+@h-lh&šh+Áh-íhi88iqi)i'ºi#âijj'j?j@Uj–jD¶jEûjAk^k{k-–k3Äk-øk8&l _l€l+žl"Êlílm'm!Dm fmpmŒm&¨m)Ïm#ùmnL1n~n“n#¢n<Æn2oC6oDzo ¿o#ào$p#)p,Mp?zp9ºp9ôp'.q@Vq4—q#Ìq ðq6üq/3r2cr–r®rÆr2ßr)sz-rz" z.Ãz=òz<0{6m{/¤{$Ô{2ù{,|;2|n|5‡|'½|%å| }}1}J}d}›ï {«-ƒ¼V¶Ñ–Ë#æKŒ%LDE8)Hô4“V-K~™+.&>B¾ Zg"o˜õR ‡‚n؈5—1ßU,}Ot °Ìñp½e®S$J•/&=+!Ûó*ðÆQ>mÒúÀ 'IÇ îü)O5㜉0DªÖ¤@²µ?j’*(ýÁRé©ë|êz_i6Ô­„M?Ýwìd19†ûÏÚ FÓP, S( §f4vkÊ/9lhqù÷žGCN;Ù= 0à£B:u`6ò¯b\LcEy'APÐAIå@±"2 W.ÞTJ%áø7Ÿ…¹Õ $ÅUG^#çx³s¦MšºFXr¸¬â¥3Š¿×ö3ÿÎ<‹Í7¨‘ŽÉä ÃHÄÈT8aCNY!þ”»Â<í:·Q2;´[Ü¢¡]€è Try `%s --help' for a complete list of options. * Menu: (File)Node Lines Size Containing File ---------- ----- ---- --------------- * Menu: Nodes whoses indices contain "%s": Options: Source files groveled to make this file include: Subfile: %s for %s from the input file %s. times"" is invalid"%s" is invalid%c%s expected `{...}'%c%s expects `i' or `j' as argument, not `%c'%c%s expects a single character `i' or `j' as argument%c%s expects a single character as an argument%c%s found outside of an insertion block%c%s is obsolete%c%s is obsolete; use %c%s instead%c%s missing close brace%c%s requires a name%cend macro not found%citemx is not meaningful inside of a `%s' block%cmenu seen before first node%cquote-arg only useful when the macro takes a single argument%csp requires a positive numeric argument%ctop used before %cnode, defaulting to %s%d times%s can be invoked via %s.%s can only be invoked via %s.%s for string [%s]: %s is defined to %s.%s is undefined.%s reference to nonexistent node `%s'%s requires an argument: the formatter for %citem%s requires letter or digit%s: %s arg must be numeric, not `%s'. %s: --footnote-style arg must be `separate' or `end', not `%s'. %s: --paragraph-indent arg must be numeric/`none'/`asis', not `%s'. %s: Removing macro output file `%s' due to errors; use --force to preserve. %s: Removing output file `%s' due to errors; use --force to preserve. %s: Skipping macro expansion to stdout as Info output is going there. %s: Specify the Info directory only once. %s: Specify the Info file only once. %s: could not read (%s) and could not create (%s) %s: getwd: %s, %s %s: missing file argument. %s: not a texinfo index file%s: warning: %s:%d: warning: %s; for file `%s'. * Menu: * Menu: * column #%d: output = %s ** Multicolumn output from last row: -%s%s-Info: (%s)%s, %d lines --%s---%s---Info: %s, %d lines --%s----*** Tags out of Date ***--- Use `\[history-node]' or `\[kill-node]' to exit --- ---------- Footnotes ---------- -----Info: (), lines ----, -Footnotes@image file `%s' unreadable: %s@image missing filename argumentAccept (or force completion of) this lineAdd this digit to the current numeric argumentAprilAugustBad argument to %c%sBad argument to `%s', `%s', using `%s'Basic Commands in Info WindowsBroken-Type in insertion_type_pnameBuilding completions...CAN'T SEE THISCancel current operationCancel or quit operationCannot delete a permanent windowCannot execute an `echo-area' command here.Cannot find "%s".Cannot kill node `%s'Cannot kill the last nodeCannot open pipe to "%s".Cannot select column #%d in multitableCannot specify more than one macro expansion outputControls what happens when scrolling is requested at the end of a nodeCould not create output file "%s".Couldn't manipulate the file %s. Couldn't open macro expansion output `%s'DecemberDelete all other windowsDelete the character behind the cursorDelete the character under the cursorDelete the current windowDescribe command: Describe key: %sDescribe variable: Display help messageDivide the available screen space among the visible windowsDone.END-INFO-DIR-ENTRY without matching START-INFO-DIR-ENTRYESC %s is undefined.Enumeration stack overflowExpected `%s'Explain the use of a variableFailing FebruaryFind file: Finding index entries...Follow xref (%s): Follow xref: Following "Next" node...Footnote defined without parent nodeFootnotes could not be displayedFormatting node %s... Found "%s" in %s. (`\[next-index-match]' tries to find next.)FunctionGenerate a sorted index for each TeX output FILE. Get Manpage: Go to the next matching index item from the last `\[index-search]' commandGoto Node: Grovel all known info file's indices for a string and build a menuGrow (or shrink) this windowHere is the %ctop nodeHere is the menu of nodes you have recently visited. Select one from this menu, or use `\[history-node]' in another window. How did @%s end up in cm_special_char? I-search backward: I-search: Index `%s' already existsIndex apropos: Index entry: Insert a TAB characterInsert completionInsert next character verbatimInsert this characterInstance VariableInternally used by \[universal-argument]JanuaryJulyJuneKill node (%s): Kill ring is emptyKill the word following the cursorKill the word preceding the cursorKill this nodeKill to the beginning of the lineKill to the end of the lineList possible completionsLook up a string in the index for this fileMacroMacro `%s' called with too many argsMake a window containing a menu of all of the currently visited nodesMaking %s file `%s' from `%s'. MarchMayMenu item (%s): Menu item: MethodMisplaced %cMissing `}' in %cdef argMove backward a characterMove backward a wordMove backwards or up through node structureMove down to the next lineMove forward a characterMove forward a wordMove forwards or down through node structureMove to the cursor to a specific line of the windowMove to the end of the lineMove to the end of this lineMove to the end of this nodeMove to the next cross referenceMove to the previous cross referenceMove to the start of the lineMove to the start of this lineMove to the start of this nodeMove to the start of this node's menuMove up to the previous lineMoving "Prev" in this window.Moving "Up" in this window.Moving to "Prev"'s last menu item.Must be in a `%s' insertion in order to use `%s'xNO_NAME!NextNo "Next" pointer for this node.No "Prev" for this node.No "Prev" or "Up" for this node.No %sindex entries containing "%s".No `%s' found in `%s'No closing brace for footnote `%s'No completionsNo cross references in this node.No dir file specified; try --help for more information.No index entries.No indices found.No input file specified; try --help for more information.No matching `%cend %s'No more nodes.No previous index search string.Node `%s' missing Up fieldNode `%s' multiply defined (line %d is first definition at)Node `%s' requires a sectioning command (e.g. %c%s)Node `%s''s Next field not pointed back toNode `%s's Prev field not pointed back toNot completeNovemberOctoberPipe the contents of this node through INFO_PRINT_COMMANDPrevPrint documentation for KEYPrinting node "%s"...Printing node "(%s)%s"...QuitQuit using InfoReached eof before matching @end %sRead a command name in the echo area and execute itRead a footnote or cross reference and select its nodeRead a manpage reference and select itRead a menu item and select its nodeRead a node name and select itRead a string and search for itRead the name of a file and select itRead the name of an Info command and describe itRedraw the displaySTART-INFO-DIR-ENTRY without matching END-INFO-DIR-ENTRYScanning indices of "%s"...Scroll backward in this windowScroll forward in this windowScroll the completions windowScroll the other windowSearchSearch backwardSearch failed.Search interactively for a string as you type itSearching subfile "%s"...Select a node which has been previously visited in a visible windowSelect reference or menu item appearing on this lineSelect the `Next' nodeSelect the `Prev' nodeSelect the `Up' nodeSelect the first node in this fileSelect the last item in this node's menuSelect the last node in this fileSelect the most recently selected nodeSelect the next windowSelect the node `(dir)'Select the node `Top' in this fileSelect the previous windowSelect this menu itemSelect visited node: Selecting "Next" node...Selecting first menu item...SeptemberSet %s to value (%d): Set %s to value (%s): Set screen height to (%d): Set the height of the displayed windowSet the value of an Info variableSet variable: Show the footnotes associated with this node in another windowSole completionSpecial FormSplit the current windowStart (or multiply by 4) the current numeric argumentThe `%c%s' command is meaningless within a `@%s' blockThe following commands can only be invoked via M-x: The number lines to scroll when the cursor moves out of the windowThe reference disappeared! (%s).There aren't %d items in this menu.There is no function named `%s'There is no menu in this node.There is no menu item "%s" in this node.This is Info file %s, produced by Makeinfo version %d.%dThis node (`%s') has the bad NextThis node (`%s') is the one with the bad `Prev'This window has no additional nodesToggle the state of line wrapping in the current windowToo many columns in multitable item (max %d)Too many errors! Gave up. TopTranspose characters at pointTry `%s --help' for more information. Unable to find the node referenced by "%s".Unknown command (%s).Unknown command `%s'Unknown index `%s'Unknown index `%s' and/or `%s' in @synindexUnknown index `%s' in @printindexUnmatched `%c%s'Unmatched }UpUsage: %s [OPTION]... FILE... User OptionUsually FILE... is `foo.??' for a document `foo.texi'. VariableVirtual memory exhausted in %s ()! Needed %d bytes.Visit Info node `(info)Help'Visit as many menu items at once as possibleWelcome to Info version %s. "\[get-help-window]" for help, "\[menu-item]" for menu item.When "On", Info accepts and displays ISO Latin charactersWhen "On", Info garbage collects files which had to be uncompressedWhen "On", creating or deleting a window resizes other windowsWhen "On", errors cause the bell to ringWhen "On", flash the screen instead of ringing the bellWhen "On", footnotes appear and disappear automaticallyWhen "On", the portion of the matched search string is highlightedWhere is command: Writing node "%s"...Writing node "(%s)%s"...Yank back a previous killYank back the contents of the last kill`%c%s' needs an argument `{...}', not just `%s'`%c%s' needs something after it`%cend' expected `%s', but saw `%s'`%s' has an Up field of `%s', but `%s' has no menu item for `%s'`%s' is not on any keys`.' or `,' must follow cross reference, not %casiscreating `Top' nodedisplay this help and exitdisplay version information and exitdo not keep temporary files around after processing (default)entry %s follows an entry with a secondary nameexcess command line argument `%s'failure reopening %shere is the previous definition of `%s'ignoring @tab outside of multitableignoring stray text `%s' after @multitablekeep temporary files around after processinglettering overflow, restarting at %cmacro `%s' previously definedmenu item `%s' already exists, for file `%s'more multitable item not in active multitableno entries found no entries found for `%s'; nothing deletedno info dir entry in `%s'node `%s' has been referenced %d timesnonesend output to FILEunreferenced node `%s'virtual memory exhausted{No Value For "%s"}Project-Id-Version: texinfo 3.11 POT-Creation-Date: 1998-03-03 13:32-0500 PO-Revision-Date: 1997-09-16 12:28-04:00 Last-Translator: Laurent Bourbeau Language-Team: French MIME-Version: 1.0 Content-Type: text/plain; charset=8859-1 Content-Transfer-Encoding: 8-bit Pour avoir la liste complète des options, faites «%s --help». * Menu: (Fichier)Noeud Lignes Taille Contenant Fichier(s) -------------- ------ ------ -------------------- * Menu: Noeuds dont les indices contiennent «%s»: Options: Les fichiers sources aplatis pour faire ce fichier incluent: Sous-fichier: %s pour %sà partir du fichier d'entrée «%s». fois"" est invalide«%s» est invalide%c%s exigeant des accolades «{...}»%c%s s'attend à argument «i» ou «j», non pas «%c»%c%s attend un argument d'un seul caractère «i» ou «j»%c%s s'attend à un seul caractère comme argument%c%s est trouvé à l'extérieur d'un bloc d'insertion%c%s est périmé%c%s est périmé; utiliser %c%s à la place%c%s sans accolade fermante%c%s nécessite un nommacro %cend non trouvée%citemx est inactif à l'intérieur d'un bloc «%s»%cmenu avant même le premier noeud%cquote-arg utile seulement lorsque la macro prend un seul argument%csp exige un argument numérique positifnoeud %ctop utilisé avant %cnode, %s implicitement%d fois%s peut être invoqué via %s.%s peut être invoqué seulement via %s.%s pour la chaîne [%s]: %s est défini à %s.%s est non défini.%s réfère au noeud «%s» non existant%s exige un argument: le formateur pour %citem%s exige une lettre ou un chiffre%s: l'argument %s doit être numérique, non pas «%s». %s: l'argument de l'option --footnote-style doit être «separate» ou «end», non pas «%s». %s: l'argument de l'option --paragraph-indent doit être numérique, «none» ou «asis», non pas «%s». %s: Enlèvement du fichier de sortie de macro «%s» à cause d'erreurs; utiliser l'option --force pour préserver. %s: Enlèvement du fichier de sortie «%s» à cause d'erreurs; utiliser l'option --force pour préserver. %s: Sauter l'expansion de macro qui irait sur stdout comme la sortie Info. %s: Spécifier le répertoire Info une seule fois seulement. %s: Spécifier le fichier Info une seule fois seulement. %s: ne peut pas lire (%s) et ne peut pas créer (%s) %s: getwd: %s, %s %s: absence d'un argument fichier. %s: pas un fichier index en format Texinfo%s: AVERTISSEMENT: %s:%d: AVERTISSEMENT: %s; pour le fichier «%s». * Menu: * Menu: * colonne #%d: sortie = %s ** Sortie en multicolonnes à partir de la dernière rangée: -%s%s-Info: (%s)%s, %d lignes --%s---%s---Info: %s, %d lignes --%s----*** Étiquettes passées Date ***--- Utiliser «\[history-node]» ou «\[kill-node]» pour sortir --- --------- Notes en bas de page --------- -----Info: (), lignes ----, -Footnotesfichier «%s» dans la commande @image est illisible: %sabsence d'un argument fichier dans la commande @imageAccepter cette ligne (ou en forcer la complétion)Ajouter ce chiffre à l'argument numérique courantavrilaoûtMauvais argument à %c%sMauvais argument à «%s», «%s», utilisant «%s»Commandes de base en Info WindowsType impossible dans la fonction insertion_type_pnameConstruction des complétions...NE PEUT PAS VOIR CECIAnnuler l'opération couranteAnnuler ou opération de quitterNe peut pas éliminer une fenêtre permanenteNe peut pas exécuter une commande «echo-area» en cet endroit.Ne peut pas trouver «%s».Ne peut pas effacer le noeud «%s»Ne peut pas effacer le dernier noeudNe peut pas ouvrir un tube de communication à «%s».Ne peut pas sélectionner la colonne #%d dans une multitable.Ne peut spécifier plus d'une sortie d'expansion de macroContrôler ce qui arrive lorsqu'un défilement est requis à la fin d'un noeudNe peut pas créer le fichier de sortie «%s».Ne peut pas manipuler le fichier %s. Ne peut ouvrir la sortie d'expansion de macro «%s»décembreÉliminer toutes les autres fenêtresÉliminer le caractère précédent le curseurÉliminer le caractère sous le curseurÉliminer la fenêtre couranteDécrire la commande: Décrire la clé: %sDécrire la variable: Afficher le message d'aideRépartir l'espace écran disponible parmi les fenêtres visiblesTerminé.END-INFO-DIR-ENTRY non apparié avec START-INFO-DIR-ENTRYESC %s est non défini.Débordement de la pile d'énumérations«%s» attendueExpliquer l'usage d'une variableÉchec févrierTrouver le fichier: Recherche des entrées d'index...Suivre xref (%s): Suivre xref: En suivant le noeud «Next»...La note en bas de page est définie sans noeud parentLes notes en bas de page ne peuvent pas être affichéesÉcriture du noeud «%s»... Trouver «%s» dans %s. («\[next-index-match]» cherchera le prochain.)FonctionGénérer un index trié pour chaque FICHIER de sortie TeX. Obtenir la Page-manuel: Passer à la référence suivante de la dernière commande «\[index-search]»Aller au Noeud: Aplatir tous les indices de fichier info connus pour une chaîne et construire un menuAgrandir (ou réduire) cette fenêtreLe noeud %ctop se trouve iciVoici le menu de noeuds que vous avez visité récemment. Sélectionner un noeud de ce menu, ou utiliser «\[history-node]» dans une autre fenêtre. Comment le caractère @%s a-t-il pu aboutir dans cm_special_char? Fouille I-search vers l'arrière: Fouille I-search: L'index «%s» existe toujoursIndex à-propos: Entrée d'index: Insérer un caractère de tabulationInsérer la complétionInsérer le prochain caractère textuellementInsérer ce caractèreVariable d'InstanceUtilisé internement par \[universal-argument]janvierjuilletjuinEffacer le noeud (%s): L'anneau des effacements temporaires est videEffacer le mot suivant le curseurEffacer le mot précédent le curseurEffacer ce noeudEffacer du point courant jusqu'au début de la ligneEffacer du point courant jusqu'à la fin de la ligneÉnumérer les complétions possiblesRechercher une chaîne dans l'index pour ce fichierMacroMacro «%s» appelée avec trop d'argumentsFaire une fenêtre contenant un menu de tous les noeuds actuellement visitésFabrication du fichier %s «%s» à partir de «%s». marsmaiItem menu (%s): Item menu: Méthode%c égarée ou mal placéeAccolade «}» manquante dans le paramètre %cdefReculer d'un caractèreReculer d'un motReculer ou monter à travers la structure de noeudsDescendre à la ligne suivanteAvancer d'un caractèreAvancer d'un motAvancer ou descendre à travers la structure de noeudsDéplacer le curseur sur une ligne spécifique de la fenêtreAller à la fin de la ligneSe déplacer à la fin de cette ligneAller au point terminal de ce noeudAller à la prochaine référence croiséeAller à la référence croisée précédenteAller au début de la ligneSe déplacer au début de cette ligneAller au point de départ de ce noeudAller au point de départ de ce menu de noeudMonter à la ligne précédenteMonter au noeud «Prev» dans cette fenêtre.Aller au noeud «Up» dans cette fenêtre.Aller au dernier item menu du noeud «Prev».Doit être dans une insertion «%s» afin d'utiliser «%s»x.NOM_INCONNU!Noeud «Next»Aucun pointeur «Next» pour ce noeud.Aucun noeud «Prev» pour ce noeud.Aucun noeud «Prev» ou «Up» pour ce noeud.Aucune entrée %sindex contenant «%s».Aucun «%s» trouvé dans «%s»Accolade fermante «}» manquante pour la note en bas de page «%s»Aucune complétionAucune référence croisée dans ce noeud.Aucun fichier dir spécifié; essayer --help pour plus d'informations.Aucune entrée d'index.Aucun indice retrouvé.Aucun fichier d'entrée spécifié; essayer --help pour plus d'informations.«%cend %s» non appariéAucun autre noeud.Aucune autre chaîne de fouille d'index.Le noeud «%s» a un champ «Up» manquantNoeud «%s» ayant plusieurs définitions (ligne %d étant la première)Le noeud «%s» exige une commande de subdivision (e.g. %c%s)Le champ Next du noeud «%s» n'a pas de pointeur de retour en amontLe champ Prev du noeud «%s» n'a pas de pointeur de retour en amontNon completnovembreoctobreAcheminer les contenus de ce noeud à travers INFO_PRINT_COMMANDNoeud «Prev»Imprimer la documentation relative à KEYImpression du noeud «%s»...Impression du noeud «(%s)%s»...QuitterQuitter en utilisant InfoFin de fichier rencontré avant l'appariement de @end %sLire le nom d'une commande dans la zone écho et l'exécuterLire une note en bas de page ou une référence croisée et sélectionner son noeudLire une référence de page-manuel et la sélectionnerLire un item menu et sélectionner son noeudLire un nom de noeud et sélectionner ce noeudLire une chaîne et en faire la fouilleLire le nom d'un fichier et le sélectionnerLire le nom d'une commande Info et la décrireRedessiner l'affichage écranSTART-INFO-DIR-ENTRY non apparié avec END-INFO-DIR-ENTRYFouille des indices de «%s»...Défiler vers l'arrière dans cette fenêtreDéfiler vers l'avant dans cette fenêtreDérouler la fenêtre des complétionsDéfiler l'autre fenêtreFouillerFouiller vers l'arrièreFouille infructueuse.Fouiller interactivement pour une chaîne telle que vous la tapezFouille du sous-fichier «%s»...Sélectionner un noeud qui a déjà été visité dans une fenêtre visibleSélectionner la référence ou l'item menu apparaissant sur cette ligneSélectionner le noeud «Next»Sélectionner le noeud «Prev»Sélectionner le noeud «Up»Sélectionner le premier noeud dans ce fichierSélectionner le dernier item dans ce menu de noeudsSélectionner le dernier noeud dans ce fichierChoisir le noeud qui a été le plus récemment sélectionnéSélectionner la fenêtre suivanteSélectionner le noeud «(dir)»Sélectionner le noeud «Top» dans ce fichierSélectionner la fenêtre précédenteSélectionner cet item menuSélectionner un noeud visité: Sélection du noeud «Next»...Sélection du premier item menu...septembreFixer %s à la valeur (%d): Fixer %s à la valeur (%s): Ajuster la hauteur de l'écran à (%d): Ajuster la hauteur de la fenêtre affichéeFixer la valeur d'une variable InfoFixer la variable: Montrer les notes en bas de page associées à ce noeud dans une autre fenêtreUne seule complétionForme SpécialeDiviser en deux la fenêtre couranteEnclencher (ou multipler par 4) l'argument numérique courantLa commande «%c%s» est inactive dans un bloc «@%s»Les commandes suivantes peuvent être invoquées seulement via M-x: Le nombre de lignes à défiler quand le curseur va hors de la fenêtreLa référence est disparue! (%s).Il n'y a pas %d items dans ce menu.Il n'y a pas de fonction nommée «%s»Il n'y a pas de menu dans ce noeud.Il n'y a pas d'item menu «%s» dans ce noeud.Ceci est le fichier Info %s, produit par Makeinfo version %d.%dCe noeud («%s») est celui dont le champ «Next» est erronéCe noeud («%s») est celui dont le champ «Prev» est erronéCette fenêtre a aucun noeud additionnelBasculer l'état du remplissage de ligne dans la fenêtre couranteTrop de colonnes dans un item de multitable (%d max)Beaucoup trop d'erreurs! Abandon. Noeud «Top»Transposer les caractères en position du point courantPour en savoir davantage, faites: «%s --help». Incappable de trouver le noeud référencé par «%s».Commande inconnue (%s).Commande inconnue «%s».Nom d'index inconnu «%s»Nom d'index «%s» inconnu et/ou «%s» dans @synindexNom d'index «%s» inconnu dans @printindex«%c%s» non appariéAccolade «}» non appariéeNoeud «Up»Usage: %s [OPTION]... FICHIER... Option de l'UsagerHabituellement FICHIER... est «foo.??» pour un document «foo.texi». VariableMémoire virtuelle épuisée dans %s ()! Besoin de %d octets.Visiter le noeud Info «(info)Aide»Visiter d'un seul coup autant d'items menu que possibleBienvenue au mode Info version %s. «\[get-help-window]» pour obtenir de l'aide, «\[menu-item]» pour obtenir l'item menu.Lorsque «On» est en fonction, Info accepte et affiche les caractères ISO LatinLorsque «On» est en fonction, le ramasse-miette Info récolte les fichiers qui devaient être décomprimésLorsque «On» est en fonction, la création ou l'effacement d'une fenêtre réajuste la dimension des autres fenêtresLorsque «On» est en fonction, les erreurs sont signalées par un bruit de clocheLorsque «On» est en fonction, un clignotement d'écran est utilisé plutôt qu'un bruit de clocheLorsque «On» est en fonction, les notes en bas de page apparaissent et disparaissent automatiquementLorsque «On» est en fonction, la portion de la chaîne de fouille appariée est mise en surbrillanceOù se trouve la commande: Écriture du noeud «%s»...Écriture du noeud «(%s)%s»...Recoller un effacement antérieurRecoller le contenu du dernier effacement«%c%s» nécessite un argument «{...}», non pas «%s» seulement«%c%s» a besoin de quelque chose après lui«%cend» attendait «%s», mais a vu «%s»Le noeud «%s» a un champ Up de «%s», mais «%s» n'a aucun item menu pour «%s»«%s» ne se trouve pas sur une quelconque clé«.» ou «,» doit suivre une référence croisée, non pas %c«asis»création du noeud «TOP»afficher cet aide-mémoire et quitterafficher la version en usage et quitterne pas conserver les fichiers temporaires après le traitement (défaut)l'entrée %s suit une entrée ayant un nom secondaireexcédent d'argument de ligne de commande `%s'échec lors de la réouverture de %sici se trouve la définition précédente de «%s»inhibition d'une commande @tab à l'extérieur d'une multitableabandon du texte orphelin «%s» après la commande @multitableconserver les fichiers temporaires après le traitementdébordement du lettrage, reprise à partir de %cmacro «%s» déjà définie précédemmentitem menu «%s» déjà existant, pour le fichier «%s»plus item de multitable qui n'est pas dans une multitable activeaucune entrée retrouvée aucune entrée trouvée pour «%s»; rien n'a été éliminéaucune entrée répertoire Info dans «%s»Le noeud «%s» a été référencé %d fois«none»envoyer la sortie dans FICHIERnoeud «%s» non référencémémoire virtuelle épuisée{Aucune Valeur Pour «%s»}texinfo-3.12/po/cat-id-tbl.c0000664000175000017500000005215106477045601013072 0ustar gg/* Automatically generated by po2tbl.sed from texinfo.pot. */ #if HAVE_CONFIG_H # include #endif #include "libgettext.h" const struct _msg_ent _msg_tbl[] = { {"", 1}, {"Move forward a character", 2}, {"Move backward a character", 3}, {"Move to the start of this line", 4}, {"Move to the end of this line", 5}, {"Move forward a word", 6}, {"Move backward a word", 7}, {"Delete the character under the cursor", 8}, {"Delete the character behind the cursor", 9}, {"Cancel or quit operation", 10}, {"Accept (or force completion of) this line", 11}, {"Insert next character verbatim", 12}, {"Insert this character", 13}, {"Insert a TAB character", 14}, {"Transpose characters at point", 15}, {"Yank back the contents of the last kill", 16}, {"Kill ring is empty", 17}, {"Yank back a previous kill", 18}, {"Kill to the end of the line", 19}, {"Kill to the beginning of the line", 20}, {"Kill the word following the cursor", 21}, {"Kill the word preceding the cursor", 22}, {"Not complete", 23}, {"List possible completions", 24}, {"No completions", 25}, {"Sole completion", 26}, {"One completion:\n", 27}, {"%d completions:\n", 28}, {"Insert completion", 29}, {"Building completions...", 30}, {"Scroll the completions window", 31}, {"Footnotes could not be displayed", 32}, {"Show the footnotes associated with this node in another window", 33}, {"Look up a string in the index for this file", 34}, {"Finding index entries...", 35}, {"No indices found.", 36}, {"Index entry: ", 37}, {"\ Go to the next matching index item from the last `\\[index-search]' command", 38}, {"No previous index search string.", 39}, {"No index entries.", 40}, {"No %sindex entries containing \"%s\".", 41}, {"more ", 42}, {"CAN'T SEE THIS", 43}, {"Found \"%s\" in %s. (`\\[next-index-match]' tries to find next.)", 44}, {"Scanning indices of \"%s\"...", 45}, {"Grovel all known info file's indices for a string and build a menu", 46}, {"Index apropos: ", 47}, {"\ \n\ * Menu: Nodes whoses indices contain \"%s\":\n", 48}, {"Try --help for more information.", 49}, {"\ Copyright (C) %s Free Software Foundation, Inc.\n\ 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", 50}, {"no entries found\n", 51}, {"There is no menu in this node.", 52}, {"There is no menu item \"%s\" in this node.", 53}, {"Unable to find the node referenced by \"%s\".", 54}, {"\ Usage: %s [OPTION]... [INFO-FILE [MENU-ITEM...]]\n\ \n\ Read documentation in Info format.\n\ For more complete documentation on how to use Info, run `info info \ options'.\n\ \n\ Options:\n\ --directory DIR add DIR to INFOPATH.\n\ --dribble FILENAME remember user keystrokes in FILENAME.\n\ --file FILENAME specify Info file to visit.\n\ --node NODENAME specify nodes in first visited Info file.\n\ --output FILENAME output selected nodes to FILENAME.\n\ --restore FILENAME read initial keystrokes from FILENAME.\n\ --subnodes recursively output menu items.\n\ --help display this help and exit.\n\ --version display version information and exit.\n\ \n\ The first argument, if present, is the name of the Info file to read.\n\ Any remaining arguments are treated as the names of menu\n\ items in the initial node visited. For example, `info emacs buffers'\n\ moves to the node `buffers' in the info file `emacs'.\n\ \n\ Email bug reports to bug-texinfo@gnu.org.", 55}, {"Basic Commands in Info Windows", 56}, {"\ The following commands can only be invoked via M-x:\n\ \n", 57}, {"--- Use `\\[history-node]' or `\\[kill-node]' to exit ---\n", 58}, {"Display help message", 59}, {"Visit Info node `(info)Help'", 60}, {"Print documentation for KEY", 61}, {"Describe key: %s", 62}, {"ESC %s is undefined.", 63}, {"%s is undefined.", 64}, {"%s is defined to %s.", 65}, {"Where is command: ", 66}, {"`%s' is not on any keys", 67}, {"%s can only be invoked via %s.", 68}, {"%s can be invoked via %s.", 69}, {"There is no function named `%s'", 70}, {"Read the name of an Info command and describe it", 71}, {"Describe command: ", 72}, {"Read a command name in the echo area and execute it", 73}, {"Cannot execute an `echo-area' command here.", 74}, {"Set the height of the displayed window", 75}, {"Set screen height to (%d): ", 76}, {"\ Source files groveled to make this file include:\n\ \n", 77}, {"Couldn't manipulate the file %s.\n", 78}, {"\ \n\ * Menu:\n\ (File)Node Lines Size Containing File\n\ ---------- ----- ---- ---------------", 79}, {"\ Here is the menu of nodes you have recently visited.\n\ Select one from this menu, or use `\\[history-node]' in another window.\n", 80}, {"Make a window containing a menu of all of the currently visited nodes", 81}, {"Select a node which has been previously visited in a visible window", 82}, {"Select visited node: ", 83}, {"The reference disappeared! (%s).", 84}, {"\ Welcome to Info version %s. \"\\[get-help-window]\" for help, \ \"\\[menu-item]\" for menu item.", 85}, {"Move down to the next line", 86}, {"Move up to the previous line", 87}, {"Move to the end of the line", 88}, {"Move to the start of the line", 89}, {" times", 90}, {"%d times", 91}, {"No \"Next\" pointer for this node.", 92}, {"Following \"Next\" node...", 93}, {"Next", 94}, {"Selecting first menu item...", 95}, {"Selecting \"Next\" node...", 96}, {"Up", 97}, {"No more nodes.", 98}, {"No \"Prev\" for this node.", 99}, {"Moving \"Prev\" in this window.", 100}, {"Prev", 101}, {"No \"Prev\" or \"Up\" for this node.", 102}, {"Moving \"Up\" in this window.", 103}, {"Moving to \"Prev\"'s last menu item.", 104}, {"Move forwards or down through node structure", 105}, {"Move backwards or up through node structure", 106}, {"Scroll forward in this window", 107}, {"Scroll backward in this window", 108}, {"Move to the start of this node", 109}, {"Move to the end of this node", 110}, {"Select the next window", 111}, {"Select the previous window", 112}, {"Split the current window", 113}, {"Delete the current window", 114}, {"Cannot delete a permanent window", 115}, {"Delete all other windows", 116}, {"Scroll the other window", 117}, {"Grow (or shrink) this window", 118}, {"Divide the available screen space among the visible windows", 119}, {"Toggle the state of line wrapping in the current window", 120}, {"Select the `Next' node", 121}, {"Select the `Prev' node", 122}, {"Select the `Up' node", 123}, {"Select the last node in this file", 124}, {"This window has no additional nodes", 125}, {"Select the first node in this file", 126}, {"Select the last item in this node's menu", 127}, {"Select this menu item", 128}, {"There aren't %d items in this menu.", 129}, {"Menu item (%s): ", 130}, {"Menu item: ", 131}, {"Follow xref (%s): ", 132}, {"Follow xref: ", 133}, {"Read a menu item and select its node", 134}, {"Read a footnote or cross reference and select its node", 135}, {"Move to the start of this node's menu", 136}, {"Visit as many menu items at once as possible", 137}, {"Read a node name and select it", 138}, {"Goto Node: ", 139}, {"Read a manpage reference and select it", 140}, {"Get Manpage: ", 141}, {"Select the node `Top' in this file", 142}, {"Top", 143}, {"Select the node `(dir)'", 144}, {"Kill node (%s): ", 145}, {"Cannot kill node `%s'", 146}, {"Cannot kill the last node", 147}, {"Select the most recently selected node", 148}, {"Kill this node", 149}, {"Read the name of a file and select it", 150}, {"Find file: ", 151}, {"Cannot find \"%s\".", 152}, {"Could not create output file \"%s\".", 153}, {"Done.", 154}, {"Writing node \"(%s)%s\"...", 155}, {"Writing node \"%s\"...", 156}, {"Pipe the contents of this node through INFO_PRINT_COMMAND", 157}, {"Cannot open pipe to \"%s\".", 158}, {"Printing node \"(%s)%s\"...", 159}, {"Printing node \"%s\"...", 160}, {"Searching subfile \"%s\"...", 161}, {"Read a string and search for it", 162}, {"%s for string [%s]: ", 163}, {"Search backward", 164}, {"Search", 165}, {"Search failed.", 166}, {"Search interactively for a string as you type it", 167}, {"I-search backward: ", 168}, {"I-search: ", 169}, {"Failing ", 170}, {"No cross references in this node.", 171}, {"Move to the previous cross reference", 172}, {"Move to the next cross reference", 173}, {"Select reference or menu item appearing on this line", 174}, {"Cancel current operation", 175}, {"Quit", 176}, {"Move to the cursor to a specific line of the window", 177}, {"Redraw the display", 178}, {"Quit using Info", 179}, {"Unknown command (%s).", 180}, {"\"\" is invalid", 181}, {"\"%s\" is invalid", 182}, {"Add this digit to the current numeric argument", 183}, {"Start (or multiply by 4) the current numeric argument", 184}, {"Internally used by \\[universal-argument]", 185}, {"readline: Out of virtual memory!\n", 186}, {"When \"On\", footnotes appear and disappear automatically", 187}, {"When \"On\", creating or deleting a window resizes other windows", 188}, {"When \"On\", flash the screen instead of ringing the bell", 189}, {"When \"On\", errors cause the bell to ring", 190}, {"When \"On\", Info garbage collects files which had to be uncompressed", 191}, {"When \"On\", the portion of the matched search string is highlighted", 192}, {"Controls what happens when scrolling is requested at the end of a node", 193}, {"The number lines to scroll when the cursor moves out of the window", 194}, {"When \"On\", Info accepts and displays ISO Latin characters", 195}, {"Explain the use of a variable", 196}, {"Describe variable: ", 197}, {"Set the value of an Info variable", 198}, {"Set variable: ", 199}, {"Set %s to value (%d): ", 200}, {"Set %s to value (%s): ", 201}, {"--*** Tags out of Date ***", 202}, {"-----Info: (), lines ----, ", 203}, {"-%s---Info: %s, %d lines --%s--", 204}, {"-%s%s-Info: (%s)%s, %d lines --%s--", 205}, {" Subfile: %s", 206}, {"%s: option `%s' is ambiguous\n", 207}, {"%s: option `--%s' doesn't allow an argument\n", 208}, {"%s: option `%c%s' doesn't allow an argument\n", 209}, {"%s: option `%s' requires an argument\n", 210}, {"%s: unrecognized option `--%s'\n", 211}, {"%s: unrecognized option `%c%s'\n", 212}, {"%s: illegal option -- %c\n", 213}, {"%s: invalid option -- %c\n", 214}, {"%s: option requires an argument -- %c\n", 215}, {"%s: option `-W %s' is ambiguous\n", 216}, {"%s: option `-W %s' doesn't allow an argument\n", 217}, {"%s:%d: warning: ", 218}, {"Too many errors! Gave up.\n", 219}, {"%s: %s arg must be numeric, not `%s'.\n", 220}, {"Couldn't open macro expansion output `%s'", 221}, {"Cannot specify more than one macro expansion output", 222}, {"%s: --paragraph-indent arg must be numeric/`none'/`asis', not `%s'.\n", 223}, {"%s: --footnote-style arg must be `separate' or `end', not `%s'.\n", 224}, {"%s: missing file argument.\n", 225}, {"Try `%s --help' for more information.\n", 226}, {"\ Usage: %s [OPTION]... TEXINFO-FILE...\n\ \n\ Translate Texinfo source documentation to a format suitable for reading\n\ with GNU Info.\n\ \n\ Options:\n\ -D VAR define a variable, as with @set.\n\ -E MACRO-OFILE process macros only, output texinfo source.\n\ -I DIR append DIR to the @include directory search path.\n\ -P DIR prepend DIR to the @include directory search path.\n\ -U VAR undefine a variable, as with @clear.\n\ --error-limit NUM quit after NUM errors (default %d).\n\ --fill-column NUM break lines at NUM characters (default %d).\n\ --footnote-style STYLE output footnotes according to STYLE:\n\ `separate' to place footnotes in their own node,\n\ `end' to place the footnotes at the end of\n\ the node in which they are defined (the default).\n\ --force preserve output even if errors.\n\ --help display this help and exit.\n\ --no-validate suppress node cross-reference validation.\n\ --no-warn suppress warnings (but not errors).\n\ --no-split suppress splitting of large files.\n\ --no-headers suppress node separators and Node: Foo headers.\n\ --output FILE, -o FILE output to FILE, and ignore any @setfilename.\n\ --paragraph-indent VAL indent paragraphs with VAL spaces (default %d).\n\ if VAL is `none', do not indent; if VAL is `asis',\n\ preserve any existing indentation.\n\ --reference-limit NUM complain about at most NUM references (default %d).\n\ --verbose report about what is being done.\n\ --version display version information and exit.\n\ \n\ Email bug reports to bug-texinfo@gnu.org.\n", 227}, {"%s: getwd: %s, %s\n", 228}, {"Expected `%s'", 229}, {"No `%s' found in `%s'", 230}, {"%s: Skipping macro expansion to stdout as Info output is going there.\n", 231}, {"Making %s file `%s' from `%s'.\n", 232}, {"This is Info file %s, produced by Makeinfo version %d.%d", 233}, {" from the input file %s.\n", 234}, {"\ %s: Removing macro output file `%s' due to errors; use --force to preserve.\n", 235}, {"%s: Removing output file `%s' due to errors; use --force to preserve.\n", 236}, {"Misplaced %c", 237}, {"Unknown command `%s'", 238}, {"NO_NAME!", 239}, {"%c%s expected `{...}'", 240}, {"Unmatched }", 241}, {"%c%s missing close brace", 242}, {"Broken-Type in insertion_type_pname", 243}, {"Enumeration stack overflow", 244}, {"lettering overflow, restarting at %c", 245}, {"* Menu:\n", 246}, {"%s requires an argument: the formatter for %citem", 247}, {"`%cend' expected `%s', but saw `%s'", 248}, {"No matching `%cend %s'", 249}, {"How did @%s end up in cm_special_char?\n", 250}, {"%c%s expects `i' or `j' as argument, not `%c'", 251}, {"%c%s expects a single character `i' or `j' as argument", 252}, {"January", 253}, {"February", 254}, {"March", 255}, {"April", 256}, {"May", 257}, {"June", 258}, {"July", 259}, {"August", 260}, {"September", 261}, {"October", 262}, {"November", 263}, {"December", 264}, {"%c%s expects a single character as an argument", 265}, {"%c%s is obsolete", 266}, {"Node with %ctop as a section already exists", 267}, {"Here is the %ctop node", 268}, {"%ctop used before %cnode, defaulting to %s", 269}, {"%c%s is obsolete; use %c%s instead", 270}, {"Node `%s' multiply defined (line %d is first definition at)", 271}, {"Formatting node %s...\n", 272}, {"Node `%s' requires a sectioning command (e.g. %c%s)", 273}, {"Node `%s''s Next field not pointed back to", 274}, {"This node (`%s') is the one with the bad `Prev'", 275}, {"Node `%s's Prev field not pointed back to", 276}, {"This node (`%s') has the bad Next", 277}, {"Node `%s' missing Up field", 278}, {"`%s' has an Up field of `%s', but `%s' has no menu item for `%s'", 279}, {"node `%s' has been referenced %d times", 280}, {"unreferenced node `%s'", 281}, {"%s reference to nonexistent node `%s'", 282}, {"%cmenu seen before first node", 283}, {"creating `Top' node", 284}, {"`.' or `,' must follow cross reference, not %c", 285}, {"@image file `%s' unreadable: %s", 286}, {"@image missing filename argument", 287}, {"%s requires letter or digit", 288}, {"Unmatched `%c%s'", 289}, {"`%c%s' needs something after it", 290}, {"Bad argument to `%s', `%s', using `%s'", 291}, {"{No Value For \"%s\"}", 292}, {"%c%s requires a name", 293}, {"Reached eof before matching @end %s", 294}, {"The `%c%s' command is meaningless within a `@%s' block", 295}, {"%citemx is not meaningful inside of a `%s' block", 296}, {"%c%s found outside of an insertion block", 297}, {"Missing `}' in %cdef arg", 298}, {"Function", 299}, {"Macro", 300}, {"Special Form", 301}, {"Variable", 302}, {"User Option", 303}, {"Instance Variable", 304}, {"Method", 305}, {"Must be in a `%s' insertion in order to use `%s'x", 306}, {"%csp requires a positive numeric argument", 307}, {"asis", 308}, {"none", 309}, {"Bad argument to %c%s", 310}, {"Unknown index `%s'", 311}, {"Index `%s' already exists", 312}, {"Unknown index `%s' and/or `%s' in @synindex", 313}, {"Unknown index `%s' in @printindex", 314}, {"\ * Menu:\n\ \n", 315}, {"`%c%s' needs an argument `{...}', not just `%s'", 316}, {"No closing brace for footnote `%s'", 317}, {"Footnote defined without parent node", 318}, {"-Footnotes", 319}, {"\ ---------- Footnotes ----------\n\ \n", 320}, {"macro `%s' previously defined", 321}, {"here is the previous definition of `%s'", 322}, {"Macro `%s' called with too many args", 323}, {"%cend macro not found", 324}, {"%cquote-arg only useful when the macro takes a single argument", 325}, {"ignoring stray text `%s' after @multitable", 326}, {"Too many columns in multitable item (max %d)", 327}, {"multitable item not in active multitable", 328}, {"Cannot select column #%d in multitable", 329}, {"ignoring @tab outside of multitable", 330}, {"** Multicolumn output from last row:\n", 331}, {"* column #%d: output = %s\n", 332}, {"virtual memory exhausted", 333}, {"%s: warning: ", 334}, {" for %s", 335}, {"\tTry `%s --help' for a complete list of options.\n", 336}, {"\ Usage: %s [OPTION]... [INFO-FILE [DIR-FILE]]\n\ \n\ Install INFO-FILE in the Info directory file DIR-FILE.\n\ \n\ Options:\n\ --delete Delete existing entries in INFO-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\ \n\ Email bug reports to bug-texinfo@gnu.org.\n", 337}, {"\ 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\ \n\ File: dir,\tNode: Top,\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\ * Menu:\n", 338}, {"%s: could not read (%s) and could not create (%s)\n", 339}, {"%s: Specify the Info directory only once.\n", 340}, {"%s: Specify the Info file only once.\n", 341}, {"excess command line argument `%s'", 342}, {"No input file specified; try --help for more information.", 343}, {"No dir file specified; try --help for more information.", 344}, {"START-INFO-DIR-ENTRY without matching END-INFO-DIR-ENTRY", 345}, {"END-INFO-DIR-ENTRY without matching START-INFO-DIR-ENTRY", 346}, {"no info dir entry in `%s'", 347}, {"menu item `%s' already exists, for file `%s'", 348}, {"no entries found for `%s'; nothing deleted", 349}, {"keep temporary files around after processing", 350}, {"do not keep temporary files around after processing (default)", 351}, {"send output to FILE", 352}, {"display version information and exit", 353}, {"display this help and exit", 354}, {"Usage: %s [OPTION]... FILE...\n", 355}, {"Generate a sorted index for each TeX output FILE.\n", 356}, {"Usually FILE... is `foo.??' for a document `foo.texi'.\n", 357}, {"\ \n\ Options:\n", 358}, {"\ \n\ Email bug reports to bug-texinfo@gnu.org.", 359}, {"%s: not a texinfo index file", 360}, {"failure reopening %s", 361}, {"entry %s follows an entry with a secondary name", 362}, {"%s; for file `%s'.\n", 363}, {"Virtual memory exhausted in %s ()! Needed %d bytes.", 364}, }; int _msg_tbl_length = 364; texinfo-3.12/po/POTFILES.in0000644000175000017500000000060406477056571012565 0ustar gg# List of source files containing translatable strings. # The last line must not be a comment. info/echo-area.c info/footnotes.c info/footnotes.h info/indices.c info/info.c info/info.h info/infodoc.c info/m-x.c info/makedoc.c info/nodemenu.c info/session.c info/tilde.c info/variables.c info/window.c lib/getopt.c makeinfo/makeinfo.c makeinfo/multi.c util/install-info.c util/texindex.c texinfo-3.12/config.guess0000555000175000017500000005774506465660636012732 0ustar gg#! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc. # # 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 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. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Written by Per Bothner . # The master version of this file is at the FSF in /home/gd/gnu/lib. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # The plan is that this can be called by configure scripts if you # don't specify an explicit system type (host/target name). # # Only a few systems have been added to this list; please add others # (but try to keep the structure clean). # # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 8/24/94.) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15 # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in alpha:OSF1:*:*) if test $UNAME_RELEASE = "V4.0"; then UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` fi # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. cat <dummy.s .globl main .ent main main: .frame \$30,0,\$26,0 .prologue 0 .long 0x47e03d80 # implver $0 lda \$2,259 .long 0x47e20c21 # amask $2,$1 srl \$1,8,\$2 sll \$2,2,\$2 sll \$0,3,\$0 addl \$1,\$0,\$0 addl \$2,\$0,\$0 ret \$31,(\$26),1 .end main EOF ${CC-cc} dummy.s -o dummy 2>/dev/null if test "$?" = 0 ; then ./dummy case "$?" in 7) UNAME_MACHINE="alpha" ;; 15) UNAME_MACHINE="alphaev5" ;; 14) UNAME_MACHINE="alphaev56" ;; 10) UNAME_MACHINE="alphapca56" ;; 16) UNAME_MACHINE="alphaev6" ;; esac fi rm -f dummy.s dummy echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr [[A-Z]] [[a-z]]` exit 0 ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit 0 ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-cbm-sysv4 exit 0;; amiga:NetBSD:*:*) echo m68k-cbm-netbsd${UNAME_RELEASE} exit 0 ;; amiga:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; arc64:OpenBSD:*:*) echo mips64el-unknown-openbsd${UNAME_RELEASE} exit 0 ;; arc:OpenBSD:*:*) echo mipsel-unknown-openbsd${UNAME_RELEASE} exit 0 ;; hkmips:OpenBSD:*:*) echo mips-unknown-openbsd${UNAME_RELEASE} exit 0 ;; pmax:OpenBSD:*:*) echo mipsel-unknown-openbsd${UNAME_RELEASE} exit 0 ;; sgi:OpenBSD:*:*) echo mips-unknown-openbsd${UNAME_RELEASE} exit 0 ;; wgrisc:OpenBSD:*:*) echo mipsel-unknown-openbsd${UNAME_RELEASE} exit 0 ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit 0;; arm32:NetBSD:*:*) echo arm-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` exit 0 ;; SR2?01:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit 0;; Pyramid*:OSx*:*:*|MIS*:OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit 0 ;; NILE:*:*:dcosx) echo pyramid-pyramid-svr4 exit 0 ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; i86pc:SunOS:5.*:*) echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit 0 ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit 0 ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit 0 ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit 0 ;; atari*:NetBSD:*:*) echo m68k-atari-netbsd${UNAME_RELEASE} exit 0 ;; atari*:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; sun3*:NetBSD:*:*) echo m68k-sun-netbsd${UNAME_RELEASE} exit 0 ;; sun3*:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mac68k:NetBSD:*:*) echo m68k-apple-netbsd${UNAME_RELEASE} exit 0 ;; mac68k:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mvme68k:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mvme88k:OpenBSD:*:*) echo m88k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit 0 ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit 0 ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit 0 ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit 0 ;; 2020:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit 0 ;; mips:*:*:UMIPS | mips:*:*:RISCos) sed 's/^ //' << EOF >dummy.c int main (argc, argv) int argc; char **argv; { #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF ${CC-cc} dummy.c -o dummy \ && ./dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ && rm dummy.c dummy && exit 0 rm -f dummy.c dummy echo mips-mips-riscos${UNAME_RELEASE} exit 0 ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit 0 ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit 0 ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit 0 ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit 0 ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \ -o ${TARGET_BINARY_INTERFACE}x = x ] ; then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit 0 ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit 0 ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit 0 ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit 0 ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit 0 ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit 0 ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i?86:AIX:*:*) echo i386-ibm-aix exit 0 ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then sed 's/^ //' << EOF >dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0 rm -f dummy.c dummy echo rs6000-ibm-aix3.2.5 elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit 0 ;; *:AIX:*:4) if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=4.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit 0 ;; *:AIX:*:*) echo rs6000-ibm-aix exit 0 ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit 0 ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit 0 ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit 0 ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit 0 ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit 0 ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit 0 ;; 9000/[3478]??:HP-UX:*:*) case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/7?? | 9000/8?[1679] ) HP_ARCH=hppa1.1 ;; 9000/8?? ) HP_ARCH=hppa1.0 ;; esac HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit 0 ;; 3050*:HI-UX:*:*) sed 's/^ //' << EOF >dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0 rm -f dummy.c dummy echo unknown-hitachi-hiuxwe2 exit 0 ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit 0 ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit 0 ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit 0 ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit 0 ;; i?86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit 0 ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit 0 ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit 0 ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit 0 ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit 0 ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit 0 ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit 0 ;; CRAY*X-MP:*:*:*) echo xmp-cray-unicos exit 0 ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} exit 0 ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ exit 0 ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} exit 0 ;; CRAY-2:*:*:*) echo cray2-cray-unicos exit 0 ;; F300:UNIX_System_V:*:*) FUJITSU_SYS=`uname -p | tr [A-Z] [a-z] | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit 0 ;; F301:UNIX_System_V:*:*) echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'` exit 0 ;; hp3[0-9][05]:NetBSD:*:*) echo m68k-hp-netbsd${UNAME_RELEASE} exit 0 ;; hp300:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; i?86:BSD/386:*:* | *:BSD/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit 0 ;; *:FreeBSD:*:*) echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit 0 ;; *:NetBSD:*:*) echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` exit 0 ;; *:OpenBSD:*:*) echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` exit 0 ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin32 exit 0 ;; i*:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit 0 ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin32 exit 0 ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; *:GNU:*:*) echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit 0 ;; *:Linux:*:*) # uname on the ARM produces all sorts of strangeness, and we need to # filter it out. case "$UNAME_MACHINE" in arm* | sa110*) UNAME_MACHINE="arm" ;; esac # The BFD linker knows what the default object file format is, so # first see if it will tell us. ld_help_string=`ld --help 2>&1` ld_supported_emulations=`echo $ld_help_string \ | sed -ne '/supported emulations:/!d s/[ ][ ]*/ /g s/.*supported emulations: *// s/ .*// p'` case "$ld_supported_emulations" in i?86linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" ; exit 0 ;; i?86coff) echo "${UNAME_MACHINE}-pc-linux-gnucoff" ; exit 0 ;; sparclinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;; armlinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;; m68klinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;; elf32ppc) echo "powerpc-unknown-linux-gnu" ; exit 0 ;; esac if test "${UNAME_MACHINE}" = "alpha" ; then sed 's/^ //' <dummy.s .globl main .ent main main: .frame \$30,0,\$26,0 .prologue 0 .long 0x47e03d80 # implver $0 lda \$2,259 .long 0x47e20c21 # amask $2,$1 srl \$1,8,\$2 sll \$2,2,\$2 sll \$0,3,\$0 addl \$1,\$0,\$0 addl \$2,\$0,\$0 ret \$31,(\$26),1 .end main EOF LIBC="" ${CC-cc} dummy.s -o dummy 2>/dev/null if test "$?" = 0 ; then ./dummy case "$?" in 7) UNAME_MACHINE="alpha" ;; 15) UNAME_MACHINE="alphaev5" ;; 14) UNAME_MACHINE="alphaev56" ;; 10) UNAME_MACHINE="alphapca56" ;; 16) UNAME_MACHINE="alphaev6" ;; esac objdump --private-headers dummy | \ grep ld.so.1 > /dev/null if test "$?" = 0 ; then LIBC="libc1" fi fi rm -f dummy.s dummy echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0 elif test "${UNAME_MACHINE}" = "mips" ; then cat >dummy.c </dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0 rm -f dummy.c dummy else # Either a pre-BFD a.out linker (linux-gnuoldld) # or one that does not give us useful --help. # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout. # If ld does not provide *any* "supported emulations:" # that means it is gnuoldld. echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:" test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0 case "${UNAME_MACHINE}" in i?86) VENDOR=pc; ;; *) VENDOR=unknown; ;; esac # Determine whether the default compiler is a.out or elf cat >dummy.c < main(argc, argv) int argc; char *argv[]; { #ifdef __ELF__ # ifdef __GLIBC__ # if __GLIBC__ >= 2 printf ("%s-${VENDOR}-linux-gnu\n", argv[1]); # else printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); # endif # else printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); # endif #else printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]); #endif return 0; } EOF ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0 rm -f dummy.c dummy fi ;; # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions # are messed up and put the nodename in both sysname and nodename. i?86:DYNIX/ptx:4*:*) echo i386-sequent-sysv4 exit 0 ;; i?86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit 0 ;; i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*) if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE} fi exit 0 ;; i?86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit 0 ;; pc:*:*:*) # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i386. echo i386-pc-msdosdjgpp exit 0 ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit 0 ;; paragon:*:*:*) echo i860-intel-osf1 exit 0 ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit 0 ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit 0 ;; M68*:*:R3V[567]*:*) test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && echo i486-ncr-sysv4.3${OS_REL} && exit 0 /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && echo i486-ncr-sysv4 && exit 0 ;; m68*:LynxOS:2.*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit 0 ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit 0 ;; i?86:LynxOS:2.*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit 0 ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit 0 ;; rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit 0 ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit 0 ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit 0 ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit 0 ;; PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit 0 ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit 0 ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit 0 ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit 0 ;; news*:NEWS-OS:*:6*) echo mips-sony-newsos6 exit 0 ;; R3000:*System_V*:*:* | R4000:UNIX_SYSV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit 0 ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 cat >dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) #if !defined (ultrix) printf ("vax-dec-bsd\n"); exit (0); #else printf ("vax-dec-ultrix\n"); exit (0); #endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0 rm -f dummy.c dummy # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit 0 ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit 0 ;; c34*) echo c34-convex-bsd exit 0 ;; c38*) echo c38-convex-bsd exit 0 ;; c4*) echo c4-convex-bsd exit 0 ;; esac fi #echo '(Unable to guess system type)' 1>&2 exit 1 texinfo-3.12/install-sh0000775000175000017500000001256206171265722012375 0ustar gg#! /bin/sh # # install - install a program, script, or datafile # This comes from X11R5 (mit/util/scripts/install.sh). # # Copyright 1991 by the Massachusetts Institute of Technology # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that # the above copyright notice appear in all copies and that both that # copyright notice and this permission notice appear in supporting # documentation, and that the name of M.I.T. not be used in advertising or # publicity pertaining to distribution of the software without specific, # written prior permission. M.I.T. makes no representations about the # suitability of this software for any purpose. It is provided "as is" # without express or implied warranty. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. # # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 texinfo-3.12/makeinfo/0000775000175000017500000000000006477056752012166 5ustar ggtexinfo-3.12/makeinfo/multi.c0000444000175000017500000003061506365750234013455 0ustar gg/* multi.c -- multitable stuff for makeinfo. $Id: multi.c,v 1.9 1997/07/24 22:01:00 karl Exp $ Copyright (C) 1996, 97 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, USA. */ #include "system.h" #include "makeinfo.h" #define MAXCOLS 100 /* remove this limit later @@ */ /* * Output environments. This is a hack grafted onto existing * structure. The "output environment" used to consist of the * global variables `output_paragraph', `fill_column', etc. * Routines like add_char would manipulate these variables. * * Now, when formatting a multitable, we maintain separate environments * for each column. That way we can build up the columns separately * and write them all out at once. The "current" output environment" * is still kept in those global variables, so that the old output * routines don't have to change. But we provide routines to save * and restore these variables in an "environment table". The * `select_output_environment' function switches from one output * environment to another. * * Environment #0 (i.e., element #0 of the table) is the regular * environment that is used when we're not formatting a multitable. * * Environment #N (where N = 1,2,3,...) is the env. for column #N of * the table, when a multitable is active. */ /* contents of an output environment */ /* some more vars may end up being needed here later @@ */ struct env { unsigned char *output_paragraph; int output_paragraph_offset; int output_column; int paragraph_is_open; int current_indent; int fill_column; } envs[MAXCOLS]; /* the environment table */ /* index in environment table of currently selected environment */ static int current_env_no; /* column number of last column in current multitable */ static int last_column; /* flags indicating whether horizontal and vertical separators need to be drawn, separating rows and columns in the current multitable. */ static int hsep, vsep; /* Output a row. Have to keep `output_position' up-to-date for each character we output, or the tags table will be off, leading to chopped-off output files and undefined nodes (because they're in the wrong file, etc.). Perhaps it would be better to accumulate this value somewhere and add it once at the end of the table, or return it as the value, but this seems simplest. */ static void out_char (ch) int ch; { extern int output_position; putc (ch, output_stream); output_position++; } void draw_horizontal_separator () { int i, j, s; for (s = 0; s < envs[0].current_indent; s++) out_char (' '); if (vsep) out_char ('+'); for (i = 1; i <= last_column; i++) { for (j = 0; j <= envs[i].fill_column; j++) out_char ('-'); if (vsep) out_char ('+'); } out_char ('\n'); } void do_multitable () { int ncolumns; /* * multitable strategy: * for each item { * for each column in an item { * initialize a new paragraph * do ordinary formatting into the new paragraph * save the paragraph away * repeat if there are more paragraphs in the column * } * dump out the saved paragraphs and free the storage * } */ if (multitable_active) { line_error ("Multitables cannot be nested"); return; } /* scan the current item function to get the field widths and number of columns, and set up the output environment list accordingly. */ ncolumns = setup_multitable_parameters (); if (hsep) draw_horizontal_separator (); /* The next @item command will direct stdout into the first column and start processing. @tab will then switch to the next column, and @item will flush out the saved output and return to the first column. Environment #1 is the first column. (Environment #0 is the normal output) */ ++multitable_active; } /* Read the parameters for a multitable from the current command line, save the parameters away, and return the number of columns. */ int setup_multitable_parameters () { char *params = insertion_stack->item_function; int nchars; float columnfrac; char command[200]; /* naughty, should be no fixed limits */ int i = 1; /* We implement @hsep and @vsep even though TeX doesn't. We don't get mixing of @columnfractions and templates right, but TeX doesn't either. */ hsep = vsep = 0; while (*params) { while (whitespace (*params)) params++; if (*params == '@') { sscanf (params, "%200s", command); nchars = strlen (command); params += nchars; if (strcmp (command, "@hsep") == 0) hsep++; else if (strcmp (command, "@vsep") == 0) vsep++; else if (strcmp (command, "@columnfractions") == 0) { /* Clobber old environments and create new ones, starting at #1. Environment #0 is the normal output, so don't mess with it. */ for ( ; i <= MAXCOLS; i++) { if (sscanf (params, "%f", &columnfrac) < 1) goto done; /* Unfortunately, can't use %n since some m68k-hp-bsd libc doesn't support it. So skip whitespace (preceding the number) and then non-whitespace (the number). */ while (*params && (*params == ' ' || *params == '\t')) params++; /* Hmm, but what what @columnfractions 3foo. Well, I suppose it's invalid input anyway. */ while (*params && *params != ' ' && *params != '\t' && *params != '\n' && *params != '@') params++; setup_output_environment (i, (int) (columnfrac * (fill_column - current_indent) + .5)); } } } else if (*params == '{') { char *start = params; while ((*params != '}' || params[-1] == '@') && *params) { params++; } /* This gives us two spaces between columns. Seems reasonable. Really should expand the text, though, so a template of `@code{foo}' has a width of five, not ten. Also have to match braces, then. How to take into account current_indent here? */ setup_output_environment (i++, params++ - start); } else { warning (_("ignoring stray text `%s' after @multitable"), params); break; } } done: flush_output (); inhibit_output_flushing (); last_column = i - 1; return last_column; } /* Initialize environment number ENV_NO, of width WIDTH. The idea is that we're going to use one environment for each column of a multitable, so we can build them up separately and print them all out at the end. */ int setup_output_environment (env_no, width) int env_no; int width; { int old_env = select_output_environment (env_no); /* clobber old environment and set width of new one */ init_paragraph (); /* make our change */ fill_column = width; /* Save new environment and restore previous one. */ select_output_environment (old_env); return env_no; } /* Direct current output to environment number N. Used when switching work from one column of a multitable to the next. Returns previous environment number. */ int select_output_environment (n) int n; { struct env *e = &envs[current_env_no]; int old_env_no = current_env_no; /* stash current env info from global vars into the old environment */ e->output_paragraph = output_paragraph; e->output_paragraph_offset = output_paragraph_offset; e->output_column = output_column; e->paragraph_is_open = paragraph_is_open; e->current_indent = current_indent; e->fill_column = fill_column; /* now copy new environment into global vars */ current_env_no = n; e = &envs[current_env_no]; output_paragraph = e->output_paragraph; output_paragraph_offset = e->output_paragraph_offset; output_column = e->output_column; paragraph_is_open = e->paragraph_is_open; current_indent = e->current_indent; fill_column = e->fill_column; return old_env_no; } /* advance to the next environment number */ void nselect_next_environment () { if (current_env_no >= last_column) { line_error (_("Too many columns in multitable item (max %d)"), last_column); return; } select_output_environment (current_env_no + 1); } static void output_multitable_row (); /* do anything needed at the beginning of processing a multitable column. */ void init_column () { /* don't indent 1st paragraph in the item */ cm_noindent (); /* throw away possible whitespace after @item or @tab command */ skip_whitespace (); } /* start a new item (row) of a multitable */ int multitable_item () { if (!multitable_active) { /* impossible, I think. */ error (_("multitable item not in active multitable")); exit (1); } if (current_env_no > 0) { output_multitable_row (); } /* start at column 1 */ select_output_environment (1); if (!output_paragraph) { line_error (_("Cannot select column #%d in multitable"), current_env_no); exit (FATAL); } init_column (); return 0; } static void output_multitable_row () { int i, j, s, remaining; /* offset in the output paragraph of the next char needing to be output for that column. */ int offset[MAXCOLS]; for (i = 0; i <= last_column; i++) offset[i] = 0; /* select the current environment, to make sure the env variables get updated */ select_output_environment (current_env_no); #define CHAR_ADDR(n) (offset[i] + (n)) #define CHAR_AT(n) (envs[i].output_paragraph[CHAR_ADDR(n)]) /* remove trailing whitespace from each column */ for (i = 1; i <= last_column; i++) { while (cr_or_whitespace (CHAR_AT (envs[i].output_paragraph_offset - 1))) { envs[i].output_paragraph_offset--; } } /* read the current line from each column, outputting them all pasted together. Do this til all lines are output from all columns. */ for (;;) { remaining = 0; /* first, see if there is any work to do */ for (i = 1; i <= last_column; i++) { if (CHAR_ADDR (0) < envs[i].output_paragraph_offset) { remaining = 1; break; } } if (!remaining) break; for (s = 0; s < envs[0].current_indent; s++) out_char (' '); if (vsep) out_char ('|'); for (i = 1; i <= last_column; i++) { for (s = 0; i < envs[i].current_indent; s++) out_char (' '); for (j = 0; CHAR_ADDR (j) < envs[i].output_paragraph_offset; j++) { if (CHAR_AT (j) == '\n') break; out_char (CHAR_AT (j)); } offset[i] += j + 1; /* skip last text plus skip the newline */ for (; j <= envs[i].fill_column; j++) out_char (' '); if (vsep) out_char ('|'); /* draw column separator */ } out_char ('\n'); /* end of line */ } if (hsep) draw_horizontal_separator (); /* Now dispose of the buffered output. */ for (i = 1; i <= last_column; i++) { select_output_environment (i); init_paragraph (); } } #undef CHAR_AT #undef CHAR_ADDR /* select a new column in current row of multitable */ void cm_tab () { if (!multitable_active) error (_("ignoring @tab outside of multitable")); nselect_next_environment (); init_column (); } /* close a multitable, flushing its output and resetting whatever needs resetting */ void end_multitable () { output_multitable_row (); /* Multitables cannot be nested. Otherwise, we'd have to save the previous output environment number on a stack somewhere, and then restore to that environment. */ select_output_environment (0); close_paragraph (); insert ('\n'); /* we swallow newlines, so insert one of our own */ multitable_active = 0; uninhibit_output_flushing (); #if 0 printf (_("** Multicolumn output from last row:\n")); for (i = 1; i <= last_column; i++) { select_output_environment (i); printf (_("* column #%d: output = %s\n"), i, output_paragraph); } #endif } texinfo-3.12/makeinfo/Makefile.in0000664000175000017500000001643106477056752014240 0ustar gg# Makefile.in generated automatically by automake 1.2f from Makefile.am # Copyright (C) 1994, 1995, 1996, 1997, 1998 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. SHELL = /bin/sh srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ bindir = @bindir@ sbindir = @sbindir@ libexecdir = @libexecdir@ datadir = @datadir@ sysconfdir = @sysconfdir@ sharedstatedir = @sharedstatedir@ localstatedir = @localstatedir@ libdir = @libdir@ infodir = @infodir@ mandir = @mandir@ includedir = @includedir@ oldincludedir = /usr/include pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. ACLOCAL = @ACLOCAL@ AUTOCONF = @AUTOCONF@ AUTOMAKE = @AUTOMAKE@ AUTOHEADER = @AUTOHEADER@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ transform = @program_transform_name@ NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : CATALOGS = @CATALOGS@ CATOBJEXT = @CATOBJEXT@ CC = @CC@ DATADIRNAME = @DATADIRNAME@ GENCAT = @GENCAT@ GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ GT_NO = @GT_NO@ GT_YES = @GT_YES@ INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@ INSTOBJEXT = @INSTOBJEXT@ INTLDEPS = @INTLDEPS@ INTLLIBS = @INTLLIBS@ INTLOBJS = @INTLOBJS@ MAKEINFO = @MAKEINFO@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ PACKAGE = @PACKAGE@ POFILES = @POFILES@ POSUB = @POSUB@ RANLIB = @RANLIB@ TERMLIBS = @TERMLIBS@ TEXCONFIG = @TEXCONFIG@ TEXMF = @TEXMF@ USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ l = @l@ bin_PROGRAMS = makeinfo localedir = $(datadir)/locale INCLUDES = -I$(top_srcdir)/lib -I../intl -DLOCALEDIR=\"$(localedir)\" LDADD = ../lib/libtxi.a @INTLLIBS@ makeinfo_SOURCES = makeinfo.c makeinfo.h multi.c EXTRA_DIST = README mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = ../config.h CONFIG_CLEAN_FILES = PROGRAMS = $(bin_PROGRAMS) DEFS = @DEFS@ -I. -I$(srcdir) -I.. CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ makeinfo_OBJECTS = makeinfo.o multi.o makeinfo_LDADD = $(LDADD) makeinfo_DEPENDENCIES = ../lib/libtxi.a makeinfo_LDFLAGS = CFLAGS = @CFLAGS@ COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) LINK = $(CC) $(CFLAGS) $(LDFLAGS) -o $@ DIST_COMMON = README Makefile.am Makefile.in DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) TAR = tar GZIP = --best SOURCES = $(makeinfo_SOURCES) OBJECTS = $(makeinfo_OBJECTS) default: all .SUFFIXES: .SUFFIXES: .S .c .o .s $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps makeinfo/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) \ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status mostlyclean-binPROGRAMS: clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) distclean-binPROGRAMS: maintainer-clean-binPROGRAMS: install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) $(mkinstalldirs) $(bindir) @list='$(bin_PROGRAMS)'; for p in $$list; do \ if test -f $$p; then \ echo " $(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p|sed '$(transform)'`"; \ $(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p|sed '$(transform)'`; \ else :; fi; \ done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) list='$(bin_PROGRAMS)'; for p in $$list; do \ rm -f $(bindir)/`echo $$p|sed '$(transform)'`; \ done .c.o: $(COMPILE) -c $< .s.o: $(COMPILE) -c $< .S.o: $(COMPILE) -c $< mostlyclean-compile: -rm -f *.o core *.core clean-compile: distclean-compile: -rm -f *.tab.c maintainer-clean-compile: makeinfo: $(makeinfo_OBJECTS) $(makeinfo_DEPENDENCIES) @rm -f makeinfo $(LINK) $(makeinfo_LDFLAGS) $(makeinfo_OBJECTS) $(makeinfo_LDADD) $(LIBS) tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) here=`pwd` && cd $(srcdir) \ && mkid -f$$here/ID $(SOURCES) $(HEADERS) $(LISP) TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS)'; \ unique=`for i in $$list; do echo $$i; done | \ awk ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) mostlyclean-tags: clean-tags: distclean-tags: -rm -f TAGS ID maintainer-clean-tags: distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) subdir = makeinfo distdir: $(DISTFILES) @for file in $(DISTFILES); do \ d=$(srcdir); \ test -f $(distdir)/$$file \ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ || cp -p $$d/$$file $(distdir)/$$file; \ done makeinfo.o: makeinfo.c ../lib/system.h ../config.h ../lib/getopt.h \ makeinfo.h multi.o: multi.c ../lib/system.h ../config.h makeinfo.h info: dvi: check: all $(MAKE) installcheck: install-exec: install-binPROGRAMS @$(NORMAL_INSTALL) install-data: @$(NORMAL_INSTALL) install: install-exec install-data all @: uninstall: uninstall-binPROGRAMS all: Makefile $(PROGRAMS) install-strip: $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install installdirs: $(mkinstalldirs) $(bindir) mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -rm -f Makefile $(DISTCLEANFILES) -rm -f config.cache config.log stamp-h stamp-h[0-9]* -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) mostlyclean: mostlyclean-binPROGRAMS mostlyclean-compile \ mostlyclean-tags mostlyclean-generic clean: clean-binPROGRAMS clean-compile clean-tags clean-generic \ mostlyclean distclean: distclean-binPROGRAMS distclean-compile distclean-tags \ distclean-generic clean -rm -f config.status maintainer-clean: maintainer-clean-binPROGRAMS maintainer-clean-compile \ maintainer-clean-tags maintainer-clean-generic \ distclean @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." .PHONY: default mostlyclean-binPROGRAMS distclean-binPROGRAMS \ clean-binPROGRAMS maintainer-clean-binPROGRAMS uninstall-binPROGRAMS \ install-binPROGRAMS mostlyclean-compile distclean-compile clean-compile \ maintainer-clean-compile tags mostlyclean-tags distclean-tags \ clean-tags maintainer-clean-tags distdir info dvi installcheck \ install-exec install-data install uninstall all installdirs \ mostlyclean-generic distclean-generic clean-generic \ maintainer-clean-generic clean mostlyclean distclean maintainer-clean # 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: texinfo-3.12/makeinfo/Makefile.am0000444000175000017500000000057606357261730014215 0ustar gg## Makefile.am for texinfo/makeinfo. ## $Id: Makefile.am,v 1.4 1997/07/04 20:58:00 karl Exp $ ## Run automake in .. to produce Makefile.in from this. bin_PROGRAMS = makeinfo localedir = $(datadir)/locale INCLUDES = -I$(top_srcdir)/lib -I../intl -DLOCALEDIR=\"$(localedir)\" LDADD = ../lib/libtxi.a @INTLLIBS@ makeinfo_SOURCES = makeinfo.c makeinfo.h multi.c EXTRA_DIST = README texinfo-3.12/makeinfo/makeinfo.c0000444000175000017500000077024606475100313014114 0ustar gg/* Makeinfo -- convert Texinfo source files into Info files. $Id: makeinfo.c,v 1.60 1998/02/25 20:36:22 karl Exp $ Copyright (C) 1987, 92, 93, 94, 95, 96, 97, 98 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, USA. Makeinfo was authored by Brian Fox (bfox@ai.mit.edu). */ /* Indent #pragma so that older Cpp's don't try to parse it. */ #ifdef _AIX #pragma alloca #endif /* _AIX */ int major_version = 1; int minor_version = 68; #include "system.h" #include "getopt.h" #ifdef TM_IN_SYS_TIME #include #else #include #endif /* !TM_IN_SYS_TIME */ #ifdef __GNUC__ # undef alloca # define alloca __builtin_alloca #else # ifdef HAVE_ALLOCA_H # include # else # ifndef _AIX char *alloca (); # endif # endif #endif /* We'd like to take advantage of _doprnt if it's around, a la error.c, but then we'd have no VA_SPRINTF. */ #if HAVE_VPRINTF # if __STDC__ # include # define VA_START(args, lastarg) va_start(args, lastarg) # else # include # define VA_START(args, lastarg) va_start(args) # endif # define VA_FPRINTF(file, fmt, ap) vfprintf (file, fmt, ap) # define VA_SPRINTF(str, fmt, ap) vsprintf (str, fmt, ap) #else /* not HAVE_VPRINTF */ # define VA_START(args, lastarg) # define va_alist a1, a2, a3, a4, a5, a6, a7, a8 # define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8; # define va_end(args) #endif /* You can change some of the behavior of Makeinfo by changing the following defines: */ /* Define INDENT_PARAGRAPHS_IN_TABLE if you want the paragraphs which appear within an @table, @ftable, or @itemize environment to have standard paragraph indentation. Without this, such paragraphs have no starting indentation. */ /* #define INDENT_PARAGRAPHS_IN_TABLE */ /* Define DEFAULT_INDENTATION_INCREMENT as an integer which is the amount that @example should increase indentation by. This incremement is used for all insertions which indent the enclosed text. */ #define DEFAULT_INDENTATION_INCREMENT 5 /* Define PARAGRAPH_START_INDENT to be the amount of indentation that the first lines of paragraphs receive by default, where no other value has been specified. Users can change this value on the command line, with the --paragraph-indent option, or within the texinfo file, with the @paragraphindent command. */ #define PARAGRAPH_START_INDENT 3 /* Define DEFAULT_PARAGRAPH_SPACING as the number of blank lines that you wish to appear between paragraphs. A value of 1 creates a single blank line between paragraphs. Paragraphs are defined by 2 or more consecutive newlines in the input file (i.e., one or more blank lines). */ #define DEFAULT_PARAGRAPH_SPACING 1 /* Define HAVE_MACROS to enable the macro facility of Texinfo. Using this facility, users can create their own command procedures with arguments. Must always be defined. */ #define HAVE_MACROS #define COMPILING_MAKEINFO #include "makeinfo.h" /* Nonzero means that we are currently hacking the insides of an insertion which would use a fixed width font. */ static int in_fixed_width_font = 0; /* Nonzero means that start_paragraph () MUST be called before we pay any attention to close_paragraph () calls. */ int must_start_paragraph = 0; /* Nonzero means a string is in execution, as opposed to a file. */ static int executing_string = 0; /* Nonzero means a macro string is in execution, as opposed to a file. */ static int me_executing_string = 0; #if defined (HAVE_MACROS) /* If non-NULL, this is an output stream to write the full macro expansion of the input text to. The result is another texinfo file, but missing @include, @infoinclude, @macro, and macro invocations. Instead, all of the text is placed within the file. */ FILE *macro_expansion_output_stream = (FILE *)NULL; char *macro_expansion_filename; /* Here is a structure used to remember input text strings and offsets within them. */ typedef struct { char *pointer; /* Pointer to the input text. */ int offset; /* Offset of the last character output. */ } ITEXT; static ITEXT **itext_info = (ITEXT **)NULL; static int itext_size = 0; /* Nonzero means to inhibit writing macro expansions to the output stream, because it has already been written. */ int me_inhibit_expansion = 0; ITEXT *remember_itext (); void forget_itext (), me_append_before_this_command (); void append_to_expansion_output (), write_region_to_macro_output (); void maybe_write_itext (), me_execute_string (); #endif /* HAVE_MACROS */ /* **************************************************************** */ /* */ /* Global Variables */ /* */ /* **************************************************************** */ /* Global pointer to argv[0]. */ char *progname; /* Return nonzero if STRING is the text at input_text + input_text_offset, else zero. */ #define looking_at(string) \ (strncmp (input_text + input_text_offset, string, strlen (string)) == 0) /* And writing to the output. */ /* The output file name. */ char *output_filename = (char *)NULL; char *pretty_output_filename; /* Name of the output file that the user elected to pass on the command line. Such a name overrides any name found with the @setfilename command. */ char *command_output_filename = (char *)NULL; /* A colon separated list of directories to search for files included with @include. This can be controlled with the `-I' option to makeinfo. */ char *include_files_path = (char *)NULL; /* Position in the output file. */ int output_position; #define INITIAL_PARAGRAPH_SPACE 5000 int paragraph_buffer_len = INITIAL_PARAGRAPH_SPACE; /* Nonzero indicates that filling will take place on long lines. */ int filling_enabled = 1; /* Nonzero means that words are not to be split, even in long lines. This gets changed for cm_w (). */ int non_splitting_words = 0; /* Nonzero indicates that filling a line also indents the new line. */ int indented_fill = 0; /* The amount of indentation to add at the starts of paragraphs. 0 means don't change existing indentation at paragraph starts. > 0 is amount to indent new paragraphs by. < 0 means indent to column zero by removing indentation if necessary. This is normally zero, but some people prefer paragraph starts to be somewhat more indented than paragraph bodies. A pretty value for this is 3. */ int paragraph_start_indent = PARAGRAPH_START_INDENT; /* Nonzero means that the use of paragraph_start_indent is inhibited. @example uses this to line up the left columns of the example text. A negative value for this variable is incremented each time it is used. @noindent uses this to inhibit indentation for a single paragraph. */ int inhibit_paragraph_indentation = 0; /* Indentation that is pending insertion. We have this for hacking lines which look blank, but contain whitespace. We want to treat those as blank lines. */ int pending_indent = 0; /* The amount that indentation increases/decreases by. */ int default_indentation_increment = DEFAULT_INDENTATION_INCREMENT; /* Nonzero indicates that indentation is temporarily turned off. */ int no_indent = 1; /* Nonzero means forcing output text to be flushright. */ int force_flush_right = 0; /* Nonzero means that the footnote style for this document was set on the command line, which overrides any other settings. */ int footnote_style_preset = 0; /* Nonzero means that we automatically number footnotes that have no specified marker. */ int number_footnotes = 1; /* The current footnote number in this node. Each time a new node is started this is reset to 1. */ int current_footnote_number = 1; /* Command name in the process of being hacked. */ char *command; /* The index in our internal command table of the currently executing command. */ int command_index; /* A search string which is used to find a line defining a node. */ char node_search_string[] = { '\n', COMMAND_PREFIX, 'n', 'o', 'd', 'e', ' ', 0 }; /* A search string which is used to find a line defining a menu. */ char menu_search_string[] = { '\n', COMMAND_PREFIX, 'm', 'e', 'n', 'u', 0 }; /* A search string which is used to find the first @setfilename. */ char setfilename_search[] = { COMMAND_PREFIX, 's', 'e', 't', 'f', 'i', 'l', 'e', 'n', 'a', 'm', 'e', 0 }; /* A stack of file information records. If a new file is read in with "@input", we remember the old input file state on this stack. */ typedef struct fstack { struct fstack *next; char *filename; char *text; int size; int offset; int line_number; } FSTACK; FSTACK *filestack = (FSTACK *) NULL; /* Stuff for nodes. */ /* The current nodes node name. */ char *current_node = (char *)NULL; /* The current nodes section level. */ int current_section = 0; /* The filename of the current input file. This is never freed. */ char *node_filename = (char *)NULL; /* What we remember for each node. */ typedef struct tentry { struct tentry *next_ent; char *node; /* name of this node. */ char *prev; /* name of "Prev:" for this node. */ char *next; /* name of "Next:" for this node. */ char *up; /* name of "Up:" for this node. */ int position; /* output file position of this node. */ int line_no; /* defining line in source file. */ char *filename; /* The file that this node was found in. */ int touched; /* Nonzero means this node has been referenced. */ int flags; /* Room for growth. Right now, contains 1 bit. */ } TAG_ENTRY; /* If node-a has a "Next" for node-b, but node-b has no "Prev" for node-a, we turn on this flag bit in node-b's tag entry. This means that when it is time to validate node-b, we don't report an additional error if there was no "Prev" field. */ #define PREV_ERROR 0x1 #define NEXT_ERROR 0x2 #define UP_ERROR 0x4 #define NO_WARN 0x8 #define IS_TOP 0x10 TAG_ENTRY *tag_table = (TAG_ENTRY *) NULL; /* Values for calling handle_variable_internal (). */ #define SET 1 #define CLEAR 2 #define IFSET 3 #define IFCLEAR 4 #if defined (HAVE_MACROS) #define ME_RECURSE 0x01 #define ME_QUOTE_ARG 0x02 /* Macro definitions for user-defined commands. */ typedef struct { char *name; /* Name of the macro. */ char **arglist; /* Args to replace when executing. */ char *body; /* Macro body. */ char *source_file; /* File where this macro is defined. */ int source_lineno; /* Line number within FILENAME. */ int inhibited; /* Nonzero means make find_macro () fail. */ int flags; /* ME_RECURSE, ME_QUOTE_ARG, etc. */ } MACRO_DEF; void add_macro (), execute_macro (); MACRO_DEF *find_macro (), *delete_macro (); #endif /* HAVE_MACROS */ /* Menu reference, *note reference, and validation hacking. */ /* The various references that we know about. */ enum reftype { menu_reference, followed_reference }; /* A structure to remember references with. A reference to a node is either an entry in a menu, or a cross-reference made with [px]ref. */ typedef struct node_ref { struct node_ref *next; char *node; /* Name of node referred to. */ char *containing_node; /* Name of node containing this reference. */ int line_no; /* Line number where the reference occurs. */ int section; /* Section level where the reference occurs. */ char *filename; /* Name of file where the reference occurs. */ enum reftype type; /* Type of reference, either menu or note. */ } NODE_REF; /* The linked list of such structures. */ NODE_REF *node_references = (NODE_REF *) NULL; /* Flag which tells us whether to examine menu lines or not. */ int in_menu = 0; /* Flag which tells us how to examine menu lines. */ int in_detailmenu = 0; /* Nonzero means that we have seen "@top" once already. */ int top_node_seen = 0; /* Nonzero means that we have seen a non-"@top" node already. */ int non_top_node_seen = 0; /* Flags controlling the operation of the program. */ /* Default is to remove output if there were errors. */ int force = 0; /* Default is to notify users of bad choices. */ int print_warnings = 1; /* Default is to check node references. */ int validating = 1; /* Nonzero means do not output "Node: Foo" for node separations. */ int no_headers = 0; /* Number of errors that we tolerate on a given fileset. */ int max_error_level = 100; /* Maximum number of references to a single node before complaining. */ int reference_warning_limit = 1000; /* Nonzero means print out information about what is going on when it is going on. */ int verbose_mode = 0; /* Nonzero means to be relaxed about the input file. This is useful when we can successfully format the input, but it doesn't strictly match our somewhat pedantic ideas of correctness. Right now, it affects what @table and @itemize do without arguments. */ int allow_lax_format = 0; /* The list of commands that we hack in texinfo. Each one has an associated function. When the command is encountered in the text, the associated function is called with START as the argument. If the function expects arguments in braces, it remembers itself on the stack. When the corresponding close brace is encountered, the function is called with END as the argument. */ #define START 0 #define END 1 typedef struct brace_element { struct brace_element *next; COMMAND_FUNCTION *proc; int pos, line; int in_fixed_width_font; } BRACE_ELEMENT; BRACE_ELEMENT *brace_stack = (BRACE_ELEMENT *) NULL; extern void do_multitable (); void print_version_info (); void usage (); void push_node_filename (), pop_node_filename (); void remember_error (), flush_file_stack (); void convert_from_stream (), convert_from_file (), convert_from_loaded_file (); void init_internals (), init_paragraph (), init_brace_stack (); void init_insertion_stack (), init_indices (); void init_tag_table (), write_tag_table (), write_tag_table_internal (); void validate_file (), validate_other_references (), split_file (); void free_node_references (), do_enumeration (), handle_variable (); void handle_variable_internal (); void normalize_node_name (); void undefindex (), top_defindex (), gen_defindex (); void define_user_command (); void free_pending_notes (), output_pending_notes (); char **get_brace_args (); char *expansion (); int array_len (); void free_array (); static int end_of_sentence_p (); static void isolate_nodename (); void reader_loop (), read_command (); void remember_brace (), remember_brace_1 (); void pop_and_call_brace (), discard_braces (); void add_word (), add_char (), insert (), flush_output (); void insert_string (); void close_paragraph_with_lines (), close_paragraph (); void ignore_blank_line (); void do_flush_right_indentation (), discard_insertions (); void start_paragraph (), indent (); #if defined (VA_FPRINTF) && __STDC__ /* Unfortunately we must use prototypes if we are to use . */ void add_word_args (char *, ...); void execute_string (char *, ...); #else void add_word_args (); void execute_string (); #endif /* will not use prototypes */ void insert_self (), insert_space (), cm_ignore_line (); void cm_TeX (), cm_asterisk (), cm_bullet (), cm_cite (), cm_code (), cm_copyright (), cm_ctrl (), cm_dfn (), cm_dircategory (), cm_direntry (), cm_dots (), cm_emph (), cm_enddots (), cm_kbd (), cm_key (), cm_no_op (), cm_no_op_line_arg (), cm_not_fixed_width (), cm_strong (), cm_var_sc (), cm_w (), cm_image (); /* Sectioning. */ void cm_chapter (), cm_unnumbered (), cm_appendix (), cm_top (), cm_section (), cm_unnumberedsec (), cm_appendixsec (), cm_subsection (), cm_unnumberedsubsec (), cm_appendixsubsec (), cm_subsubsection (), cm_unnumberedsubsubsec (), cm_appendixsubsubsec (), cm_heading (), cm_chapheading (), cm_subheading (), cm_subsubheading (), cm_majorheading (), cm_raisesections (), cm_lowersections (); /* All @def... commands map to cm_defun, most accent commands map to cm_accent, most non-English letters map to cm_special_char. */ void cm_defun (), cm_accent (), cm_special_char (), cm_dotless (); void cm_node (), cm_menu (), cm_xref (), cm_ftable (), cm_vtable (), cm_pxref (), cm_inforef (), cm_uref (), cm_email (), cm_quotation (), cm_display (), cm_itemize (), cm_enumerate (), cm_tab (), cm_table (), cm_itemx (), cm_noindent (), cm_setfilename (), cm_br (), cm_sp (), cm_page (), cm_group (), cm_center (), cm_include (), cm_bye (), cm_item (), cm_end (), cm_ifinfo (), cm_ifnothtml (), cm_ifnottex (), cm_kindex (), cm_cindex (), cm_findex (), cm_pindex (), cm_vindex (), cm_tindex (), cm_synindex (), cm_printindex (), cm_minus (), cm_footnote (), cm_example (), cm_smallexample (), cm_lisp (), cm_format (), cm_exdent (), cm_defindex (), cm_defcodeindex (), cm_result (), cm_expansion (), cm_equiv (), cm_print (), cm_error (), cm_point (), cm_today (), cm_flushleft (), cm_flushright (), cm_smalllisp (), cm_finalout (), cm_cartouche (), cm_detailmenu (), cm_multitable (); /* Conditionals. */ void cm_set (), cm_clear (), cm_ifset (), cm_ifclear (); void cm_value (), cm_ifeq (); #if defined (HAVE_MACROS) /* Define a user-defined command which is simple substitution. */ void cm_macro (), cm_unmacro (); #endif /* HAVE_MACROS */ /* Options. */ void cm_paragraphindent (), cm_footnotestyle (); /* Internals. */ void command_name_condition (), misplaced_brace (), cm_obsolete (), cm_ideprecated (); typedef struct { char *name; COMMAND_FUNCTION *proc; int argument_in_braces; } COMMAND; /* Stuff for defining commands on the fly. */ COMMAND **user_command_array = (COMMAND **) NULL; int user_command_array_len = 0; #define NO_BRACE_ARGS 0 #define BRACE_ARGS 1 static COMMAND command_table[] = { { "\t", insert_space, NO_BRACE_ARGS }, { "\n", insert_space, NO_BRACE_ARGS }, { " ", insert_self, NO_BRACE_ARGS }, { "!", insert_self, NO_BRACE_ARGS }, { "\"", insert_self, NO_BRACE_ARGS }, { "'", insert_self, NO_BRACE_ARGS }, { "*", cm_asterisk, NO_BRACE_ARGS }, { ",", cm_accent, BRACE_ARGS }, { "-", cm_no_op, NO_BRACE_ARGS }, { ".", insert_self, NO_BRACE_ARGS }, { ":", cm_no_op, NO_BRACE_ARGS }, { "=", insert_self, NO_BRACE_ARGS }, { "?", insert_self, NO_BRACE_ARGS }, { "@", insert_self, NO_BRACE_ARGS }, { "^", insert_self, NO_BRACE_ARGS }, { "`", insert_self, NO_BRACE_ARGS }, { "{", insert_self, NO_BRACE_ARGS }, { "|", cm_no_op, NO_BRACE_ARGS }, { "}", insert_self, NO_BRACE_ARGS }, { "~", insert_self, NO_BRACE_ARGS }, { "AA", insert_self, BRACE_ARGS }, { "AE", insert_self, BRACE_ARGS }, { "H", cm_accent, BRACE_ARGS }, { "L", cm_special_char, BRACE_ARGS }, { "O", cm_special_char, BRACE_ARGS }, { "OE", insert_self, BRACE_ARGS }, { "TeX", cm_TeX, BRACE_ARGS }, { "aa", insert_self, BRACE_ARGS }, { "ae", insert_self, BRACE_ARGS }, { "appendix", cm_appendix, NO_BRACE_ARGS }, { "appendixsection", cm_appendixsec, NO_BRACE_ARGS }, { "appendixsec", cm_appendixsec, NO_BRACE_ARGS }, { "appendixsubsec", cm_appendixsubsec, NO_BRACE_ARGS }, { "appendixsubsubsec", cm_appendixsubsubsec, NO_BRACE_ARGS }, { "asis", cm_no_op, BRACE_ARGS }, { "b", cm_not_fixed_width, BRACE_ARGS }, { "bullet", cm_bullet, BRACE_ARGS }, { "bye", cm_bye, NO_BRACE_ARGS }, { "c", cm_ignore_line, NO_BRACE_ARGS }, { "cartouche", cm_cartouche, NO_BRACE_ARGS }, { "center", cm_center, NO_BRACE_ARGS }, { "centerchap", cm_unnumbered, NO_BRACE_ARGS }, { "chapheading", cm_chapheading, NO_BRACE_ARGS }, { "chapter", cm_chapter, NO_BRACE_ARGS }, { "cindex", cm_cindex, NO_BRACE_ARGS }, { "cite", cm_cite, BRACE_ARGS }, { "clear", cm_clear, NO_BRACE_ARGS }, { "code", cm_code, BRACE_ARGS }, { "comment", cm_ignore_line, NO_BRACE_ARGS }, { "contents", cm_no_op, NO_BRACE_ARGS }, { "copyright", cm_copyright, BRACE_ARGS }, { "ctrl", cm_obsolete, BRACE_ARGS }, { "defcodeindex", cm_defcodeindex, NO_BRACE_ARGS }, { "defindex", cm_defindex, NO_BRACE_ARGS }, /* The `def' commands. */ { "defcv", cm_defun, NO_BRACE_ARGS }, { "defcvx", cm_defun, NO_BRACE_ARGS }, { "deffn", cm_defun, NO_BRACE_ARGS }, { "deffnx", cm_defun, NO_BRACE_ARGS }, { "defivar", cm_defun, NO_BRACE_ARGS }, { "defivarx", cm_defun, NO_BRACE_ARGS }, { "defmac", cm_defun, NO_BRACE_ARGS }, { "defmacx", cm_defun, NO_BRACE_ARGS }, { "defmethod", cm_defun, NO_BRACE_ARGS }, { "defmethodx", cm_defun, NO_BRACE_ARGS }, { "defop", cm_defun, NO_BRACE_ARGS }, { "defopt", cm_defun, NO_BRACE_ARGS }, { "defoptx", cm_defun, NO_BRACE_ARGS }, { "defopx", cm_defun, NO_BRACE_ARGS }, { "defspec", cm_defun, NO_BRACE_ARGS }, { "defspecx", cm_defun, NO_BRACE_ARGS }, { "deftp", cm_defun, NO_BRACE_ARGS }, { "deftpx", cm_defun, NO_BRACE_ARGS }, { "deftypefn", cm_defun, NO_BRACE_ARGS }, { "deftypefnx", cm_defun, NO_BRACE_ARGS }, { "deftypefun", cm_defun, NO_BRACE_ARGS }, { "deftypefunx", cm_defun, NO_BRACE_ARGS }, { "deftypemethod", cm_defun, NO_BRACE_ARGS }, { "deftypemethodx", cm_defun, NO_BRACE_ARGS }, { "deftypevar", cm_defun, NO_BRACE_ARGS }, { "deftypevarx", cm_defun, NO_BRACE_ARGS }, { "deftypevr", cm_defun, NO_BRACE_ARGS }, { "deftypevrx", cm_defun, NO_BRACE_ARGS }, { "defun", cm_defun, NO_BRACE_ARGS }, { "defunx", cm_defun, NO_BRACE_ARGS }, { "defvar", cm_defun, NO_BRACE_ARGS }, { "defvarx", cm_defun, NO_BRACE_ARGS }, { "defvr", cm_defun, NO_BRACE_ARGS }, { "defvrx", cm_defun, NO_BRACE_ARGS }, /* The end of the `def' commands. */ { "detailmenu", cm_detailmenu, NO_BRACE_ARGS }, { "dfn", cm_dfn, BRACE_ARGS }, { "dircategory", cm_dircategory, NO_BRACE_ARGS }, { "direntry", cm_direntry, NO_BRACE_ARGS }, { "display", cm_display, NO_BRACE_ARGS }, { "dmn", cm_no_op, BRACE_ARGS }, { "dotaccent", cm_accent, BRACE_ARGS }, { "dotless", cm_dotless, BRACE_ARGS }, { "dots", cm_dots, BRACE_ARGS }, { "email", cm_email, BRACE_ARGS }, { "emph", cm_emph, BRACE_ARGS }, { "end", cm_end, NO_BRACE_ARGS }, { "enddots", cm_enddots, BRACE_ARGS }, { "enumerate", cm_enumerate, NO_BRACE_ARGS }, { "equiv", cm_equiv, BRACE_ARGS }, { "error", cm_error, BRACE_ARGS }, { "example", cm_example, NO_BRACE_ARGS }, { "exclamdown", cm_special_char, BRACE_ARGS }, { "exdent", cm_exdent, NO_BRACE_ARGS }, { "expansion", cm_expansion, BRACE_ARGS }, { "file", cm_code, BRACE_ARGS }, { "finalout", cm_no_op, NO_BRACE_ARGS }, { "findex", cm_findex, NO_BRACE_ARGS }, { "flushleft", cm_flushleft, NO_BRACE_ARGS }, { "flushright", cm_flushright, NO_BRACE_ARGS }, { "footnote", cm_footnote, NO_BRACE_ARGS}, /* self-arg eater */ { "footnotestyle", cm_footnotestyle, NO_BRACE_ARGS }, { "format", cm_format, NO_BRACE_ARGS }, { "ftable", cm_ftable, NO_BRACE_ARGS }, { "group", cm_group, NO_BRACE_ARGS }, { "heading", cm_heading, NO_BRACE_ARGS }, { "headings", cm_ignore_line, NO_BRACE_ARGS }, { "html", command_name_condition, NO_BRACE_ARGS }, { "hyphenation", cm_no_op, BRACE_ARGS }, { "i", cm_not_fixed_width, BRACE_ARGS }, { "ifclear", cm_ifclear, NO_BRACE_ARGS }, { "ifeq", cm_ifeq, NO_BRACE_ARGS }, { "ifhtml", command_name_condition, NO_BRACE_ARGS }, { "ifinfo", cm_ifinfo, NO_BRACE_ARGS }, { "ifnothtml", cm_ifnothtml, NO_BRACE_ARGS }, { "ifnotinfo", command_name_condition, NO_BRACE_ARGS }, { "ifnottex", cm_ifnottex, NO_BRACE_ARGS }, { "ifset", cm_ifset, NO_BRACE_ARGS }, { "iftex", command_name_condition, NO_BRACE_ARGS }, { "ignore", command_name_condition, NO_BRACE_ARGS }, { "image", cm_image, BRACE_ARGS }, { "include", cm_include, NO_BRACE_ARGS }, { "inforef", cm_inforef, BRACE_ARGS }, { "item", cm_item, NO_BRACE_ARGS }, { "itemize", cm_itemize, NO_BRACE_ARGS }, { "itemx", cm_itemx, NO_BRACE_ARGS }, { "kbd", cm_kbd, BRACE_ARGS }, { "kbdinputstyle", cm_no_op_line_arg, NO_BRACE_ARGS }, { "key", cm_key, BRACE_ARGS }, { "kindex", cm_kindex, NO_BRACE_ARGS }, { "l", cm_special_char, BRACE_ARGS }, { "lisp", cm_lisp, NO_BRACE_ARGS }, { "lowersections", cm_lowersections, NO_BRACE_ARGS }, { "macro", cm_macro, NO_BRACE_ARGS }, { "majorheading", cm_majorheading, NO_BRACE_ARGS }, { "math", cm_no_op, BRACE_ARGS }, { "menu", cm_menu, NO_BRACE_ARGS }, { "minus", cm_minus, BRACE_ARGS }, { "multitable", cm_multitable, NO_BRACE_ARGS }, { "need", cm_ignore_line, NO_BRACE_ARGS }, { "node", cm_node, NO_BRACE_ARGS }, { "noindent", cm_noindent, NO_BRACE_ARGS }, { "nwnode", cm_node, NO_BRACE_ARGS }, { "o", cm_special_char, BRACE_ARGS }, { "oe", insert_self, BRACE_ARGS }, { "page", cm_no_op, NO_BRACE_ARGS }, { "paragraphindent", cm_paragraphindent, NO_BRACE_ARGS }, { "pindex", cm_pindex, NO_BRACE_ARGS }, { "point", cm_point, BRACE_ARGS }, { "pounds", cm_special_char, BRACE_ARGS }, { "print", cm_print, BRACE_ARGS }, { "printindex", cm_printindex, NO_BRACE_ARGS }, { "pxref", cm_pxref, BRACE_ARGS }, { "questiondown", cm_special_char, BRACE_ARGS }, { "quotation", cm_quotation, NO_BRACE_ARGS }, { "r", cm_not_fixed_width, BRACE_ARGS }, { "raisesections", cm_raisesections, NO_BRACE_ARGS }, { "ref", cm_xref, BRACE_ARGS }, { "refill", cm_no_op, NO_BRACE_ARGS }, { "result", cm_result, BRACE_ARGS }, { "ringaccent", cm_accent, BRACE_ARGS }, { "samp", cm_code, BRACE_ARGS }, { "sc", cm_var_sc, BRACE_ARGS }, { "section", cm_section, NO_BRACE_ARGS }, { "set", cm_set, NO_BRACE_ARGS }, { "setchapternewpage", cm_ignore_line, NO_BRACE_ARGS }, { "setchapterstyle", cm_obsolete, NO_BRACE_ARGS }, { "setfilename", cm_setfilename, NO_BRACE_ARGS }, { "settitle", cm_ignore_line, NO_BRACE_ARGS }, { "shortcontents", cm_no_op, NO_BRACE_ARGS }, { "shorttitlepage", cm_ignore_line, NO_BRACE_ARGS }, { "smallbook", cm_ignore_line, NO_BRACE_ARGS }, { "smallexample", cm_smallexample, NO_BRACE_ARGS }, { "smalllisp", cm_smalllisp, NO_BRACE_ARGS }, { "sp", cm_sp, NO_BRACE_ARGS }, { "ss", insert_self, BRACE_ARGS }, { "strong", cm_strong, BRACE_ARGS }, { "subheading", cm_subheading, NO_BRACE_ARGS }, { "subsection", cm_subsection, NO_BRACE_ARGS }, { "subsubheading", cm_subsubheading, NO_BRACE_ARGS }, { "subsubsection", cm_subsubsection, NO_BRACE_ARGS }, { "summarycontents", cm_no_op, NO_BRACE_ARGS }, { "syncodeindex", cm_synindex, NO_BRACE_ARGS }, { "synindex", cm_synindex, NO_BRACE_ARGS }, { "t", cm_no_op, BRACE_ARGS }, { "tab", cm_tab, NO_BRACE_ARGS }, { "table", cm_table, NO_BRACE_ARGS }, { "tex", command_name_condition, NO_BRACE_ARGS }, { "tieaccent", cm_accent, BRACE_ARGS }, { "tindex", cm_tindex, NO_BRACE_ARGS }, { "titlefont", cm_not_fixed_width, BRACE_ARGS }, { "titlepage", command_name_condition, NO_BRACE_ARGS }, { "today", cm_today, BRACE_ARGS }, { "top", cm_top, NO_BRACE_ARGS }, { "u", cm_accent, BRACE_ARGS }, { "ubaraccent", cm_accent, BRACE_ARGS }, { "udotaccent", cm_accent, BRACE_ARGS }, #if defined (HAVE_MACROS) { "unmacro", cm_unmacro, NO_BRACE_ARGS }, #endif { "unnumbered", cm_unnumbered, NO_BRACE_ARGS }, { "unnumberedsec", cm_unnumberedsec, NO_BRACE_ARGS }, { "unnumberedsubsec", cm_unnumberedsubsec, NO_BRACE_ARGS }, { "unnumberedsubsubsec", cm_unnumberedsubsubsec, NO_BRACE_ARGS }, { "uref", cm_uref, BRACE_ARGS }, { "url", cm_code, BRACE_ARGS }, { "v", cm_accent, BRACE_ARGS }, { "value", cm_value, BRACE_ARGS }, { "var", cm_var_sc, BRACE_ARGS }, { "vindex", cm_vindex, NO_BRACE_ARGS }, { "vtable", cm_vtable, NO_BRACE_ARGS }, { "w", cm_w, BRACE_ARGS }, { "xref", cm_xref, BRACE_ARGS }, /* Deprecated commands. These used to be for italics. */ { "iappendix", cm_ideprecated, NO_BRACE_ARGS }, { "iappendixsec", cm_ideprecated, NO_BRACE_ARGS }, { "iappendixsection", cm_ideprecated, NO_BRACE_ARGS }, { "iappendixsubsec", cm_ideprecated, NO_BRACE_ARGS }, { "iappendixsubsubsec", cm_ideprecated, NO_BRACE_ARGS }, { "ichapter", cm_ideprecated, NO_BRACE_ARGS }, { "isection", cm_ideprecated, NO_BRACE_ARGS }, { "isubsection", cm_ideprecated, NO_BRACE_ARGS }, { "isubsubsection", cm_ideprecated, NO_BRACE_ARGS }, { "iunnumbered", cm_ideprecated, NO_BRACE_ARGS }, { "iunnumberedsec", cm_ideprecated, NO_BRACE_ARGS }, { "iunnumberedsubsec", cm_ideprecated, NO_BRACE_ARGS }, { "iunnumberedsubsubsec", cm_ideprecated, NO_BRACE_ARGS }, /* Now @include does what this was used to. */ { "infoinclude", cm_obsolete, NO_BRACE_ARGS }, { "titlespec", cm_obsolete, NO_BRACE_ARGS }, { NULL, NULL, NO_BRACE_ARGS } }; struct option long_options[] = { { "error-limit", 1, 0, 'e' }, /* formerly -el */ { "fill-column", 1, 0, 'f' }, /* formerly -fc */ { "footnote-style", 1, 0, 's' }, /* formerly -ft */ { "force", 0, 0, 'F' }, /* do not remove output */ { "no-headers", 0, &no_headers, 1 }, /* do not output Node: foo */ { "no-pointer-validate", 0, &validating, 0 }, /* formerly -nv */ { "no-validate", 0, &validating, 0 }, /* formerly -nv */ { "no-split", 0, &splitting, 0 }, /* formerly -ns */ { "no-warn", 0, &print_warnings, 0 }, /* formerly -nw */ { "macro-expand", 1, 0, 'E' }, { "number-footnotes", 0, &number_footnotes, 1 }, { "no-number-footnotes", 0, &number_footnotes, 0 }, { "output", 1, 0, 'o' }, { "paragraph-indent", 1, 0, 'p' }, /* formerly -pi */ { "reference-limit", 1, 0, 'r' }, /* formerly -rl */ { "verbose", 0, &verbose_mode, 1 }, /* formerly -verbose */ { "help", 0, 0, 'h' }, { "version", 0, 0, 'V' }, {NULL, 0, NULL, 0} }; /* **************************************************************** */ /* */ /* Error Handling */ /* */ /* **************************************************************** */ /* Number of errors encountered. */ int errors_printed = 0; /* Print the last error gotten from the file system. */ int fs_error (filename) char *filename; { remember_error (); perror (filename); return (0); } /* Print an error message, and return false. */ void #if defined (VA_FPRINTF) && __STDC__ error (char *format, ...) #else error (format, va_alist) char *format; va_dcl #endif { #ifdef VA_FPRINTF va_list ap; #endif remember_error (); VA_START (ap, format); #ifdef VA_FPRINTF VA_FPRINTF (stderr, format, ap); #else fprintf (stderr, format, a1, a2, a3, a4, a5, a6, a7, a8); #endif /* not VA_FPRINTF */ va_end (ap); putc ('\n', stderr); } /* Just like error (), but print the line number as well. */ void #if defined (VA_FPRINTF) && __STDC__ line_error (char *format, ...) #else line_error (format, va_alist) char *format; va_dcl #endif { #ifdef VA_FPRINTF va_list ap; #endif remember_error (); fprintf (stderr, "%s:%d: ", input_filename, line_number); VA_START (ap, format); #ifdef VA_FPRINTF VA_FPRINTF (stderr, format, ap); #else fprintf (stderr, format, a1, a2, a3, a4, a5, a6, a7, a8); #endif /* not VA_FPRINTF */ va_end (ap); fprintf (stderr, ".\n"); } void #if defined (VA_FPRINTF) && __STDC__ warning (char *format, ...) #else warning (format, va_alist) char *format; va_dcl #endif { #ifdef VA_FPRINTF va_list ap; #endif if (print_warnings) { fprintf (stderr, _("%s:%d: warning: "), input_filename, line_number); VA_START (ap, format); #ifdef VA_FPRINTF VA_FPRINTF (stderr, format, ap); #else fprintf (stderr, format, a1, a2, a3, a4, a5, a6, a7, a8); #endif /* not VA_FPRINTF */ va_end (ap); fprintf (stderr, ".\n"); } } /* Remember that an error has been printed. If more than max_error_level have been printed, then exit the program. */ void remember_error () { errors_printed++; if (max_error_level && (errors_printed > max_error_level)) { fprintf (stderr, _("Too many errors! Gave up.\n")); flush_file_stack (); cm_bye (); exit (FATAL); } } /* **************************************************************** */ /* */ /* Main () Start of code */ /* */ /* **************************************************************** */ /* For each file mentioned in the command line, process it, turning Texinfo commands into wonderfully formatted output text. */ int main (argc, argv) int argc; char **argv; { extern int errors_printed; char *filename_part (); int c, ind; int reading_from_stdin = 0; /* The name of this program is the last filename in argv[0]. */ progname = filename_part (argv[0]); #ifdef HAVE_SETLOCALE /* Do not use LC_ALL, because LC_NUMERIC screws up the scanf parsing of the argument to @multicolumn. */ setlocale (LC_TIME, ""); setlocale (LC_MESSAGES, ""); #endif /* Set the text message domain. */ bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); /* Parse argument flags from the input line. */ while ((c = getopt_long (argc, argv, "D:e:E:f:I:o:p:P:r:s:U:V", long_options, &ind)) != EOF) { if (c == 0 && long_options[ind].flag == 0) c = long_options[ind].val; switch (c) { case 'D': case 'U': /* User specified variable to set or clear. */ handle_variable_internal ((c == 'D') ? SET : CLEAR, optarg); break; case 'e': /* User specified error level. */ if (sscanf (optarg, "%d", &max_error_level) != 1) { fprintf (stderr, _("%s: %s arg must be numeric, not `%s'.\n"), "--error-limit", progname, optarg); usage (stderr, FATAL); } break; case 'E': /* User specified a macro expansion output file. */ if (!macro_expansion_output_stream) { macro_expansion_filename = optarg; macro_expansion_output_stream = strcmp (optarg, "-") == 0 ? stdout : fopen (optarg, "w"); if (!macro_expansion_output_stream) error (_("Couldn't open macro expansion output `%s'"), optarg); } else error (_("Cannot specify more than one macro expansion output")); break; case 'f': /* User specified fill_column. */ if (sscanf (optarg, "%d", &fill_column) != 1) { fprintf (stderr, _("%s: %s arg must be numeric, not `%s'.\n"), "--fill-column", progname, optarg); usage (FATAL); } break; case 'F': force++; /* Do not remove erroneous output. */ break; case 'h': usage (NO_ERROR); break; case 'I': /* Append user-specified dir to include file path. */ if (!include_files_path) include_files_path = xstrdup ("."); include_files_path = (char *) xrealloc (include_files_path, 2 + strlen (include_files_path) + strlen (optarg)); strcat (include_files_path, ":"); strcat (include_files_path, optarg); break; case 'o': /* User specified output file. */ command_output_filename = xstrdup (optarg); break; case 'p': /* User specified paragraph indent (paragraph_start_index). */ if (set_paragraph_indent (optarg) < 0) { fprintf (stderr, _("%s: --paragraph-indent arg must be numeric/`none'/`asis', not `%s'.\n"), progname, optarg); usage (FATAL); } break; case 'P': /* Prepend user-specified include dir to include path. */ if (!include_files_path) { include_files_path = xstrdup (optarg); include_files_path = (char *) xrealloc (include_files_path, strlen (include_files_path) + 3); /* 3 for ":.\0" */ strcat (include_files_path, ":."); } else { char *tmp = xstrdup (include_files_path); include_files_path = (char *) xrealloc (include_files_path, strlen (include_files_path) + strlen (optarg) + 2); /* 2 for ":\0" */ strcpy (include_files_path, optarg); strcat (include_files_path, ":"); strcat (include_files_path, tmp); free (tmp); } break; case 'r': /* User specified reference warning limit. */ if (sscanf (optarg, "%d", &reference_warning_limit) != 1) { fprintf (stderr, _("%s: %s arg must be numeric, not `%s'.\n"), "--reference-limit", progname, optarg); usage (FATAL); } break; case 's': /* User specified footnote style. */ if (set_footnote_style (optarg) < 0) { fprintf (stderr, _("%s: --footnote-style arg must be `separate' or `end', not `%s'.\n"), progname, optarg); usage (FATAL); } footnote_style_preset = 1; break; case 'V': /* User requested version info. */ print_version_info (); printf (_("Copyright (C) %s Free Software Foundation, Inc.\n\ 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"), "1998"); exit (NO_ERROR); break; case '?': usage (FATAL); break; } } if (optind == argc) { /* Check to see if input is a file. If so, process that. */ if (!isatty (fileno (stdin))) reading_from_stdin = 1; else { fprintf (stderr, _("%s: missing file argument.\n"), progname); usage (FATAL); } } /* If the user has specified --no-headers, this should imply --no-split. Do that here. I think it might also imply that we should ignore the setfilename at the top of the file, but this might break some FSF things, so I will hold off on that. */ if (no_headers) { splitting = 0; /* If the user has not specified an output file, use stdout. */ if (!command_output_filename) command_output_filename = xstrdup ("-"); } if (verbose_mode) print_version_info (); /* Remaining arguments are file names of texinfo files. Convert them, one by one. */ if (!reading_from_stdin) { while (optind != argc) convert_from_file (argv[optind++]); } else convert_from_stream (stdin, "stdin"); if (errors_printed) return (SYNTAX); else return (NO_ERROR); } /* Display the version info of this invocation of Makeinfo. */ void print_version_info () { printf ("makeinfo (GNU %s %s) %d.%d\n", PACKAGE, VERSION, major_version, minor_version); } /* If EXIT_VALUE is zero, print the full usage message to stdout. Otherwise, just say to use --help for more info. Then exit with EXIT_VALUE. */ void usage (exit_value) int exit_value; { if (exit_value != 0) fprintf (stderr, _("Try `%s --help' for more information.\n"), progname); else printf (_("Usage: %s [OPTION]... TEXINFO-FILE...\n\ \n\ Translate Texinfo source documentation to a format suitable for reading\n\ with GNU Info.\n\ \n\ Options:\n\ -D VAR define a variable, as with @set.\n\ -E MACRO-OFILE process macros only, output texinfo source.\n\ -I DIR append DIR to the @include directory search path.\n\ -P DIR prepend DIR to the @include directory search path.\n\ -U VAR undefine a variable, as with @clear.\n\ --error-limit NUM quit after NUM errors (default %d).\n\ --fill-column NUM break lines at NUM characters (default %d).\n\ --footnote-style STYLE output footnotes according to STYLE:\n\ `separate' to place footnotes in their own node,\n\ `end' to place the footnotes at the end of\n\ the node in which they are defined (the default).\n\ --force preserve output even if errors.\n\ --help display this help and exit.\n\ --no-validate suppress node cross-reference validation.\n\ --no-warn suppress warnings (but not errors).\n\ --no-split suppress splitting of large files.\n\ --no-headers suppress node separators and Node: Foo headers.\n\ --output FILE, -o FILE output to FILE, and ignore any @setfilename.\n\ --paragraph-indent VAL indent paragraphs with VAL spaces (default %d).\n\ if VAL is `none', do not indent; if VAL is `asis',\n\ preserve any existing indentation.\n\ --reference-limit NUM complain about at most NUM references (default %d).\n\ --verbose report about what is being done.\n\ --version display version information and exit.\n\ \n\ Email bug reports to bug-texinfo@gnu.org.\n\ "), progname, max_error_level, fill_column, paragraph_start_indent, reference_warning_limit); exit (exit_value); } /* Manipulating Lists */ typedef struct generic_list { struct generic_list *next; } GENERIC_LIST; /* Reverse the chain of structures in LIST. Output the new head of the chain. You should always assign the output value of this function to something, or you will lose the chain. */ GENERIC_LIST * reverse_list (list) register GENERIC_LIST *list; { register GENERIC_LIST *next; register GENERIC_LIST *prev = (GENERIC_LIST *) NULL; while (list) { next = list->next; list->next = prev; prev = list; list = next; } return (prev); } /* Pushing and Popping Files */ /* Find and load the file named FILENAME. Return a pointer to the loaded file, or NULL if it can't be loaded. */ char * find_and_load (filename) char *filename; { struct stat fileinfo; long file_size; int file = -1, count = 0; char *fullpath, *result, *get_file_info_in_path (); result = fullpath = (char *)NULL; fullpath = get_file_info_in_path (filename, include_files_path, &fileinfo); if (!fullpath) goto error_exit; filename = fullpath; file_size = (long) fileinfo.st_size; file = open (filename, O_RDONLY); if (file < 0) goto error_exit; /* Load the file, with enough room for a newline and a null. */ result = xmalloc (file_size + 2); /* VMS stat lies about the st_size value. The actual number of readable bytes is always less than this value. The arcane mysteries of VMS/RMS are too much to probe, so this hack suffices to make things work. */ #if defined (VMS) || defined (WIN32) #ifdef VMS while ((n = read (file, result + count, file_size)) > 0) #else /* WIN32 */ while ((n = read (file, result + count, 1)) > 0) #endif /* WIN32 */ count += n; if (n == -1) #else /* !VMS && !WIN32 */ count = file_size; if (read (file, result, file_size) != file_size) #endif /* !VMS && !WIN32 */ error_exit: { if (result) free (result); if (fullpath) free (fullpath); if (file != -1) close (file); return ((char *) NULL); } close (file); /* Set the globals to the new file. */ input_text = result; size_of_input_text = count; input_filename = fullpath; node_filename = xstrdup (fullpath); input_text_offset = 0; line_number = 1; /* Not strictly necessary. This magic prevents read_token () from doing extra unnecessary work each time it is called (that is a lot of times). SIZE_OF_INPUT_TEXT is one past the actual end of the text. */ input_text[size_of_input_text] = '\n'; /* This, on the other hand, is always necessary. */ input_text[size_of_input_text+1] = 0; return (result); } /* Save the state of the current input file. */ void pushfile () { FSTACK *newstack = (FSTACK *) xmalloc (sizeof (FSTACK)); newstack->filename = input_filename; newstack->text = input_text; newstack->size = size_of_input_text; newstack->offset = input_text_offset; newstack->line_number = line_number; newstack->next = filestack; filestack = newstack; push_node_filename (); } /* Make the current file globals be what is on top of the file stack. */ void popfile () { FSTACK *tos = filestack; if (!tos) abort (); /* My fault. I wonder what I did? */ #if defined (HAVE_MACROS) if (macro_expansion_output_stream) { maybe_write_itext (input_text, input_text_offset); forget_itext (input_text); } #endif /* HAVE_MACROS */ /* Pop the stack. */ filestack = filestack->next; /* Make sure that commands with braces have been satisfied. */ if (!executing_string && !me_executing_string) discard_braces (); /* Get the top of the stack into the globals. */ input_filename = tos->filename; input_text = tos->text; size_of_input_text = tos->size; input_text_offset = tos->offset; line_number = tos->line_number; free (tos); /* Go back to the (now) current node. */ pop_node_filename (); } /* Flush all open files on the file stack. */ void flush_file_stack () { while (filestack) { char *fname = input_filename; char *text = input_text; popfile (); free (fname); free (text); } } int node_filename_stack_index = 0; int node_filename_stack_size = 0; char **node_filename_stack = (char **)NULL; void push_node_filename () { if (node_filename_stack_index + 1 > node_filename_stack_size) node_filename_stack = (char **)xrealloc (node_filename_stack, (node_filename_stack_size += 10) * sizeof (char *)); node_filename_stack[node_filename_stack_index] = node_filename; node_filename_stack_index++; } void pop_node_filename () { node_filename = node_filename_stack[--node_filename_stack_index]; } /* Return just the simple part of the filename; i.e. the filename without the path information, or extensions. This conses up a new string. */ char * filename_part (filename) char *filename; { char *basename; basename = strrchr (filename, '/'); if (!basename) basename = filename; else basename++; basename = xstrdup (basename); #if defined (REMOVE_OUTPUT_EXTENSIONS) /* See if there is an extension to remove. If so, remove it. */ { char *temp; temp = strrchr (basename, '.'); if (temp) *temp = 0; } #endif /* REMOVE_OUTPUT_EXTENSIONS */ return (basename); } /* Return the pathname part of filename. This can be NULL. */ char * pathname_part (filename) char *filename; { char *expand_filename (); char *result = (char *) NULL; register int i; filename = expand_filename (filename, ""); i = strlen (filename) - 1; while (i && filename[i] != '/') i--; if (filename[i] == '/') i++; if (i) { result = (char *)xmalloc (1 + i); strncpy (result, filename, i); result[i] = 0; } free (filename); return (result); } char * filename_non_directory (name) char *name; { register int i; for (i = strlen (name) - 1; i; i--) if (name[i] == '/') return (xstrdup (name + i + 1)); return (xstrdup (name)); } /* Return the expansion of FILENAME. */ char * expand_filename (filename, input_name) char *filename, *input_name; { register int i; char *full_pathname (); if (filename) filename = full_pathname (filename); else { filename = filename_non_directory (input_name); if (!*filename) { free (filename); filename = xstrdup ("noname.texi"); } for (i = strlen (filename) - 1; i; i--) if (filename[i] == '.') break; if (!i) i = strlen (filename); if (i + 6 > (strlen (filename))) filename = (char *)xrealloc (filename, i + 6); strcpy (filename + i, ".info"); return (filename); } if (filename[0] == '.' || filename[0] == '/') return (filename); if (filename[0] != '/' && input_name[0] == '/') { /* Make it so that relative names work. */ char *result; i = strlen (input_name) - 1; result = (char *)xmalloc (1 + strlen (input_name) + strlen (filename)); strcpy (result, input_name); while (result[i] != '/' && i) i--; if (result[i] == '/') i++; strcpy (&result[i], filename); free (filename); return (result); } return (filename); } /* Return the full path to FILENAME. */ char * full_pathname (filename) char *filename; { int initial_character; char *result; /* No filename given? */ if (!filename || !(initial_character = *filename)) return (xstrdup ("")); /* Already absolute? */ if ((initial_character == '/') || ((strncmp (filename, "./", 2) == 0) || (strncmp (filename, "../", 3) == 0))) return (xstrdup (filename)); if (initial_character != '~') { char *localdir; localdir = (char *)xmalloc (1025); #if defined (HAVE_GETCWD) if (!getcwd (localdir, 1024)) #else /* !HAVE_GETCWD */ if (!getwd (localdir)) #endif /* !HAVE_GETCWD */ { fprintf (stderr, _("%s: getwd: %s, %s\n"), progname, filename, localdir); exit (1); } strcat (localdir, "/"); strcat (localdir, filename); result = xstrdup (localdir); free (localdir); } else { #ifndef WIN32 if (filename[1] == '/') { /* Return the concatenation of the environment variable HOME and the rest of the string. */ char *temp_home; temp_home = (char *) getenv ("HOME"); result = (char *)xmalloc (strlen (&filename[1]) + 1 + temp_home ? strlen (temp_home) : 0); *result = 0; if (temp_home) strcpy (result, temp_home); strcat (result, &filename[1]); } else { struct passwd *user_entry; int i, c; char *username = (char *)xmalloc (257); for (i = 1; (c = filename[i]); i++) { if (c == '/') break; else username[i - 1] = c; } if (c) username[i - 1] = 0; user_entry = getpwnam (username); if (!user_entry) return (xstrdup (filename)); result = (char *)xmalloc (1 + strlen (user_entry->pw_dir) + strlen (&filename[i])); strcpy (result, user_entry->pw_dir); strcat (result, &filename[i]); } } #endif /* not WIN32 */ return (result); } char * output_name_from_input_name (name) char *name; { return (expand_filename ((char *)NULL, name)); } /* **************************************************************** */ /* */ /* Hacking Tokens and Strings */ /* */ /* **************************************************************** */ /* Return the next token as a string pointer. We cons the string. */ char * read_token () { int i, character; char *result; /* If the first character to be read is self-delimiting, then that is the command itself. */ character = curchar (); if (self_delimiting (character)) { input_text_offset++; if (character == '\n') line_number++; result = xstrdup (" "); *result = character; return (result); } for (i = 0; ((input_text_offset != size_of_input_text) && (character = curchar ()) && command_char (character)); i++, input_text_offset++); result = (char *)xmalloc (i + 1); memcpy (result, &input_text[input_text_offset - i], i); result[i] = 0; return (result); } /* Return nonzero if CHARACTER is self-delimiting. */ int self_delimiting (character) int character; { /* @; and @\ are not Texinfo commands, but they are listed here anyway. I don't know why. --karl, 10aug96. */ return member (character, "~{|}`^\\@?=;:.-,*\'\" !\n\t"); } /* Clear whitespace from the front and end of string. */ void canon_white (string) char *string; { int len = strlen (string); int x; if (!len) return; for (x = 0; x < len; x++) { if (!cr_or_whitespace (string[x])) { strcpy (string, string + x); break; } } len = strlen (string); if (len) len--; while (len > -1 && cr_or_whitespace (string[len])) len--; string[len + 1] = 0; } /* Bash STRING, replacing all whitespace with just one space. */ void fix_whitespace (string) char *string; { char *temp = (char *)xmalloc (strlen (string) + 1); int string_index = 0; int temp_index = 0; int c; canon_white (string); while (string[string_index]) { c = temp[temp_index++] = string[string_index++]; if (c == ' ' || c == '\n' || c == '\t') { temp[temp_index - 1] = ' '; while ((c = string[string_index]) && (c == ' ' || c == '\t' || c == '\n')) string_index++; } } temp[temp_index] = 0; strcpy (string, temp); free (temp); } /* Discard text until the desired string is found. The string is included in the discarded text. */ void discard_until (string) char *string; { int temp = search_forward (string, input_text_offset); int tt = (temp < 0) ? size_of_input_text : temp + strlen (string); int from = input_text_offset; /* Find out what line we are on. */ while (from != tt) if (input_text[from++] == '\n') line_number++; if (temp < 0) { input_text_offset = size_of_input_text - strlen (string); if (strcmp (string, "\n") != 0) { line_error (_("Expected `%s'"), string); return; } } else input_text_offset = temp; input_text_offset += strlen (string); } /* Read characters from the file until we are at MATCH. Place the characters read into STRING. On exit input_text_offset is after the match string. Return the offset where the string starts. */ int get_until (match, string) char *match, **string; { int len, current_point, x, new_point, tem; current_point = x = input_text_offset; new_point = search_forward (match, input_text_offset); if (new_point < 0) new_point = size_of_input_text; len = new_point - current_point; /* Keep track of which line number we are at. */ tem = new_point + (strlen (match) - 1); while (x != tem) if (input_text[x++] == '\n') line_number++; *string = (char *)xmalloc (len + 1); memcpy (*string, &input_text[current_point], len); (*string)[len] = 0; /* Now leave input_text_offset in a consistent state. */ input_text_offset = tem; if (input_text_offset > size_of_input_text) input_text_offset = size_of_input_text; return (new_point); } /* Read characters from the file until we are at MATCH or end of line. Place the characters read into STRING. */ void get_until_in_line (expand, match, string) int expand; char *match, **string; { int real_bottom = size_of_input_text; int limit = search_forward ("\n", input_text_offset); if (limit < 0) limit = size_of_input_text; /* Replace input_text[input_text_offset .. limit-1] with its macro expansion (actually, we expand all commands). This allows the node names themselves to be constructed via a macro, as in: @macro foo{p, q} Together: \p\ & \q\. @end macro @node @foo{A,B}, next, prev, top Otherwise, the `,' separating the macro args A and B is taken as the node argument separator, so the node name is `@foo{A'. This expansion is only necessary on the first call, since we expand the whole line then. Furthermore, if we're executing a string, don't do it -- we'll end up shrinking the execution string which is currently aliased to `input_text', so it might get moved, and not updated in the `execution_strings' array. This happens when processing the (synthetic) Overview-Footnotes node in the Texinfo manual. */ if (expand && !executing_string && !me_executing_string) { char *xp; unsigned xp_len, new_len; /* Get original string from input. */ unsigned raw_len = limit - input_text_offset; char *str = xmalloc (raw_len + 1); strncpy (str, input_text + input_text_offset, raw_len); str[raw_len] = 0; /* Expand it. */ xp = expansion (str, 0); xp_len = strlen (xp); free (str); /* Plunk the expansion into the middle of `input_text' -- which is terminated by a newline, not a null. */ str = xmalloc (real_bottom - limit + 1); strncpy (str, input_text + limit, real_bottom - limit + 1); new_len = input_text_offset + xp_len + real_bottom - limit + 1; input_text = xrealloc (input_text, new_len); strcpy (input_text + input_text_offset, xp); strncpy (input_text + input_text_offset + xp_len, str, real_bottom - limit + 1); free (str); free (xp); limit += xp_len - raw_len; real_bottom += xp_len - raw_len; } size_of_input_text = limit; get_until (match, string); size_of_input_text = real_bottom; } void get_rest_of_line (string) char **string; { get_until ("\n", string); canon_white (*string); if (curchar () == '\n') /* as opposed to the end of the file... */ { line_number++; input_text_offset++; } } /* Backup the input pointer to the previous character, keeping track of the current line number. */ void backup_input_pointer () { if (input_text_offset) { input_text_offset--; if (curchar () == '\n') line_number--; } } /* Read characters from the file until we are at MATCH or closing brace. Place the characters read into STRING. */ void get_until_in_braces (match, string) char *match, **string; { char *temp; int i, brace = 0; int match_len = strlen (match); for (i = input_text_offset; i < size_of_input_text; i++) { if (input_text[i] == '{') brace++; else if (input_text[i] == '}') brace--; else if (input_text[i] == '\n') line_number++; if (brace < 0 || (brace == 0 && strncmp (input_text + i, match, match_len) == 0)) break; } match_len = i - input_text_offset; temp = (char *)xmalloc (2 + match_len); strncpy (temp, input_text + input_text_offset, match_len); temp[match_len] = 0; input_text_offset = i; *string = temp; } /* **************************************************************** */ /* */ /* Converting the File */ /* */ /* **************************************************************** */ /* Convert the file named by NAME. The output is saved on the file named as the argument to the @setfilename command. */ static char *suffixes[] = { ".texinfo", ".texi", ".txinfo", "", (char *)NULL }; void initialize_conversion () { init_tag_table (); init_indices (); init_internals (); init_paragraph (); /* This is used for splitting the output file and for doing section headings. It was previously initialized in `init_paragraph', but its use there loses with the `init_paragraph' calls done by the multitable code; the tag indices get reset to zero. */ output_position = 0; } /* We read in multiples of 4k, simply because it is a typical pipe size on unix systems. */ #define READ_BUFFER_GROWTH (4 * 4096) /* Convert the Texinfo file coming from the open stream STREAM. Assume the source of the stream is named NAME. */ void convert_from_stream (stream, name) FILE *stream; char *name; { char *buffer = (char *)NULL; int buffer_offset = 0, buffer_size = 0; initialize_conversion (); /* Read until the end of the stream. This isn't strictly correct, since the texinfo input may end before the stream ends, but it is a quick working hueristic. */ while (!feof (stream)) { int count; if (buffer_offset + (READ_BUFFER_GROWTH + 1) >= buffer_size) buffer = (char *) xrealloc (buffer, (buffer_size += READ_BUFFER_GROWTH)); count = fread (buffer + buffer_offset, 1, READ_BUFFER_GROWTH, stream); if (count < 0) { perror (name); exit (FATAL); } buffer_offset += count; if (count == 0) break; } /* Set the globals to the new file. */ input_text = buffer; size_of_input_text = buffer_offset; input_filename = xstrdup (name); node_filename = xstrdup (name); input_text_offset = 0; line_number = 1; /* Not strictly necessary. This magic prevents read_token () from doing extra unnecessary work each time it is called (that is a lot of times). The SIZE_OF_INPUT_TEXT is one past the actual end of the text. */ input_text[size_of_input_text] = '\n'; convert_from_loaded_file (name); } void convert_from_file (name) char *name; { register int i; char *filename = (char *)xmalloc (strlen (name) + 50); initialize_conversion (); /* Try to load the file specified by NAME, concatenated with our various suffixes. Prefer files like `makeinfo.texi' to `makeinfo'. */ for (i = 0; suffixes[i]; i++) { strcpy (filename, name); strcat (filename, suffixes[i]); if (find_and_load (filename)) break; if (!suffixes[i][0] && strrchr (filename, '.')) { fs_error (filename); free (filename); return; } } if (!suffixes[i]) { fs_error (name); free (filename); return; } input_filename = filename; convert_from_loaded_file (name); } void convert_from_loaded_file (name) char *name; { char *expand_filename (), *filename_part (); char *real_output_filename = (char *)NULL; #if defined (HAVE_MACROS) remember_itext (input_text, 0); #endif /* HAVE_MACROS */ /* Search this file looking for the special string which starts conversion. Once found, we may truly begin. */ input_text_offset = 0; while (input_text_offset >= 0) { input_text_offset = search_forward (setfilename_search, input_text_offset); if ((input_text_offset == 0) || ((input_text_offset > 0) && (input_text[input_text_offset -1] == '\n'))) break; else if (input_text_offset > 0) input_text_offset++; } if (input_text_offset < 0) { if (!command_output_filename) { #if defined (REQUIRE_SETFILENAME) error (_("No `%s' found in `%s'"), setfilename_search, name); goto finished; #else register int i, end_of_first_line; /* Find the end of the first line in the file. */ for (i = 0; i < size_of_input_text - 1; i++) if (input_text[i] == '\n') break; end_of_first_line = i + 1; input_text_offset = 0; for (i = 0; i < end_of_first_line; i++) { if ((input_text[i] == '\\') && (strncmp (input_text + i + 1, "include", 7) == 0)) { input_text_offset = end_of_first_line; break; } } command_output_filename = output_name_from_input_name (name); #endif /* !REQUIRE_SETFILENAME */ } } else input_text_offset += strlen (setfilename_search); if (!command_output_filename) get_until ("\n", &output_filename); else { if (input_text_offset != -1) discard_until ("\n"); else input_text_offset = 0; real_output_filename = output_filename = command_output_filename; command_output_filename = (char *)NULL; } canon_white (output_filename); if (real_output_filename && strcmp (real_output_filename, "-") == 0) { if (macro_expansion_filename && strcmp (macro_expansion_filename, "-") == 0) { fprintf (stderr, _("%s: Skipping macro expansion to stdout as Info output is going there.\n"), progname); macro_expansion_output_stream = NULL; } real_output_filename = xstrdup (real_output_filename); output_stream = stdout; splitting = 0; /* Cannot split when writing to stdout. */ } else { if (!real_output_filename) real_output_filename = expand_filename (output_filename, name); else real_output_filename = xstrdup (real_output_filename); output_stream = fopen (real_output_filename, "w"); } if (output_stream != stdout) printf (_("Making %s file `%s' from `%s'.\n"), no_headers ? "text" : "info", output_filename, input_filename); if (output_stream == NULL) { fs_error (real_output_filename); goto finished; } /* Make the displayable filename from output_filename. Only the base portion of the filename need be displayed. */ if (output_stream != stdout) pretty_output_filename = filename_part (output_filename); else pretty_output_filename = xstrdup ("stdout"); /* For this file only, count the number of newlines from the top of the file to here. This way, we keep track of line numbers for error reporting. Line_number starts at 1, since the user isn't zero-based. */ { int temp = 0; line_number = 1; while (temp != input_text_offset) if (input_text[temp++] == '\n') line_number++; } if (!no_headers) { add_word_args (_("This is Info file %s, produced by Makeinfo version %d.%d"), output_filename, major_version, minor_version); add_word_args (_(" from the input file %s.\n"), input_filename); } close_paragraph (); reader_loop (); finished: discard_insertions (0); close_paragraph (); flush_file_stack (); #if defined (HAVE_MACROS) if (macro_expansion_output_stream) { fclose (macro_expansion_output_stream); if (errors_printed && !force && strcmp (macro_expansion_filename, "-") != 0 && strcmp (macro_expansion_filename, "/dev/null") != 0) { fprintf (stderr, _("%s: Removing macro output file `%s' due to errors; use --force to preserve.\n"), progname, macro_expansion_filename); if (unlink (macro_expansion_filename) < 0) perror (macro_expansion_filename); } } #endif /* HAVE_MACROS */ if (output_stream) { output_pending_notes (); free_pending_notes (); if (tag_table != NULL) { tag_table = (TAG_ENTRY *) reverse_list (tag_table); if (!no_headers) write_tag_table (); } if (output_stream != stdout) fclose (output_stream); /* If validating, then validate the entire file right now. */ if (validating) validate_file (tag_table); if (splitting && (!errors_printed || force)) split_file (real_output_filename, 0); else if (errors_printed && !force && strcmp (real_output_filename, "-") != 0 && strcmp (real_output_filename, "/dev/null") != 0) { /* If there were errors, and no --force, remove the output. */ fprintf (stderr, _("%s: Removing output file `%s' due to errors; use --force to preserve.\n"), progname, real_output_filename); if (unlink (real_output_filename) < 0) perror (real_output_filename); } } free (real_output_filename); } void free_and_clear (pointer) char **pointer; { if (*pointer) { free (*pointer); *pointer = (char *) NULL; } } /* Initialize some state. */ void init_internals () { free_and_clear (&output_filename); free_and_clear (&command); free_and_clear (&input_filename); free_node_references (); init_insertion_stack (); init_brace_stack (); current_node = NULL; /* sometimes already freed */ command_index = 0; in_menu = 0; in_detailmenu = 0; top_node_seen = 0; non_top_node_seen = 0; } void init_paragraph () { free_and_clear (&output_paragraph); output_paragraph = (unsigned char *)xmalloc (paragraph_buffer_len); output_paragraph[0] = 0; output_paragraph_offset = 0; output_column = 0; paragraph_is_open = 0; current_indent = 0; } /* Okay, we are ready to start the conversion. Call the reader on some text, and fill the text as it is output. Handle commands by remembering things like open braces and the current file position on a stack, and when the corresponding close brace is found, you can call the function with the proper arguments. */ void reader_loop () { int character; int done = 0; int dash_count = 0; while (!done) { if (input_text_offset >= size_of_input_text) break; character = curchar (); if (!in_fixed_width_font && (character == '\'' || character == '`') && input_text[input_text_offset + 1] == character) { input_text_offset++; character = '"'; } if (character == '-') { dash_count++; if (dash_count == 2 && !in_fixed_width_font) { input_text_offset++; continue; } } else { dash_count = 0; } /* If this is a whitespace character, then check to see if the line is blank. If so, advance to the carriage return. */ if (whitespace (character)) { register int i = input_text_offset + 1; while (i < size_of_input_text && whitespace (input_text[i])) i++; if (i == size_of_input_text || input_text[i] == '\n') { if (i == size_of_input_text) i--; input_text_offset = i; character = curchar (); } } if (character == '\n') { line_number++; /* Check for a menu entry here, since the "escape sequence" that begins menu entries is "\n* ". */ if (in_menu && input_text_offset + 1 < size_of_input_text) { char *glean_node_from_menu (), *tem; /* Note that the value of TEM is discarded, since it is gauranteed to be NULL when glean_node_from_menu () is called with a Nonzero argument. */ if (!in_detailmenu) tem = glean_node_from_menu (1); } } switch (character) { case COMMAND_PREFIX: read_command (); break; case '{': /* Special case. I'm not supposed to see this character by itself. If I do, it means there is a syntax error in the input text. Report the error here, but remember this brace on the stack so you can ignore its partner. */ line_error (_("Misplaced %c"), '{'); remember_brace (misplaced_brace); /* Don't advance input_text_offset since this happens in remember_brace (). input_text_offset++; */ break; case '}': pop_and_call_brace (); input_text_offset++; break; default: add_char (character); input_text_offset++; } } #if defined (HAVE_MACROS) if (macro_expansion_output_stream) maybe_write_itext (input_text, input_text_offset); #endif /* HAVE_MACROS */ } /* Find the command corresponding to STRING. If the command is found, return a pointer to the data structure. Otherwise return (-1). */ COMMAND * get_command_entry (string) char *string; { register int i; for (i = 0; command_table[i].name; i++) if (strcmp (command_table[i].name, string) == 0) return (&command_table[i]); /* This command is not in our predefined command table. Perhaps it is a user defined command. */ for (i = 0; i < user_command_array_len; i++) if (user_command_array[i] && (strcmp (user_command_array[i]->name, string) == 0)) return (user_command_array[i]); /* We never heard of this command. */ return ((COMMAND *) -1); } /* input_text_offset is right at the command prefix character. Read the next token to determine what to do. */ void read_command () { COMMAND *entry; input_text_offset++; free_and_clear (&command); command = read_token (); #if defined (HAVE_MACROS) /* Check to see if this command is a macro. If so, execute it here. */ { MACRO_DEF *def; def = find_macro (command); if (def) { /* We disallow recursive use of a macro call. Inhibit the expansion of this macro during the life of its execution. */ if (!(def->flags & ME_RECURSE)) def->inhibited = 1; execute_macro (def); if (!(def->flags & ME_RECURSE)) def->inhibited = 0; return; } } #endif /* HAVE_MACROS */ entry = get_command_entry (command); if (entry == (COMMAND *)-1) { line_error (_("Unknown command `%s'"), command); return; } if (entry->argument_in_braces) remember_brace (entry->proc); (*(entry->proc)) (START, output_paragraph_offset, 0); } /* Return the string which invokes PROC; a pointer to a function. */ char * find_proc_name (proc) COMMAND_FUNCTION *proc; { register int i; for (i = 0; command_table[i].name; i++) if (proc == command_table[i].proc) return command_table[i].name; return _("NO_NAME!"); } void init_brace_stack () { brace_stack = (BRACE_ELEMENT *) NULL; } void remember_brace (proc) COMMAND_FUNCTION *proc; { if (curchar () != '{') line_error (_("%c%s expected `{...}'"), COMMAND_PREFIX, command); else input_text_offset++; remember_brace_1 (proc, output_paragraph_offset); } /* Remember the current output position here. Save PROC along with it so you can call it later. */ void remember_brace_1 (proc, position) COMMAND_FUNCTION *proc; int position; { BRACE_ELEMENT *new = (BRACE_ELEMENT *) xmalloc (sizeof (BRACE_ELEMENT)); new->next = brace_stack; new->proc = proc; new->pos = position; new->line = line_number; new->in_fixed_width_font = in_fixed_width_font; brace_stack = new; } /* Pop the top of the brace stack, and call the associated function with the args END and POS. */ void pop_and_call_brace () { BRACE_ELEMENT *temp; COMMAND_FUNCTION *proc; int pos; if (brace_stack == (BRACE_ELEMENT *) NULL) { line_error (_("Unmatched }")); return; } pos = brace_stack->pos; proc = brace_stack->proc; in_fixed_width_font = brace_stack->in_fixed_width_font; temp = brace_stack->next; free (brace_stack); brace_stack = temp; (*proc) (END, pos, output_paragraph_offset); } /* Shift all of the markers in `brace_stack' by AMOUNT. */ void adjust_braces_following (here, amount) int here, amount; { register BRACE_ELEMENT *stack = brace_stack; while (stack) { if (stack->pos >= here) stack->pos += amount; stack = stack->next; } } /* You call discard_braces () when you shouldn't have any braces on the stack. I used to think that this happens for commands that don't take arguments in braces, but that was wrong because of things like @code{foo @@}. So now I only detect it at the beginning of nodes. */ void discard_braces () { if (!brace_stack) return; while (brace_stack) { if (brace_stack->proc != misplaced_brace) { char *proc_name; int temp_line_number = line_number; line_number = brace_stack->line; proc_name = find_proc_name (brace_stack->proc); line_error (_("%c%s missing close brace"), COMMAND_PREFIX, proc_name); line_number = temp_line_number; pop_and_call_brace (); } else { BRACE_ELEMENT *temp; temp = brace_stack->next; free (brace_stack); brace_stack = temp; } } } int get_char_len (character) int character; { /* Return the printed length of the character. */ int len; switch (character) { case '\t': len = (output_column + 8) & 0xf7; if (len > fill_column) len = fill_column - output_column; else len = len - output_column; break; case '\n': len = fill_column - output_column; break; default: /* ASCII control characters appear as two characters in the output (e.g., ^A). But characters with the high bit set are just one on suitable terminals, so don't count them as two for line breaking purposes. */ if (0 <= character && character < ' ') len = 2; else len = 1; } return (len); } void #if defined (VA_FPRINTF) && __STDC__ add_word_args (char *format, ...) #else add_word_args (format, va_alist) char *format; va_dcl #endif { char buffer[1000]; #ifdef VA_FPRINTF va_list ap; #endif VA_START (ap, format); #ifdef VA_SPRINTF VA_SPRINTF (buffer, format, ap); #else sprintf (temp_string, format, a1, a2, a3, a4, a5, a6, a7, a8); #endif /* not VA_SPRINTF */ va_end (ap); add_word (buffer); } /* Add STRING to output_paragraph. */ void add_word (string) char *string; { while (*string) add_char (*string++); } /* Nonzero if the last character inserted has the syntax class of NEWLINE. */ int last_char_was_newline = 1; /* The actual last inserted character. Note that this may be something other than NEWLINE even if last_char_was_newline is 1. */ int last_inserted_character = 0; /* Nonzero means that a newline character has already been inserted, so close_paragraph () should insert one less. */ int line_already_broken = 0; /* When nonzero we have finished an insertion (see `end_insertion') and we want to ignore false continued paragraph closings. */ int insertion_paragraph_closed = 0; /* Nonzero means attempt to make all of the lines have fill_column width. */ int do_justification = 0; /* Add the character to the current paragraph. If filling_enabled is nonzero, then do filling as well. */ void add_char (character) int character; { /* If we are avoiding outputting headers, and we are currently in a menu, then simply return. */ if (no_headers && (in_menu || in_detailmenu)) return; /* If we are adding a character now, then we don't have to ignore close_paragraph () calls any more. */ if (must_start_paragraph && character != '\n') { must_start_paragraph = 0; line_already_broken = 0; /* The line is no longer broken. */ if (current_indent > output_column) { indent (current_indent - output_column); output_column = current_indent; } } if (non_splitting_words && member (character, " \t\n")) character = ' ' | 0x80; insertion_paragraph_closed = 0; switch (character) { case '\n': if (!filling_enabled) { insert ('\n'); if (force_flush_right) { close_paragraph (); /* Hack to force single blank lines out in this mode. */ flush_output (); } output_column = 0; if (!no_indent && paragraph_is_open) indent (output_column = current_indent); break; } else /* CHARACTER is newline, and filling is enabled. */ { if (end_of_sentence_p ()) { insert (' '); output_column++; last_inserted_character = character; } } if (last_char_was_newline) { close_paragraph (); pending_indent = 0; } else { last_char_was_newline = 1; insert (' '); output_column++; } break; default: { int len = get_char_len (character); int suppress_insert = 0; if ((character == ' ') && (last_char_was_newline)) { if (!paragraph_is_open) { pending_indent++; return; } } if (!paragraph_is_open) { start_paragraph (); /* If the paragraph is supposed to be indented a certain way, then discard all of the pending whitespace. Otherwise, we let the whitespace stay. */ if (!paragraph_start_indent) indent (pending_indent); pending_indent = 0; } if ((output_column += len) > fill_column) { if (filling_enabled) { int temp = output_paragraph_offset; while (--temp > 0 && output_paragraph[temp] != '\n') { /* If we have found a space, we have the place to break the line. */ if (output_paragraph[temp] == ' ') { /* Remove trailing whitespace from output. */ while (temp && whitespace (output_paragraph[temp - 1])) temp--; output_paragraph[temp++] = '\n'; /* We have correctly broken the line where we want to. What we don't want is spaces following where we have decided to break the line. We get rid of them. */ { int t1 = temp; for (;; t1++) { if (t1 == output_paragraph_offset) { if (whitespace (character)) suppress_insert = 1; break; } if (!whitespace (output_paragraph[t1])) break; } if (t1 != temp) { adjust_braces_following (temp, (- (t1 - temp))); strncpy ((char *) &output_paragraph[temp], (char *) &output_paragraph[t1], (output_paragraph_offset - t1)); output_paragraph_offset -= (t1 - temp); } } /* Filled, but now indent if that is right. */ if (indented_fill && current_indent) { int buffer_len = ((output_paragraph_offset - temp) + current_indent); char *temp_buffer = (char *)xmalloc (buffer_len); int indentation = 0; /* We have to shift any markers that are in front of the wrap point. */ adjust_braces_following (temp, current_indent); while (current_indent > 0 && indentation != current_indent) temp_buffer[indentation++] = ' '; strncpy ((char *) &temp_buffer[current_indent], (char *) &output_paragraph[temp], buffer_len - current_indent); if (output_paragraph_offset + buffer_len >= paragraph_buffer_len) { unsigned char *tt = xrealloc (output_paragraph, (paragraph_buffer_len += buffer_len)); output_paragraph = tt; } strncpy ((char *) &output_paragraph[temp], temp_buffer, buffer_len); output_paragraph_offset += current_indent; free (temp_buffer); } output_column = 0; while (temp < output_paragraph_offset) output_column += get_char_len (output_paragraph[temp++]); output_column += len; break; } } } } if (!suppress_insert) { insert (character); last_inserted_character = character; } last_char_was_newline = 0; line_already_broken = 0; } } } /* Insert CHARACTER into `output_paragraph'. */ void insert (character) int character; { output_paragraph[output_paragraph_offset++] = character; if (output_paragraph_offset == paragraph_buffer_len) { output_paragraph = xrealloc (output_paragraph, (paragraph_buffer_len += 100)); } } /* Insert the null-terminated string STRING into `output_paragraph'. */ void insert_string (string) char *string; { while (*string) insert (*string++); } /* Sentences might have these characters after the period (or whatever). */ #define post_sentence(c) ((c) == ')' || (c) == '\'' || (c) == '"' \ || (c) == ']') /* Return true if at an end-of-sentence character, possibly followed by post-sentence punctuation to ignore. */ static int end_of_sentence_p () { int loc = output_paragraph_offset - 1; while (loc > 0 && post_sentence (output_paragraph[loc])) loc--; return sentence_ender (output_paragraph[loc]); } /* Remove upto COUNT characters of whitespace from the the current output line. If COUNT is less than zero, then remove until none left. */ void kill_self_indent (count) int count; { /* Handle infinite case first. */ if (count < 0) { output_column = 0; while (output_paragraph_offset) { if (whitespace (output_paragraph[output_paragraph_offset - 1])) output_paragraph_offset--; else break; } } else { while (output_paragraph_offset && count--) if (whitespace (output_paragraph[output_paragraph_offset - 1])) output_paragraph_offset--; else break; } } /* Nonzero means do not honor calls to flush_output (). */ static int flushing_ignored = 0; /* Prevent calls to flush_output () from having any effect. */ void inhibit_output_flushing () { flushing_ignored++; } /* Allow calls to flush_output () to write the paragraph data. */ void uninhibit_output_flushing () { flushing_ignored--; } void flush_output () { register int i; if (!output_paragraph_offset || flushing_ignored) return; for (i = 0; i < output_paragraph_offset; i++) { /* If we turned on the 8th bit for a space inside @w, turn it back off for output. */ if (output_paragraph[i] & meta_character_bit) { int temp = UNMETA (output_paragraph[i]); if (temp == ' ') output_paragraph[i] &= 0x7f; } } fwrite (output_paragraph, 1, output_paragraph_offset, output_stream); output_position += output_paragraph_offset; output_paragraph_offset = 0; } /* How to close a paragraph controlling the number of lines between this one and the last one. */ /* Paragraph spacing is controlled by this variable. It is the number of blank lines that you wish to appear between paragraphs. A value of 1 creates a single blank line between paragraphs. */ int paragraph_spacing = DEFAULT_PARAGRAPH_SPACING; /* Close the current paragraph, leaving no blank lines between them. */ void close_single_paragraph () { close_paragraph_with_lines (0); } /* Close a paragraph after an insertion has ended. */ void close_insertion_paragraph () { if (!insertion_paragraph_closed) { /* Close the current paragraph, breaking the line. */ close_single_paragraph (); /* Start a new paragraph, with the correct indentation for the now current insertion level (one above the one that we are ending). */ start_paragraph (); /* Tell `close_paragraph' that the previous line has already been broken, so it should insert one less newline. */ line_already_broken = 1; /* Tell functions such as `add_char' we've already found a newline. */ ignore_blank_line (); } else { /* If the insertion paragraph is closed already, then we are seeing two `@end' commands in a row. Note that the first one we saw was handled in the first part of this if-then-else clause, and at that time `start_paragraph' was called, partially to handle the proper indentation of the current line. However, the indentation level may have just changed again, so we may have to outdent the current line to the new indentation level. */ if (current_indent < output_column) kill_self_indent (output_column - current_indent); } insertion_paragraph_closed = 1; } void close_paragraph_with_lines (lines) int lines; { int old_spacing = paragraph_spacing; paragraph_spacing = lines; close_paragraph (); paragraph_spacing = old_spacing; } /* Close the currently open paragraph. */ void close_paragraph () { register int i; /* The insertion paragraph is no longer closed. */ insertion_paragraph_closed = 0; if (paragraph_is_open && !must_start_paragraph) { register int tindex, c; tindex = output_paragraph_offset; /* Back up to last non-newline/space character, forcing all such subsequent characters to be newlines. This isn't strictly necessary, but a couple of functions use the presence of a newline to make decisions. */ for (tindex = output_paragraph_offset - 1; tindex >= 0; --tindex) { c = output_paragraph[tindex]; if (c == ' '|| c == '\n') output_paragraph[tindex] = '\n'; else break; } /* All trailing whitespace is ignored. */ output_paragraph_offset = ++tindex; /* Break the line if that is appropriate. */ if (paragraph_spacing >= 0) insert ('\n'); /* Add as many blank lines as is specified in `paragraph_spacing'. */ if (!force_flush_right) { for (i = 0; i < (paragraph_spacing - line_already_broken); i++) insert ('\n'); } /* If we are doing flush right indentation, then do it now on the paragraph (really a single line). */ if (force_flush_right) do_flush_right_indentation (); flush_output (); paragraph_is_open = 0; no_indent = 0; output_column = 0; } ignore_blank_line (); } /* Make the last line just read look as if it were only a newline. */ void ignore_blank_line () { last_inserted_character = '\n'; last_char_was_newline = 1; } /* Align the end of the text in output_paragraph with fill_column. */ void do_flush_right_indentation () { char *temp; int temp_len; kill_self_indent (-1); if (output_paragraph[0] != '\n') { output_paragraph[output_paragraph_offset] = 0; if (output_paragraph_offset < fill_column) { register int i; if (fill_column >= paragraph_buffer_len) output_paragraph = xrealloc (output_paragraph, (paragraph_buffer_len += fill_column)); temp_len = strlen ((char *)output_paragraph); temp = (char *)xmalloc (temp_len + 1); memcpy (temp, (char *)output_paragraph, temp_len); for (i = 0; i < fill_column - output_paragraph_offset; i++) output_paragraph[i] = ' '; memcpy ((char *)output_paragraph + i, temp, temp_len); free (temp); output_paragraph_offset = fill_column; } } } /* Begin a new paragraph. */ void start_paragraph () { /* First close existing one. */ if (paragraph_is_open) close_paragraph (); /* In either case, the insertion paragraph is no longer closed. */ insertion_paragraph_closed = 0; /* However, the paragraph is open! */ paragraph_is_open = 1; /* If we MUST_START_PARAGRAPH, that simply means that start_paragraph () had to be called before we would allow any other paragraph operations to have an effect. */ if (!must_start_paragraph) { int amount_to_indent = 0; /* If doing indentation, then insert the appropriate amount. */ if (!no_indent) { if (inhibit_paragraph_indentation) { amount_to_indent = current_indent; if (inhibit_paragraph_indentation < 0) inhibit_paragraph_indentation++; } else if (paragraph_start_indent < 0) amount_to_indent = current_indent; else amount_to_indent = current_indent + paragraph_start_indent; if (amount_to_indent >= output_column) { amount_to_indent -= output_column; indent (amount_to_indent); output_column += amount_to_indent; } } } else must_start_paragraph = 0; } /* Insert the indentation specified by AMOUNT. */ void indent (amount) int amount; { register BRACE_ELEMENT *elt = brace_stack; /* For every START_POS saved within the brace stack which will be affected by this indentation, bump that start pos forward. */ while (elt) { if (elt->pos >= output_paragraph_offset) elt->pos += amount; elt = elt->next; } while (--amount >= 0) insert (' '); } /* Search forward for STRING in input_text. FROM says where where to start. */ int search_forward (string, from) char *string; int from; { int len = strlen (string); while (from < size_of_input_text) { if (strncmp (input_text + from, string, len) == 0) return (from); from++; } return (-1); } /* Whoops, Unix doesn't have strcasecmp. */ /* Case independent string compare. */ #if !defined (HAVE_STRCASECMP) int strcasecmp (string1, string2) char *string1, *string2; { char ch1, ch2; for (;;) { ch1 = *string1++; ch2 = *string2++; if (!(ch1 | ch2)) return (0); ch1 = coerce_to_upper (ch1); ch2 = coerce_to_upper (ch2); if (ch1 != ch2) return (ch1 - ch2); } } #endif /* !HAVE_STRCASECMP */ void init_insertion_stack () { insertion_stack = (INSERTION_ELT *) NULL; } /* Return the type of the current insertion. */ enum insertion_type current_insertion_type () { if (!insertion_level) return (bad_type); else return (insertion_stack->insertion); } /* Return a pointer to the string which is the function to wrap around items. */ char * current_item_function () { register int level, done; register INSERTION_ELT *elt; level = insertion_level; elt = insertion_stack; done = 0; /* Skip down through the stack until we find a non-conditional insertion. */ while (!done && (elt != NULL)) { switch (elt->insertion) { case ifinfo: case ifnothtml: case ifnottex: case ifset: case ifclear: case cartouche: elt = elt->next; level--; break; default: done = 1; } } if (!level) return ((char *) NULL); else return (elt->item_function); } char * get_item_function () { char *item_function; get_rest_of_line (&item_function); backup_input_pointer (); return (item_function); } /* Push the state of the current insertion on the stack. */ void push_insertion (type, item_function) enum insertion_type type; char *item_function; { INSERTION_ELT *new = (INSERTION_ELT *) xmalloc (sizeof (INSERTION_ELT)); new->item_function = item_function; new->filling_enabled = filling_enabled; new->indented_fill = indented_fill; new->insertion = type; new->line_number = line_number; new->filename = xstrdup (input_filename); new->inhibited = inhibit_paragraph_indentation; new->in_fixed_width_font = in_fixed_width_font; new->next = insertion_stack; insertion_stack = new; insertion_level++; } /* Pop the value on top of the insertion stack into the global variables. */ void pop_insertion () { INSERTION_ELT *temp = insertion_stack; if (temp == (INSERTION_ELT *) NULL) return; in_fixed_width_font = temp->in_fixed_width_font; inhibit_paragraph_indentation = temp->inhibited; filling_enabled = temp->filling_enabled; indented_fill = temp->indented_fill; free_and_clear (&(temp->item_function)); free_and_clear (&(temp->filename)); insertion_stack = insertion_stack->next; free (temp); insertion_level--; } /* Return a pointer to the print name of this enumerated type. */ char * insertion_type_pname (type) enum insertion_type type; { if ((int) type < (int) bad_type) return (insertion_type_names[(int) type]); else return (_("Broken-Type in insertion_type_pname")); } /* Return the insertion_type associated with NAME. If the type is not one of the known ones, return BAD_TYPE. */ enum insertion_type find_type_from_name (name) char *name; { int index = 0; while (index < (int) bad_type) { if (strcmp (name, insertion_type_names[index]) == 0) return (enum insertion_type) index; index++; } return (bad_type); } int defun_insertion (type) enum insertion_type type; { return ((type == deffn) || (type == defun) || (type == defmac) || (type == defspec) || (type == defvr) || (type == defvar) || (type == defopt) || (type == deftypefn) || (type == deftypefun) || (type == deftypevr) || (type == deftypevar) || (type == defcv) || (type == defivar) || (type == defop) || (type == defmethod) || (type == deftypemethod) || (type == deftp)); } /* MAX_NS is the maximum nesting level for enumerations. I picked 100 which seemed reasonable. This doesn't control the number of items, just the number of nested lists. */ #define max_stack_depth 100 #define ENUM_DIGITS 1 #define ENUM_ALPHA 2 typedef struct { int enumtype; int enumval; } DIGIT_ALPHA; DIGIT_ALPHA enumstack[max_stack_depth]; int enumstack_offset = 0; int current_enumval = 1; int current_enumtype = ENUM_DIGITS; char *enumeration_arg = (char *)NULL; void start_enumerating (at, type) int at, type; { if ((enumstack_offset + 1) == max_stack_depth) { line_error (_("Enumeration stack overflow")); return; } enumstack[enumstack_offset].enumtype = current_enumtype; enumstack[enumstack_offset].enumval = current_enumval; enumstack_offset++; current_enumval = at; current_enumtype = type; } void stop_enumerating () { --enumstack_offset; if (enumstack_offset < 0) enumstack_offset = 0; current_enumval = enumstack[enumstack_offset].enumval; current_enumtype = enumstack[enumstack_offset].enumtype; } /* Place a letter or digits into the output stream. */ void enumerate_item () { char temp[10]; if (current_enumtype == ENUM_ALPHA) { if (current_enumval == ('z' + 1) || current_enumval == ('Z' + 1)) { current_enumval = ((current_enumval - 1) == 'z' ? 'a' : 'A'); warning (_("lettering overflow, restarting at %c"), current_enumval); } sprintf (temp, "%c. ", current_enumval); } else sprintf (temp, "%d. ", current_enumval); indent (output_column += (current_indent - strlen (temp))); add_word (temp); current_enumval++; } /* This is where the work for all the "insertion" style commands is done. A huge switch statement handles the various setups, and generic code is on both sides. */ void begin_insertion (type) enum insertion_type type; { int no_discard = 0; if (defun_insertion (type)) { push_insertion (type, xstrdup ("")); no_discard++; } else push_insertion (type, get_item_function ()); switch (type) { case menu: if (!no_headers) close_paragraph (); filling_enabled = no_indent = 0; inhibit_paragraph_indentation = 1; if (!no_headers) add_word (_("* Menu:\n")); in_menu++; no_discard++; break; case detailmenu: if (!in_menu) { if (!no_headers) close_paragraph (); filling_enabled = no_indent = 0; inhibit_paragraph_indentation = 1; no_discard++; } in_detailmenu++; break; case direntry: close_single_paragraph (); filling_enabled = no_indent = 0; inhibit_paragraph_indentation = 1; insert_string ("START-INFO-DIR-ENTRY\n"); break; /* I think @quotation is meant to do filling. If you don't want filling, then use @display. */ case quotation: close_single_paragraph (); last_char_was_newline = no_indent = 0; indented_fill = filling_enabled = 1; inhibit_paragraph_indentation = 1; current_indent += default_indentation_increment; break; case display: case example: case smallexample: case lisp: case smalllisp: /* Just like @example, but no indentation. */ case format: close_single_paragraph (); inhibit_paragraph_indentation = 1; in_fixed_width_font++; filling_enabled = 0; last_char_was_newline = 0; if (type != format) current_indent += default_indentation_increment; break; case multitable: do_multitable (); break; case table: case ftable: case vtable: case itemize: close_single_paragraph (); current_indent += default_indentation_increment; filling_enabled = indented_fill = 1; #if defined (INDENT_PARAGRAPHS_IN_TABLE) inhibit_paragraph_indentation = 0; #else inhibit_paragraph_indentation = 1; #endif /* !INDENT_PARAGRAPHS_IN_TABLE */ /* Make things work for losers who forget the itemize syntax. */ if (allow_lax_format && (type == itemize)) { if (!(*insertion_stack->item_function)) { free (insertion_stack->item_function); insertion_stack->item_function = xstrdup ("@bullet"); insertion_stack->item_function[0] = COMMAND_PREFIX; } } if (!*insertion_stack->item_function) { line_error (_("%s requires an argument: the formatter for %citem"), insertion_type_pname (type), COMMAND_PREFIX); } break; case enumerate: close_single_paragraph (); no_indent = 0; #if defined (INDENT_PARAGRAPHS_IN_TABLE) inhibit_paragraph_indentation = 0; #else inhibit_paragraph_indentation = 1; #endif /* !INDENT_PARAGRAPHS_IN_TABLE */ current_indent += default_indentation_increment; filling_enabled = indented_fill = 1; if (isdigit (*enumeration_arg)) start_enumerating (atoi (enumeration_arg), ENUM_DIGITS); else start_enumerating (*enumeration_arg, ENUM_ALPHA); break; /* Does nothing special in makeinfo. */ case group: /* Only close the paragraph if we are not inside of an @example. */ if (!insertion_stack->next || insertion_stack->next->insertion != example) close_single_paragraph (); break; /* Insertions that are no-ops in info, but do something in TeX. */ case ifinfo: case ifnothtml: case ifnottex: case ifset: case ifclear: case cartouche: if (in_menu) no_discard++; break; case deffn: case defun: case defmac: case defspec: case defvr: case defvar: case defopt: case deftypefn: case deftypefun: case deftypevr: case deftypevar: case defcv: case defivar: case defop: case defmethod: case deftypemethod: case deftp: inhibit_paragraph_indentation = 1; filling_enabled = indented_fill = 1; current_indent += default_indentation_increment; no_indent = 0; break; case flushleft: close_single_paragraph (); inhibit_paragraph_indentation = 1; filling_enabled = indented_fill = no_indent = 0; break; case flushright: close_single_paragraph (); filling_enabled = indented_fill = no_indent = 0; inhibit_paragraph_indentation = 1; force_flush_right++; break; } if (!no_discard) discard_until ("\n"); } /* Try to end the insertion with the specified TYPE. With a value of `bad_type', TYPE gets translated to match the value currently on top of the stack. Otherwise, if TYPE doesn't match the top of the insertion stack, give error. */ void end_insertion (type) enum insertion_type type; { enum insertion_type temp_type; if (!insertion_level) return; temp_type = current_insertion_type (); if (type == bad_type) type = temp_type; if (type != temp_type) { line_error (_("`%cend' expected `%s', but saw `%s'"), COMMAND_PREFIX, insertion_type_pname (temp_type), insertion_type_pname (type)); return; } pop_insertion (); switch (type) { /* Insertions which have no effect on paragraph formatting. */ case ifnothtml: case ifnottex: case ifinfo: case ifset: case ifclear: break; case direntry: insert_string ("END-INFO-DIR-ENTRY\n\n"); close_insertion_paragraph (); break; case detailmenu: in_detailmenu--; /* No longer hacking menus. */ if (!in_menu) { if (!no_headers) close_insertion_paragraph (); } break; case menu: in_menu--; /* No longer hacking menus. */ if (!no_headers) close_insertion_paragraph (); break; case multitable: end_multitable (); break; case enumerate: stop_enumerating (); close_insertion_paragraph (); current_indent -= default_indentation_increment; break; case flushleft: case group: case cartouche: close_insertion_paragraph (); break; case format: case display: case example: case smallexample: case lisp: case smalllisp: case quotation: /* @format is the only fixed_width insertion without a change in indentation. */ if (type != format) current_indent -= default_indentation_increment; /* The ending of one of these insertions always marks the start of a new paragraph. */ close_insertion_paragraph (); break; case table: case ftable: case vtable: case itemize: current_indent -= default_indentation_increment; break; case flushright: force_flush_right--; close_insertion_paragraph (); break; /* Handle the @defun style insertions with a default clause. */ default: current_indent -= default_indentation_increment; close_insertion_paragraph (); break; } } /* Insertions cannot cross certain boundaries, such as node beginnings. In code that creates such boundaries, you should call `discard_insertions' before doing anything else. It prints the errors for you, and cleans up the insertion stack. With nonzero SPECIALS_OK, allows unmatched ifinfo, ifset, ifclear, otherwise not. */ void discard_insertions (specials_ok) int specials_ok; { int real_line_number = line_number; while (insertion_stack) { if (specials_ok && (insertion_stack->insertion == ifinfo || insertion_stack->insertion == ifset || insertion_stack->insertion == ifclear)) break; else { char *offender = insertion_type_pname (insertion_stack->insertion); char *current_filename = input_filename; input_filename = insertion_stack->filename; line_number = insertion_stack->line_number; line_error (_("No matching `%cend %s'"), COMMAND_PREFIX, offender); input_filename = current_filename; pop_insertion (); } } line_number = real_line_number; } /* The Texinfo commands. */ /* Commands which insert their own names. */ void insert_self (arg) int arg; { if (arg == START) add_word (command); } void insert_space (arg) int arg; { if (arg == START) add_char (' '); } /* Force a line break in the output. */ void cm_asterisk () { close_single_paragraph (); cm_noindent (); } /* Insert ellipsis. */ void cm_dots (arg) int arg; { if (arg == START) add_word ("..."); } /* Insert ellipsis for sentence end. */ void cm_enddots (arg) int arg; { if (arg == START) add_word ("...."); } void cm_bullet (arg) int arg; { if (arg == START) add_char ('*'); } void cm_minus (arg) int arg; { if (arg == START) add_char ('-'); } /* Insert "TeX". */ void cm_TeX (arg) int arg; { if (arg == START) add_word ("TeX"); } /* Copyright symbol. */ void cm_copyright (arg) int arg; { if (arg == START) add_word ("(C)"); } /* Accent commands that take explicit arguments. */ void cm_accent (arg) int arg; { if (arg == START) { if (strcmp (command, "dotaccent") == 0) /* overdot */ add_char ('.'); else if (strcmp (command, "H") == 0) /* Hungarian umlaut */ add_word ("''"); else if (strcmp (command, "ringaccent") == 0) add_char ('*'); else if (strcmp (command, "tieaccent") == 0) add_char ('['); else if (strcmp (command, "u") == 0) /* breve */ add_char ('('); else if (strcmp (command, "v") == 0) /* hacek/check */ add_char ('<'); } else if (arg == END) { if (strcmp (command, "ubaraccent") == 0) /* underbar */ add_char ('_'); else if (strcmp (command, "udotaccent") == 0) /* underdot */ add_word ("-."); else if (strcmp (command, ",") == 0) /* cedilla */ add_word (","); } } /* Non-English letters/characters that don't insert themselves. */ void cm_special_char (arg) { if (arg == START) { if ((*command == 'L' || *command == 'l' || *command == 'O' || *command == 'o') && command[1] == 0) { /* Lslash lslash Oslash oslash */ add_char (*command); add_char ('/'); } else if (strcmp (command, "exclamdown") == 0) add_char ('!'); else if (strcmp (command, "pounds") == 0) add_char ('#'); else if (strcmp (command, "questiondown") == 0) add_char ('?'); else fprintf (stderr, _("How did @%s end up in cm_special_char?\n"), command); } } /* Dotless i or j. */ void cm_dotless (arg, start, end) int arg, start, end; { if (arg == END) { if (output_paragraph[start] != 'i' && output_paragraph[start] != 'j') /* This error message isn't perfect if the argument is multiple characters, but it doesn't seem worth getting right. */ line_error (_("%c%s expects `i' or `j' as argument, not `%c'"), COMMAND_PREFIX, command, output_paragraph[start]); else if (end - start != 1) line_error (_("%c%s expects a single character `i' or `j' as argument"), COMMAND_PREFIX, command); /* We've already inserted the `i' or `j', so nothing to do. */ } } void cm_today (arg) int arg; { static char *months [12] = { N_("January"), N_("February"), N_("March"), N_("April"), N_("May"), N_("June"), N_("July"), N_("August"), N_("September"), N_("October"), N_("November"), N_("December") }; if (arg == START) { time_t timer = time (0); struct tm *ts = localtime (&timer); add_word_args ("%d %s %d", ts->tm_mday, _(months[ts->tm_mon]), ts->tm_year + 1900); } } void cm_code (arg) int arg; { extern int printing_index; if (arg == START) { in_fixed_width_font++; if (!printing_index) add_char ('`'); } else { if (!printing_index) add_char ('\''); } } void cm_kbd (arg) int arg; { /* People use @kbd in an example to get the "user input" font. We don't want quotes in that case. */ if (!in_fixed_width_font) cm_code (arg); } void cm_key (arg) int arg; { add_char (arg == START ? '<' : '>'); } /* Convert the character at position into a true control character. */ void cm_ctrl (arg, start, end) int arg, start, end; { /* Should we allow multiple character arguments? I think yes. */ if (arg == END) { register int i, character; #if defined (NO_MULTIPLE_CTRL) if ((end - start) != 1) line_error (_("%c%s expects a single character as an argument"), COMMAND_PREFIX, command); else #endif for (i = start; i < end; i++) { character = output_paragraph[i]; if (isletter (character)) output_paragraph[i] = CTL (coerce_to_upper (character)); } } } /* Handle a command that switches to a non-fixed-width font. */ void not_fixed_width (arg) int arg; { if (arg == START) in_fixed_width_font = 0; } /* Small caps and @var in makeinfo just uppercase the text. */ void cm_var_sc (arg, start_pos, end_pos) int arg, start_pos, end_pos; { not_fixed_width (arg); if (arg == END) { while (start_pos < end_pos) { output_paragraph[start_pos] = coerce_to_upper (output_paragraph[start_pos]); start_pos++; } } } void cm_dfn (arg, position) int arg, position; { add_char ('"'); } void cm_emph (arg) int arg; { add_char ('*'); } void cm_strong (arg, position) int arg, position; { cm_emph (arg); } void cm_cite (arg, position) int arg, position; { if (arg == START) add_word ("`"); else add_word ("'"); } /* No highlighting, but argument switches fonts. */ void cm_not_fixed_width (arg, start, end) int arg, start, end; { not_fixed_width (arg); } /* Various commands are no-op's. */ void cm_no_op () { } /* No-op that eats its argument on same line. */ void cm_no_op_line_arg () { char *temp; get_rest_of_line (&temp); free (temp); } /* Prevent the argument from being split across two lines. */ void cm_w (arg, start, end) int arg, start, end; { if (arg == START) non_splitting_words++; else non_splitting_words--; } /* Explain that this command is obsolete, thus the user shouldn't do anything with it. */ void cm_obsolete (arg, start, end) int arg, start, end; { if (arg == START) warning (_("%c%s is obsolete"), COMMAND_PREFIX, command); } /* Insert the text following input_text_offset up to the end of the line in a new, separate paragraph. Directly underneath it, insert a line of WITH_CHAR, the same length of the inserted text. */ void insert_and_underscore (with_char) int with_char; { register int i, len; int old_no_indent, starting_pos, ending_pos; char *temp; close_paragraph (); filling_enabled = indented_fill = 0; old_no_indent = no_indent; no_indent = 1; #if defined (HAVE_MACROS) if (macro_expansion_output_stream && !executing_string) append_to_expansion_output (input_text_offset + 1); #endif /* HAVE_MACROS */ get_rest_of_line (&temp); starting_pos = output_position + output_paragraph_offset; #if defined (HAVE_MACROS) if (macro_expansion_output_stream && !executing_string) { char *temp1 = (char *) xmalloc (2 + strlen (temp)); sprintf (temp1, "%s\n", temp); remember_itext (input_text, input_text_offset); me_execute_string (temp1); free (temp1); } else #endif /* HAVE_MACROS */ execute_string ("%s\n", temp); ending_pos = output_position + output_paragraph_offset; free (temp); len = (ending_pos - starting_pos) - 1; for (i = 0; i < len; i++) add_char (with_char); insert ('\n'); close_paragraph (); filling_enabled = 1; no_indent = old_no_indent; } /* Here is a structure which associates sectioning commands with an integer, hopefully to reflect the `depth' of the current section. */ struct { char *name; int level; } section_alist[] = { { "unnumberedsubsubsec", 5 }, { "unnumberedsubsec", 4 }, { "unnumberedsec", 3 }, { "unnumbered", 2 }, { "appendixsubsubsec", 5 }, { "appendixsubsec", 4 }, { "appendixsec", 3 }, { "appendixsection", 3 }, { "appendix", 2 }, { "subsubsec", 5 }, { "subsubsection", 5 }, { "subsection", 4 }, { "section", 3 }, { "chapter", 2 }, { "top", 1 }, { (char *)NULL, 0 } }; /* Amount to offset the name of sectioning commands to levels by. */ int section_alist_offset = 0; /* Shift the meaning of @section to @chapter. */ void cm_raisesections () { discard_until ("\n"); section_alist_offset--; } /* Shift the meaning of @chapter to @section. */ void cm_lowersections () { discard_until ("\n"); section_alist_offset++; } /* Return an integer which identifies the type section present in TEXT. */ int what_section (text) char *text; { register int i, j; char *t; find_section_command: for (j = 0; text[j] && cr_or_whitespace (text[j]); j++); if (text[j] != COMMAND_PREFIX) return (-1); text = text + j + 1; /* We skip @c, @comment, and @?index commands. */ if ((strncmp (text, "comment", strlen ("comment")) == 0) || (text[0] == 'c' && cr_or_whitespace (text[1])) || (strcmp (text + 1, "index") == 0)) { while (*text++ != '\n'); goto find_section_command; } /* Handle italicized sectioning commands. */ if (*text == 'i') text++; for (j = 0; text[j] && !cr_or_whitespace (text[j]); j++); for (i = 0; (t = section_alist[i].name); i++) { if (j == strlen (t) && strncmp (t, text, j) == 0) { int return_val; return_val = (section_alist[i].level + section_alist_offset); if (return_val < 0) return_val = 0; else if (return_val > 5) return_val = 5; return (return_val); } } return (-1); } /* Set the level of @top to LEVEL. Return the old level of @top. */ int set_top_section_level (level) int level; { register int i, result = -1; for (i = 0; section_alist[i].name; i++) if (strcmp (section_alist[i].name, "top") == 0) { result = section_alist[i].level; section_alist[i].level = level; break; } return (result); } /* Treat this just like @unnumbered. The only difference is in node defaulting. */ void cm_top () { /* It is an error to have more than one @top. */ if (top_node_seen) { TAG_ENTRY *tag = tag_table; line_error (_("Node with %ctop as a section already exists"), COMMAND_PREFIX); while (tag != (TAG_ENTRY *)NULL) { if ((tag->flags & IS_TOP)) { int old_line_number = line_number; char *old_input_filename = input_filename; line_number = tag->line_no; input_filename = tag->filename; line_error (_("Here is the %ctop node"), COMMAND_PREFIX); input_filename = old_input_filename; line_number = old_line_number; return; } tag = tag->next_ent; } } else { top_node_seen = 1; /* It is an error to use @top before you have used @node. */ if (!tag_table) { char *top_name; get_rest_of_line (&top_name); free (top_name); line_error (_("%ctop used before %cnode, defaulting to %s"), COMMAND_PREFIX, COMMAND_PREFIX, top_name); execute_string ("@node Top, , (dir), (dir)\n@top %s\n", top_name); return; } cm_unnumbered (); /* The most recently defined node is the top node. */ tag_table->flags |= IS_TOP; /* Now set the logical hierarchical level of the Top node. */ { int orig_offset = input_text_offset; input_text_offset = search_forward (node_search_string, orig_offset); if (input_text_offset > 0) { int this_section; /* We have encountered a non-top node, so mark that one exists. */ non_top_node_seen = 1; /* Move to the end of this line, and find out what the sectioning command is here. */ while (input_text[input_text_offset] != '\n') input_text_offset++; if (input_text_offset < size_of_input_text) input_text_offset++; this_section = what_section (input_text + input_text_offset); /* If we found a sectioning command, then give the top section a level of this section - 1. */ if (this_section != -1) set_top_section_level (this_section - 1); } input_text_offset = orig_offset; } } } /* Organized by level commands. That is, "*" == chapter, "=" == section. */ char *scoring_characters = "*=-."; void sectioning_underscore (command) char *command; { char character; char *temp; int level; temp = (char *)xmalloc (2 + strlen (command)); temp[0] = COMMAND_PREFIX; strcpy (&temp[1], command); level = what_section (temp); free (temp); level -= 2; if (level < 0) level = 0; character = scoring_characters[level]; insert_and_underscore (character); } /* The command still works, but prints a warning message in addition. */ void cm_ideprecated (arg, start, end) int arg, start, end; { warning (_("%c%s is obsolete; use %c%s instead"), COMMAND_PREFIX, command, COMMAND_PREFIX, command + 1); sectioning_underscore (command + 1); } /* The remainder of the text on this line is a chapter heading. */ void cm_chapter () { sectioning_underscore ("chapter"); } /* The remainder of the text on this line is a section heading. */ void cm_section () { sectioning_underscore ("section"); } /* The remainder of the text on this line is a subsection heading. */ void cm_subsection () { sectioning_underscore ("subsection"); } /* The remainder of the text on this line is a subsubsection heading. */ void cm_subsubsection () { sectioning_underscore ("subsubsection"); } /* The remainder of the text on this line is an unnumbered heading. */ void cm_unnumbered () { cm_chapter (); } /* The remainder of the text on this line is an unnumbered section heading. */ void cm_unnumberedsec () { cm_section (); } /* The remainder of the text on this line is an unnumbered subsection heading. */ void cm_unnumberedsubsec () { cm_subsection (); } /* The remainder of the text on this line is an unnumbered subsubsection heading. */ void cm_unnumberedsubsubsec () { cm_subsubsection (); } /* The remainder of the text on this line is an appendix heading. */ void cm_appendix () { cm_chapter (); } /* The remainder of the text on this line is an appendix section heading. */ void cm_appendixsec () { cm_section (); } /* The remainder of the text on this line is an appendix subsection heading. */ void cm_appendixsubsec () { cm_subsection (); } /* The remainder of the text on this line is an appendix subsubsection heading. */ void cm_appendixsubsubsec () { cm_subsubsection (); } /* Compatibility functions substitute for chapter, section, etc. */ void cm_majorheading () { cm_chapheading (); } void cm_chapheading () { cm_chapter (); } void cm_heading () { cm_section (); } void cm_subheading () { cm_subsection (); } void cm_subsubheading () { cm_subsubsection (); } /* **************************************************************** */ /* */ /* Adding nodes, and making tags */ /* */ /* **************************************************************** */ /* Start a new tag table. */ void init_tag_table () { while (tag_table != (TAG_ENTRY *) NULL) { TAG_ENTRY *temp = tag_table; free (temp->node); free (temp->prev); free (temp->next); free (temp->up); tag_table = tag_table->next_ent; free (temp); } } void write_tag_table () { write_tag_table_internal (0); /* Not indirect. */ } void write_tag_table_indirect () { write_tag_table_internal (1); } /* Write out the contents of the existing tag table. INDIRECT_P says how to format the output. */ void write_tag_table_internal (indirect_p) int indirect_p; { TAG_ENTRY *node = tag_table; int old_indent = no_indent; no_indent = 1; filling_enabled = 0; must_start_paragraph = 0; close_paragraph (); if (!indirect_p) { no_indent = 1; insert ('\n'); } add_word_args ("\037\nTag Table:\n%s", indirect_p ? "(Indirect)\n" : ""); while (node != (TAG_ENTRY *) NULL) { execute_string ("Node: %s", node->node); add_word_args ("\177%d\n", node->position); node = node->next_ent; } add_word ("\037\nEnd Tag Table\n"); flush_output (); no_indent = old_indent; } char * get_node_token (expand) int expand; { char *string; get_until_in_line (expand, ",", &string); if (curchar () == ',') input_text_offset++; canon_white (string); /* Force all versions of "top" to be "Top". */ normalize_node_name (string); return (string); } /* Convert "top" and friends into "Top". */ void normalize_node_name (string) char *string; { if (strcasecmp (string, "Top") == 0) strcpy (string, "Top"); } /* Look up NAME in the tag table, and return the associated tag_entry. If the node is not in the table return NULL. */ TAG_ENTRY * find_node (name) char *name; { TAG_ENTRY *tag = tag_table; while (tag != (TAG_ENTRY *) NULL) { if (strcmp (tag->node, name) == 0) return (tag); tag = tag->next_ent; } return ((TAG_ENTRY *) NULL); } /* Remember NODE and associates. */ void remember_node (node, prev, next, up, position, line_no, no_warn) char *node, *prev, *next, *up; int position, line_no, no_warn; { /* Check for existence of this tag already. */ if (validating) { register TAG_ENTRY *tag = find_node (node); if (tag) { line_error ( _("Node `%s' multiply defined (line %d is first definition at)"), node, tag->line_no); return; } } /* First, make this the current node. */ current_node = node; /* Now add it to the list. */ { TAG_ENTRY *new = (TAG_ENTRY *) xmalloc (sizeof (TAG_ENTRY)); new->node = node; new->prev = prev; new->next = next; new->up = up; new->position = position; new->line_no = line_no; new->filename = node_filename; new->touched = 0; /* not yet referenced. */ new->flags = 0; if (no_warn) new->flags |= NO_WARN; new->next_ent = tag_table; tag_table = new; } } /* The order is: nodename, nextnode, prevnode, upnode. If all of the NEXT, PREV, and UP fields are empty, they are defaulted. You must follow a node command which has those fields defaulted with a sectioning command (e.g. @chapter) giving the "level" of that node. It is an error not to do so. The defaults come from the menu in this node's parent. */ void cm_node () { char *node, *prev, *next, *up; int new_node_pos, defaulting, this_section, no_warn = 0; extern int already_outputting_pending_notes; if (strcmp (command, "nwnode") == 0) no_warn = 1; /* Get rid of unmatched brace arguments from previous commands. */ discard_braces (); /* There also might be insertions left lying around that haven't been ended yet. Do that also. */ discard_insertions (1); if (!already_outputting_pending_notes) { close_paragraph (); output_pending_notes (); free_pending_notes (); } filling_enabled = indented_fill = 0; new_node_pos = output_position; current_footnote_number = 1; #if defined (HAVE_MACROS) if (macro_expansion_output_stream && !executing_string) append_to_expansion_output (input_text_offset + 1); #endif /* HAVE_MACROS */ node = get_node_token (1); next = get_node_token (0); prev = get_node_token (0); up = get_node_token (0); if (verbose_mode) printf (_("Formatting node %s...\n"), node); #if defined (HAVE_MACROS) if (macro_expansion_output_stream && !executing_string) remember_itext (input_text, input_text_offset); #endif /* HAVE_MACROS */ no_indent = 1; if (!no_headers) { add_word_args ("\037\nFile: %s, Node: ", pretty_output_filename); #if defined (HAVE_MACROS) if (macro_expansion_output_stream && !executing_string) me_execute_string (node); else #endif /* HAVE_MACROS */ execute_string ("%s", node); filling_enabled = indented_fill = 0; } /* Check for defaulting of this node's next, prev, and up fields. */ defaulting = (*next == 0 && *prev == 0 && *up == 0); this_section = what_section (input_text + input_text_offset); /* If we are defaulting, then look at the immediately following sectioning command (error if none) to determine the node's level. Find the node that contains the menu mentioning this node that is one level up (error if not found). That node is the "Up" of this node. Default the "Next" and "Prev" from the menu. */ if (defaulting) { NODE_REF *last_ref = (NODE_REF *)NULL; NODE_REF *ref = node_references; if ((this_section < 0) && (strcmp (node, "Top") != 0)) { char *polite_section_name = "top"; int i; for (i = 0; section_alist[i].name; i++) if (section_alist[i].level == current_section + 1) { polite_section_name = section_alist[i].name; break; } line_error (_("Node `%s' requires a sectioning command (e.g. %c%s)"), node, COMMAND_PREFIX, polite_section_name); } else { if (strcmp (node, "Top") == 0) { /* Default the NEXT pointer to be the first menu item in this node, if there is a menu in this node. We have to try very hard to find the menu, as it may be obscured by execution_strings which are on the filestack. For every member of the filestack which has a FILENAME member which is identical to the current INPUT_FILENAME, search forward from that offset. */ int saved_input_text_offset = input_text_offset; int saved_size_of_input_text = size_of_input_text; char *saved_input_text = input_text; FSTACK *next_file = filestack; int orig_offset, orig_size; char *glean_node_from_menu (); /* No matter what, make this file point back at `(dir)'. */ free (up); up = xstrdup ("(dir)"); while (1) { orig_offset = input_text_offset; orig_size = search_forward (node_search_string, orig_offset); if (orig_size < 0) orig_size = size_of_input_text; input_text_offset = search_forward (menu_search_string, orig_offset); if (input_text_offset > -1) { char *nodename_from_menu = (char *)NULL; input_text_offset = search_forward ("\n* ", input_text_offset); if (input_text_offset != -1) nodename_from_menu = glean_node_from_menu (0); if (nodename_from_menu) { free (next); next = nodename_from_menu; break; } } /* We got here, so it hasn't been found yet. Try the next file on the filestack if there is one. */ if (next_file && (strcmp (next_file->filename, input_filename) == 0)) { input_text = next_file->text; input_text_offset = next_file->offset; size_of_input_text = next_file->size; next_file = next_file->next; } else { /* No more input files to check. */ break; } } input_text = saved_input_text; input_text_offset = saved_input_text_offset; size_of_input_text = saved_size_of_input_text; } } /* Fix the level of the menu references in the Top node, iff it was declared with @top, and no subsequent reference was found. */ if (top_node_seen && !non_top_node_seen) { /* Then this is the first non-@top node seen. */ int level; level = set_top_section_level (this_section - 1); non_top_node_seen = 1; while (ref) { if (ref->section == level) ref->section = this_section - 1; ref = ref->next; } ref = node_references; } while (ref) { if (ref->section == (this_section - 1) && ref->type == menu_reference && strcmp (ref->node, node) == 0) { char *containing_node = ref->containing_node; free (up); up = xstrdup (containing_node); if (last_ref && last_ref->type == menu_reference && (strcmp (last_ref->containing_node, containing_node) == 0)) { free (next); next = xstrdup (last_ref->node); } while ((ref->section == this_section - 1) && (ref->next) && (ref->next->type != menu_reference)) ref = ref->next; if (ref->next && ref->type == menu_reference && (strcmp (ref->next->containing_node, containing_node) == 0)) { free (prev); prev = xstrdup (ref->next->node); } else if (!ref->next && strcasecmp (ref->containing_node, "Top") == 0) { free (prev); prev = xstrdup (ref->containing_node); } break; } last_ref = ref; ref = ref->next; } } #if defined (HAVE_MACROS) /* Insert the correct args if we are expanding macros, and the node's pointers weren't defaulted. */ if (macro_expansion_output_stream && !executing_string && !defaulting) { char *temp; int op_orig = output_paragraph_offset; temp = (char *)xmalloc (3 + strlen (next)); sprintf (temp, ", %s", next); me_execute_string (temp); free (temp); temp = (char *)xmalloc (3 + strlen (prev)); sprintf (temp, ", %s", prev); me_execute_string (temp); free (temp); temp = (char *)xmalloc (4 + strlen (up)); sprintf (temp, ", %s", up); me_execute_string (temp); free (temp); output_paragraph_offset = op_orig; } #endif /* HAVE_MACROS */ if (!no_headers) { #if defined (HAVE_MACROS) if (macro_expansion_output_stream) me_inhibit_expansion++; #endif /* HAVE_MACROS */ if (*next) { execute_string (", Next: %s", next); filling_enabled = indented_fill = 0; } if (*prev) { execute_string (", Prev: %s", prev); filling_enabled = indented_fill = 0; } if (*up) { execute_string (", Up: %s", up); filling_enabled = indented_fill = 0; } #if defined (HAVE_MACROS) if (macro_expansion_output_stream) me_inhibit_expansion--; #endif /* HAVE_MACROS */ } close_paragraph (); no_indent = 0; if (!*node) { line_error ("No node name specified for `%c%s' command", COMMAND_PREFIX, command); free (node); free (next); free (prev); free (up); } else { if (!*next) { free (next); next = (char *)NULL; } if (!*prev) { free (prev); prev = (char *)NULL; } if (!*up) { free (up); up = (char *)NULL; } remember_node (node, prev, next, up, new_node_pos, line_number, no_warn); } /* Change the section only if there was a sectioning command. */ if (this_section >= 0) current_section = this_section; filling_enabled = 1; } /* Validation of an info file. Scan through the list of tag entries touching the Prev, Next, and Up elements of each. It is an error not to be able to touch one of them, except in the case of external node references, such as "(DIR)". If the Prev is different from the Up, then the Prev node must have a Next pointing at this node. Every node except Top must have an Up. The Up node must contain some sort of reference, other than a Next, to this node. If the Next is different from the Next of the Up, then the Next node must have a Prev pointing at this node. */ void validate_file (tag_table) TAG_ENTRY *tag_table; { char *old_input_filename = input_filename; TAG_ENTRY *tags = tag_table; while (tags != (TAG_ENTRY *) NULL) { register TAG_ENTRY *temp_tag; input_filename = tags->filename; line_number = tags->line_no; /* If this is a "no warn" node, don't validate it in any way. */ if (tags->flags & NO_WARN) { tags = tags->next_ent; continue; } /* If this node has a Next, then make sure that the Next exists. */ if (tags->next) { validate (tags->next, tags->line_no, "Next"); /* If the Next node exists, and there is no Up, then make sure that the Prev of the Next points back. */ temp_tag = find_node (tags->next); if (temp_tag) { char *prev; if (temp_tag->flags & NO_WARN) { /* Do nothing if we aren't supposed to issue warnings about this node. */ } else { prev = temp_tag->prev; if (!prev || (strcmp (prev, tags->node) != 0)) { line_error (_("Node `%s''s Next field not pointed back to"), tags->node); line_number = temp_tag->line_no; input_filename = temp_tag->filename; line_error (_("This node (`%s') is the one with the bad `Prev'"), temp_tag->node); input_filename = tags->filename; line_number = tags->line_no; temp_tag->flags |= PREV_ERROR; } } } } /* Validate the Prev field if there is one, and we haven't already complained about it in some way. You don't have to have a Prev field at this stage. */ if (!(tags->flags & PREV_ERROR) && tags->prev) { int valid_p = validate (tags->prev, tags->line_no, "Prev"); if (!valid_p) tags->flags |= PREV_ERROR; else { /* If the Prev field is not the same as the Up field, then the node pointed to by the Prev field must have a Next field which points to this node. */ if (tags->up && (strcmp (tags->prev, tags->up) != 0)) { temp_tag = find_node (tags->prev); /* If we aren't supposed to issue warnings about the target node, do nothing. */ if (!temp_tag || (temp_tag->flags & NO_WARN)) { /* Do nothing. */ } else { if (!temp_tag->next || (strcmp (temp_tag->next, tags->node) != 0)) { line_error (_("Node `%s's Prev field not pointed back to"), tags->node); line_number = temp_tag->line_no; input_filename = temp_tag->filename; line_error (_("This node (`%s') has the bad Next"), temp_tag->node); input_filename = tags->filename; line_number = tags->line_no; temp_tag->flags |= NEXT_ERROR; } } } } } if (!tags->up && (strcasecmp (tags->node, _("Top")) != 0)) line_error (_("Node `%s' missing Up field"), tags->node); else if (tags->up) { int valid_p = validate (tags->up, tags->line_no, "Up"); /* If node X has Up: Y, then warn if Y fails to have a menu item or note pointing at X, if Y isn't of the form "(Y)". */ if (valid_p && *tags->up != '(') { NODE_REF *nref, *tref, *list; NODE_REF *find_node_reference (); tref = (NODE_REF *) NULL; list = node_references; for (;;) { if (!(nref = find_node_reference (tags->node, list))) break; if (strcmp (nref->containing_node, tags->up) == 0) { if (nref->type != menu_reference) { tref = nref; list = nref->next; } else break; } list = nref->next; } if (!nref) { temp_tag = find_node (tags->up); line_number = temp_tag->line_no; input_filename = temp_tag->filename; if (!tref) line_error ( _("`%s' has an Up field of `%s', but `%s' has no menu item for `%s'"), tags->node, tags->up, tags->up, tags->node); line_number = tags->line_no; input_filename = tags->filename; } } } tags = tags->next_ent; } validate_other_references (node_references); /* We have told the user about the references which didn't exist. Now tell him about the nodes which aren't referenced. */ tags = tag_table; while (tags != (TAG_ENTRY *) NULL) { /* If this node is a "no warn" node, do nothing. */ if (tags->flags & NO_WARN) { tags = tags->next_ent; continue; } /* Special hack. If the node in question appears to have been referenced more than REFERENCE_WARNING_LIMIT times, give a warning. */ if (tags->touched > reference_warning_limit) { input_filename = tags->filename; line_number = tags->line_no; warning (_("node `%s' has been referenced %d times"), tags->node, tags->touched); } if (tags->touched == 0) { input_filename = tags->filename; line_number = tags->line_no; /* Notice that the node "Top" is special, and doesn't have to be referenced. */ if (strcasecmp (tags->node, _("Top")) != 0) warning (_("unreferenced node `%s'"), tags->node); } tags = tags->next_ent; } input_filename = old_input_filename; } /* Return 1 if tag correctly validated, or 0 if not. */ int validate (tag, line, label) char *tag; int line; char *label; { TAG_ENTRY *result; /* If there isn't a tag to verify, or if the tag is in another file, then it must be okay. */ if (!tag || !*tag || *tag == '(') return (1); /* Otherwise, the tag must exist. */ result = find_node (tag); if (!result) { line_number = line; line_error (_("%s reference to nonexistent node `%s'"), label, tag); return (0); } result->touched++; return (1); } /* Split large output files into a series of smaller files. Each file is pointed to in the tag table, which then gets written out as the original file. The new files have the same name as the original file with a "-num" attached. SIZE is the largest number of bytes to allow in any single split file. */ void split_file (filename, size) char *filename; int size; { char *root_filename, *root_pathname; char *the_file, *filename_part (); struct stat fileinfo; long file_size; char *the_header; int header_size; /* Can only do this to files with tag tables. */ if (!tag_table) return; if (size == 0) size = DEFAULT_SPLIT_SIZE; if ((stat (filename, &fileinfo) != 0) || (((long) fileinfo.st_size) < SPLIT_SIZE_THRESHOLD)) return; file_size = (long) fileinfo.st_size; the_file = find_and_load (filename); if (!the_file) return; root_filename = filename_part (filename); root_pathname = pathname_part (filename); if (!root_pathname) root_pathname = xstrdup (""); /* Start splitting the file. Walk along the tag table outputting sections of the file. When we have written all of the nodes in the tag table, make the top-level pointer file, which contains indirect pointers and tags for the nodes. */ { int which_file = 1; TAG_ENTRY *tags = tag_table; char *indirect_info = (char *)NULL; /* Remember the `header' of this file. The first tag in the file is the bottom of the header; the top of the file is the start. */ the_header = (char *)xmalloc (1 + (header_size = tags->position)); memcpy (the_header, the_file, header_size); while (tags) { int file_top, file_bot, limit; /* Have to include the Control-_. */ file_top = file_bot = tags->position; limit = file_top + size; /* If the rest of this file is only one node, then that is the entire subfile. */ if (!tags->next_ent) { int i = tags->position + 1; char last_char = the_file[i]; while (i < file_size) { if ((the_file[i] == '\037') && ((last_char == '\n') || (last_char == '\014'))) break; else last_char = the_file[i]; i++; } file_bot = i; tags = tags->next_ent; goto write_region; } /* Otherwise, find the largest number of nodes that can fit in this subfile. */ for (; tags; tags = tags->next_ent) { if (!tags->next_ent) { /* This entry is the last node. Search forward for the end of this node, and that is the end of this file. */ int i = tags->position + 1; char last_char = the_file[i]; while (i < file_size) { if ((the_file[i] == '\037') && ((last_char == '\n') || (last_char == '\014'))) break; else last_char = the_file[i]; i++; } file_bot = i; if (file_bot < limit) { tags = tags->next_ent; goto write_region; } else { /* Here we want to write out everything before the last node, and then write the last node out in a file by itself. */ file_bot = tags->position; goto write_region; } } if (tags->next_ent->position > limit) { if (tags->position == file_top) tags = tags->next_ent; file_bot = tags->position; write_region: { int fd; char *split_filename; split_filename = (char *) xmalloc (10 + strlen (root_pathname) + strlen (root_filename)); sprintf (split_filename, "%s%s-%d", root_pathname, root_filename, which_file); fd = open (split_filename, O_WRONLY | O_TRUNC | O_CREAT, 0666); if ((fd < 0) || (write (fd, the_header, header_size) != header_size) || (write (fd, the_file + file_top, file_bot - file_top) != (file_bot - file_top)) || ((close (fd)) < 0)) { perror (split_filename); if (fd != -1) close (fd); exit (FATAL); } if (!indirect_info) { indirect_info = the_file + file_top; sprintf (indirect_info, "\037\nIndirect:\n"); indirect_info += strlen (indirect_info); } sprintf (indirect_info, "%s-%d: %d\n", root_filename, which_file, file_top); free (split_filename); indirect_info += strlen (indirect_info); which_file++; break; } } } } /* We have sucessfully created the subfiles. Now write out the original again. We must use `output_stream', or write_tag_table_indirect () won't know where to place the output. */ output_stream = fopen (filename, "w"); if (!output_stream) { perror (filename); exit (FATAL); } { int distance = indirect_info - the_file; fwrite (the_file, 1, distance, output_stream); /* Inhibit newlines. */ paragraph_is_open = 0; write_tag_table_indirect (); fclose (output_stream); free (the_header); free (the_file); return; } } } /* The strings here are followed in the message by `reference to...' in the `validate' routine. */ char * reftype_type_string (type) enum reftype type; { switch (type) { case menu_reference: return ("Menu"); case followed_reference: return ("Cross"); default: return ("Internal-bad-reference-type"); } } /* Remember this node name for later validation use. This is used to remember menu references while reading the input file. After the output file has been written, if validation is on, then we use the contents of `node_references' as a list of nodes to validate. */ void remember_node_reference (node, line, type) char *node; int line; enum reftype type; { NODE_REF *temp = (NODE_REF *) xmalloc (sizeof (NODE_REF)); temp->next = node_references; temp->node = xstrdup (node); temp->line_no = line; temp->section = current_section; temp->type = type; temp->containing_node = xstrdup (current_node ? current_node : ""); temp->filename = node_filename; node_references = temp; } void validate_other_references (ref_list) register NODE_REF *ref_list; { char *old_input_filename = input_filename; while (ref_list != (NODE_REF *) NULL) { input_filename = ref_list->filename; validate (ref_list->node, ref_list->line_no, reftype_type_string (ref_list->type)); ref_list = ref_list->next; } input_filename = old_input_filename; } /* Find NODE in REF_LIST. */ NODE_REF * find_node_reference (node, ref_list) char *node; register NODE_REF *ref_list; { while (ref_list) { if (strcmp (node, ref_list->node) == 0) break; ref_list = ref_list->next; } return (ref_list); } void free_node_references () { register NODE_REF *list, *temp; list = node_references; while (list) { temp = list; free (list->node); free (list->containing_node); list = list->next; free (temp); } node_references = (NODE_REF *) NULL; } /* This function gets called at the start of every line while inside of a menu. It checks to see if the line starts with "* ", and if so, remembers the node reference that this menu refers to. input_text_offset is at the \n just before the line start. */ #define menu_starter "* " char * glean_node_from_menu (remember_reference) int remember_reference; { int i, orig_offset = input_text_offset; char *nodename; if (strncmp (&input_text[input_text_offset + 1], menu_starter, strlen (menu_starter)) != 0) return ((char *)NULL); else input_text_offset += strlen (menu_starter) + 1; get_until_in_line (0, ":", &nodename); if (curchar () == ':') input_text_offset++; canon_white (nodename); if (curchar () == ':') goto save_node; free (nodename); get_rest_of_line (&nodename); /* Special hack: If the nodename follows the menu item name, then we have to read the rest of the line in order to find out what the nodename is. But we still have to read the line later, in order to process any formatting commands that might be present. So un-count the carriage return that has just been counted. */ line_number--; isolate_nodename (nodename); save_node: input_text_offset = orig_offset; normalize_node_name (nodename); i = strlen (nodename); if (i && nodename[i - 1] == ':') nodename[i - 1] = 0; if (remember_reference) { remember_node_reference (nodename, line_number, menu_reference); free (nodename); return ((char *)NULL); } else return (nodename); } static void isolate_nodename (nodename) char *nodename; { register int i, c; int paren_seen, paren; if (!nodename) return; canon_white (nodename); paren_seen = paren = i = 0; if (*nodename == '.' || !*nodename) { *nodename = 0; return; } if (*nodename == '(') { paren++; paren_seen++; i++; } for (; (c = nodename[i]); i++) { if (paren) { if (c == '(') paren++; else if (c == ')') paren--; continue; } /* If the character following the close paren is a space, then this node has no more characters associated with it. */ if (c == '\t' || c == '\n' || c == ',' || ((paren_seen && nodename[i - 1] == ')') && (c == ' ' || c == '.')) || (c == '.' && ((!nodename[i + 1] || (cr_or_whitespace (nodename[i + 1])) || (nodename[i + 1] == ')'))))) break; } nodename[i] = 0; } void cm_menu () { if (current_node == (char *)NULL) { warning (_("%cmenu seen before first node"), COMMAND_PREFIX); warning (_("creating `Top' node")); execute_string ("@node Top"); } begin_insertion (menu); } void cm_detailmenu () { if (current_node == (char *)NULL) { warning (_("%cmenu seen before first node"), COMMAND_PREFIX); warning (_("creating `Top' node")); execute_string ("@node Top"); } begin_insertion (detailmenu); } /* **************************************************************** */ /* */ /* Cross Reference Hacking */ /* */ /* **************************************************************** */ /* Return next comma-delimited argument, but do not cross a close-brace boundary. Clean up whitespace, too. */ char * get_xref_token () { char *string; get_until_in_braces (",", &string); if (curchar () == ',') input_text_offset++; fix_whitespace (string); return (string); } int px_ref_flag = 0; /* Controls initial output string. */ /* Make a cross reference. */ void cm_xref (arg) { if (arg == START) { char *arg1, *arg2, *arg3, *arg4, *arg5; arg1 = get_xref_token (); arg2 = get_xref_token (); arg3 = get_xref_token (); arg4 = get_xref_token (); arg5 = get_xref_token (); add_word_args ("%s", px_ref_flag ? "*note " : "*Note "); if (*arg5 || *arg4) { char *node_name; if (!*arg2) { if (*arg3) node_name = arg3; else node_name = arg1; } else node_name = arg2; execute_string ("%s: (%s)%s", node_name, arg4, arg1); /* Free all of the arguments found. */ if (arg1) free (arg1); if (arg2) free (arg2); if (arg3) free (arg3); if (arg4) free (arg4); if (arg5) free (arg5); return; } else remember_node_reference (arg1, line_number, followed_reference); if (*arg3) { if (!*arg2) execute_string ("%s: %s", arg3, arg1); else execute_string ("%s: %s", arg2, arg1); } else { if (*arg2) execute_string ("%s: %s", arg2, arg1); else execute_string ("%s::", arg1); } /* Free all of the arguments found. */ if (arg1) free (arg1); if (arg2) free (arg2); if (arg3) free (arg3); if (arg4) free (arg4); if (arg5) free (arg5); } else { /* Check to make sure that the next non-whitespace character is either a period or a comma. input_text_offset is pointing at the "}" which ended the xref or pxref command. */ int temp = input_text_offset + 1; if (output_paragraph[output_paragraph_offset - 2] == ':' && output_paragraph[output_paragraph_offset - 1] == ':') return; while (temp < size_of_input_text) { if (cr_or_whitespace (input_text[temp])) temp++; else { if (input_text[temp] != '.' && input_text[temp] != ',' && input_text[temp] != '\t') { line_error ( _("`.' or `,' must follow cross reference, not %c"), input_text[temp]); } break; } } } } void cm_pxref (arg) int arg; { if (arg == START) { px_ref_flag++; cm_xref (arg); px_ref_flag--; } else add_char ('.'); } void cm_inforef (arg) int arg; { if (arg == START) { char *node = get_xref_token (); char *pname = get_xref_token (); char *file = get_xref_token (); if (*pname) execute_string ("*note %s: (%s)%s", pname, file, node); else execute_string ("*note (%s)%s::", file, node); free (node); free (pname); free (file); } } /* A URL reference. */ void cm_uref (arg, start_pos, end_pos) int arg, start_pos, end_pos; { if (arg == END) { char *comma; char *arg = (char *) &output_paragraph[start_pos]; output_paragraph[end_pos] = 0; output_column -= end_pos - start_pos; output_paragraph_offset = start_pos; arg = xstrdup (arg); comma = strchr (arg, ','); /* let's hope for no commas in the url */ if (comma) { *comma = 0; /* Ignore spaces at beginning of second arg. */ for (comma++; isspace (*comma); comma++) ; add_word (comma); add_char (' '); add_char ('('); add_word (arg); add_char (')'); } else { extern int printing_index; if (!printing_index) add_char ('`'); add_word (arg); if (!printing_index) add_char ('\''); } free (arg); } } /* An email reference. */ void cm_email (arg, start_pos, end_pos) int arg, start_pos, end_pos; { if (arg == END) { char *comma; char *arg = (char *) &output_paragraph[start_pos]; output_paragraph[end_pos] = 0; output_column -= end_pos - start_pos; output_paragraph_offset = start_pos; arg = xstrdup (arg); comma = strchr (arg, ','); if (comma) { *comma = 0; for (comma++; isspace (*comma); comma++) ; add_word (comma); add_char (' '); } add_char ('<'); add_word (arg); add_char ('>'); free (arg); } } /* An external image is a reference, kind of. The parsing is (not coincidentally) similar, anyway. */ void cm_image (arg) int arg; { if (arg == START) { char *name_arg = get_xref_token (); /* We don't yet care about any other args, but read them so they don't end up in the text. */ char *arg = get_xref_token (); if (arg) free (arg); arg = get_xref_token (); if (arg) free (arg); if (*name_arg) { /* Try to open foo.txt. */ FILE *image_file; char *name = xmalloc (strlen (name_arg) + 4); strcpy (name, name_arg); strcat (name, ".txt"); image_file = fopen (name, "r"); if (image_file) { int ch; int save_inhibit_indentation = inhibit_paragraph_indentation; int save_filling_enabled = filling_enabled; inhibit_paragraph_indentation = 1; filling_enabled = 0; last_char_was_newline = 0; /* Maybe we need to remove the final newline if the image file is only one line to allow in-line images. On the other hand, they could just make the file without a final newline. */ while ((ch = getc (image_file)) != EOF) add_char (ch); inhibit_paragraph_indentation = save_inhibit_indentation; filling_enabled = save_filling_enabled; if (fclose (image_file) != 0) { perror (name); } } else warning (_("@image file `%s' unreadable: %s"), name, strerror (errno)); } else line_error (_("@image missing filename argument")); if (name_arg) free (name_arg); } } /* **************************************************************** */ /* */ /* Insertion Command Stubs */ /* */ /* **************************************************************** */ void cm_quotation () { begin_insertion (quotation); } void cm_example () { begin_insertion (example); } void cm_smallexample () { begin_insertion (smallexample); } void cm_lisp () { begin_insertion (lisp); } void cm_smalllisp () { begin_insertion (smalllisp); } /* @cartouche/@end cartouche draws box with rounded corners in TeX output. Right now, just a no-op insertion. */ void cm_cartouche () { begin_insertion (cartouche); } void cm_format () { begin_insertion (format); } void cm_display () { begin_insertion (display); } void cm_direntry () { if (no_headers) command_name_condition (); else begin_insertion (direntry); } void cm_itemize () { begin_insertion (itemize); } void cm_enumerate () { do_enumeration (enumerate, "1"); } /* Start an enumeration insertion of type TYPE. If the user supplied no argument on the line, then use DEFAULT_STRING as the initial string. */ void do_enumeration (type, default_string) int type; char *default_string; { get_until_in_line (0, ".", &enumeration_arg); canon_white (enumeration_arg); if (!*enumeration_arg) { free (enumeration_arg); enumeration_arg = xstrdup (default_string); } if (!isdigit (*enumeration_arg) && !isletter (*enumeration_arg)) { warning (_("%s requires letter or digit"), insertion_type_pname (type)); switch (type) { case enumerate: default_string = "1"; break; } enumeration_arg = xstrdup (default_string); } begin_insertion (type); } void cm_table () { begin_insertion (table); } void cm_multitable () { begin_insertion (multitable); /* @@ */ } void cm_ftable () { begin_insertion (ftable); } void cm_vtable () { begin_insertion (vtable); } void cm_group () { begin_insertion (group); } void cm_ifinfo () { begin_insertion (ifinfo); } void cm_ifnothtml () { begin_insertion (ifnothtml); } void cm_ifnottex () { begin_insertion (ifnottex); } /* Begin an insertion where the lines are not filled or indented. */ void cm_flushleft () { begin_insertion (flushleft); } /* Begin an insertion where the lines are not filled, and each line is forced to the right-hand side of the page. */ void cm_flushright () { begin_insertion (flushright); } /* End existing insertion block. */ void cm_end () { char *temp; enum insertion_type type; if (!insertion_level) { line_error (_("Unmatched `%c%s'"), COMMAND_PREFIX, command); return; } get_rest_of_line (&temp); if (temp[0] == 0) line_error (_("`%c%s' needs something after it"), COMMAND_PREFIX, command); type = find_type_from_name (temp); if (type == bad_type) { line_error (_("Bad argument to `%s', `%s', using `%s'"), command, temp, insertion_type_pname (current_insertion_type ())); } end_insertion (type); free (temp); } /* **************************************************************** */ /* */ /* Conditional Handling */ /* */ /* **************************************************************** */ /* A structure which contains `defined' variables. */ typedef struct defines { struct defines *next; char *name; char *value; } DEFINE; /* The linked list of `set' defines. */ DEFINE *defines = (DEFINE *)NULL; /* Add NAME to the list of `set' defines. */ void set (name, value) char *name; char *value; { DEFINE *temp; for (temp = defines; temp; temp = temp->next) if (strcmp (name, temp->name) == 0) { free (temp->value); temp->value = xstrdup (value); return; } temp = (DEFINE *)xmalloc (sizeof (DEFINE)); temp->next = defines; temp->name = xstrdup (name); temp->value = xstrdup (value); defines = temp; } /* Remove NAME from the list of `set' defines. */ void clear (name) char *name; { register DEFINE *temp, *last; last = (DEFINE *)NULL; temp = defines; while (temp) { if (strcmp (temp->name, name) == 0) { if (last) last->next = temp->next; else defines = temp->next; free (temp->name); free (temp->value); free (temp); break; } last = temp; temp = temp->next; } } /* Return the value of NAME. The return value is NULL if NAME is unset. */ char * set_p (name) char *name; { register DEFINE *temp; for (temp = defines; temp; temp = temp->next) if (strcmp (temp->name, name) == 0) return (temp->value); return ((char *)NULL); } /* Conditionally parse based on the current command name. */ void command_name_condition () { char *discarder; discarder = (char *)xmalloc (8 + strlen (command)); sprintf (discarder, "\n%cend %s", COMMAND_PREFIX, command); discard_until (discarder); discard_until ("\n"); free (discarder); } /* Create a variable whose name appears as the first word on this line. */ void cm_set () { handle_variable (SET); } /* Remove a variable whose name appears as the first word on this line. */ void cm_clear () { handle_variable (CLEAR); } void cm_ifset () { handle_variable (IFSET); } void cm_ifclear () { handle_variable (IFCLEAR); } /* This command takes braces, but we parse the contents specially, so we don't use the standard brace popping code. The syntax @ifeq{arg1, arg2, texinfo-commands} performs texinfo-commands if ARG1 and ARG2 caselessly string compare to the same string, otherwise, it produces no output. */ void cm_ifeq () { char **arglist; arglist = get_brace_args (0); if (arglist) { if (array_len (arglist) > 1) { if ((strcasecmp (arglist[0], arglist[1]) == 0) && (arglist[2] != (char *)NULL)) execute_string ("%s\n", arglist[2]); } free_array (arglist); } } void cm_value (arg, start_pos, end_pos) int arg, start_pos, end_pos; { if (arg == END) { char *name = (char *) &output_paragraph[start_pos]; char *value; output_paragraph[end_pos] = 0; name = xstrdup (name); value = set_p (name); output_column -= end_pos - start_pos; output_paragraph_offset = start_pos; if (value) execute_string ("%s", value); else add_word_args (_("{No Value For \"%s\"}"), name); free (name); } } /* Set, clear, or conditionalize based on ACTION. */ void handle_variable (action) int action; { char *name; get_rest_of_line (&name); backup_input_pointer (); handle_variable_internal (action, name); free (name); } void handle_variable_internal (action, name) int action; char *name; { char *temp; int delimiter, additional_text_present = 0; /* Only the first word of NAME is a valid tag. */ temp = name; delimiter = 0; while (*temp && (delimiter || !whitespace (*temp))) { /* #if defined (SET_WITH_EQUAL) */ if (*temp == '"' || *temp == '\'') { if (*temp == delimiter) delimiter = 0; else delimiter = *temp; } /* #endif SET_WITH_EQUAL */ temp++; } if (*temp) additional_text_present++; *temp = 0; if (!*name) line_error (_("%c%s requires a name"), COMMAND_PREFIX, command); else { switch (action) { case SET: { char *value; #if defined (SET_WITH_EQUAL) /* Allow a value to be saved along with a variable. The value is the text following an `=' sign in NAME, if any is present. */ for (value = name; *value && *value != '='; value++); if (*value) *value++ = 0; if (*value == '"' || *value == '\'') { value++; value[strlen (value) - 1] = 0; } #else /* !SET_WITH_EQUAL */ /* The VALUE of NAME is the remainder of the line sans whitespace. */ if (additional_text_present) { value = temp + 1; canon_white (value); } else value = ""; #endif /* !SET_WITH_VALUE */ set (name, value); } break; case CLEAR: clear (name); break; case IFSET: case IFCLEAR: /* If IFSET and NAME is not set, or if IFCLEAR and NAME is set, read lines from the the file until we reach a matching "@end CONDITION". This means that we only take note of "@ifset/clear" and "@end" commands. */ { char condition[8]; int condition_len; int orig_line_number = line_number; if (action == IFSET) strcpy (condition, "ifset"); else strcpy (condition, "ifclear"); condition_len = strlen (condition); if ((action == IFSET && !set_p (name)) || (action == IFCLEAR && set_p (name))) { int level = 0, done = 0; while (!done && input_text_offset < size_of_input_text) { char *freeable_line, *line; get_rest_of_line (&freeable_line); for (line = freeable_line; whitespace (*line); line++); if (*line == COMMAND_PREFIX && (strncmp (line + 1, condition, condition_len) == 0)) level++; else if (strncmp (line, "@end", 4) == 0) { char *cname = line + 4; char *temp; while (*cname && whitespace (*cname)) cname++; temp = cname; while (*temp && !whitespace (*temp)) temp++; *temp = 0; if (strcmp (cname, condition) == 0) { if (!level) { done = 1; } else level--; } } free (freeable_line); } if (!done) { int save = line_number; line_number = orig_line_number; line_error (_("Reached eof before matching @end %s"), condition); line_number = save; } /* We found the end of a false @ifset/ifclear. If we are in a menu, back up over the newline that ends the ifset, since that newline may also begin the next menu entry. */ break; } else { if (action == IFSET) begin_insertion (ifset); else begin_insertion (ifclear); } } break; } } } /* Execution of random text not in file. */ typedef struct { char *string; /* The string buffer. */ int size; /* The size of the buffer. */ int in_use; /* Nonzero means string currently in use. */ } EXECUTION_STRING; static EXECUTION_STRING **execution_strings = (EXECUTION_STRING **)NULL; static int execution_strings_index = 0; static int execution_strings_slots = 0; EXECUTION_STRING * get_execution_string (initial_size) int initial_size; { register int i = 0; EXECUTION_STRING *es = (EXECUTION_STRING *)NULL; if (execution_strings) { for (i = 0; i < execution_strings_index; i++) if (execution_strings[i] && (execution_strings[i]->in_use == 0)) { es = execution_strings[i]; break; } } if (!es) { if (execution_strings_index + 1 >= execution_strings_slots) { execution_strings = (EXECUTION_STRING **)xrealloc (execution_strings, (execution_strings_slots += 3) * sizeof (EXECUTION_STRING *)); for (; i < execution_strings_slots; i++) execution_strings[i] = (EXECUTION_STRING *)NULL; } execution_strings[execution_strings_index] = (EXECUTION_STRING *)xmalloc (sizeof (EXECUTION_STRING)); es = execution_strings[execution_strings_index]; execution_strings_index++; es->size = 0; es->string = (char *)NULL; es->in_use = 0; } if (initial_size > es->size) { es->string = (char *) xrealloc (es->string, initial_size); es->size = initial_size; } return (es); } /* Execute the string produced by formatting the ARGs with FORMAT. This is like submitting a new file with @include. */ void #if defined (VA_FPRINTF) && __STDC__ execute_string (char *format, ...) #else execute_string (format, va_alist) char *format; va_dcl #endif { EXECUTION_STRING *es; char *temp_string; #ifdef VA_FPRINTF va_list ap; #endif es = get_execution_string (4000); temp_string = es->string; es->in_use = 1; VA_START (ap, format); #ifdef VA_SPRINTF VA_SPRINTF (temp_string, format, ap); #else sprintf (temp_string, format, a1, a2, a3, a4, a5, a6, a7, a8); #endif /* not VA_SPRINTF */ va_end (ap); pushfile (); input_text_offset = 0; input_text = temp_string; input_filename = xstrdup (input_filename); size_of_input_text = strlen (temp_string); executing_string++; reader_loop (); free (input_filename); popfile (); executing_string--; es->in_use = 0; } /* Return what would be output for STR, i.e., expand Texinfo commands. If IMPLICIT_CODE is set, expand @code{STR}. */ char * expansion (str, implicit_code) char *str; int implicit_code; { int length; char *result; /* Inhibit any real output. */ int start = output_paragraph_offset; int saved_paragraph_is_open = paragraph_is_open; inhibit_output_flushing (); paragraph_is_open = 1; execute_string (implicit_code ? "@code{%s}" : "%s", str); uninhibit_output_flushing (); /* Copy the expansion from the buffer. */ length = output_paragraph_offset - start; result = xmalloc (1 + length); memcpy (result, (char *) (output_paragraph + start), length); result[length] = 0; /* Pretend it never happened. */ output_paragraph_offset = start; paragraph_is_open = saved_paragraph_is_open; return result; } /* @itemx, @item. */ static int itemx_flag = 0; void cm_itemx () { itemx_flag++; cm_item (); itemx_flag--; } void cm_item () { char *rest_of_line, *item_func; /* Can only hack "@item" while inside of an insertion. */ if (insertion_level) { INSERTION_ELT *stack = insertion_stack; int original_input_text_offset; skip_whitespace (); original_input_text_offset = input_text_offset; get_rest_of_line (&rest_of_line); item_func = current_item_function (); /* Okay, do the right thing depending on which insertion function is active. */ switch_top: switch (stack->insertion) { case multitable: multitable_item (); /* Ultra special hack. It appears that some people incorrectly place text directly after the @item, instead of on a new line by itself. This happens to work in TeX, so I make it work here. */ if (*rest_of_line) { line_number--; input_text_offset = original_input_text_offset; } break; case ifinfo: case ifset: case ifclear: case cartouche: stack = stack->next; if (!stack) goto no_insertion; else goto switch_top; break; case menu: case quotation: case example: case smallexample: case lisp: case format: case display: case group: line_error (_("The `%c%s' command is meaningless within a `@%s' block"), COMMAND_PREFIX, command, insertion_type_pname (current_insertion_type ())); break; case itemize: case enumerate: if (itemx_flag) { line_error (_("%citemx is not meaningful inside of a `%s' block"), COMMAND_PREFIX, insertion_type_pname (current_insertion_type ())); } else { start_paragraph (); kill_self_indent (-1); filling_enabled = indented_fill = 1; if (current_insertion_type () == itemize) { indent (output_column = current_indent - 2); /* I need some way to determine whether this command takes braces or not. I believe the user can type either "@bullet" or "@bullet{}". Of course, they can also type "o" or "#" or whatever else they want. */ if (item_func && *item_func) { if (*item_func == COMMAND_PREFIX) if (item_func[strlen (item_func) - 1] != '}') execute_string ("%s{}", item_func); else execute_string ("%s", item_func); else execute_string ("%s", item_func); } insert (' '); output_column++; } else enumerate_item (); /* Special hack. This makes `close_paragraph' a no-op until `start_paragraph' has been called. */ must_start_paragraph = 1; /* Handle text directly after the @item. */ if (*rest_of_line) { line_number--; input_text_offset = original_input_text_offset; } } break; case table: case ftable: case vtable: { /* We need this to determine if we have two @item's in a row (see test just below). */ static int last_item_output_position = 0; /* Get rid of extra characters. */ kill_self_indent (-1); /* If we have one @item followed directly by another @item, we need to insert a blank line. This is not true for @itemx, though. */ if (!itemx_flag && last_item_output_position == output_position) insert ('\n'); /* `close_paragraph' almost does what we want. The problem is when paragraph_is_open, and last_char_was_newline, and the last newline has been turned into a space, because filling_enabled. I handle it here. */ if (last_char_was_newline && filling_enabled && paragraph_is_open) insert ('\n'); close_paragraph (); #if defined (INDENT_PARAGRAPHS_IN_TABLE) /* Indent on a new line, but back up one indentation level. */ { int save = inhibit_paragraph_indentation; inhibit_paragraph_indentation = 1; /* At this point, inserting any non-whitespace character will force the existing indentation to be output. */ add_char ('i'); inhibit_paragraph_indentation = save; } #else /* !INDENT_PARAGRAPHS_IN_TABLE */ add_char ('i'); #endif /* !INDENT_PARAGRAPHS_IN_TABLE */ output_paragraph_offset--; kill_self_indent (default_indentation_increment + 1); /* Add item's argument to the line. */ filling_enabled = 0; if (item_func && *item_func) execute_string ("%s{%s}", item_func, rest_of_line); else execute_string ("%s", rest_of_line); if (current_insertion_type () == ftable) execute_string ("%cfindex %s\n", COMMAND_PREFIX, rest_of_line); else if (current_insertion_type () == vtable) execute_string ("%cvindex %s\n", COMMAND_PREFIX, rest_of_line); /* Start a new line, and let start_paragraph () do the indenting of it for you. */ close_single_paragraph (); indented_fill = filling_enabled = 1; last_item_output_position = output_position; } } free (rest_of_line); } else { no_insertion: line_error (_("%c%s found outside of an insertion block"), COMMAND_PREFIX, command); } } /* **************************************************************** */ /* */ /* Defun and Friends */ /* */ /* **************************************************************** */ #define DEFUN_SELF_DELIMITING(c) \ (((c) == '(') \ || ((c) == ')') \ || ((c) == '[') \ || ((c) == ']')) struct token_accumulator { unsigned int length; unsigned int index; char **tokens; }; void initialize_token_accumulator (accumulator) struct token_accumulator *accumulator; { (accumulator->length) = 0; (accumulator->index) = 0; (accumulator->tokens) = NULL; } void accumulate_token (accumulator, token) struct token_accumulator *accumulator; char *token; { if ((accumulator->index) >= (accumulator->length)) { (accumulator->length) += 10; (accumulator->tokens) = (char **) xrealloc (accumulator->tokens, (accumulator->length * sizeof (char *))); } accumulator->tokens[accumulator->index] = token; accumulator->index += 1; } char * copy_substring (start, end) char *start; char *end; { char *result, *scan, *scan_result; result = (char *) xmalloc ((end - start) + 1); scan_result = result; scan = start; while (scan < end) *scan_result++ = *scan++; *scan_result = 0; return (result); } /* Given `string' pointing at an open brace, skip forward and return a pointer to just past the matching close brace. */ int scan_group_in_string (string_pointer) char **string_pointer; { register int c; register char *scan_string; register unsigned int level = 1; scan_string = (*string_pointer) + 1; while (1) { if (level == 0) { (*string_pointer) = scan_string; return (1); } c = (*scan_string++); if (c == 0) { /* Tweak line_number to compensate for fact that we gobbled the whole line before coming here. */ line_number -= 1; line_error (_("Missing `}' in %cdef arg"), COMMAND_PREFIX); line_number += 1; (*string_pointer) = (scan_string - 1); return (0); } if (c == '{') level += 1; if (c == '}') level -= 1; } } /* Return a list of tokens from the contents of `string'. Commands and brace-delimited groups count as single tokens. Contiguous whitespace characters are converted to a token consisting of a single space. */ char ** args_from_string (string) char *string; { struct token_accumulator accumulator; register char *scan_string = string; char *token_start, *token_end; initialize_token_accumulator (&accumulator); while ((*scan_string) != 0) { /* Replace arbitrary whitespace by a single space. */ if (whitespace (*scan_string)) { scan_string += 1; while (whitespace (*scan_string)) scan_string += 1; accumulate_token ((&accumulator), (xstrdup (" "))); continue; } /* Commands count as single tokens. */ if ((*scan_string) == COMMAND_PREFIX) { token_start = scan_string; scan_string += 1; if (self_delimiting (*scan_string)) scan_string += 1; else { register int c; while (1) { c = *scan_string++; if ((c == 0) || (c == '{') || (whitespace (c))) { scan_string -= 1; break; } } if (*scan_string == '{') { char *s = scan_string; (void) scan_group_in_string (&s); scan_string = s; } } token_end = scan_string; } /* Parentheses and brackets are self-delimiting. */ else if (DEFUN_SELF_DELIMITING (*scan_string)) { token_start = scan_string; scan_string += 1; token_end = scan_string; } /* Open brace introduces a group that is a single token. */ else if (*scan_string == '{') { char *s = scan_string; int balanced = scan_group_in_string (&s); token_start = scan_string + 1; scan_string = s; token_end = balanced ? (scan_string - 1) : scan_string; } /* Otherwise a token is delimited by whitespace, parentheses, brackets, or braces. A token is also ended by a command. */ else { token_start = scan_string; while (1) { register int c; c = *scan_string++; /* Do not back up if we're looking at a }; since the only valid }'s are those matched with {'s, we want to give an error. If we back up, we go into an infinite loop. */ if (!c || whitespace (c) || DEFUN_SELF_DELIMITING (c) || c == '{') { scan_string--; break; } /* If we encounter a command embedded within a token, then end the token. */ if (c == COMMAND_PREFIX) { scan_string--; break; } } token_end = scan_string; } accumulate_token (&accumulator, copy_substring (token_start, token_end)); } accumulate_token (&accumulator, NULL); return (accumulator.tokens); } void process_defun_args (defun_args, auto_var_p) char **defun_args; int auto_var_p; { int pending_space = 0; while (1) { char *defun_arg = *defun_args++; if (defun_arg == NULL) break; if (defun_arg[0] == ' ') { pending_space = 1; continue; } if (pending_space) { add_char (' '); pending_space = 0; } if (DEFUN_SELF_DELIMITING (defun_arg[0])) add_char (defun_arg[0]); else if (defun_arg[0] == '&') add_word (defun_arg); else if (defun_arg[0] == COMMAND_PREFIX) execute_string ("%s", defun_arg); else if (auto_var_p) execute_string ("%cvar{%s}", COMMAND_PREFIX, defun_arg); else add_word (defun_arg); } } char * next_nonwhite_defun_arg (arg_pointer) char ***arg_pointer; { char **scan = (*arg_pointer); char *arg = (*scan++); if ((arg != 0) && (*arg == ' ')) arg = *scan++; if (arg == 0) scan -= 1; *arg_pointer = scan; return ((arg == 0) ? "" : arg); } /* Make the defun type insertion. TYPE says which insertion this is. X_P, if nonzero, says not to start a new insertion. */ void defun_internal (type, x_p) enum insertion_type type; int x_p; { enum insertion_type base_type; char **defun_args, **scan_args; char *category, *defined_name, *type_name, *type_name2; { char *line; get_rest_of_line (&line); defun_args = (args_from_string (line)); free (line); } scan_args = defun_args; switch (type) { case defun: category = _("Function"); base_type = deffn; break; case defmac: category = _("Macro"); base_type = deffn; break; case defspec: category = _("Special Form"); base_type = deffn; break; case defvar: category = _("Variable"); base_type = defvr; break; case defopt: category = _("User Option"); base_type = defvr; break; case deftypefun: category = _("Function"); base_type = deftypefn; break; case deftypevar: category = _("Variable"); base_type = deftypevr; break; case defivar: category = _("Instance Variable"); base_type = defcv; break; case defmethod: category = _("Method"); base_type = defop; break; case deftypemethod: category = _("Method"); base_type = deftypemethod; break; default: category = next_nonwhite_defun_arg (&scan_args); base_type = type; break; } if ((base_type == deftypefn) || (base_type == deftypevr) || (base_type == defcv) || (base_type == defop) || (base_type == deftypemethod)) type_name = next_nonwhite_defun_arg (&scan_args); if (base_type == deftypemethod) type_name2 = next_nonwhite_defun_arg (&scan_args); defined_name = next_nonwhite_defun_arg (&scan_args); /* This hack exists solely for the purposes of formatting the texinfo manual. I couldn't think of a better way. The token might be a simple @@ followed immediately by more text. If this is the case, then the next defun arg is part of this one, and we should concatenate them. */ if (*scan_args && **scan_args && !whitespace (**scan_args) && (strcmp (defined_name, "@@") == 0)) { char *tem = (char *)xmalloc (3 + strlen (scan_args[0])); sprintf (tem, "@@%s", scan_args[0]); free (scan_args[0]); scan_args[0] = tem; scan_args++; defined_name = tem; } if (!x_p) begin_insertion (type); /* Write the definition header line. This should start at the normal indentation. */ current_indent -= default_indentation_increment; start_paragraph (); switch (base_type) { case deffn: case defvr: case deftp: execute_string (" -- %s: %s", category, defined_name); break; case deftypefn: case deftypevr: execute_string (" -- %s: %s %s", category, type_name, defined_name); break; case defcv: execute_string (" -- %s of %s: %s", category, type_name, defined_name); break; case defop: execute_string (" -- %s on %s: %s", category, type_name, defined_name); break; case deftypemethod: execute_string (" -- %s on %s: %s %s", category, type_name, type_name2, defined_name); break; } current_indent += default_indentation_increment; /* Now process the function arguments, if any. If these carry onto the next line, they should be indented by two increments to distinguish them from the body of the definition, which is indented by one increment. */ current_indent += default_indentation_increment; switch (base_type) { case deffn: case defop: process_defun_args (scan_args, 1); break; /* Through Makeinfo 1.67 we processed remaining args only for deftp, deftypefn, and deftypemethod. But the libc manual, for example, needs to say: @deftypevar {char *} tzname[2] And simply allowing the extra text seems far simpler than trying to invent yet more defn commands. In any case, we should either output it or give an error, not silently ignore it. */ default: process_defun_args (scan_args, 0); break; } current_indent -= default_indentation_increment; close_single_paragraph (); /* Make an entry in the appropriate index. */ switch (base_type) { case deffn: case deftypefn: execute_string ("%cfindex %s\n", COMMAND_PREFIX, defined_name); break; case defvr: case deftypevr: case defcv: execute_string ("%cvindex %s\n", COMMAND_PREFIX, defined_name); break; case defop: case deftypemethod: execute_string ("%cfindex %s on %s\n", COMMAND_PREFIX, defined_name, type_name); break; case deftp: execute_string ("%ctindex %s\n", COMMAND_PREFIX, defined_name); break; } /* Deallocate the token list. */ scan_args = defun_args; while (1) { char * arg = (*scan_args++); if (arg == NULL) break; free (arg); } free (defun_args); } /* Add an entry for a function, macro, special form, variable, or option. If the name of the calling command ends in `x', then this is an extra entry included in the body of an insertion of the same type. */ void cm_defun () { int x_p; enum insertion_type type; char *temp = xstrdup (command); x_p = (command[strlen (command) - 1] == 'x'); if (x_p) temp[strlen (temp) - 1] = 0; type = find_type_from_name (temp); free (temp); /* If we are adding to an already existing insertion, then make sure that we are already in an insertion of type TYPE. */ if (x_p && (!insertion_level || insertion_stack->insertion != type)) { line_error (_("Must be in a `%s' insertion in order to use `%s'x"), command, command); discard_until ("\n"); return; } defun_internal (type, x_p); } /* **************************************************************** */ /* */ /* Other Random Commands */ /* */ /* **************************************************************** */ /* This says to inhibit the indentation of the next paragraph, but not of following paragraphs. */ void cm_noindent () { if (!inhibit_paragraph_indentation) inhibit_paragraph_indentation = -1; } /* I don't know exactly what to do with this. Should I allow someone to switch filenames in the middle of output? Since the file could be partially written, this doesn't seem to make sense. Another option: ignore it, since they don't *really* want to switch files. Finally, complain, or at least warn. */ void cm_setfilename () { char *filename; get_rest_of_line (&filename); /* warning ("`@%s %s' encountered and ignored", command, filename); */ free (filename); } void cm_ignore_line () { discard_until ("\n"); } /* @br can be immediately followed by `{}', so we have to read those here. It should simply close the paragraph. */ void cm_br () { if (looking_at ("{}")) input_text_offset += 2; if (curchar () == '\n') { input_text_offset++; line_number++; } close_paragraph (); } /* Insert the number of blank lines passed as argument. */ void cm_sp () { int lines; char *line; get_rest_of_line (&line); if (sscanf (line, "%d", &lines) != 1) { line_error (_("%csp requires a positive numeric argument"), COMMAND_PREFIX); } else { if (lines < 0) lines = 0; while (lines--) add_char ('\n'); } free (line); } /* @dircategory LINE outputs INFO-DIR-SECTION LINE, but not if --no-headers. */ void cm_dircategory () { char *line; get_rest_of_line (&line);; if (!no_headers) { insert_string ("INFO-DIR-SECTION "); insert_string (line); insert ('\n'); } free (line); } /* Start a new line with just this text on it. Then center the line of text. This always ends the current paragraph. */ void cm_center () { register int i, start, length; int fudge_factor = 1; unsigned char *line; close_paragraph (); filling_enabled = indented_fill = 0; cm_noindent (); start = output_paragraph_offset; inhibit_output_flushing (); get_rest_of_line ((char **)&line); execute_string ("%s", (char *)line); free (line); uninhibit_output_flushing (); i = output_paragraph_offset - 1; while (i > (start - 1) && output_paragraph[i] == '\n') i--; output_paragraph_offset = ++i; length = output_paragraph_offset - start; if (length < (fill_column - fudge_factor)) { line = (unsigned char *)xmalloc (1 + length); memcpy (line, (char *)(output_paragraph + start), length); i = (fill_column - fudge_factor - length) / 2; output_paragraph_offset = start; while (i--) insert (' '); for (i = 0; i < length; i++) insert (line[i]); free (line); } insert ('\n'); close_paragraph (); filling_enabled = 1; } /* Show what an expression returns. */ void cm_result (arg) int arg; { if (arg == END) add_word ("=>"); } /* What an expression expands to. */ void cm_expansion (arg) int arg; { if (arg == END) add_word ("==>"); } /* Indicates two expressions are equivalent. */ void cm_equiv (arg) int arg; { if (arg == END) add_word ("=="); } /* What an expression may print. */ void cm_print (arg) int arg; { if (arg == END) add_word ("-|"); } /* An error signaled. */ void cm_error (arg) int arg; { if (arg == END) add_word ("error-->"); } /* The location of point in an example of a buffer. */ void cm_point (arg) int arg; { if (arg == END) add_word ("-!-"); } /* Start a new line with just this text on it. The text is outdented one level if possible. */ void cm_exdent () { char *line; int i = current_indent; if (current_indent) current_indent -= default_indentation_increment; get_rest_of_line (&line); close_single_paragraph (); execute_string ("%s", line); current_indent = i; free (line); close_single_paragraph (); } /* Remember this file, and move onto the next. */ void cm_include () { char *filename; #if defined (HAVE_MACROS) if (macro_expansion_output_stream && !executing_string) me_append_before_this_command (); #endif /* HAVE_MACROS */ close_paragraph (); get_rest_of_line (&filename); #if defined (HAVE_MACROS) if (macro_expansion_output_stream && !executing_string) remember_itext (input_text, input_text_offset); #endif /* HAVE_MACROS */ pushfile (); /* In verbose mode we print info about including another file. */ if (verbose_mode) { register int i = 0; register FSTACK *stack = filestack; for (i = 0, stack = filestack; stack; stack = stack->next, i++); i *= 2; printf ("%*s", i, ""); printf ("%c%s %s\n", COMMAND_PREFIX, command, filename); fflush (stdout); } if (!find_and_load (filename)) { extern int errno; popfile (); line_number--; /* Cannot "@include foo", in line 5 of "/wh/bar". */ line_error ("%c%s %s: %s", COMMAND_PREFIX, command, filename, strerror (errno)); free (filename); return; } else { #if defined (HAVE_MACROS) if (macro_expansion_output_stream && !executing_string) remember_itext (input_text, input_text_offset); #endif /* HAVE_MACROS */ reader_loop (); } free (filename); popfile (); } /* The other side of a malformed expression. */ void misplaced_brace () { line_error (_("Misplaced %c"), '}'); } /* Signals end of processing. Easy to make this happen. */ void cm_bye () { input_text_offset = size_of_input_text; } /* Set the paragraph indentation variable to the value specified in STRING. Values can be: `asis': Don't change existing indentation. `none': Remove existing indentation. NUM: Indent NUM spaces at the starts of paragraphs. If NUM is zero, we assume `none'. Returns 0 if successful, or nonzero if STRING isn't one of the above. */ int set_paragraph_indent (string) char *string; { if (strcmp (string, "asis") == 0 || strcmp (string, _("asis")) == 0) paragraph_start_indent = 0; else if (strcmp (string, "none") == 0 || strcmp (string, _("none")) == 0) paragraph_start_indent = -1; else { if (sscanf (string, "%d", ¶graph_start_indent) != 1) return (-1); else { if (paragraph_start_indent == 0) paragraph_start_indent = -1; } } return (0); } void cm_paragraphindent () { char *arg; get_rest_of_line (&arg); if (set_paragraph_indent (arg) != 0) line_error (_("Bad argument to %c%s"), COMMAND_PREFIX, command); free (arg); } /* **************************************************************** */ /* */ /* Indexing Stuff */ /* */ /* **************************************************************** */ /* An index element... */ typedef struct index_elt { struct index_elt *next; char *entry; /* The index entry itself. */ char *node; /* The node from whence it came. */ int code; /* Nonzero means add `@code{...}' when printing this element. */ int defining_line; /* Line number where this entry was written. */ char *defining_file; /* Source file for defining_line. */ } INDEX_ELT; /* A list of short-names for each index. There are two indices into the the_indices array. * read_index is the index that points to the list of index entries that we will find if we ask for the list of entries for this name. * write_index is the index that points to the list of index entries that we will add new entries to. Initially, read_index and write index are the same, but the @syncodeindex and @synindex commands can change the list we add entries to. For example, after the commands @cindex foo @defindex ii @synindex cp ii @cindex bar the cp index will contain the entry `foo', and the new ii index will contain the entry `bar'. This is consistent with the way texinfo.tex handles the same situation. In addition, for each index, it is remembered whether that index is a code index or not. Code indices have @code{} inserted around the first word when they are printed with printindex. */ typedef struct { char *name; int read_index; /* index entries for `name' */ int write_index; /* store index entries here, @synindex can change it */ int code; } INDEX_ALIST; INDEX_ALIST **name_index_alist = (INDEX_ALIST **) NULL; /* An array of pointers. Each one is for a different index. The "synindex" command changes which array slot is pointed to by a given "index". */ INDEX_ELT **the_indices = (INDEX_ELT **) NULL; /* The number of defined indices. */ int defined_indices = 0; void init_indices () { int i; /* Create the default data structures. */ /* Initialize data space. */ if (!the_indices) { the_indices = (INDEX_ELT **) xmalloc ((1 + defined_indices) * sizeof (INDEX_ELT *)); the_indices[defined_indices] = (INDEX_ELT *) NULL; name_index_alist = (INDEX_ALIST **) xmalloc ((1 + defined_indices) * sizeof (INDEX_ALIST *)); name_index_alist[defined_indices] = (INDEX_ALIST *) NULL; } /* If there were existing indices, get rid of them now. */ for (i = 0; i < defined_indices; i++) { undefindex (name_index_alist[i]->name); if (name_index_alist[i]) { /* Suppose we're called with two input files, and the first does a @synindex pg cp. Then, when we get here to start the second file, the "pg" element won't get freed by undefindex (because it's pointing to "cp"). So free it here; otherwise, when we try to define the pg index again just below, it will still point to cp. */ free (name_index_alist[i]->name); free (name_index_alist[i]); name_index_alist[i] = (INDEX_ALIST *) NULL; } } /* Add the default indices. */ top_defindex ("cp", 0); /* cp is the only non-code index. */ top_defindex ("fn", 1); top_defindex ("ky", 1); top_defindex ("pg", 1); top_defindex ("tp", 1); top_defindex ("vr", 1); } /* Find which element in the known list of indices has this name. Returns -1 if NAME isn't found. */ int find_index_offset (name) char *name; { register int i; for (i = 0; i < defined_indices; i++) if (name_index_alist[i] && strcmp (name, name_index_alist[i]->name) == 0) return (i); return (-1); } /* Return a pointer to the entry of (name . index) for this name. Return NULL if the index doesn't exist. */ INDEX_ALIST * find_index (name) char *name; { int offset = find_index_offset (name); if (offset > -1) return (name_index_alist[offset]); else return ((INDEX_ALIST *) NULL); } /* Given an index name, return the offset in the_indices of this index, or -1 if there is no such index. */ int translate_index (name) char *name; { INDEX_ALIST *which = find_index (name); if (which) return (which->read_index); else return (-1); } /* Return the index list which belongs to NAME. */ INDEX_ELT * index_list (name) char *name; { int which = translate_index (name); if (which < 0) return ((INDEX_ELT *) -1); else return (the_indices[which]); } /* Please release me, let me go... */ void free_index (index) INDEX_ELT *index; { INDEX_ELT *temp; while ((temp = index) != (INDEX_ELT *) NULL) { free (temp->entry); /* Do not free the node, because we already freed the tag table, which freed all the node names. */ /* free (temp->node); */ index = index->next; free (temp); } } /* Flush an index by name. This will delete the list of entries that would be written by a @printindex command for this index. */ void undefindex (name) char *name; { int i; int which = find_index_offset (name); /* The index might have already been freed if this was the target of an @synindex. */ if (which < 0 || !name_index_alist[which]) return; i = name_index_alist[which]->read_index; free_index (the_indices[i]); the_indices[i] = (INDEX_ELT *) NULL; free (name_index_alist[which]->name); free (name_index_alist[which]); name_index_alist[which] = (INDEX_ALIST *) NULL; } /* Define an index known as NAME. We assign the slot number. CODE if Nonzero says to make this a code index. */ void defindex (name, code) char *name; int code; { register int i, slot; /* If it already exists, flush it. */ undefindex (name); /* Try to find an empty slot. */ slot = -1; for (i = 0; i < defined_indices; i++) if (!name_index_alist[i]) { slot = i; break; } if (slot < 0) { /* No such luck. Make space for another index. */ slot = defined_indices; defined_indices++; name_index_alist = (INDEX_ALIST **) xrealloc ((char *)name_index_alist, (1 + defined_indices) * sizeof (INDEX_ALIST *)); the_indices = (INDEX_ELT **) xrealloc ((char *)the_indices, (1 + defined_indices) * sizeof (INDEX_ELT *)); } /* We have a slot. Start assigning. */ name_index_alist[slot] = (INDEX_ALIST *) xmalloc (sizeof (INDEX_ALIST)); name_index_alist[slot]->name = xstrdup (name); name_index_alist[slot]->read_index = slot; name_index_alist[slot]->write_index = slot; name_index_alist[slot]->code = code; the_indices[slot] = (INDEX_ELT *) NULL; } /* Add the arguments to the current index command to the index NAME. */ void index_add_arg (name) char *name; { int which; char *index_entry; INDEX_ALIST *tem; tem = find_index (name); which = tem ? tem->write_index : -1; #if defined (HAVE_MACROS) if (macro_expansion_output_stream && !executing_string) append_to_expansion_output (input_text_offset + 1); #endif /* HAVE_MACROS */ get_rest_of_line (&index_entry); ignore_blank_line (); #if defined (HAVE_MACROS) if (macro_expansion_output_stream && !executing_string) { int op_orig; remember_itext (input_text, input_text_offset); op_orig = output_paragraph_offset; me_execute_string (index_entry); me_execute_string ("\n"); output_paragraph_offset = op_orig; } #endif /* HAVE_MACROS */ if (which < 0) { line_error (_("Unknown index `%s'"), name); free (index_entry); } else { INDEX_ELT *new = (INDEX_ELT *) xmalloc (sizeof (INDEX_ELT)); new->next = the_indices[which]; new->entry = index_entry; new->node = current_node; new->code = tem->code; new->defining_line = line_number - 1; new->defining_file = input_filename; the_indices[which] = new; } } #define INDEX_COMMAND_SUFFIX "index" /* The function which user defined index commands call. */ void gen_index () { char *name = xstrdup (command); if (strlen (name) >= strlen ("index")) name[strlen (name) - strlen ("index")] = 0; index_add_arg (name); free (name); } void top_defindex (name, code) char *name; int code; { char *temp; temp = (char *) xmalloc (1 + strlen (name) + strlen ("index")); sprintf (temp, "%sindex", name); define_user_command (temp, gen_index, 0); defindex (name, code); free (temp); } /* Define a new index command. Arg is name of index. */ void cm_defindex () { gen_defindex (0); } void cm_defcodeindex () { gen_defindex (1); } void gen_defindex (code) int code; { char *name; get_rest_of_line (&name); if (find_index (name)) { line_error (_("Index `%s' already exists"), name); free (name); return; } else { char *temp = (char *) alloca (1 + strlen (name) + strlen ("index")); sprintf (temp, "%sindex", name); define_user_command (temp, gen_index, 0); defindex (name, code); free (name); } } /* Expects 2 args, on the same line. Both are index abbreviations. Make the first one be a synonym for the second one, i.e. make the first one have the same index as the second one. */ void cm_synindex () { int source, target; char *abbrev1, *abbrev2; skip_whitespace (); get_until_in_line (0, " ", &abbrev1); target = find_index_offset (abbrev1); skip_whitespace (); get_until_in_line (0, " ", &abbrev2); source = find_index_offset (abbrev2); if (source < 0 || target < 0) { line_error (_("Unknown index `%s' and/or `%s' in @synindex"), abbrev1, abbrev2); } else { name_index_alist[target]->write_index = name_index_alist[source]->write_index; } free (abbrev1); free (abbrev2); } void cm_pindex () /* Pinhead index. */ { index_add_arg ("pg"); } void cm_vindex () /* Variable index. */ { index_add_arg ("vr"); } void cm_kindex () /* Key index. */ { index_add_arg ("ky"); } void cm_cindex () /* Concept index. */ { index_add_arg ("cp"); } void cm_findex () /* Function index. */ { index_add_arg ("fn"); } void cm_tindex () /* Data Type index. */ { index_add_arg ("tp"); } /* Sorting the index. */ int index_element_compare (element1, element2) INDEX_ELT **element1, **element2; { return (strcasecmp ((*element1)->entry, (*element2)->entry)); } /* Force all index entries to be unique. */ void make_index_entries_unique (array, count) INDEX_ELT **array; int count; { register int i, j; INDEX_ELT **copy; int counter = 1; copy = (INDEX_ELT **)xmalloc ((1 + count) * sizeof (INDEX_ELT *)); for (i = 0, j = 0; i < count; i++) { if ((i == (count - 1)) || (array[i]->node != array[i + 1]->node) || (strcmp (array[i]->entry, array[i + 1]->entry) != 0)) copy[j++] = array[i]; else { free (array[i]->entry); free (array[i]); } } copy[j] = (INDEX_ELT *)NULL; /* Now COPY contains only unique entries. Duplicated entries in the original array have been freed. Replace the current array with the copy, fixing the NEXT pointers. */ for (i = 0; copy[i] != (INDEX_ELT *)NULL; i++) { copy[i]->next = copy[i + 1]; /* Fix entry names which are the same. They point to different nodes, so we make the entry name unique. */ if ((copy[i + 1] != (INDEX_ELT *)NULL) && (strcmp (copy[i]->entry, copy[i + 1]->entry) == 0)) { char *new_entry_name; new_entry_name = (char *)xmalloc (10 + strlen (copy[i]->entry)); sprintf (new_entry_name, "%s <%d>", copy[i]->entry, counter); free (copy[i]->entry); copy[i]->entry = new_entry_name; counter++; } else counter = 1; array[i] = copy[i]; } array[i] = (INDEX_ELT *)NULL; /* Free the storage used only by COPY. */ free (copy); } /* Sort the index passed in INDEX, returning an array of pointers to elements. The array is terminated with a NULL pointer. We call qsort because it's supposed to be fast. I think this looks bad. */ INDEX_ELT ** sort_index (index) INDEX_ELT *index; { INDEX_ELT **array; INDEX_ELT *temp = index; int count = 0; int save_line_number = line_number; char *save_input_filename = input_filename; while (temp != (INDEX_ELT *) NULL) { count++; temp = temp->next; } /* We have the length. Make an array. */ array = (INDEX_ELT **) xmalloc ((count + 1) * sizeof (INDEX_ELT *)); count = 0; temp = index; while (temp != (INDEX_ELT *) NULL) { array[count++] = temp; /* Set line number and input filename to the source line for this index entry, as this expansion finds any errors. */ line_number = array[count - 1]->defining_line; input_filename = array[count - 1]->defining_file; /* If this particular entry should be printed as a "code" index, then wrap the entry with "@code{...}". */ array[count - 1]->entry = expansion (temp->entry, index->code); temp = temp->next; } array[count] = (INDEX_ELT *) NULL; /* terminate the array. */ line_number = save_line_number; input_filename = save_input_filename; /* Sort the array. */ qsort (array, count, sizeof (INDEX_ELT *), index_element_compare); make_index_entries_unique (array, count); return (array); } /* Nonzero means that we are in the middle of printing an index. */ int printing_index = 0; /* Takes one arg, a short name of an index to print. Outputs a menu of the sorted elements of the index. */ void cm_printindex () { int item; INDEX_ELT *index; INDEX_ELT **array; char *index_name; unsigned line_length; char *line; int saved_inhibit_paragraph_indentation = inhibit_paragraph_indentation; int saved_filling_enabled = filling_enabled; close_paragraph (); get_rest_of_line (&index_name); index = index_list (index_name); if (index == (INDEX_ELT *)-1) { line_error (_("Unknown index `%s' in @printindex"), index_name); free (index_name); return; } else free (index_name); /* Do this before sorting, so execute_string in index_element_compare will give the same results as when we actually print. */ printing_index = 1; filling_enabled = 0; inhibit_paragraph_indentation = 1; array = sort_index (index); close_paragraph (); add_word (_("* Menu:\n\n")); #if defined (HAVE_MACROS) me_inhibit_expansion++; #endif /* HAVE_MACROS */ /* This will probably be enough. */ line_length = 100; line = xmalloc (line_length); for (item = 0; (index = array[item]); item++) { /* A pathological document might have an index entry outside of any node. Don't crash. Perhaps should warn. */ char *index_node = index->node ? index->node : "(none)"; unsigned new_length = strlen (index->entry); if (new_length < 37) /* minimum length used below */ new_length = 37; new_length += strlen (index_node) + 7; /* * : .\n\0 */ if (new_length > line_length) { line_length = new_length; line = xrealloc (line, line_length); } /* Print the entry, nicely formatted. We've already expanded any commands, including any implicit @code. Thus, can't call execute_string, since @@ has turned into @. */ sprintf (line, "* %-37s %s.\n", index->entry, index_node); line[2 + strlen (index->entry)] = ':'; insert_string (line); /* Previous `output_paragraph' from growing to the size of the whole index. */ flush_output (); } free (line); #if defined (HAVE_MACROS) me_inhibit_expansion--; #endif /* HAVE_MACROS */ printing_index = 0; free (array); close_single_paragraph (); filling_enabled = saved_filling_enabled; inhibit_paragraph_indentation = saved_inhibit_paragraph_indentation; } /* User-defined commands, which happens only from user-defined indexes. */ void define_user_command (name, proc, needs_braces_p) char *name; COMMAND_FUNCTION *proc; int needs_braces_p; { int slot = user_command_array_len; user_command_array_len++; if (!user_command_array) user_command_array = (COMMAND **) xmalloc (1 * sizeof (COMMAND *)); user_command_array = (COMMAND **) xrealloc (user_command_array, (1 + user_command_array_len) * sizeof (COMMAND *)); user_command_array[slot] = (COMMAND *) xmalloc (sizeof (COMMAND)); user_command_array[slot]->name = xstrdup (name); user_command_array[slot]->proc = proc; user_command_array[slot]->argument_in_braces = needs_braces_p; } /* Some support for footnotes. */ /* Footnotes are a new construct in Info. We don't know the best method of implementing them for sure, so we present two possiblities. SeparateNode: Make them look like followed references, with the reference destinations in a makeinfo manufactured node or, EndNode: Make them appear at the bottom of the node that they originally appeared in. */ #define SeparateNode 0 #define EndNode 1 int footnote_style = EndNode; int first_footnote_this_node = 1; int footnote_count = 0; /* Set the footnote style based on he style identifier in STRING. */ int set_footnote_style (string) char *string; { if ((strcasecmp (string, "separate") == 0) || (strcasecmp (string, "MN") == 0)) footnote_style = SeparateNode; else if ((strcasecmp (string, "end") == 0) || (strcasecmp (string, "EN") == 0)) footnote_style = EndNode; else return (-1); return (0); } void cm_footnotestyle () { char *arg; get_rest_of_line (&arg); /* If set on command line, do not change the footnote style. */ if (!footnote_style_preset && set_footnote_style (arg) != 0) line_error ("Bad argument to %c%s", COMMAND_PREFIX, command); free (arg); } typedef struct fn { struct fn *next; char *marker; char *note; } FN; FN *pending_notes = (FN *) NULL; /* A method for remembering footnotes. Note that this list gets output at the end of the current node. */ void remember_note (marker, note) char *marker, *note; { FN *temp = (FN *) xmalloc (sizeof (FN)); temp->marker = xstrdup (marker); temp->note = xstrdup (note); temp->next = pending_notes; pending_notes = temp; footnote_count++; } /* How to get rid of existing footnotes. */ void free_pending_notes () { FN *temp; while ((temp = pending_notes) != (FN *) NULL) { free (temp->marker); free (temp->note); pending_notes = pending_notes->next; free (temp); } first_footnote_this_node = 1; footnote_count = 0; } /* What to do when you see a @footnote construct. */ /* Handle a "footnote". footnote *{this is a footnote} where "*" is the (optional) marker character for this note. */ void cm_footnote () { char *marker; char *note; get_until ("{", &marker); canon_white (marker); if (macro_expansion_output_stream && !executing_string) append_to_expansion_output (input_text_offset + 1); /* include the { */ /* Read the argument in braces. */ if (curchar () != '{') { line_error (_("`%c%s' needs an argument `{...}', not just `%s'"), COMMAND_PREFIX, command, marker); free (marker); return; } else { int len; int braces = 1; int loc = ++input_text_offset; while (braces) { if (loc == size_of_input_text) { line_error (_("No closing brace for footnote `%s'"), marker); return; } if (input_text[loc] == '{') braces++; else if (input_text[loc] == '}') braces--; else if (input_text[loc] == '\n') line_number++; loc++; } len = (loc - input_text_offset) - 1; note = (char *)xmalloc (len + 1); strncpy (note, &input_text[input_text_offset], len); note[len] = 0; input_text_offset = loc; } /* Must write the macro-expanded argument to the macro expansion output stream. This is like the case in index_add_arg. */ if (macro_expansion_output_stream && !executing_string) { int op_orig; remember_itext (input_text, input_text_offset); op_orig = output_paragraph_offset; me_execute_string (note); /* Calling me_execute_string on a lone } provokes an error, since as far as the reader knows there is no matching {. We wrote the { above in the call to append_to_expansion_output. */ write_region_to_macro_output ("}", 0, 1); output_paragraph_offset = op_orig; } if (!current_node || !*current_node) { line_error (_("Footnote defined without parent node")); free (marker); free (note); return; } if (!*marker) { free (marker); if (number_footnotes) { marker = (char *)xmalloc (10); sprintf (marker, "%d", current_footnote_number); current_footnote_number++; } else marker = xstrdup ("*"); } remember_note (marker, note); /* Your method should at least insert MARKER. */ switch (footnote_style) { case SeparateNode: add_word_args ("(%s)", marker); if (first_footnote_this_node) { char *temp_string; temp_string = (char *) xmalloc ((strlen (current_node)) + (strlen (_("-Footnotes"))) + 1); add_word_args (" (*note %s-Footnotes::)", current_node); strcpy (temp_string, current_node); strcat (temp_string, "-Footnotes"); remember_node_reference (temp_string, line_number, followed_reference); free (temp_string); first_footnote_this_node = 0; } break; case EndNode: add_word_args ("(%s)", marker); break; default: break; } free (marker); free (note); } /* Nonzero means that we are currently in the process of outputting footnotes. */ int already_outputting_pending_notes = 0; /* Output the footnotes. We are at the end of the current node. */ void output_pending_notes () { FN *footnote = pending_notes; if (!pending_notes) return; switch (footnote_style) { case SeparateNode: { char *old_current_node = current_node; char *old_command = xstrdup (command); already_outputting_pending_notes++; execute_string ("%cnode %s-Footnotes,,,%s\n", COMMAND_PREFIX, current_node, current_node); already_outputting_pending_notes--; current_node = old_current_node; free (command); command = old_command; } break; case EndNode: close_paragraph (); in_fixed_width_font++; execute_string (_("---------- Footnotes ----------\n\n")); in_fixed_width_font--; break; } /* Handle the footnotes in reverse order. */ { FN **array = (FN **) xmalloc ((footnote_count + 1) * sizeof (FN *)); array[footnote_count] = (FN *) NULL; while (--footnote_count > -1) { array[footnote_count] = footnote; footnote = footnote->next; } filling_enabled = 1; indented_fill = 1; while ((footnote = array[++footnote_count])) { execute_string ("(%s) %s", footnote->marker, footnote->note); close_paragraph (); } close_paragraph (); free (array); } } /* **************************************************************** */ /* */ /* User definable Macros (text substitution) */ /* */ /* **************************************************************** */ #if defined (HAVE_MACROS) /* Array of macros and definitions. */ MACRO_DEF **macro_list = (MACRO_DEF **)NULL; int macro_list_len = 0; /* Number of elements. */ int macro_list_size = 0; /* Number of slots in total. */ /* Return the macro definition of NAME or NULL if NAME is not defined. */ MACRO_DEF * find_macro (name) char *name; { register int i; register MACRO_DEF *def; def = (MACRO_DEF *)NULL; for (i = 0; macro_list && (def = macro_list[i]); i++) { if ((!def->inhibited) && (strcmp (def->name, name) == 0)) break; } return (def); } /* Add the macro NAME with ARGLIST and BODY to the list of defined macros. SOURCE_FILE is the name of the file where this definition can be found, and SOURCE_LINENO is the line number within that file. If a macro already exists with NAME, then a warning is produced, and that previous definition is overwritten. */ void add_macro (name, arglist, body, source_file, source_lineno, flags) char *name; char **arglist; char *body; char *source_file; int source_lineno, flags; { register MACRO_DEF *def; def = find_macro (name); if (!def) { if (macro_list_len + 2 >= macro_list_size) macro_list = (MACRO_DEF **)xrealloc (macro_list, ((macro_list_size += 10) * sizeof (MACRO_DEF *))); macro_list[macro_list_len] = (MACRO_DEF *)xmalloc (sizeof (MACRO_DEF)); macro_list[macro_list_len + 1] = (MACRO_DEF *)NULL; def = macro_list[macro_list_len]; macro_list_len += 1; def->name = name; } else { char *temp_filename = input_filename; int temp_line = line_number; warning (_("macro `%s' previously defined"), name); input_filename = def->source_file; line_number = def->source_lineno; warning (_("here is the previous definition of `%s'"), name); input_filename = temp_filename; line_number = temp_line; if (def->arglist) { register int i; for (i = 0; def->arglist[i]; i++) free (def->arglist[i]); free (def->arglist); } free (def->source_file); free (def->body); } def->source_file = xstrdup (source_file); def->source_lineno = source_lineno; def->body = body; def->arglist = arglist; def->inhibited = 0; def->flags = flags; } /* Delete the macro with name NAME. The macro is deleted from the list, but it is also returned. If there was no macro defined, NULL is returned. */ MACRO_DEF * delete_macro (name) char *name; { register int i; register MACRO_DEF *def; def = (MACRO_DEF *)NULL; for (i = 0; macro_list && (def = macro_list[i]); i++) if (strcmp (def->name, name) == 0) { memmove (macro_list + i, macro_list + i + 1, ((macro_list_len + 1) - i) * sizeof (MACRO_DEF *)); macro_list_len--; break; } return (def); } /* Return the arglist on the current line. This can behave in two different ways, depending on the variable BRACES_REQUIRED_FOR_MACRO_ARGS. */ int braces_required_for_macro_args = 0; char ** get_macro_args (def) MACRO_DEF *def; { register int i; char *word; /* Quickly check to see if this macro has been invoked with any arguments. If not, then don't skip any of the following whitespace. */ for (i = input_text_offset; i < size_of_input_text; i++) if (!cr_or_whitespace (input_text[i])) break; if (input_text[i] != '{') { if (braces_required_for_macro_args) { return ((char **)NULL); } else { /* Braces are not required to fill out the macro arguments. If this macro takes one argument, it is considered to be the remainder of the line, sans whitespace. */ if (def->arglist && def->arglist[0] && !def->arglist[1]) { char **arglist; get_rest_of_line (&word); if (input_text[input_text_offset - 1] == '\n') { input_text_offset--; line_number--; } /* canon_white (word); */ arglist = (char **)xmalloc (2 * sizeof (char *)); arglist[0] = word; arglist[1] = (char *)NULL; return (arglist); } else { /* The macro either took no arguments, or took more than one argument. In that case, it must be invoked with arguments surrounded by braces. */ return ((char **)NULL); } } } return (get_brace_args (def->flags & ME_QUOTE_ARG)); } /* Substitute actual parameters for named parameters in body. The named parameters which appear in BODY must by surrounded reverse slashes, as in \foo\. */ char * apply (named, actuals, body) char **named, **actuals, *body; { register int i; int new_body_index, new_body_size; char *new_body, *text; int length_of_actuals; length_of_actuals = array_len (actuals); new_body_size = strlen (body); new_body = (char *)xmalloc (1 + new_body_size); /* Copy chars from BODY into NEW_BODY. */ i = 0; new_body_index = 0; while (1) { if (!body[i]) break; if (body[i] != '\\') new_body[new_body_index++] = body[i++]; else { /* Snarf parameter name, check against named parameters. */ char *param; int param_start, which, len; param_start = ++i; while ((body[i]) && (body[i] != '\\')) i++; len = i - param_start; param = (char *)xmalloc (1 + len); memcpy (param, body + param_start, len); param[len] = 0; if (body[i]) /* move past \ */ i++; /* Now check against named parameters. */ for (which = 0; named && named[which]; which++) if (strcmp (named[which], param) == 0) break; if (named && named[which]) { if (which < length_of_actuals) text = actuals[which]; else text = (char *)NULL; if (!text) text = ""; len = strlen (text); } else { /* not a parameter, restore \'s */ i = body[i] ? (i - 1) : i; len++; text = xmalloc (1 + len); sprintf (text, "\\%s", param); } if ((2 + strlen (param)) < len) { new_body_size += len + 1; new_body = xrealloc (new_body, new_body_size); } free (param); strcpy (new_body + new_body_index, text); new_body_index += len; if (!named || !named[which]) free (text); } } new_body[new_body_index] = 0; return (new_body); } /* Execute the macro passed in DEF, a pointer to a MACRO_DEF. */ void execute_macro (def) MACRO_DEF *def; { char **arglist; int num_args; char *execution_string = (char *)NULL; if (macro_expansion_output_stream && !executing_string && !me_inhibit_expansion) me_append_before_this_command (); /* Find out how many arguments this macro definition takes. */ num_args = array_len (def->arglist); /* Gather the arguments present on the line if there are any. */ arglist = get_macro_args (def); if (num_args < array_len (arglist)) { free_array (arglist); line_error (_("Macro `%s' called with too many args"), def->name); return; } if (def->body) execution_string = apply (def->arglist, arglist, def->body); free_array (arglist); if (def->body) { if (macro_expansion_output_stream && !executing_string && !me_inhibit_expansion) { remember_itext (input_text, input_text_offset); me_execute_string (execution_string); } else execute_string ("%s", execution_string); free (execution_string); } } /* Read and remember the definition of a macro. */ void cm_macro () { register int i; char *name, **arglist, *body, *line; int body_size, body_index; int depth = 1; int defining_line = line_number; int flags = 0; arglist = (char **)NULL; body = (char *)NULL; body_size = 0; body_index = 0; if (macro_expansion_output_stream && !executing_string) me_append_before_this_command (); skip_whitespace (); /* Get the name of the macro. This is the set of characters which are not whitespace and are not `{' immediately following the @macro. */ { int start = input_text_offset; int len; for (i = start; (i < size_of_input_text) && (input_text[i] != '{') && (!cr_or_whitespace (input_text[i])); i++); len = i - start; name = (char *)xmalloc (1 + len); strncpy (name, input_text + start, len); name[len] = 0; input_text_offset = i; } skip_whitespace (); /* It is not required that the definition of a macro includes an arglist. If not, don't try to get the named parameters, just use a null list. */ if (curchar () == '{') { int arglist_index = 0, arglist_size = 0; int gathering_words = 1; char *word = (char *)NULL; int character; /* Read the words inside of the braces which determine the arglist. These words will be replaced within the body of the macro at execution time. */ input_text_offset++; skip_whitespace_and_newlines (); while (gathering_words) { int len; for (i = input_text_offset; (character = input_text[i]); i++) { switch (character) { case '\n': line_number++; case ' ': case '\t': case ',': case '}': /* Found the end of the current arglist word. Save it. */ len = i - input_text_offset; word = (char *)xmalloc (1 + len); strncpy (word, input_text + input_text_offset, len); word[len] = 0; input_text_offset = i; /* Advance to the comma or close-brace that signified the end of the argument. */ while ((character = curchar ()) && character != ',' && character != '}') { input_text_offset++; if (character == '\n') line_number++; } /* Add the word to our list of words. */ if ((arglist_index + 2) >= arglist_size) arglist = (char **)xrealloc (arglist, (arglist_size += 10) * sizeof (char *)); arglist[arglist_index++] = word; arglist[arglist_index] = (char *)NULL; break; } if (character == '}') { input_text_offset++; gathering_words = 0; break; } if (character == ',') { input_text_offset++; skip_whitespace_and_newlines (); i = input_text_offset - 1; } } } } /* Read the text carefully until we find an "@end macro" which matches this one. The text in between is the body of the macro. */ skip_whitespace_and_newlines (); while (depth) { if ((input_text_offset + 9) > size_of_input_text) { int temp_line = line_number; line_number = defining_line; line_error (_("%cend macro not found"), COMMAND_PREFIX); line_number = temp_line; return; } get_rest_of_line (&line); /* Handle commands only meaningful within a macro. */ if ((*line == COMMAND_PREFIX) && (depth == 1) && (strncmp (line + 1, "allow-recursion", 15) == 0) && (line[16] == 0 || whitespace (line[16]))) { for (i = 16; whitespace (line[i]); i++); strcpy (line, line + i); flags |= ME_RECURSE; if (!*line) { free (line); continue; } } if ((*line == COMMAND_PREFIX) && (depth == 1) && (strncmp (line + 1, "quote-arg", 9) == 0) && (line[10] == 0 || whitespace (line[10]))) { for (i = 10; whitespace (line[i]); i++); strcpy (line, line + i); if (arglist && arglist[0] && !arglist[1]) { flags |= ME_QUOTE_ARG; if (!*line) { free (line); continue; } } else { line_error (_("%cquote-arg only useful when the macro takes a single argument"), COMMAND_PREFIX); } } if ((*line == COMMAND_PREFIX) && (strncmp (line + 1, "macro ", 6) == 0)) depth++; if ((*line == COMMAND_PREFIX) && (strncmp (line + 1, "end macro", 9) == 0)) depth--; if (depth) { if ((body_index + strlen (line) + 3) >= body_size) body = (char *)xrealloc (body, body_size += 3 + strlen (line)); strcpy (body + body_index, line); body_index += strlen (line); body[body_index++] = '\n'; body[body_index] = 0; } free (line); } /* If it was an empty macro like @macro foo @end macro create an empty body. (Otherwise, the macro is not expanded.) */ if (!body) { body = (char *)malloc(1); *body = 0; } /* We now have the name, the arglist, and the body. However, BODY includes the final newline which preceded the `@end macro' text. Delete it. */ if (body && strlen (body)) body[strlen (body) - 1] = 0; add_macro (name, arglist, body, input_filename, defining_line, flags); if (macro_expansion_output_stream && !executing_string) remember_itext (input_text, input_text_offset); } void cm_unmacro () { register int i; char *line, *name; MACRO_DEF *def; if (macro_expansion_output_stream && !executing_string) me_append_before_this_command (); get_rest_of_line (&line); for (i = 0; line[i] && !whitespace (line[i]); i++); name = (char *)xmalloc (i + 1); strncpy (name, line, i); name[i] = 0; def = delete_macro (name); if (def) { free (def->source_file); free (def->name); free (def->body); if (def->arglist) { register int i; for (i = 0; def->arglist[i]; i++) free (def->arglist[i]); free (def->arglist); } free (def); } free (line); free (name); if (macro_expansion_output_stream && !executing_string) remember_itext (input_text, input_text_offset); } /* How to output sections of the input file verbatim. */ /* Set the value of POINTER's offset to OFFSET. */ ITEXT * remember_itext (pointer, offset) char *pointer; int offset; { register int i; ITEXT *itext = (ITEXT *)NULL; /* If we have no info, initialize a blank list. */ if (!itext_info) { itext_info = (ITEXT **)xmalloc ((itext_size = 10) * sizeof (ITEXT *)); for (i = 0; i < itext_size; i++) itext_info[i] = (ITEXT *)NULL; } /* If the pointer is already present in the list, then set the offset. */ for (i = 0; i < itext_size; i++) if ((itext_info[i] != (ITEXT *)NULL) && (itext_info[i]->pointer == pointer)) { itext = itext_info[i]; itext_info[i]->offset = offset; break; } if (i == itext_size) { /* Find a blank slot (or create a new one), and remember the pointer and offset. */ for (i = 0; i < itext_size; i++) if (itext_info[i] == (ITEXT *)NULL) break; /* If not found, then add some slots. */ if (i == itext_size) { register int j; itext_info = (ITEXT **)xrealloc (itext_info, (itext_size += 10) * sizeof (ITEXT *)); for (j = i; j < itext_size; j++) itext_info[j] = (ITEXT *)NULL; } /* Now add the pointer and the offset. */ itext_info[i] = (ITEXT *)xmalloc (sizeof (ITEXT)); itext_info[i]->pointer = pointer; itext_info[i]->offset = offset; itext = itext_info[i]; } return (itext); } /* Forget the input text associated with POINTER. */ void forget_itext (pointer) char *pointer; { register int i; for (i = 0; i < itext_size; i++) if (itext_info[i] && (itext_info[i]->pointer == pointer)) { free (itext_info[i]); itext_info[i] = (ITEXT *)NULL; break; } } /* Append the text which appeared in input_text from the last offset to the character just before the command that we are currently executing. */ void me_append_before_this_command () { register int i; for (i = input_text_offset; i && (input_text[i] != COMMAND_PREFIX); i--); maybe_write_itext (input_text, i); } /* Similar to execute_string (), but only takes a single string argument, and remembers the input text location, etc. */ void me_execute_string (execution_string) char *execution_string; { pushfile (); input_text_offset = 0; input_text = execution_string; input_filename = xstrdup (input_filename); size_of_input_text = strlen (execution_string); remember_itext (execution_string, 0); me_executing_string++; reader_loop (); popfile (); me_executing_string--; } /* Append the text which appears in input_text from the last offset to the current OFFSET. */ void append_to_expansion_output (offset) int offset; { register int i; ITEXT *itext = (ITEXT *)NULL; for (i = 0; i < itext_size; i++) if (itext_info[i] && itext_info[i]->pointer == input_text) { itext = itext_info[i]; break; } if (!itext) return; if (offset > itext->offset) { write_region_to_macro_output (input_text, itext->offset, offset); remember_itext (input_text, offset); } } /* Only write this input text iff it appears in our itext list. */ void maybe_write_itext (pointer, offset) char *pointer; int offset; { register int i; ITEXT *itext = (ITEXT *)NULL; for (i = 0; i < itext_size; i++) if (itext_info[i] && (itext_info[i]->pointer == pointer)) { itext = itext_info[i]; break; } if (itext && (itext->offset < offset)) { write_region_to_macro_output (itext->pointer, itext->offset, offset); remember_itext (pointer, offset); } } void write_region_to_macro_output (string, start, end) char *string; int start, end; { if (macro_expansion_output_stream) fwrite (string + start, 1, end - start, macro_expansion_output_stream); } #endif /* HAVE_MACROS */ /* Return the length of the array in ARRAY. */ int array_len (array) char **array; { register int i = 0; if (array) for (i = 0; array[i] != (char *)NULL; i++); return (i); } void free_array (array) char **array; { if (array) { register int i; for (i = 0; array[i] != (char *)NULL; i++) free (array[i]); free (array); } } /* Function is used even when we don't have macros. Although, I have to admit, it is unlikely that you would have a use for it if you aren't using macros. */ char ** get_brace_args (quote_single) int quote_single; { char **arglist, *word; int arglist_index, arglist_size; int character, escape_seen, start; int depth = 1; /* There is an arglist in braces here, so gather the args inside of it. */ skip_whitespace_and_newlines (); input_text_offset++; arglist = (char **)NULL; arglist_index = arglist_size = 0; get_arg: skip_whitespace_and_newlines (); start = input_text_offset; escape_seen = 0; while ((character = curchar ())) { if (character == '\\') { input_text_offset += 2; escape_seen = 1; } else if (character == '{') { depth++; input_text_offset++; } else if ((character == ',' && !quote_single) || ((character == '}') && depth == 1)) { int len = input_text_offset - start; if (len || (character != '}')) { word = (char *)xmalloc (1 + len); strncpy (word, input_text + start, len); word[len] = 0; /* Clean up escaped characters. */ if (escape_seen) { register int i; for (i = 0; word[i]; i++) if (word[i] == '\\') memmove (word + i, word + i + 1, 1 + strlen (word + i + 1)); } if (arglist_index + 2 >= arglist_size) arglist = (char **)xrealloc (arglist, (arglist_size += 10) * sizeof (char *)); arglist[arglist_index++] = word; arglist[arglist_index] = (char *)NULL; } input_text_offset++; if (character == '}') break; else goto get_arg; } else if (character == '}') { depth--; input_text_offset++; } else { input_text_offset++; if (character == '\n') line_number++; } } return (arglist); } /* **************************************************************** */ /* */ /* Looking For Include Files */ /* */ /* **************************************************************** */ /* Given a string containing units of information separated by colons, return the next one pointed to by INDEX, or NULL if there are no more. Advance INDEX to the character after the colon. */ char * extract_colon_unit (string, index) char *string; int *index; { int i, start; i = *index; if (!string || (i >= strlen (string))) return ((char *)NULL); /* Each call to this routine leaves the index pointing at a colon if there is more to the path. If I is > 0, then increment past the `:'. If I is 0, then the path has a leading colon. Trailing colons are handled OK by the `else' part of the if statement; an empty string is returned in that case. */ if (i && string[i] == ':') i++; start = i; while (string[i] && string[i] != ':') i++; *index = i; if (i == start) { if (string[i]) (*index)++; /* Return "" in the case of a trailing `:'. */ return (xstrdup ("")); } else { char *value; value = (char *)xmalloc (1 + (i - start)); strncpy (value, &string[start], (i - start)); value [i - start] = 0; return (value); } } /* Return the full pathname for FILENAME by searching along PATH. When found, return the stat () info for FILENAME in FINFO. If PATH is NULL, only the current directory is searched. If the file could not be found, return a NULL pointer. */ char * get_file_info_in_path (filename, path, finfo) char *filename, *path; struct stat *finfo; { char *dir; int result, index = 0; if (path == (char *)NULL) path = "."; /* Handle absolute pathnames. "./foo", "/foo", "../foo". */ if (*filename == '/' || (*filename == '.' && (filename[1] == '/' || (filename[1] == '.' && filename[2] == '/'))) #ifdef WIN32 /* Handle names that look like "d:/foo/bar" */ || (isalpha (*filename) && filename [1] == ':' && (filename [2] == '/' || filename [2] == '\\')) #endif ) { if (stat (filename, finfo) == 0) return (xstrdup (filename)); else return ((char *)NULL); } while ((dir = extract_colon_unit (path, &index))) { char *fullpath; if (!*dir) { free (dir); dir = xstrdup ("."); } fullpath = (char *)xmalloc (2 + strlen (dir) + strlen (filename)); sprintf (fullpath, "%s/%s", dir, filename); free (dir); result = stat (fullpath, finfo); if (result == 0) return (fullpath); else free (fullpath); } return NULL; } texinfo-3.12/makeinfo/README0000664000175000017500000000054706475365720013050 0ustar ggmakeinfo is a standalone program to convert Texinfo source into Info files readable with standalone info or M-x info in Emacs. makeinfo can also output plain ASCII. Work to support HTML and Troff output is almost complete. The Emacs function M-x texinfo-format-buffer does more or less the same job, but makeinfo is faster and gives better error messages. texinfo-3.12/makeinfo/makeinfo.h0000444000175000017500000001456006362740527014123 0ustar gg/* makeinfo.h -- Declarations for Makeinfo. $Id: makeinfo.h,v 1.3 1997/07/15 18:28:38 karl Exp $ Copyright (C) 1996, 97 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ /* Why, oh why, did I ever listen to rms when he said: "Don't make lots of small files, just make one big one!" I've regretted it ever since with this program, and with readline. bfox@ai.mit.edu Thu Jul 11 07:54:32 1996 */ #if !defined (MAKEINFO_H) #define MAKEINFO_H #if defined (COMPILING_MAKEINFO) # define DECLARE(type, var, init) type var = init #else # define DECLARE(type, var, init) extern type var #endif enum insertion_type { cartouche, defcv, deffn, defivar, defmac, defmethod, defop, defopt, defspec, deftp, deftypefn, deftypefun, deftypemethod, deftypevar, deftypevr, defun, defvar, defvr, detailmenu, direntry, display, enumerate, example, flushleft, flushright, format, ftable, group, ifclear, ifinfo, ifnothtml, ifnottex, ifset, itemize, lisp, menu, multitable, quotation, smallexample, smalllisp, table, vtable, bad_type }; DECLARE (int, insertion_level, 0); #if defined (COMPILING_MAKEINFO) char *insertion_type_names[] = { "cartouche", "defcv", "deffn", "defivar", "defmac", "defmethod", "defop", "defopt", "defspec", "deftp", "deftypefn", "deftypefun", "deftypemethod", "deftypevar", "deftypevr", "defun", "defvar", "defvr", "detailmenu", "direntry", "display", "enumerate", "example", "flushleft", "flushright", "format", "ftable", "group", "ifclear", "ifinfo", "ifnothtml", "ifnottex", "ifset", "itemize", "lisp", "menu", "multitable", "quotation", "smallexample", "smalllisp", "table", "vtable", "bad_type" }; #endif typedef struct istack_elt { struct istack_elt *next; char *item_function; char *filename; int line_number; int filling_enabled; int indented_fill; enum insertion_type insertion; int inhibited; int in_fixed_width_font; } INSERTION_ELT; DECLARE (INSERTION_ELT *, insertion_stack, (INSERTION_ELT *)NULL); /* Current output stream. */ DECLARE (FILE *, output_stream, (FILE *)NULL); /* Output paragraph buffer. */ DECLARE (unsigned char *, output_paragraph, (unsigned char *)NULL); /* Offset into OUTPUT_PARAGRAPH. */ DECLARE (int, output_paragraph_offset, 0); /* The output paragraph "cursor" horizontal position. */ DECLARE (int, output_column, 0); /* Non-zero means output_paragraph contains text. */ DECLARE (int, paragraph_is_open, 0); /* The amount of indentation to apply at the start of each line. */ DECLARE (int, current_indent, 0); /* nonzero if we are currently processing a multitable command */ DECLARE (int, multitable_active, 0); /* The column at which long lines are broken. */ DECLARE (int, fill_column, 72); /* The current input file state. */ DECLARE (char *, input_filename, (char *)NULL); DECLARE (char *, input_text, (char *)NULL); DECLARE (int, size_of_input_text, 0); DECLARE (int, input_text_offset, 0); DECLARE (int, line_number, 0); #define curchar() input_text[input_text_offset] /* **************************************************************** */ /* */ /* Global Defines */ /* */ /* **************************************************************** */ /* Error levels */ #define NO_ERROR 0 #define SYNTAX 2 #define FATAL 4 /* C's standard macros don't check to make sure that the characters being changed are within range. So I have to check explicitly. */ /* GNU Library doesn't have toupper(). Until GNU gets this fixed, I will have to do it. */ #ifndef toupper #define toupper(c) ((c) - 32) #endif #define coerce_to_upper(c) ((islower(c) ? toupper(c) : (c))) #define coerce_to_lower(c) ((isupper(c) ? tolower(c) : (c))) #define control_character_bit 0x40 /* %01000000, must be off. */ #define meta_character_bit 0x080/* %10000000, must be on. */ #define CTL(c) ((c) & (~control_character_bit)) #define UNCTL(c) coerce_to_upper(((c)|control_character_bit)) #define META(c) ((c) | (meta_character_bit)) #define UNMETA(c) ((c) & (~meta_character_bit)) #define whitespace(c) (((c) == '\t') || ((c) == ' ')) #define sentence_ender(c) ((c) == '.' || (c) == '?' || (c) == '!') #define cr_or_whitespace(c) (((c) == '\t') || ((c) == ' ') || ((c) == '\n')) #ifndef isletter #define isletter(c) (((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z')) #endif #ifndef isupper #define isupper(c) ((c) >= 'A' && (c) <= 'Z') #endif #ifndef isdigit #define isdigit(c) ((c) >= '0' && (c) <= '9') #endif #ifndef digit_value #define digit_value(c) ((c) - '0') #endif #define member(c, s) (strchr (s, c) != NULL) #define COMMAND_PREFIX '@' /* Stuff for splitting large files. */ #define SPLIT_SIZE_THRESHOLD 70000 /* What's good enough for Stallman... */ #define DEFAULT_SPLIT_SIZE 50000 /* Is probably good enough for me. */ DECLARE (int, splitting, 1); /* Defaults to true for now. */ typedef void COMMAND_FUNCTION (); /* So I can say COMMAND_FUNCTION *foo; */ #define command_char(c) ((!whitespace(c)) && \ ((c) != '\n') && \ ((c) != '{') && \ ((c) != '}') && \ ((c) != '=')) #define skip_whitespace() \ while ((input_text_offset != size_of_input_text) && \ whitespace (curchar())) \ input_text_offset++ #define skip_whitespace_and_newlines() \ do { \ while ((input_text_offset != size_of_input_text) && \ (whitespace (curchar ()) || (curchar () == '\n'))) \ { \ if (curchar () == '\n') \ line_number++; \ input_text_offset++; \ } \ } while (0) #endif /* !MAKEINFO_H */ texinfo-3.12/INTRODUCTION0000664000175000017500000001016206475624273012236 0ustar ggGetting Started with Texinfo ============================ "Texinfo" is a documentation system that uses a single source file to produce both on-line information and printed output. Using Texinfo, you can create a printed document with the normal features of a book, including chapters, sections, cross references, and indices. From the same Texinfo source file, you can create a menu-driven, on-line Info file with nodes, menus, cross references, and indices. The name of the Texinfo source documentation file is `texinfo.txi'. You can produce both on-line information and printed output from this source file. The documentation describes Texinfo in detail, including how to write Texinfo files, how to format them for both hard copy and Info, and how to install Info files. To get started, you need to create either a printed manual or an on-line Info file from the `texinfo.txi' file. You do not need to create both, although you will probably want both eventually. To learn how to use Info, read the info documentation. You can do this in one of two ways: using the standalone `info' program, or using Info mode in GNU Emacs. * If you want to use the `info' program, run info -f info-stnd * If you want to use Emacs, start up emacs and type `C-h i' [M-x info]. Follow the instructions to learn how to use Info. After learning how to use Info, you can read the Texinfo documentation. Using the standalone `info', type the following at the shell prompt: info -f texinfo To use read this manual in Emacs, you first need to edit the Info-directory menu (the file `dir' in the system info directory) to contain the appropriate node. To learn how to do this, see node: Add in the Info documentation. The Texinfo documentation describes Texinfo in detail; among other things, it tells how to install Info files in the usual manner. (See node: Install an Info File.) The `info-stnd.info' file describes the standalone Info reader in detail. To read this file, type $ info -f info-stnd If you are using GNU Emacs, you may want to install the Emacs Lisp files permanently. Move them them to a directory in the load-path for Emacs; otherwise Emacs will not be able to load the autoloaded support files, such as `texinfmt.el'. The `texinfo.el' file contains the autoload commands; it is the only file that needs to be loaded initially. If your Emacs does not automatically load `texinfo.el', you can tell it to do so by placing the following in `default.el' or in your `.emacs' file: (load "texinfo") To create a printed manual ========================== You need: * The `tex' program, which typesets the manual using TeX. * The `texinfo.tex' definition file that tells TeX how to typeset a Texinfo file. * The `texindex' program, which sorts the unsorted index files created by TeX. * A printing program such as `lp' or `lpr', * A printer. This Texinfo distribution package contains `texinfo.tex', the C source for `texindex', and the handy shell script `texi2dvi'. The `tex' program is not part of this distribution, but is available separately. (See `How to Obtain TeX' in the Texinfo documentation.) * Install `tex'. (`texindex' is installed automagically by `make install' in this distribution.) * Move the `texinfo.tex' file to an appropriate directory; the current directory will do. (`/usr/local/lib/tex/inputs' might be a good place. See ``Preparing to Use TeX'' in the Texinfo manual, for more information.) After following those instructions, type the following to make the .dvi files: $ make texinfo.dvi $ (cd info; make info.dvi info-stnd.dvi) $ (cd makeinfo; make makeinfo.dvi) You can then print the resulting .dvi files with the `lpr' command (on BSD systems. On SysV systems the command is `lp'. Consult your man pages for more information). For example, the command to print the texinfo.dvi file might be: $ lpr -d texinfo.dvi The name of the printing command depends on the system; `lpr -d' is common, and is illustrated here. You may use a different name for the printing command. Please report bugs to bug-texinfo@gnu.org. Happy formatting. texinfo-3.12/stamp-h.in0000664000175000017500000000001206477046124012257 0ustar ggtimestamp texinfo-3.12/Makefile.am0000444000175000017500000000113206475357704012421 0ustar gg## Makefile.am for texinfo. ## $Id: Makefile.am,v 1.9 1998/02/26 21:33:56 karl Exp $ ## Process this file with automake to produce Makefile.in in all directories. # Be sure we're using the right version of Automake. # 1.2f was the first version that supported .txi as a Texinfo suffix. AUTOMAKE_OPTIONS = 1.2f # Additional files to distribute. EXTRA_DIST = INTRODUCTION dir-example # All subdirectories. # Do intl/ and lib/ first since the C programs depend on them. # Do doc/ last so makeinfo will be built when we get there. # Others are alphabetical. SUBDIRS = intl lib info makeinfo po util doc texinfo-3.12/ORIGIN0000644000175000017500000000053013751602722011266 0ustar ggMakefile.in was edited to allow upload of this file, due to the following error: file rejected: texinfo-3.12.tar.gz contains a vulnerable Makefile.in CVE-2009-4029 Regenerate it with automake 1.11.6 / 1.12.2 or newer. The original file is identifiable with $ md5sum texinfo-3.12.tar.gz 731f0955cdaa5260d0f81053576a6482 texinfo-3.12.tar.gz texinfo-3.12/info/0000775000175000017500000000000006477056751011327 5ustar ggtexinfo-3.12/info/display.h0000444000175000017500000000562706362741551013143 0ustar gg/* display.h -- How the display in Info is done. $Id: display.h,v 1.2 1997/07/15 18:37:29 karl Exp $ This file is part of GNU Info, a program for reading online documentation stored in Info format. Copyright (C) 1993, 97 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ #ifndef INFO_DISPLAY_H #define INFO_DISPLAY_H #include "info-utils.h" #include "terminal.h" typedef struct { char *text; /* Text of the line as it appears. */ int textlen; /* Printable Length of TEXT. */ int inverse; /* Non-zero means this line is inverse. */ } DISPLAY_LINE; /* An array of display lines which tell us what is currently visible on the display. */ extern DISPLAY_LINE **the_display; /* Non-zero means do no output. */ extern int display_inhibited; /* Non-zero if we didn't completely redisplay a window. */ extern int display_was_interrupted_p; /* Initialize THE_DISPLAY to WIDTH and HEIGHT, with nothing in it. */ extern void display_initialize_display (); /* Clear all of the lines in DISPLAY making the screen blank. */ extern void display_clear_display (); /* Update the windows pointed to by WINDOWS in THE_DISPLAY. This actually writes the text on the screen. */ extern void display_update_display (); /* Display WIN on THE_DISPLAY. Unlike display_update_display (), this function only does one window. */ extern void display_update_one_window (); /* Move the screen cursor to directly over the current character in WINDOW. */ extern void display_cursor_at_point (); /* Scroll the region of the_display starting at START, ending at END, and moving the lines AMOUNT lines. If AMOUNT is less than zero, the lines are moved up in the screen, otherwise down. Actually, it is possible for no scrolling to take place in the case that the terminal doesn't support it. This doesn't matter to us. */ extern void display_scroll_display (); /* Try to scroll lines in WINDOW. OLD_PAGETOP is the pagetop of WINDOW before having had its line starts recalculated. OLD_STARTS is the list of line starts that used to appear in this window. OLD_COUNT is the number of lines that appear in the OLD_STARTS array. */ extern void display_scroll_line_starts (); #endif /* not INFO_DISPLAY_H */ texinfo-3.12/info/session.c0000444000175000017500000035601206474124350013145 0ustar gg/* session.c -- The user windowing interface to Info. $Id: session.c,v 1.13 1998/02/22 22:38:30 karl Exp $ Copyright (C) 1993, 96, 97 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ #include "info.h" #include #if defined (HAVE_SYS_TIME_H) # include # define HAVE_STRUCT_TIMEVAL #endif /* HAVE_SYS_TIME_H */ #if defined (HANDLE_MAN_PAGES) # include "man.h" #endif static void info_clear_pending_input (), info_set_pending_input (); static void info_handle_pointer (); /* **************************************************************** */ /* */ /* Running an Info Session */ /* */ /* **************************************************************** */ /* The place that we are reading input from. */ static FILE *info_input_stream = NULL; /* The last executed command. */ VFunction *info_last_executed_command = NULL; /* Becomes non-zero when 'q' is typed to an Info window. */ int quit_info_immediately = 0; /* Array of structures describing for each window which nodes have been visited in that window. */ INFO_WINDOW **info_windows = NULL; /* Where to add the next window, if we need to add one. */ static int info_windows_index = 0; /* Number of slots allocated to `info_windows'. */ static int info_windows_slots = 0; void remember_window_and_node (), forget_window_and_nodes (); void initialize_info_session (), info_session (); void display_startup_message_and_start (); /* Begin an info session finding the nodes specified by FILENAME and NODENAMES. For each loaded node, create a new window. Always split the largest of the available windows. */ void begin_multiple_window_info_session (filename, nodenames) char *filename; char **nodenames; { register int i; WINDOW *window = (WINDOW *)NULL; for (i = 0; nodenames[i]; i++) { NODE *node; node = info_get_node (filename, nodenames[i]); if (!node) break; /* If this is the first node, initialize the info session. */ if (!window) { initialize_info_session (node, 1); window = active_window; } else { /* Find the largest window in WINDOWS, and make that be the active one. Then split it and add our window and node to the list of remembered windows and nodes. Then tile the windows. */ register WINDOW *win, *largest = (WINDOW *)NULL; int max_height = 0; for (win = windows; win; win = win->next) if (win->height > max_height) { max_height = win->height; largest = win; } if (!largest) { display_update_display (windows); info_error (CANT_FIND_WIND); info_session (); exit (0); } active_window = largest; window = window_make_window (node); if (window) { window_tile_windows (TILE_INTERNALS); remember_window_and_node (window, node); } else { display_update_display (windows); info_error (WIN_TOO_SMALL); info_session (); exit (0); } } } display_startup_message_and_start (); } /* Start an info session with INITIAL_NODE, and an error message in the echo area made from FORMAT and ARG. */ void begin_info_session_with_error (initial_node, format, arg) NODE *initial_node; char *format; void *arg; { initialize_info_session (initial_node, 1); info_error (format, arg, (void *)NULL); info_session (); } /* Start an info session with INITIAL_NODE. */ void begin_info_session (initial_node) NODE *initial_node; { initialize_info_session (initial_node, 1); display_startup_message_and_start (); } void display_startup_message_and_start () { char *format; format = replace_in_documentation (_("Welcome to Info version %s. \"\\[get-help-window]\" for help, \"\\[menu-item]\" for menu item.")); window_message_in_echo_area (format, version_string ()); info_session (); } /* Run an info session with an already initialized window and node. */ void info_session () { display_update_display (windows); info_last_executed_command = NULL; info_read_and_dispatch (); /* On program exit, leave the cursor at the bottom of the window, and restore the terminal I/O. */ terminal_goto_xy (0, screenheight - 1); terminal_clear_to_eol (); fflush (stdout); terminal_unprep_terminal (); close_dribble_file (); } /* Here is a window-location dependent event loop. Called from the functions info_session (), and from read_xxx_in_echo_area (). */ void info_read_and_dispatch () { unsigned char key; int done; done = 0; while (!done && !quit_info_immediately) { int lk; /* If we haven't just gone up or down a line, there is no goal column for this window. */ if ((info_last_executed_command != info_next_line) && (info_last_executed_command != info_prev_line)) active_window->goal_column = -1; if (echo_area_is_active) { lk = echo_area_last_command_was_kill; echo_area_prep_read (); } if (!info_any_buffered_input_p ()) display_update_display (windows); display_cursor_at_point (active_window); info_initialize_numeric_arg (); initialize_keyseq (); key = info_get_input_char (); /* No errors yet. We just read a character, that's all. Only clear the echo_area if it is not currently active. */ if (!echo_area_is_active) window_clear_echo_area (); info_error_was_printed = 0; /* Do the selected command. */ info_dispatch_on_key (key, active_window->keymap); if (echo_area_is_active) { /* Echo area commands that do killing increment the value of ECHO_AREA_LAST_COMMAND_WAS_KILL. Thus, if there is no change in the value of this variable, the last command executed was not a kill command. */ if (lk == echo_area_last_command_was_kill) echo_area_last_command_was_kill = 0; if (ea_last_executed_command == ea_newline || info_aborted_echo_area) { ea_last_executed_command = (VFunction *)NULL; done = 1; } if (info_last_executed_command == info_quit) quit_info_immediately = 1; } else if (info_last_executed_command == info_quit) done = 1; } } /* Found in signals.c */ extern void initialize_info_signal_handler (); /* Initialize the first info session by starting the terminal, window, and display systems. If CLEAR_SCREEN is 0, don't clear the screen. */ void initialize_info_session (node, clear_screen) NODE *node; int clear_screen; { char *term_name = getenv ("TERM"); terminal_initialize_terminal (term_name); if (terminal_is_dumb_p) { if (!term_name) term_name = "dumb"; info_error (TERM_TOO_DUMB, term_name); exit (1); } if (clear_screen) { terminal_prep_terminal (); terminal_clear_screen (); } initialize_info_keymaps (); window_initialize_windows (screenwidth, screenheight); initialize_info_signal_handler (); display_initialize_display (screenwidth, screenheight); info_set_node_of_window (active_window, node); /* Tell the window system how to notify us when a window needs to be asynchronously deleted (e.g., user resizes window very small). */ window_deletion_notifier = forget_window_and_nodes; /* If input has not been redirected yet, make it come from unbuffered standard input. */ if (!info_input_stream) { setbuf(stdin, NULL); info_input_stream = stdin; } info_windows_initialized_p = 1; } /* Tell Info that input is coming from the file FILENAME. */ void info_set_input_from_file (filename) char *filename; { FILE *stream; stream = fopen (filename, "r"); if (!stream) return; if ((info_input_stream != (FILE *)NULL) && (info_input_stream != stdin)) fclose (info_input_stream); info_input_stream = stream; if (stream != stdin) display_inhibited = 1; } /* Return the INFO_WINDOW containing WINDOW, or NULL if there isn't one. */ static INFO_WINDOW * get_info_window_of_window (window) WINDOW *window; { register int i; INFO_WINDOW *info_win = (INFO_WINDOW *)NULL; for (i = 0; info_windows && (info_win = info_windows[i]); i++) if (info_win->window == window) break; return (info_win); } /* Reset the remembered pagetop and point of WINDOW to WINDOW's current values if the window and node are the same as the current one being displayed. */ void set_remembered_pagetop_and_point (window) WINDOW *window; { INFO_WINDOW *info_win; info_win = get_info_window_of_window (window); if (!info_win) return; if (info_win->nodes_index && (info_win->nodes[info_win->current] == window->node)) { info_win->pagetops[info_win->current] = window->pagetop; info_win->points[info_win->current] = window->point; } } void remember_window_and_node (window, node) WINDOW *window; NODE *node; { /* See if we already have this window in our list. */ INFO_WINDOW *info_win = get_info_window_of_window (window); /* If the window wasn't already on our list, then make a new entry. */ if (!info_win) { info_win = (INFO_WINDOW *)xmalloc (sizeof (INFO_WINDOW)); info_win->window = window; info_win->nodes = (NODE **)NULL; info_win->pagetops = (int *)NULL; info_win->points = (long *)NULL; info_win->current = 0; info_win->nodes_index = 0; info_win->nodes_slots = 0; add_pointer_to_array (info_win, info_windows_index, info_windows, info_windows_slots, 10, INFO_WINDOW *); } /* If this node, the current pagetop, and the current point are the same as the current saved node and pagetop, don't really add this to the list of history nodes. This may happen only at the very beginning of the program, I'm not sure. --karl */ if (info_win->nodes && info_win->current >= 0 && info_win->nodes[info_win->current]->contents == node->contents && info_win->pagetops[info_win->current] == window->pagetop && info_win->points[info_win->current] == window->point) return; /* Remember this node, the currently displayed pagetop, and the current location of point in this window. Because we are updating pagetops and points as well as nodes, it is more efficient to avoid the add_pointer_to_array macro here. */ if (info_win->nodes_index + 2 >= info_win->nodes_slots) { info_win->nodes_slots += 20; info_win->nodes = (NODE **) xrealloc (info_win->nodes, info_win->nodes_slots * sizeof (NODE *)); info_win->pagetops = (int *) xrealloc (info_win->pagetops, info_win->nodes_slots * sizeof (int)); info_win->points = (long *) xrealloc (info_win->points, info_win->nodes_slots * sizeof (long)); } info_win->nodes[info_win->nodes_index] = node; info_win->pagetops[info_win->nodes_index] = window->pagetop; info_win->points[info_win->nodes_index] = window->point; info_win->current = info_win->nodes_index++; info_win->nodes[info_win->nodes_index] = NULL; info_win->pagetops[info_win->nodes_index] = 0; info_win->points[info_win->nodes_index] = 0; } #define DEBUG_FORGET_WINDOW_AND_NODES #if defined (DEBUG_FORGET_WINDOW_AND_NODES) static void consistency_check_info_windows () { register int i; for (i = 0; i < info_windows_index; i++) { WINDOW *win; for (win = windows; win; win = win->next) if (win == info_windows[i]->window) break; if (!win) abort (); } } #endif /* DEBUG_FORGET_WINDOW_AND_NODES */ /* Remove WINDOW and its associated list of nodes from INFO_WINDOWS. */ void forget_window_and_nodes (window) WINDOW *window; { register int i; INFO_WINDOW *info_win = (INFO_WINDOW *)NULL; for (i = 0; info_windows && (info_win = info_windows[i]); i++) if (info_win->window == window) break; /* If we found the window to forget, then do so. */ if (info_win) { while (i < info_windows_index) { info_windows[i] = info_windows[i + 1]; i++; } info_windows_index--; info_windows[info_windows_index] = (INFO_WINDOW *)NULL; if (info_win->nodes) { /* Free the node structures which held onto internal node contents here. This doesn't free the contents; we have a garbage collector which does that. */ for (i = 0; info_win->nodes[i]; i++) if (internal_info_node_p (info_win->nodes[i])) free (info_win->nodes[i]); free (info_win->nodes); maybe_free (info_win->pagetops); maybe_free (info_win->points); } free (info_win); } #if defined (DEBUG_FORGET_WINDOW_AND_NODES) consistency_check_info_windows (); #endif /* DEBUG_FORGET_WINDOW_AND_NODES */ } /* Set WINDOW to show NODE. Remember the new window in our list of Info windows. If we are doing automatic footnote display, also try to display the footnotes for this window. */ void info_set_node_of_window (window, node) WINDOW *window; NODE *node; { /* Put this node into the window. */ window_set_node_of_window (window, node); /* Remember this node and window in our list of info windows. */ remember_window_and_node (window, node); /* If doing auto-footnote display/undisplay, show the footnotes belonging to this window's node. */ if (auto_footnotes_p) info_get_or_remove_footnotes (window); } /* **************************************************************** */ /* */ /* Info Movement Commands */ /* */ /* **************************************************************** */ /* Change the pagetop of WINDOW to DESIRED_TOP, perhaps scrolling the screen to do so. */ void set_window_pagetop (window, desired_top) WINDOW *window; int desired_top; { int point_line, old_pagetop; if (desired_top < 0) desired_top = 0; else if (desired_top > window->line_count) desired_top = window->line_count - 1; if (window->pagetop == desired_top) return; old_pagetop = window->pagetop; window->pagetop = desired_top; /* Make sure that point appears in this window. */ point_line = window_line_of_point (window); if ((point_line < window->pagetop) || ((point_line - window->pagetop) > window->height - 1)) window->point = window->line_starts[window->pagetop] - window->node->contents; window->flags |= W_UpdateWindow; /* Find out which direction to scroll, and scroll the window in that direction. Do this only if there would be a savings in redisplay time. This is true if the amount to scroll is less than the height of the window, and if the number of lines scrolled would be greater than 10 % of the window's height. */ if (old_pagetop < desired_top) { int start, end, amount; amount = desired_top - old_pagetop; if ((amount >= window->height) || (((window->height - amount) * 10) < window->height)) return; start = amount + window->first_row; end = window->height + window->first_row; display_scroll_display (start, end, -amount); } else { int start, end, amount; amount = old_pagetop - desired_top; if ((amount >= window->height) || (((window->height - amount) * 10) < window->height)) return; start = window->first_row; end = (window->first_row + window->height) - amount; display_scroll_display (start, end, amount); } } /* Immediately make WINDOW->point visible on the screen, and move the terminal cursor there. */ static void info_show_point (window) WINDOW *window; { int old_pagetop; old_pagetop = window->pagetop; window_adjust_pagetop (window); if (old_pagetop != window->pagetop) { int new_pagetop; new_pagetop = window->pagetop; window->pagetop = old_pagetop; set_window_pagetop (window, new_pagetop); } if (window->flags & W_UpdateWindow) display_update_one_window (window); display_cursor_at_point (window); } /* Move WINDOW->point from OLD line index to NEW line index. */ static void move_to_new_line (old, new, window) int old, new; WINDOW *window; { if (old == -1) { info_error (CANT_FIND_POINT); } else { int goal; if (new >= window->line_count || new < 0) return; goal = window_get_goal_column (window); window->goal_column = goal; window->point = window->line_starts[new] - window->node->contents; window->point += window_chars_to_goal (window->line_starts[new], goal); info_show_point (window); } } /* Move WINDOW's point down to the next line if possible. */ DECLARE_INFO_COMMAND (info_next_line, _("Move down to the next line")) { int old_line, new_line; if (count < 0) info_prev_line (window, -count, key); else { old_line = window_line_of_point (window); new_line = old_line + count; move_to_new_line (old_line, new_line, window); } } /* Move WINDOW's point up to the previous line if possible. */ DECLARE_INFO_COMMAND (info_prev_line, _("Move up to the previous line")) { int old_line, new_line; if (count < 0) info_next_line (window, -count, key); else { old_line = window_line_of_point (window); new_line = old_line - count; move_to_new_line (old_line, new_line, window); } } /* Move WINDOW's point to the end of the true line. */ DECLARE_INFO_COMMAND (info_end_of_line, _("Move to the end of the line")) { register int point, len; register char *buffer; buffer = window->node->contents; len = window->node->nodelen; for (point = window->point; (point < len) && (buffer[point] != '\n'); point++); if (point != window->point) { window->point = point; info_show_point (window); } } /* Move WINDOW's point to the beginning of the true line. */ DECLARE_INFO_COMMAND (info_beginning_of_line, _("Move to the start of the line")) { register int point; register char *buffer; buffer = window->node->contents; point = window->point; for (; (point) && (buffer[point - 1] != '\n'); point--); /* If at a line start alreay, do nothing. */ if (point != window->point) { window->point = point; info_show_point (window); } } /* Move point forward in the node. */ DECLARE_INFO_COMMAND (info_forward_char, _("Move forward a character")) { if (count < 0) info_backward_char (window, -count, key); else { window->point += count; if (window->point >= window->node->nodelen) window->point = window->node->nodelen - 1; info_show_point (window); } } /* Move point backward in the node. */ DECLARE_INFO_COMMAND (info_backward_char, _("Move backward a character")) { if (count < 0) info_forward_char (window, -count, key); else { window->point -= count; if (window->point < 0) window->point = 0; info_show_point (window); } } #define alphabetic(c) (islower (c) || isupper (c) || isdigit (c)) /* Move forward a word in this node. */ DECLARE_INFO_COMMAND (info_forward_word, _("Move forward a word")) { long point; char *buffer; int end, c; if (count < 0) { info_backward_word (window, -count, key); return; } point = window->point; buffer = window->node->contents; end = window->node->nodelen; while (count) { if (point + 1 >= end) return; /* If we are not in a word, move forward until we are in one. Then, move forward until we hit a non-alphabetic character. */ c = buffer[point]; if (!alphabetic (c)) { while (++point < end) { c = buffer[point]; if (alphabetic (c)) break; } } if (point >= end) return; while (++point < end) { c = buffer[point]; if (!alphabetic (c)) break; } --count; } window->point = point; info_show_point (window); } DECLARE_INFO_COMMAND (info_backward_word, _("Move backward a word")) { long point; char *buffer; int c; if (count < 0) { info_forward_word (window, -count, key); return; } buffer = window->node->contents; point = window->point; while (count) { if (point == 0) break; /* Like info_forward_word (), except that we look at the characters just before point. */ c = buffer[point - 1]; if (!alphabetic (c)) { while (--point) { c = buffer[point - 1]; if (alphabetic (c)) break; } } while (point) { c = buffer[point - 1]; if (!alphabetic (c)) break; else --point; } --count; } window->point = point; info_show_point (window); } /* Here is a list of time counter names which correspond to ordinal numbers. It is used to print "once" instead of "1". */ static char *counter_names[] = { "not at all", "once", "twice", "three", "four", "five", "six", (char *)NULL }; /* Buffer used to return values from times_description (). */ static char td_buffer[50]; /* Function returns a static string fully describing the number of times present in COUNT. */ static char * times_description (count) int count; { register int i; td_buffer[0] = '\0'; for (i = 0; counter_names[i]; i++) if (count == i) break; if (counter_names[i]) sprintf (td_buffer, "%s%s", counter_names[i], count > 2 ? _(" times") : ""); else sprintf (td_buffer, _("%d times"), count); return (td_buffer); } /* Variable controlling the behaviour of default scrolling when you are already at the bottom of a node. Possible values are defined in session.h. The meanings are: IS_Continuous Try to get first menu item, or failing that, the "Next:" pointer, or failing that, the "Up:" and "Next:" of the up. IS_NextOnly Try to get "Next:" menu item. IS_PageOnly Simply give up at the bottom of a node. */ int info_scroll_behaviour = IS_Continuous; /* Choices used by the completer when reading a value for the user-visible variable "scroll-behaviour". */ char *info_scroll_choices[] = { "Continuous", "Next Only", "Page Only", (char *)NULL }; /* Move to 1st menu item, Next, Up/Next, or error in this window. */ static void forward_move_node_structure (window, behaviour) WINDOW *window; int behaviour; { switch (behaviour) { case IS_PageOnly: info_error (AT_NODE_BOTTOM); break; case IS_NextOnly: info_next_label_of_node (window->node); if (!info_parsed_nodename && !info_parsed_filename) info_error (_("No \"Next\" pointer for this node.")); else { window_message_in_echo_area (_("Following \"Next\" node...")); info_handle_pointer (_("Next"), window); } break; case IS_Continuous: { /* First things first. If this node contains a menu, move down into the menu. */ { REFERENCE **menu; menu = info_menu_of_node (window->node); if (menu) { info_free_references (menu); window_message_in_echo_area (_("Selecting first menu item...")); info_menu_digit (window, 1, '1'); return; } } /* Okay, this node does not contain a menu. If it contains a "Next:" pointer, use that. */ info_next_label_of_node (window->node); if (info_label_was_found) { window_message_in_echo_area (_("Selecting \"Next\" node...")); info_handle_pointer (_("Next"), window); return; } /* Okay, there wasn't a "Next:" for this node. Move "Up:" until we can move "Next:". If that isn't possible, complain that there are no more nodes. */ { int up_counter, old_current; INFO_WINDOW *info_win; /* Remember the current node and location. */ info_win = get_info_window_of_window (window); old_current = info_win->current; /* Back up through the "Up:" pointers until we have found a "Next:" that isn't the same as the first menu item found in that node. */ up_counter = 0; while (!info_error_was_printed) { info_up_label_of_node (window->node); if (info_label_was_found) { info_handle_pointer (_("Up"), window); if (info_error_was_printed) continue; up_counter++; info_next_label_of_node (window->node); /* If no "Next" pointer, keep backing up. */ if (!info_label_was_found) continue; /* If this node's first menu item is the same as this node's Next pointer, keep backing up. */ if (!info_parsed_filename) { REFERENCE **menu; char *next_nodename; /* Remember the name of the Next node, since reading the menu can overwrite the contents of the info_parsed_xxx strings. */ next_nodename = xstrdup (info_parsed_nodename); menu = info_menu_of_node (window->node); if (menu && (strcmp (menu[0]->nodename, next_nodename) == 0)) { info_free_references (menu); free (next_nodename); continue; } else { /* Restore the world to where it was before reading the menu contents. */ info_free_references (menu); free (next_nodename); info_next_label_of_node (window->node); } } /* This node has a "Next" pointer, and it is not the same as the first menu item found in this node. */ window_message_in_echo_area ("Moving \"Up\" %s, then \"Next\".", times_description (up_counter)); info_handle_pointer (_("Next"), window); return; } else { /* No more "Up" pointers. Print an error, and call it quits. */ register int i; for (i = 0; i < up_counter; i++) { info_win->nodes_index--; free (info_win->nodes[info_win->nodes_index]); info_win->nodes[info_win->nodes_index] = (NODE *)NULL; } info_win->current = old_current; window->node = info_win->nodes[old_current]; window->pagetop = info_win->pagetops[old_current]; window->point = info_win->points[old_current]; recalculate_line_starts (window); window->flags |= W_UpdateWindow; info_error (_("No more nodes.")); } } } break; } } } /* Move Prev, Up or error in WINDOW depending on BEHAVIOUR. */ static void backward_move_node_structure (window, behaviour) WINDOW *window; int behaviour; { switch (behaviour) { case IS_PageOnly: info_error (AT_NODE_TOP); break; case IS_NextOnly: info_prev_label_of_node (window->node); if (!info_parsed_nodename && !info_parsed_filename) info_error (_("No \"Prev\" for this node.")); else { window_message_in_echo_area (_("Moving \"Prev\" in this window.")); info_handle_pointer (_("Prev"), window); } break; case IS_Continuous: info_prev_label_of_node (window->node); if (!info_parsed_nodename && !info_parsed_filename) { info_up_label_of_node (window->node); if (!info_parsed_nodename && !info_parsed_filename) info_error (_("No \"Prev\" or \"Up\" for this node.")); else { window_message_in_echo_area (_("Moving \"Up\" in this window.")); info_handle_pointer (_("Up"), window); } } else { REFERENCE **menu; int inhibit_menu_traversing = 0; /* Watch out! If this node's Prev is the same as the Up, then move Up. Otherwise, we could move Prev, and then to the last menu item in the Prev. This would cause the user to loop through a subsection of the info file. */ if (!info_parsed_filename && info_parsed_nodename) { char *pnode; pnode = xstrdup (info_parsed_nodename); info_up_label_of_node (window->node); if (!info_parsed_filename && info_parsed_nodename && strcmp (info_parsed_nodename, pnode) == 0) { /* The nodes are the same. Inhibit moving to the last menu item. */ free (pnode); inhibit_menu_traversing = 1; } else { free (pnode); info_prev_label_of_node (window->node); } } /* Move to the previous node. If this node now contains a menu, and we have not inhibited movement to it, move to the node corresponding to the last menu item. */ window_message_in_echo_area (_("Moving \"Prev\" in this window.")); info_handle_pointer (_("Prev"), window); if (!inhibit_menu_traversing) { while (!info_error_was_printed && (menu = info_menu_of_node (window->node))) { info_free_references (menu); window_message_in_echo_area (_("Moving to \"Prev\"'s last menu item.")); info_menu_digit (window, 1, '0'); } } } break; } } /* Move continuously forward through the node structure of this info file. */ DECLARE_INFO_COMMAND (info_global_next_node, _("Move forwards or down through node structure")) { if (count < 0) info_global_prev_node (window, -count, key); else { while (count && !info_error_was_printed) { forward_move_node_structure (window, IS_Continuous); count--; } } } /* Move continuously backward through the node structure of this info file. */ DECLARE_INFO_COMMAND (info_global_prev_node, _("Move backwards or up through node structure")) { if (count < 0) info_global_next_node (window, -count, key); else { while (count && !info_error_was_printed) { backward_move_node_structure (window, IS_Continuous); count--; } } } /* Show the next screen of WINDOW's node. */ DECLARE_INFO_COMMAND (info_scroll_forward, _("Scroll forward in this window")) { if (count < 0) info_scroll_backward (window, -count, key); else { int desired_top; /* Without an explicit numeric argument, scroll the bottom two lines to the top of this window, Or, if at bottom of window, and the user wishes to scroll through nodes get the "Next" node for this window. */ if (!info_explicit_arg && count == 1) { desired_top = window->pagetop + (window->height - 2); /* If there are no more lines to scroll here, error, or get another node, depending on INFO_SCROLL_BEHAVIOUR. */ if (desired_top > window->line_count) { int behaviour = info_scroll_behaviour; /* Here is a hack. If the key being used is not SPC, do the PageOnly behaviour. */ if (key != SPC && key != DEL) behaviour = IS_PageOnly; forward_move_node_structure (window, behaviour); return; } } else desired_top = window->pagetop + count; if (desired_top >= window->line_count) desired_top = window->line_count - 2; if (window->pagetop > desired_top) return; else set_window_pagetop (window, desired_top); } } /* Show the previous screen of WINDOW's node. */ DECLARE_INFO_COMMAND (info_scroll_backward, _("Scroll backward in this window")) { if (count < 0) info_scroll_forward (window, -count, key); else { int desired_top; /* Without an explicit numeric argument, scroll the top two lines to the bottom of this window, or move to the previous, or Up'th node. */ if (!info_explicit_arg && count == 1) { desired_top = window->pagetop - (window->height - 2); if ((desired_top < 0) && (window->pagetop == 0)) { int behaviour = info_scroll_behaviour; /* Same kind of hack as in info_scroll_forward. If the key used to invoke this command is not DEL, do only the PageOnly behaviour. */ if (key != DEL && key != SPC) behaviour = IS_PageOnly; backward_move_node_structure (window, behaviour); return; } } else desired_top = window->pagetop - count; if (desired_top < 0) desired_top = 0; set_window_pagetop (window, desired_top); } } /* Move to the beginning of the node. */ DECLARE_INFO_COMMAND (info_beginning_of_node, _("Move to the start of this node")) { window->pagetop = window->point = 0; window->flags |= W_UpdateWindow; } /* Move to the end of the node. */ DECLARE_INFO_COMMAND (info_end_of_node, _("Move to the end of this node")) { window->point = window->node->nodelen - 1; info_show_point (window); } /* **************************************************************** */ /* */ /* Commands for Manipulating Windows */ /* */ /* **************************************************************** */ /* Make the next window in the chain be the active window. */ DECLARE_INFO_COMMAND (info_next_window, _("Select the next window")) { if (count < 0) { info_prev_window (window, -count, key); return; } /* If no other window, error now. */ if (!windows->next && !echo_area_is_active) { info_error (ONE_WINDOW); return; } while (count--) { if (window->next) window = window->next; else { if (window == the_echo_area || !echo_area_is_active) window = windows; else window = the_echo_area; } } if (active_window != window) { if (auto_footnotes_p) info_get_or_remove_footnotes (window); window->flags |= W_UpdateWindow; active_window = window; } } /* Make the previous window in the chain be the active window. */ DECLARE_INFO_COMMAND (info_prev_window, _("Select the previous window")) { if (count < 0) { info_next_window (window, -count, key); return; } /* Only one window? */ if (!windows->next && !echo_area_is_active) { info_error (ONE_WINDOW); return; } while (count--) { /* If we are in the echo area, or if the echo area isn't active and we are in the first window, find the last window in the chain. */ if (window == the_echo_area || (window == windows && !echo_area_is_active)) { register WINDOW *win, *last; for (win = windows; win; win = win->next) last = win; window = last; } else { if (window == windows) window = the_echo_area; else window = window->prev; } } if (active_window != window) { if (auto_footnotes_p) info_get_or_remove_footnotes (window); window->flags |= W_UpdateWindow; active_window = window; } } /* Split WINDOW into two windows, both showing the same node. If we are automatically tiling windows, re-tile after the split. */ DECLARE_INFO_COMMAND (info_split_window, _("Split the current window")) { WINDOW *split, *old_active; int pagetop; /* Remember the current pagetop of the window being split. If it doesn't change, we can scroll its contents around after the split. */ pagetop = window->pagetop; /* Make the new window. */ old_active = active_window; active_window = window; split = window_make_window (window->node); active_window = old_active; if (!split) { info_error (WIN_TOO_SMALL); } else { #if defined (SPLIT_BEFORE_ACTIVE) /* Try to scroll the old window into its new postion. */ if (pagetop == window->pagetop) { int start, end, amount; start = split->first_row; end = start + window->height; amount = split->height + 1; display_scroll_display (start, end, amount); } #else /* !SPLIT_BEFORE_ACTIVE */ /* Make sure point still appears in the active window. */ info_show_point (window); #endif /* !SPLIT_BEFORE_ACTIVE */ /* If the window just split was one internal to Info, try to display something else in it. */ if (internal_info_node_p (split->node)) { register int i, j; INFO_WINDOW *iw; NODE *node = (NODE *)NULL; char *filename; for (i = 0; (iw = info_windows[i]); i++) { for (j = 0; j < iw->nodes_index; j++) if (!internal_info_node_p (iw->nodes[j])) { if (iw->nodes[j]->parent) filename = iw->nodes[j]->parent; else filename = iw->nodes[j]->filename; node = info_get_node (filename, iw->nodes[j]->nodename); if (node) { window_set_node_of_window (split, node); i = info_windows_index - 1; break; } } } } split->pagetop = window->pagetop; if (auto_tiling_p) window_tile_windows (DONT_TILE_INTERNALS); else window_adjust_pagetop (split); remember_window_and_node (split, split->node); } } /* Delete WINDOW, forgetting the list of last visited nodes. If we are automatically displaying footnotes, show or remove the footnotes window. If we are automatically tiling windows, re-tile after the deletion. */ DECLARE_INFO_COMMAND (info_delete_window, _("Delete the current window")) { if (!windows->next) { info_error (CANT_KILL_LAST); } else if (window->flags & W_WindowIsPerm) { info_error (_("Cannot delete a permanent window")); } else { info_delete_window_internal (window); if (auto_footnotes_p) info_get_or_remove_footnotes (active_window); if (auto_tiling_p) window_tile_windows (DONT_TILE_INTERNALS); } } /* Do the physical deletion of WINDOW, and forget this window and associated nodes. */ void info_delete_window_internal (window) WINDOW *window; { if (windows->next && ((window->flags & W_WindowIsPerm) == 0)) { /* We not only delete the window from the display, we forget it from our list of remembered windows. */ forget_window_and_nodes (window); window_delete_window (window); if (echo_area_is_active) echo_area_inform_of_deleted_window (window); } } /* Just keep WINDOW, deleting all others. */ DECLARE_INFO_COMMAND (info_keep_one_window, _("Delete all other windows")) { int num_deleted; /* The number of windows we deleted. */ int pagetop, start, end; /* Remember a few things about this window. We may be able to speed up redisplay later by scrolling its contents. */ pagetop = window->pagetop; start = window->first_row; end = start + window->height; num_deleted = 0; while (1) { WINDOW *win; /* Find an eligible window and delete it. If no eligible windows are found, we are done. A window is eligible for deletion if is it not permanent, and it is not WINDOW. */ for (win = windows; win; win = win->next) if (win != window && ((win->flags & W_WindowIsPerm) == 0)) break; if (!win) break; info_delete_window_internal (win); num_deleted++; } /* Scroll the contents of this window into the right place so that the user doesn't have to wait any longer than necessary for redisplay. */ if (num_deleted) { int amount; amount = (window->first_row - start); amount -= (window->pagetop - pagetop); display_scroll_display (start, end, amount); } window->flags |= W_UpdateWindow; } /* Scroll the "other" window of WINDOW. */ DECLARE_INFO_COMMAND (info_scroll_other_window, _("Scroll the other window")) { WINDOW *other; /* If only one window, give up. */ if (!windows->next) { info_error (ONE_WINDOW); return; } other = window->next; if (!other) other = window->prev; info_scroll_forward (other, count, key); } /* Change the size of WINDOW by AMOUNT. */ DECLARE_INFO_COMMAND (info_grow_window, _("Grow (or shrink) this window")) { window_change_window_height (window, count); } /* When non-zero, tiling takes place automatically when info_split_window is called. */ int auto_tiling_p = 0; /* Tile all of the visible windows. */ DECLARE_INFO_COMMAND (info_tile_windows, _("Divide the available screen space among the visible windows")) { window_tile_windows (TILE_INTERNALS); } /* Toggle the state of this window's wrapping of lines. */ DECLARE_INFO_COMMAND (info_toggle_wrap, _("Toggle the state of line wrapping in the current window")) { window_toggle_wrap (window); } /* **************************************************************** */ /* */ /* Info Node Commands */ /* */ /* **************************************************************** */ /* Using WINDOW for various defaults, select the node referenced by ENTRY in it. If the node is selected, the window and node are remembered. */ void info_select_reference (window, entry) WINDOW *window; REFERENCE *entry; { NODE *node; char *filename, *nodename, *file_system_error; file_system_error = (char *)NULL; filename = entry->filename; if (!filename) filename = window->node->parent; if (!filename) filename = window->node->filename; if (filename) filename = xstrdup (filename); if (entry->nodename) nodename = xstrdup (entry->nodename); else nodename = xstrdup ("Top"); node = info_get_node (filename, nodename); /* Try something a little weird. If the node couldn't be found, and the reference was of the form "foo::", see if the entry->label can be found as a file, with a node of "Top". */ if (!node) { if (info_recent_file_error) file_system_error = xstrdup (info_recent_file_error); if (entry->nodename && (strcmp (entry->nodename, entry->label) == 0)) { node = info_get_node (entry->label, "Top"); if (!node && info_recent_file_error) { maybe_free (file_system_error); file_system_error = xstrdup (info_recent_file_error); } } } if (!node) { if (file_system_error) info_error (file_system_error); else info_error (CANT_FIND_NODE, nodename); } maybe_free (file_system_error); maybe_free (filename); maybe_free (nodename); if (node) { set_remembered_pagetop_and_point (window); info_set_node_of_window (window, node); } } /* Parse the node specification in LINE using WINDOW to default the filename. Select the parsed node in WINDOW and remember it, or error if the node couldn't be found. */ static void info_parse_and_select (line, window) char *line; WINDOW *window; { REFERENCE entry; info_parse_node (line, DONT_SKIP_NEWLINES); entry.nodename = info_parsed_nodename; entry.filename = info_parsed_filename; entry.label = "*info-parse-and-select*"; info_select_reference (window, &entry); } /* Given that the values of INFO_PARSED_FILENAME and INFO_PARSED_NODENAME are previously filled, try to get the node represented by them into WINDOW. The node should have been pointed to by the LABEL pointer of WINDOW->node. */ static void info_handle_pointer (label, window) char *label; WINDOW *window; { if (info_parsed_filename || info_parsed_nodename) { char *filename, *nodename; NODE *node; filename = nodename = (char *)NULL; if (info_parsed_filename) filename = xstrdup (info_parsed_filename); else { if (window->node->parent) filename = xstrdup (window->node->parent); else if (window->node->filename) filename = xstrdup (window->node->filename); } if (info_parsed_nodename) nodename = xstrdup (info_parsed_nodename); else nodename = xstrdup ("Top"); node = info_get_node (filename, nodename); if (node) { INFO_WINDOW *info_win; info_win = get_info_window_of_window (window); if (info_win) { info_win->pagetops[info_win->current] = window->pagetop; info_win->points[info_win->current] = window->point; } set_remembered_pagetop_and_point (window); info_set_node_of_window (window, node); } else { if (info_recent_file_error) info_error (info_recent_file_error); else info_error (CANT_FILE_NODE, filename, nodename); } free (filename); free (nodename); } else { info_error (NO_POINTER, label); } } /* Make WINDOW display the "Next:" node of the node currently being displayed. */ DECLARE_INFO_COMMAND (info_next_node, _("Select the `Next' node")) { info_next_label_of_node (window->node); info_handle_pointer (_("Next"), window); } /* Make WINDOW display the "Prev:" node of the node currently being displayed. */ DECLARE_INFO_COMMAND (info_prev_node, _("Select the `Prev' node")) { info_prev_label_of_node (window->node); info_handle_pointer (_("Prev"), window); } /* Make WINDOW display the "Up:" node of the node currently being displayed. */ DECLARE_INFO_COMMAND (info_up_node, _("Select the `Up' node")) { info_up_label_of_node (window->node); info_handle_pointer (_("Up"), window); } /* Make WINDOW display the last node of this info file. */ DECLARE_INFO_COMMAND (info_last_node, _("Select the last node in this file")) { register int i; FILE_BUFFER *fb = file_buffer_of_window (window); NODE *node = (NODE *)NULL; if (fb && fb->tags) { for (i = 0; fb->tags[i]; i++); node = info_get_node (fb->filename, fb->tags[i - 1]->nodename); } if (!node) info_error (_("This window has no additional nodes")); else { set_remembered_pagetop_and_point (window); info_set_node_of_window (window, node); } } /* Make WINDOW display the first node of this info file. */ DECLARE_INFO_COMMAND (info_first_node, _("Select the first node in this file")) { FILE_BUFFER *fb = file_buffer_of_window (window); NODE *node = (NODE *)NULL; if (fb && fb->tags) node = info_get_node (fb->filename, fb->tags[0]->nodename); if (!node) info_error (_("This window has no additional nodes")); else { set_remembered_pagetop_and_point (window); info_set_node_of_window (window, node); } } /* Select the last menu item in WINDOW->node. */ DECLARE_INFO_COMMAND (info_last_menu_item, _("Select the last item in this node's menu")) { info_menu_digit (window, 1, '0'); } /* Use KEY (a digit) to select the Nth menu item in WINDOW->node. */ DECLARE_INFO_COMMAND (info_menu_digit, _("Select this menu item")) { register int i, item; register REFERENCE *entry, **menu; menu = info_menu_of_node (window->node); if (!menu) { info_error (NO_MENU_NODE); return; } /* We have the menu. See if there are this many items in it. */ item = key - '0'; /* Special case. Item "0" is the last item in this menu. */ if (item == 0) for (i = 0; menu[i + 1]; i++); else { for (i = 0; (entry = menu[i]); i++) if (i == item - 1) break; } if (menu[i]) info_select_reference (window, menu[i]); else info_error (_("There aren't %d items in this menu."), item); info_free_references (menu); return; } /* Read a menu or followed reference from the user defaulting to the reference found on the current line, and select that node. The reading is done with completion. BUILDER is the function used to build the list of references. ASK_P is non-zero if the user should be prompted, or zero to select the default item. */ static void info_menu_or_ref_item (window, count, key, builder, ask_p) WINDOW *window; int count; unsigned char key; REFERENCE **(*builder) (); int ask_p; { REFERENCE **menu, *entry, *defentry = (REFERENCE *)NULL; char *line; menu = (*builder) (window->node); if (!menu) { if (builder == info_menu_of_node) info_error (NO_MENU_NODE); else info_error (NO_XREF_NODE); return; } /* Default the selected reference to the one which is on the line that point is in. */ { REFERENCE **refs = (REFERENCE **)NULL; int point_line; point_line = window_line_of_point (window); if (point_line != -1) { SEARCH_BINDING binding; binding.buffer = window->node->contents; binding.start = window->line_starts[point_line] - binding.buffer; if (window->line_starts[point_line + 1]) binding.end = window->line_starts[point_line + 1] - binding.buffer; else binding.end = window->node->nodelen; binding.flags = 0; if (builder == info_menu_of_node) { if (point_line) { binding.start--; refs = info_menu_items (&binding); } } else { #if defined (HANDLE_MAN_PAGES) if (window->node->flags & N_IsManPage) refs = manpage_xrefs_in_binding (window->node, &binding); else #endif /* HANDLE_MAN_PAGES */ refs = info_xrefs (&binding); } if (refs) { if ((strcmp (refs[0]->label, "Menu") != 0) || (builder == info_xrefs_of_node)) { int which = 0; /* Find the closest reference to point. */ if (builder == info_xrefs_of_node) { int closest = -1; for (; refs[which]; which++) { if ((window->point >= refs[which]->start) && (window->point <= refs[which]->end)) { closest = which; break; } else if (window->point < refs[which]->start) { break; } } if (closest == -1) which--; else which = closest; } defentry = (REFERENCE *)xmalloc (sizeof (REFERENCE)); defentry->label = xstrdup (refs[which]->label); defentry->filename = refs[which]->filename; defentry->nodename = refs[which]->nodename; if (defentry->filename) defentry->filename = xstrdup (defentry->filename); if (defentry->nodename) defentry->nodename = xstrdup (defentry->nodename); } info_free_references (refs); } } } /* If we are going to ask the user a question, do it now. */ if (ask_p) { char *prompt; /* Build the prompt string. */ if (defentry) prompt = (char *)xmalloc (20 + strlen (defentry->label)); else prompt = (char *)xmalloc (20); if (builder == info_menu_of_node) { if (defentry) sprintf (prompt, _("Menu item (%s): "), defentry->label); else sprintf (prompt, _("Menu item: ")); } else { if (defentry) sprintf (prompt, _("Follow xref (%s): "), defentry->label); else sprintf (prompt, _("Follow xref: ")); } line = info_read_completing_in_echo_area (window, prompt, menu); free (prompt); window = active_window; /* User aborts, just quit. */ if (!line) { maybe_free (defentry); info_free_references (menu); info_abort_key (window, 0, 0); return; } /* If we had a default and the user accepted it, use that. */ if (!*line) { free (line); if (defentry) line = xstrdup (defentry->label); else line = (char *)NULL; } } else { /* Not going to ask any questions. If we have a default entry, use that, otherwise return. */ if (!defentry) return; else line = xstrdup (defentry->label); } if (line) { /* Find the selected label in the references. */ entry = info_get_labeled_reference (line, menu); if (!entry && defentry) info_error (_("The reference disappeared! (%s)."), line); else { NODE *orig; orig = window->node; info_select_reference (window, entry); if ((builder == info_xrefs_of_node) && (window->node != orig)) { long offset; long start; if (window->line_count > 0) start = window->line_starts[1] - window->node->contents; else start = 0; offset = info_target_search_node (window->node, entry->label, start); if (offset != -1) { window->point = offset; window_adjust_pagetop (window); } } } free (line); if (defentry) { free (defentry->label); maybe_free (defentry->filename); maybe_free (defentry->nodename); free (defentry); } } info_free_references (menu); if (!info_error_was_printed) window_clear_echo_area (); } /* Read a line (with completion) which is the name of a menu item, and select that item. */ DECLARE_INFO_COMMAND (info_menu_item, _("Read a menu item and select its node")) { info_menu_or_ref_item (window, count, key, info_menu_of_node, 1); } /* Read a line (with completion) which is the name of a reference to follow, and select the node. */ DECLARE_INFO_COMMAND (info_xref_item, _("Read a footnote or cross reference and select its node")) { info_menu_or_ref_item (window, count, key, info_xrefs_of_node, 1); } /* Position the cursor at the start of this node's menu. */ DECLARE_INFO_COMMAND (info_find_menu, _("Move to the start of this node's menu")) { SEARCH_BINDING binding; long position; binding.buffer = window->node->contents; binding.start = 0; binding.end = window->node->nodelen; binding.flags = S_FoldCase | S_SkipDest; position = search (INFO_MENU_LABEL, &binding); if (position == -1) info_error (NO_MENU_NODE); else { window->point = position; window_adjust_pagetop (window); window->flags |= W_UpdateWindow; } } /* Visit as many menu items as is possible, each in a separate window. */ DECLARE_INFO_COMMAND (info_visit_menu, _("Visit as many menu items at once as possible")) { register int i; REFERENCE *entry, **menu; menu = info_menu_of_node (window->node); if (!menu) info_error (NO_MENU_NODE); for (i = 0; (!info_error_was_printed) && (entry = menu[i]); i++) { WINDOW *new; new = window_make_window (window->node); window_tile_windows (TILE_INTERNALS); if (!new) info_error (WIN_TOO_SMALL); else { active_window = new; info_select_reference (new, entry); } } } /* Read a line of input which is a node name, and go to that node. */ DECLARE_INFO_COMMAND (info_goto_node, _("Read a node name and select it")) { char *line; #define GOTO_COMPLETES #if defined (GOTO_COMPLETES) /* Build a completion list of all of the known nodes. */ { register int fbi, i; FILE_BUFFER *current; REFERENCE **items = (REFERENCE **)NULL; int items_index = 0; int items_slots = 0; current = file_buffer_of_window (window); for (fbi = 0; info_loaded_files && info_loaded_files[fbi]; fbi++) { FILE_BUFFER *fb; REFERENCE *entry; int this_is_the_current_fb; fb = info_loaded_files[fbi]; this_is_the_current_fb = (current == fb); entry = (REFERENCE *)xmalloc (sizeof (REFERENCE)); entry->filename = entry->nodename = (char *)NULL; entry->label = (char *)xmalloc (4 + strlen (fb->filename)); sprintf (entry->label, "(%s)*", fb->filename); add_pointer_to_array (entry, items_index, items, items_slots, 10, REFERENCE *); if (fb->tags) { for (i = 0; fb->tags[i]; i++) { entry = (REFERENCE *)xmalloc (sizeof (REFERENCE)); entry->filename = entry->nodename = (char *)NULL; entry->label = (char *) xmalloc (4 + strlen (fb->filename) + strlen (fb->tags[i]->nodename)); sprintf (entry->label, "(%s)%s", fb->filename, fb->tags[i]->nodename); add_pointer_to_array (entry, items_index, items, items_slots, 100, REFERENCE *); } if (this_is_the_current_fb) { for (i = 0; fb->tags[i]; i++) { entry = (REFERENCE *)xmalloc (sizeof (REFERENCE)); entry->filename = entry->nodename = (char *)NULL; entry->label = xstrdup (fb->tags[i]->nodename); add_pointer_to_array (entry, items_index, items, items_slots, 100, REFERENCE *); } } } } line = info_read_maybe_completing (window, _("Goto Node: "), items); info_free_references (items); } #else /* !GOTO_COMPLETES */ line = info_read_in_echo_area (window, _("Goto Node: ")); #endif /* !GOTO_COMPLETES */ /* If the user aborted, quit now. */ if (!line) { info_abort_key (window, 0, 0); return; } canonicalize_whitespace (line); if (*line) info_parse_and_select (line, window); free (line); if (!info_error_was_printed) window_clear_echo_area (); } #if defined (HANDLE_MAN_PAGES) DECLARE_INFO_COMMAND (info_man, _("Read a manpage reference and select it")) { char *line; line = info_read_in_echo_area (window, _("Get Manpage: ")); if (!line) { info_abort_key (window, 0, 0); return; } canonicalize_whitespace (line); if (*line) { char *goto_command; goto_command = (char *)xmalloc (4 + strlen (MANPAGE_FILE_BUFFER_NAME) + strlen (line)); sprintf (goto_command, "(%s)%s", MANPAGE_FILE_BUFFER_NAME, line); info_parse_and_select (goto_command, window); free (goto_command); } free (line); if (!info_error_was_printed) window_clear_echo_area (); } #endif /* HANDLE_MAN_PAGES */ /* Move to the "Top" node in this file. */ DECLARE_INFO_COMMAND (info_top_node, _("Select the node `Top' in this file")) { info_parse_and_select (_("Top"), window); } /* Move to the node "(dir)Top". */ DECLARE_INFO_COMMAND (info_dir_node, _("Select the node `(dir)'")) { info_parse_and_select ("(dir)Top", window); } /* Read the name of a node to kill. The list of available nodes comes from the nodes appearing in the current window configuration. */ static char * read_nodename_to_kill (window) WINDOW *window; { int iw; char *nodename; INFO_WINDOW *info_win; REFERENCE **menu = NULL; int menu_index = 0, menu_slots = 0; char *default_nodename = xstrdup (active_window->node->nodename); char *prompt = xmalloc (40 + strlen (default_nodename)); sprintf (prompt, _("Kill node (%s): "), default_nodename); for (iw = 0; (info_win = info_windows[iw]); iw++) { REFERENCE *entry = (REFERENCE *)xmalloc (sizeof (REFERENCE)); entry->label = xstrdup (info_win->window->node->nodename); entry->filename = entry->nodename = (char *)NULL; add_pointer_to_array (entry, menu_index, menu, menu_slots, 10, REFERENCE *); } nodename = info_read_completing_in_echo_area (window, prompt, menu); free (prompt); info_free_references (menu); if (nodename && !*nodename) { free (nodename); nodename = default_nodename; } else free (default_nodename); return nodename; } /* Delete NODENAME from this window, showing the most recently selected node in this window. */ static void kill_node (window, nodename) WINDOW *window; char *nodename; { int iw, i; INFO_WINDOW *info_win; NODE *temp; /* If there is no nodename to kill, quit now. */ if (!nodename) { info_abort_key (window, 0, 0); return; } /* If there is a nodename, find it in our window list. */ for (iw = 0; (info_win = info_windows[iw]); iw++) if (strcmp (nodename, info_win->nodes[info_win->current]->nodename) == 0) break; if (!info_win) { if (*nodename) info_error (_("Cannot kill node `%s'"), nodename); else window_clear_echo_area (); return; } /* If there are no more nodes left anywhere to view, complain and exit. */ if (info_windows_index == 1 && info_windows[0]->nodes_index == 1) { info_error (_("Cannot kill the last node")); return; } /* INFO_WIN contains the node that the user wants to stop viewing. Delete this node from the list of nodes previously shown in this window. */ for (i = info_win->current; i < info_win->nodes_index; i++) info_win->nodes[i] = info_win->nodes[i++]; /* There is one less node in this window's history list. */ info_win->nodes_index--; /* Make this window show the most recent history node. */ info_win->current = info_win->nodes_index - 1; /* If there aren't any nodes left in this window, steal one from the next window. */ if (info_win->current < 0) { INFO_WINDOW *stealer; int which, pagetop; long point; if (info_windows[iw + 1]) stealer = info_windows[iw + 1]; else stealer = info_windows[0]; /* If the node being displayed in the next window is not the most recently loaded one, get the most recently loaded one. */ if ((stealer->nodes_index - 1) != stealer->current) which = stealer->nodes_index - 1; /* Else, if there is another node behind the stealers current node, use that one. */ else if (stealer->current > 0) which = stealer->current - 1; /* Else, just use the node appearing in STEALER's window. */ else which = stealer->current; /* Copy this node. */ { NODE *copy = xmalloc (sizeof (NODE)); temp = stealer->nodes[which]; point = stealer->points[which]; pagetop = stealer->pagetops[which]; copy->filename = temp->filename; copy->parent = temp->parent; copy->nodename = temp->nodename; copy->contents = temp->contents; copy->nodelen = temp->nodelen; copy->flags = temp->flags; temp = copy; } window_set_node_of_window (info_win->window, temp); window->point = point; window->pagetop = pagetop; remember_window_and_node (info_win->window, temp); } else { temp = info_win->nodes[info_win->current]; window_set_node_of_window (info_win->window, temp); } if (!info_error_was_printed) window_clear_echo_area (); if (auto_footnotes_p) info_get_or_remove_footnotes (window); } /* Kill current node, thus going back one in the node history. I (karl) do not think this is completely correct yet, because of the window-changing stuff in kill_node, but it's a lot better than the previous implementation, which did not account for nodes being visited twice at all. */ DECLARE_INFO_COMMAND (info_history_node, _("Select the most recently selected node")) { kill_node (window, active_window->node->nodename); } /* Kill named node. */ DECLARE_INFO_COMMAND (info_kill_node, _("Kill this node")) { char *nodename = read_nodename_to_kill (window); kill_node (window, nodename); } /* Read the name of a file and select the entire file. */ DECLARE_INFO_COMMAND (info_view_file, _("Read the name of a file and select it")) { char *line; line = info_read_in_echo_area (window, _("Find file: ")); if (!line) { info_abort_key (active_window, 1, 0); return; } if (*line) { NODE *node; node = info_get_node (line, "*"); if (!node) { if (info_recent_file_error) info_error (info_recent_file_error); else info_error (_("Cannot find \"%s\"."), line); } else { set_remembered_pagetop_and_point (active_window); info_set_node_of_window (window, node); } free (line); } if (!info_error_was_printed) window_clear_echo_area (); } /* **************************************************************** */ /* */ /* Dumping and Printing Nodes */ /* */ /* **************************************************************** */ #define VERBOSE_NODE_DUMPING static void write_node_to_stream (); static void dump_node_to_stream (); static void initialize_dumping (); /* Dump the nodes specified by FILENAME and NODENAMES to the file named in OUTPUT_FILENAME. If DUMP_SUBNODES is non-zero, recursively dump the nodes which appear in the menu of each node dumped. */ void dump_nodes_to_file (filename, nodenames, output_filename, dump_subnodes) char *filename; char **nodenames; char *output_filename; int dump_subnodes; { register int i; FILE *output_stream; /* Get the stream to print the nodes to. Special case of an output filename of "-" means to dump the nodes to stdout. */ if (strcmp (output_filename, "-") == 0) output_stream = stdout; else output_stream = fopen (output_filename, "w"); if (!output_stream) { info_error (_("Could not create output file \"%s\"."), output_filename); return; } /* Print each node to stream. */ initialize_dumping (); for (i = 0; nodenames[i]; i++) dump_node_to_stream (filename, nodenames[i], output_stream, dump_subnodes); if (output_stream != stdout) fclose (output_stream); #if defined (VERBOSE_NODE_DUMPING) info_error (_("Done.")); #endif /* VERBOSE_NODE_DUMPING */ } /* A place to remember already dumped nodes. */ static char **dumped_already = (char **)NULL; static int dumped_already_index = 0; static int dumped_already_slots = 0; static void initialize_dumping () { dumped_already_index = 0; } /* Get and print the node specified by FILENAME and NODENAME to STREAM. If DUMP_SUBNODES is non-zero, recursively dump the nodes which appear in the menu of each node dumped. */ static void dump_node_to_stream (filename, nodename, stream, dump_subnodes) char *filename, *nodename; FILE *stream; int dump_subnodes; { register int i; NODE *node; node = info_get_node (filename, nodename); if (!node) { if (info_recent_file_error) info_error (info_recent_file_error); else { if (filename && *nodename != '(') info_error (CANT_FILE_NODE, filename_non_directory (filename), nodename); else info_error (CANT_FIND_NODE, nodename); } return; } /* If we have already dumped this node, don't dump it again. */ for (i = 0; i < dumped_already_index; i++) if (strcmp (node->nodename, dumped_already[i]) == 0) { free (node); return; } add_pointer_to_array (node->nodename, dumped_already_index, dumped_already, dumped_already_slots, 50, char *); #if defined (VERBOSE_NODE_DUMPING) /* Maybe we should print some information about the node being output. */ if (node->filename) info_error (_("Writing node \"(%s)%s\"..."), filename_non_directory (node->filename), node->nodename); else info_error (_("Writing node \"%s\"..."), node->nodename); #endif /* VERBOSE_NODE_DUMPING */ write_node_to_stream (node, stream); /* If we are dumping subnodes, get the list of menu items in this node, and dump each one recursively. */ if (dump_subnodes) { REFERENCE **menu = (REFERENCE **)NULL; /* If this node is an Index, do not dump the menu references. */ if (string_in_line ("Index", node->nodename) == -1) menu = info_menu_of_node (node); if (menu) { for (i = 0; menu[i]; i++) { /* We don't dump Info files which are different than the current one. */ if (!menu[i]->filename) dump_node_to_stream (filename, menu[i]->nodename, stream, dump_subnodes); } info_free_references (menu); } } free (node); } /* Dump NODE to FILENAME. If DUMP_SUBNODES is non-zero, recursively dump the nodes which appear in the menu of each node dumped. */ void dump_node_to_file (node, filename, dump_subnodes) NODE *node; char *filename; int dump_subnodes; { FILE *output_stream; char *nodes_filename; /* Get the stream to print this node to. Special case of an output filename of "-" means to dump the nodes to stdout. */ if (strcmp (filename, "-") == 0) output_stream = stdout; else output_stream = fopen (filename, "w"); if (!output_stream) { info_error (_("Could not create output file \"%s\"."), filename); return; } if (node->parent) nodes_filename = node->parent; else nodes_filename = node->filename; initialize_dumping (); dump_node_to_stream (nodes_filename, node->nodename, output_stream, dump_subnodes); if (output_stream != stdout) fclose (output_stream); #if defined (VERBOSE_NODE_DUMPING) info_error (_("Done.")); #endif /* VERBOSE_NODE_DUMPING */ } #if !defined (DEFAULT_INFO_PRINT_COMMAND) # define DEFAULT_INFO_PRINT_COMMAND "lpr" #endif /* !DEFAULT_INFO_PRINT_COMMAND */ DECLARE_INFO_COMMAND (info_print_node, _("Pipe the contents of this node through INFO_PRINT_COMMAND")) { print_node (window->node); } /* Print NODE on a printer piping it into INFO_PRINT_COMMAND. */ void print_node (node) NODE *node; { FILE *printer_pipe; char *print_command = getenv ("INFO_PRINT_COMMAND"); if (!print_command || !*print_command) print_command = DEFAULT_INFO_PRINT_COMMAND; printer_pipe = popen (print_command, "w"); if (!printer_pipe) { info_error (_("Cannot open pipe to \"%s\"."), print_command); return; } #if defined (VERBOSE_NODE_DUMPING) /* Maybe we should print some information about the node being output. */ if (node->filename) info_error (_("Printing node \"(%s)%s\"..."), filename_non_directory (node->filename), node->nodename); else info_error (_("Printing node \"%s\"..."), node->nodename); #endif /* VERBOSE_NODE_DUMPING */ write_node_to_stream (node, printer_pipe); pclose (printer_pipe); #if defined (VERBOSE_NODE_DUMPING) info_error (_("Done.")); #endif /* VERBOSE_NODE_DUMPING */ } static void write_node_to_stream (node, stream) NODE *node; FILE *stream; { fwrite (node->contents, 1, node->nodelen, stream); } /* **************************************************************** */ /* */ /* Info Searching Commands */ /* */ /* **************************************************************** */ /* Variable controlling the garbage collection of files briefly visited during searches. Such files are normally gc'ed, unless they were compressed to begin with. If this variable is non-zero, it says to gc even those file buffer contents which had to be uncompressed. */ int gc_compressed_files = 0; static void info_gc_file_buffers (); static char *search_string = (char *)NULL; static int search_string_index = 0; static int search_string_size = 0; static int isearch_is_active = 0; /* Return the file buffer which belongs to WINDOW's node. */ FILE_BUFFER * file_buffer_of_window (window) WINDOW *window; { /* If this window has no node, then it has no file buffer. */ if (!window->node) return ((FILE_BUFFER *)NULL); if (window->node->parent) return (info_find_file (window->node->parent)); if (window->node->filename) return (info_find_file (window->node->filename)); return ((FILE_BUFFER *)NULL); } /* Search for STRING in NODE starting at START. Return -1 if the string was not found, or the location of the string if it was. If WINDOW is passed as non-null, set the window's node to be NODE, its point to be the found string, and readjust the window's pagetop. Final argument DIR says which direction to search in. If it is positive, search forward, else backwards. */ long info_search_in_node (string, node, start, window, dir) char *string; NODE *node; long start; WINDOW *window; int dir; { SEARCH_BINDING binding; long offset; binding.buffer = node->contents; binding.start = start; binding.end = node->nodelen; binding.flags = S_FoldCase; if (dir < 0) { binding.end = 0; binding.flags |= S_SkipDest; } if (binding.start < 0) return (-1); /* For incremental searches, we always wish to skip past the string. */ if (isearch_is_active) binding.flags |= S_SkipDest; offset = search (string, &binding); if (offset != -1 && window) { set_remembered_pagetop_and_point (window); if (window->node != node) window_set_node_of_window (window, node); window->point = offset; window_adjust_pagetop (window); } return (offset); } /* Search NODE, looking for the largest possible match of STRING. Start the search at START. Return the absolute position of the match, or -1, if no part of the string could be found. */ long info_target_search_node (node, string, start) NODE *node; char *string; long start; { register int i; long offset; char *target; target = xstrdup (string); i = strlen (target); /* Try repeatedly searching for this string while removing words from the end of it. */ while (i) { target[i] = '\0'; offset = info_search_in_node (target, node, start, (WINDOW *)NULL, 1); if (offset != -1) break; /* Delete the last word from TARGET. */ for (; i && (!whitespace (target[i]) && (target[i] != ',')); i--); } free (target); return (offset); } /* Search for STRING starting in WINDOW at point. If the string is found in this node, set point to that position. Otherwise, get the file buffer associated with WINDOW's node, and search through each node in that file. If the search fails, return non-zero, else zero. Side-effect window leaving the node and point where the string was found current. */ static char *last_searched_for_string = (char *)NULL; static int info_search_internal (string, window, dir) char *string; WINDOW *window; int dir; { register int i; FILE_BUFFER *file_buffer; char *initial_nodename; long ret, start = 0; file_buffer = file_buffer_of_window (window); initial_nodename = window->node->nodename; if ((info_last_executed_command == info_search) && (last_searched_for_string) && (strcmp (last_searched_for_string, string) == 0)) { ret = info_search_in_node (string, window->node, window->point + dir, window, dir); } else { ret = info_search_in_node (string, window->node, window->point, window, dir); } maybe_free (last_searched_for_string); last_searched_for_string = xstrdup (string); if (ret != -1) { /* We won! */ if (!echo_area_is_active && !isearch_is_active) window_clear_echo_area (); return (0); } /* The string wasn't found in the current node. Search through the window's file buffer, iff the current node is not "*". */ if (!file_buffer || (strcmp (initial_nodename, "*") == 0)) return (-1); /* If this file has tags, search through every subfile, starting at this node's subfile and node. Otherwise, search through the file's node list. */ if (file_buffer->tags) { register int current_tag, number_of_tags; char *last_subfile; TAG *tag; /* Find number of tags and current tag. */ last_subfile = (char *)NULL; for (i = 0; file_buffer->tags[i]; i++) if (strcmp (initial_nodename, file_buffer->tags[i]->nodename) == 0) { current_tag = i; last_subfile = file_buffer->tags[i]->filename; } number_of_tags = i; /* If there is no last_subfile, our tag wasn't found. */ if (!last_subfile) return (-1); /* Search through subsequent nodes, wrapping around to the top of the info file until we find the string or return to this window's node and point. */ while (1) { NODE *node; /* Allow C-g to quit the search, failing it if pressed. */ return_if_control_g (-1); current_tag += dir; if (current_tag < 0) current_tag = number_of_tags - 1; else if (current_tag == number_of_tags) current_tag = 0; tag = file_buffer->tags[current_tag]; if (!echo_area_is_active && (last_subfile != tag->filename)) { window_message_in_echo_area (_("Searching subfile \"%s\"..."), filename_non_directory (tag->filename)); last_subfile = tag->filename; } node = info_get_node (file_buffer->filename, tag->nodename); if (!node) { /* If not doing i-search... */ if (!echo_area_is_active) { if (info_recent_file_error) info_error (info_recent_file_error); else info_error (CANT_FILE_NODE, filename_non_directory (file_buffer->filename), tag->nodename); } return (-1); } if (dir < 0) start = tag->nodelen; ret = info_search_in_node (string, node, start, window, dir); /* Did we find the string in this node? */ if (ret != -1) { /* Yes! We win. */ remember_window_and_node (window, node); if (!echo_area_is_active) window_clear_echo_area (); return (0); } /* No. Free this node, and make sure that we haven't passed our starting point. */ free (node); if (strcmp (initial_nodename, tag->nodename) == 0) return (-1); } } return (-1); } DECLARE_INFO_COMMAND (info_search, _("Read a string and search for it")) { char *line, *prompt; int result, old_pagetop; int direction; if (count < 0) direction = -1; else direction = 1; /* Read a string from the user, defaulting the search to SEARCH_STRING. */ if (!search_string) { search_string = (char *)xmalloc (search_string_size = 100); search_string[0] = '\0'; } prompt = (char *)xmalloc (50 + strlen (search_string)); sprintf (prompt, _("%s for string [%s]: "), direction < 0 ? _("Search backward") : _("Search"), search_string); line = info_read_in_echo_area (window, prompt); free (prompt); if (!line) { info_abort_key (); return; } if (*line) { if (strlen (line) + 1 > search_string_size) search_string = (char *) xrealloc (search_string, (search_string_size += 50 + strlen (line))); strcpy (search_string, line); search_string_index = strlen (line); free (line); } old_pagetop = active_window->pagetop; result = info_search_internal (search_string, active_window, direction); if (result != 0 && !info_error_was_printed) info_error (_("Search failed.")); else if (old_pagetop != active_window->pagetop) { int new_pagetop; new_pagetop = active_window->pagetop; active_window->pagetop = old_pagetop; set_window_pagetop (active_window, new_pagetop); if (auto_footnotes_p) info_get_or_remove_footnotes (active_window); } /* Perhaps free the unreferenced file buffers that were searched, but not retained. */ info_gc_file_buffers (); } /* **************************************************************** */ /* */ /* Incremental Searching */ /* */ /* **************************************************************** */ static void incremental_search (); DECLARE_INFO_COMMAND (isearch_forward, _("Search interactively for a string as you type it")) { incremental_search (window, count, key); } DECLARE_INFO_COMMAND (isearch_backward, _("Search interactively for a string as you type it")) { incremental_search (window, -count, key); } /* Incrementally search for a string as it is typed. */ /* The last accepted incremental search string. */ static char *last_isearch_accepted = (char *)NULL; /* The current incremental search string. */ static char *isearch_string = (char *)NULL; static int isearch_string_index = 0; static int isearch_string_size = 0; static unsigned char isearch_terminate_search_key = ESC; /* Structure defining the current state of an incremental search. */ typedef struct { WINDOW_STATE_DECL; /* The node, pagetop and point. */ int search_index; /* Offset of the last char in the search string. */ int direction; /* The direction that this search is heading in. */ int failing; /* Whether or not this search failed. */ } SEARCH_STATE; /* Array of search states. */ static SEARCH_STATE **isearch_states = (SEARCH_STATE **)NULL; static int isearch_states_index = 0; static int isearch_states_slots = 0; /* Push the state of this search. */ static void push_isearch (window, search_index, direction, failing) WINDOW *window; int search_index, direction, failing; { SEARCH_STATE *state; state = (SEARCH_STATE *)xmalloc (sizeof (SEARCH_STATE)); window_get_state (window, state); state->search_index = search_index; state->direction = direction; state->failing = failing; add_pointer_to_array (state, isearch_states_index, isearch_states, isearch_states_slots, 20, SEARCH_STATE *); } /* Pop the state of this search to WINDOW, SEARCH_INDEX, and DIRECTION. */ static void pop_isearch (window, search_index, direction, failing) WINDOW *window; int *search_index, *direction, *failing; { SEARCH_STATE *state; if (isearch_states_index) { isearch_states_index--; state = isearch_states[isearch_states_index]; window_set_state (window, state); *search_index = state->search_index; *direction = state->direction; *failing = state->failing; free (state); isearch_states[isearch_states_index] = (SEARCH_STATE *)NULL; } } /* Free the memory used by isearch_states. */ static void free_isearch_states () { register int i; for (i = 0; i < isearch_states_index; i++) { free (isearch_states[i]); isearch_states[i] = (SEARCH_STATE *)NULL; } isearch_states_index = 0; } /* Display the current search in the echo area. */ static void show_isearch_prompt (dir, string, failing_p) int dir; unsigned char *string; int failing_p; { register int i; char *prefix, *prompt, *p_rep; int prompt_len, p_rep_index, p_rep_size; if (dir < 0) prefix = _("I-search backward: "); else prefix = _("I-search: "); p_rep_index = p_rep_size = 0; p_rep = (char *)NULL; for (i = 0; string[i]; i++) { char *rep; switch (string[i]) { case ' ': rep = " "; break; case LFD: rep = "\\n"; break; case TAB: rep = "\\t"; break; default: rep = pretty_keyname (string[i]); } if ((p_rep_index + strlen (rep) + 1) >= p_rep_size) p_rep = (char *)xrealloc (p_rep, p_rep_size += 100); strcpy (p_rep + p_rep_index, rep); p_rep_index += strlen (rep); } prompt_len = strlen (prefix) + p_rep_index + 20; prompt = (char *)xmalloc (prompt_len); sprintf (prompt, "%s%s%s", failing_p ? _("Failing ") : "", prefix, p_rep ? p_rep : ""); window_message_in_echo_area ("%s", prompt); maybe_free (p_rep); free (prompt); display_cursor_at_point (active_window); } static void incremental_search (window, count, ignore) WINDOW *window; int count; unsigned char ignore; { unsigned char key; int last_search_result, search_result, dir; SEARCH_STATE mystate, orig_state; if (count < 0) dir = -1; else dir = 1; last_search_result = search_result = 0; window_get_state (window, &orig_state); isearch_string_index = 0; if (!isearch_string_size) isearch_string = (char *)xmalloc (isearch_string_size = 50); /* Show the search string in the echo area. */ isearch_string[isearch_string_index] = '\0'; show_isearch_prompt (dir, isearch_string, search_result); isearch_is_active = 1; while (isearch_is_active) { VFunction *func = (VFunction *)NULL; int quoted = 0; /* If a recent display was interrupted, then do the redisplay now if it is convenient. */ if (!info_any_buffered_input_p () && display_was_interrupted_p) { display_update_one_window (window); display_cursor_at_point (active_window); } /* Read a character and dispatch on it. */ key = info_get_input_char (); window_get_state (window, &mystate); if (key == DEL) { /* User wants to delete one level of search? */ if (!isearch_states_index) { terminal_ring_bell (); continue; } else { pop_isearch (window, &isearch_string_index, &dir, &search_result); isearch_string[isearch_string_index] = '\0'; show_isearch_prompt (dir, isearch_string, search_result); goto after_search; } } else if (key == Control ('q')) { key = info_get_input_char (); quoted = 1; } /* We are about to search again, or quit. Save the current search. */ push_isearch (window, isearch_string_index, dir, search_result); if (quoted) goto insert_and_search; if (!Meta_p (key) || (ISO_Latin_p && key < 160)) { func = window->keymap[key].function; /* If this key invokes an incremental search, then this means that we will either search again in the same direction, search again in the reverse direction, or insert the last search string that was accepted through incremental searching. */ if (func == isearch_forward || func == isearch_backward) { if ((func == isearch_forward && dir > 0) || (func == isearch_backward && dir < 0)) { /* If the user has typed no characters, then insert the last successful search into the current search string. */ if (isearch_string_index == 0) { /* Of course, there must be something to insert. */ if (last_isearch_accepted) { if (strlen (last_isearch_accepted) + 1 >= isearch_string_size) isearch_string = (char *) xrealloc (isearch_string, isearch_string_size += 10 + strlen (last_isearch_accepted)); strcpy (isearch_string, last_isearch_accepted); isearch_string_index = strlen (isearch_string); goto search_now; } else continue; } else { /* Search again in the same direction. This means start from a new place if the last search was successful. */ if (search_result == 0) window->point += dir; } } else { /* Reverse the direction of the search. */ dir = -dir; } } else if (isprint (key) || func == (VFunction *)NULL) { insert_and_search: if (isearch_string_index + 2 >= isearch_string_size) isearch_string = (char *)xrealloc (isearch_string, isearch_string_size += 100); isearch_string[isearch_string_index++] = key; isearch_string[isearch_string_index] = '\0'; goto search_now; } else if (func == info_abort_key) { /* If C-g pressed, and the search is failing, pop the search stack back to the last unfailed search. */ if (isearch_states_index && (search_result != 0)) { terminal_ring_bell (); while (isearch_states_index && (search_result != 0)) pop_isearch (window, &isearch_string_index, &dir, &search_result); isearch_string[isearch_string_index] = '\0'; show_isearch_prompt (dir, isearch_string, search_result); continue; } else goto exit_search; } else goto exit_search; } else { exit_search: /* The character is not printable, or it has a function which is non-null. Exit the search, remembering the search string. If the key is not the same as the isearch_terminate_search_key, then push it into pending input. */ if (isearch_string_index && func != info_abort_key) { maybe_free (last_isearch_accepted); last_isearch_accepted = xstrdup (isearch_string); } if (key != isearch_terminate_search_key) info_set_pending_input (key); if (func == info_abort_key) { if (isearch_states_index) window_set_state (window, &orig_state); } if (!echo_area_is_active) window_clear_echo_area (); if (auto_footnotes_p) info_get_or_remove_footnotes (active_window); isearch_is_active = 0; continue; } /* Search for the contents of isearch_string. */ search_now: show_isearch_prompt (dir, isearch_string, search_result); if (search_result == 0) { /* Check to see if the current search string is right here. If we are looking at it, then don't bother calling the search function. */ if (((dir < 0) && (strncasecmp (window->node->contents + window->point, isearch_string, isearch_string_index) == 0)) || ((dir > 0) && ((window->point - isearch_string_index) >= 0) && (strncasecmp (window->node->contents + (window->point - (isearch_string_index - 1)), isearch_string, isearch_string_index) == 0))) { if (dir > 0) window->point++; } else search_result = info_search_internal (isearch_string, window, dir); } /* If this search failed, and we didn't already have a failed search, then ring the terminal bell. */ if (search_result != 0 && last_search_result == 0) terminal_ring_bell (); after_search: show_isearch_prompt (dir, isearch_string, search_result); if (search_result == 0) { if ((mystate.node == window->node) && (mystate.pagetop != window->pagetop)) { int newtop = window->pagetop; window->pagetop = mystate.pagetop; set_window_pagetop (window, newtop); } display_update_one_window (window); display_cursor_at_point (window); } last_search_result = search_result; } /* Free the memory used to remember each search state. */ free_isearch_states (); /* Perhaps GC some file buffers. */ info_gc_file_buffers (); /* After searching, leave the window in the correct state. */ if (!echo_area_is_active) window_clear_echo_area (); } /* GC some file buffers. A file buffer can be gc-ed if there we have no nodes in INFO_WINDOWS that reference this file buffer's contents. Garbage collecting a file buffer means to free the file buffers contents. */ static void info_gc_file_buffers () { register int fb_index, iw_index, i; register FILE_BUFFER *fb; register INFO_WINDOW *iw; if (!info_loaded_files) return; for (fb_index = 0; (fb = info_loaded_files[fb_index]); fb_index++) { int fb_referenced_p = 0; /* If already gc-ed, do nothing. */ if (!fb->contents) continue; /* If this file had to be uncompressed, check to see if we should gc it. This means that the user-variable "gc-compressed-files" is non-zero. */ if ((fb->flags & N_IsCompressed) && !gc_compressed_files) continue; /* If this file's contents are not gc-able, move on. */ if (fb->flags & N_CannotGC) continue; /* Check each INFO_WINDOW to see if it has any nodes which reference this file. */ for (iw_index = 0; (iw = info_windows[iw_index]); iw_index++) { for (i = 0; iw->nodes && iw->nodes[i]; i++) { if ((strcmp (fb->fullpath, iw->nodes[i]->filename) == 0) || (strcmp (fb->filename, iw->nodes[i]->filename) == 0)) { fb_referenced_p = 1; break; } } } /* If this file buffer wasn't referenced, free its contents. */ if (!fb_referenced_p) { free (fb->contents); fb->contents = (char *)NULL; } } } /* **************************************************************** */ /* */ /* Traversing and Selecting References */ /* */ /* **************************************************************** */ /* Move to the next or previous cross reference in this node. */ static void info_move_to_xref (window, count, key, dir) WINDOW *window; int count; unsigned char key; int dir; { long firstmenu, firstxref; long nextmenu, nextxref; long placement = -1; long start = 0; NODE *node = window->node; if (dir < 0) start = node->nodelen; /* This search is only allowed to fail if there is no menu or cross reference in the current node. Otherwise, the first menu or xref found is moved to. */ firstmenu = info_search_in_node (INFO_MENU_ENTRY_LABEL, node, start, (WINDOW *)NULL, dir); /* FIRSTMENU may point directly to the line defining the menu. Skip that and go directly to the first item. */ if (firstmenu != -1) { char *text = node->contents + firstmenu; if (strncmp (text, INFO_MENU_LABEL, strlen (INFO_MENU_LABEL)) == 0) firstmenu = info_search_in_node (INFO_MENU_ENTRY_LABEL, node, firstmenu + dir, (WINDOW *)NULL, dir); } firstxref = info_search_in_node (INFO_XREF_LABEL, node, start, (WINDOW *)NULL, dir); #if defined (HANDLE_MAN_PAGES) if ((firstxref == -1) && (node->flags & N_IsManPage)) { firstxref = locate_manpage_xref (node, start, dir); } #endif /* HANDLE_MAN_PAGES */ if (firstmenu == -1 && firstxref == -1) { info_error (_("No cross references in this node.")); return; } /* There is at least one cross reference or menu entry in this node. Try hard to find the next available one. */ nextmenu = info_search_in_node (INFO_MENU_ENTRY_LABEL, node, window->point + dir, (WINDOW *)NULL, dir); nextxref = info_search_in_node (INFO_XREF_LABEL, node, window->point + dir, (WINDOW *)NULL, dir); #if defined (HANDLE_MAN_PAGES) if ((nextxref == -1) && (node->flags & N_IsManPage) && (firstxref != -1)) nextxref = locate_manpage_xref (node, window->point + dir, dir); #endif /* HANDLE_MAN_PAGES */ /* Ignore "Menu:" as a menu item. */ if (nextmenu != -1) { char *text = node->contents + nextmenu; if (strncmp (text, INFO_MENU_LABEL, strlen (INFO_MENU_LABEL)) == 0) nextmenu = info_search_in_node (INFO_MENU_ENTRY_LABEL, node, nextmenu + dir, (WINDOW *)NULL, dir); } /* If there is both a next menu entry, and a next xref entry, choose the one which occurs first. Otherwise, select the one which actually appears in this node following point. */ if (nextmenu != -1 && nextxref != -1) { if (((dir == 1) && (nextmenu < nextxref)) || ((dir == -1) && (nextmenu > nextxref))) placement = nextmenu + 1; else placement = nextxref; } else if (nextmenu != -1) placement = nextmenu + 1; else if (nextxref != -1) placement = nextxref; /* If there was neither a menu or xref entry appearing in this node after point, choose the first menu or xref entry appearing in this node. */ if (placement == -1) { if (firstmenu != -1 && firstxref != -1) { if (((dir == 1) && (firstmenu < firstxref)) || ((dir == -1) && (firstmenu > firstxref))) placement = firstmenu + 1; else placement = firstxref; } else if (firstmenu != -1) placement = firstmenu + 1; else placement = firstxref; } window->point = placement; window_adjust_pagetop (window); window->flags |= W_UpdateWindow; } DECLARE_INFO_COMMAND (info_move_to_prev_xref, _("Move to the previous cross reference")) { if (count < 0) info_move_to_prev_xref (window, -count, key); else info_move_to_xref (window, count, key, -1); } DECLARE_INFO_COMMAND (info_move_to_next_xref, _("Move to the next cross reference")) { if (count < 0) info_move_to_next_xref (window, -count, key); else info_move_to_xref (window, count, key, 1); } /* Select the menu item or reference that appears on this line. */ DECLARE_INFO_COMMAND (info_select_reference_this_line, _("Select reference or menu item appearing on this line")) { char *line; NODE *orig; line = window->line_starts[window_line_of_point (window)]; orig = window->node; /* If this line contains a menu item, select that one. */ if (strncmp ("* ", line, 2) == 0) info_menu_or_ref_item (window, count, key, info_menu_of_node, 0); else info_menu_or_ref_item (window, count, key, info_xrefs_of_node, 0); } /* **************************************************************** */ /* */ /* Miscellaneous Info Commands */ /* */ /* **************************************************************** */ /* What to do when C-g is pressed in a window. */ DECLARE_INFO_COMMAND (info_abort_key, _("Cancel current operation")) { /* If error printing doesn't oridinarily ring the bell, do it now, since C-g always rings the bell. Otherwise, let the error printer do it. */ if (!info_error_rings_bell_p) terminal_ring_bell (); info_error (_("Quit")); info_initialize_numeric_arg (); info_clear_pending_input (); info_last_executed_command = (VFunction *)NULL; } /* Move the cursor to the desired line of the window. */ DECLARE_INFO_COMMAND (info_move_to_window_line, _("Move to the cursor to a specific line of the window")) { int line; /* With no numeric argument of any kind, default to the center line. */ if (!info_explicit_arg && count == 1) line = (window->height / 2) + window->pagetop; else { if (count < 0) line = (window->height + count) + window->pagetop; else line = window->pagetop + count; } /* If the line doesn't appear in this window, make it do so. */ if ((line - window->pagetop) >= window->height) line = window->pagetop + (window->height - 1); /* If the line is too small, make it fit. */ if (line < window->pagetop) line = window->pagetop; /* If the selected line is past the bottom of the node, force it back. */ if (line >= window->line_count) line = window->line_count - 1; window->point = (window->line_starts[line] - window->node->contents); } /* Clear the screen and redraw its contents. Given a numeric argument, move the line the cursor is on to the COUNT'th line of the window. */ DECLARE_INFO_COMMAND (info_redraw_display, _("Redraw the display")) { if ((!info_explicit_arg && count == 1) || echo_area_is_active) { terminal_clear_screen (); display_clear_display (the_display); window_mark_chain (windows, W_UpdateWindow); display_update_display (windows); } else { int desired_line, point_line; int new_pagetop; point_line = window_line_of_point (window) - window->pagetop; if (count < 0) desired_line = window->height + count; else desired_line = count; if (desired_line < 0) desired_line = 0; if (desired_line >= window->height) desired_line = window->height - 1; if (desired_line == point_line) return; new_pagetop = window->pagetop + (point_line - desired_line); set_window_pagetop (window, new_pagetop); } } /* This command does nothing. It is the fact that a key is bound to it that has meaning. See the code at the top of info_session (). */ DECLARE_INFO_COMMAND (info_quit, _("Quit using Info")) {} /* **************************************************************** */ /* */ /* Reading Keys and Dispatching on Them */ /* */ /* **************************************************************** */ /* Declaration only. Special cased in info_dispatch_on_key (). */ DECLARE_INFO_COMMAND (info_do_lowercase_version, "") {} static void dispatch_error (keyseq) char *keyseq; { char *rep; rep = pretty_keyseq (keyseq); if (!echo_area_is_active) info_error (_("Unknown command (%s)."), rep); else { char *temp; temp = (char *)xmalloc (1 + strlen (rep) + strlen (_("\"\" is invalid"))); sprintf (temp, _("\"%s\" is invalid"), rep); terminal_ring_bell (); inform_in_echo_area (temp); free (temp); } } /* Keeping track of key sequences. */ static char *info_keyseq = (char *)NULL; static char keyseq_rep[100]; static int info_keyseq_index = 0; static int info_keyseq_size = 0; static int info_keyseq_displayed_p = 0; /* Initialize the length of the current key sequence. */ void initialize_keyseq () { info_keyseq_index = 0; info_keyseq_displayed_p = 0; } /* Add CHARACTER to the current key sequence. */ void add_char_to_keyseq (character) char character; { if (info_keyseq_index + 2 >= info_keyseq_size) info_keyseq = (char *)xrealloc (info_keyseq, info_keyseq_size += 10); info_keyseq[info_keyseq_index++] = character; info_keyseq[info_keyseq_index] = '\0'; } /* Return the pretty printable string which represents KEYSEQ. */ char * pretty_keyseq (keyseq) char *keyseq; { register int i; keyseq_rep[0] = '\0'; for (i = 0; keyseq[i]; i++) { sprintf (keyseq_rep + strlen (keyseq_rep), "%s%s", strlen (keyseq_rep) ? " " : "", pretty_keyname (keyseq[i])); } return (keyseq_rep); } /* Display the current value of info_keyseq. If argument EXPECTING is non-zero, input is expected to be read after the key sequence is displayed, so add an additional prompting character to the sequence. */ void display_info_keyseq (expecting_future_input) int expecting_future_input; { char *rep; rep = pretty_keyseq (info_keyseq); if (expecting_future_input) strcat (rep, "-"); if (echo_area_is_active) inform_in_echo_area (rep); else { window_message_in_echo_area (rep); display_cursor_at_point (active_window); } info_keyseq_displayed_p = 1; } /* Called by interactive commands to read a keystroke. */ unsigned char info_get_another_input_char () { int ready = !info_keyseq_displayed_p; /* ready if new and pending key */ /* If there isn't any input currently available, then wait a moment looking for input. If we don't get it fast enough, prompt a little bit with the current key sequence. */ if (!info_keyseq_displayed_p) { ready = 1; if (!info_any_buffered_input_p () && !info_input_pending_p ()) { #if defined (FD_SET) struct timeval timer; fd_set readfds; FD_ZERO (&readfds); FD_SET (fileno (info_input_stream), &readfds); timer.tv_sec = 1; timer.tv_usec = 750; ready = select (fileno(info_input_stream)+1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &timer); #else ready = 0; #endif /* FD_SET */ } } if (!ready) display_info_keyseq (1); return (info_get_input_char ()); } /* Do the command associated with KEY in MAP. If the associated command is really a keymap, then read another key, and dispatch into that map. */ void info_dispatch_on_key (key, map) unsigned char key; Keymap map; { if (Meta_p (key) && (!ISO_Latin_p || map[key].function != ea_insert)) { if (map[ESC].type == ISKMAP) { map = (Keymap)map[ESC].function; add_char_to_keyseq (ESC); key = UnMeta (key); info_dispatch_on_key (key, map); } else { dispatch_error (info_keyseq); } return; } switch (map[key].type) { case ISFUNC: { VFunction *func; func = map[key].function; if (func != (VFunction *)NULL) { /* Special case info_do_lowercase_version (). */ if (func == info_do_lowercase_version) { info_dispatch_on_key (tolower (key), map); return; } add_char_to_keyseq (key); if (info_keyseq_displayed_p) display_info_keyseq (0); { WINDOW *where; where = active_window; (*map[key].function) (active_window, info_numeric_arg * info_numeric_arg_sign, key); /* If we have input pending, then the last command was a prefix command. Don't change the value of the last function vars. Otherwise, remember the last command executed in the var appropriate to the window in which it was executed. */ if (!info_input_pending_p ()) { if (where == the_echo_area) ea_last_executed_command = map[key].function; else info_last_executed_command = map[key].function; } } } else { add_char_to_keyseq (key); dispatch_error (info_keyseq); return; } } break; case ISKMAP: add_char_to_keyseq (key); if (map[key].function != (VFunction *)NULL) { unsigned char newkey; newkey = info_get_another_input_char (); info_dispatch_on_key (newkey, (Keymap)map[key].function); } else { dispatch_error (info_keyseq); return; } break; } } /* **************************************************************** */ /* */ /* Numeric Arguments */ /* */ /* **************************************************************** */ /* Handle C-u style numeric args, as well as M--, and M-digits. */ /* Non-zero means that an explicit argument has been passed to this command, as in C-u C-v. */ int info_explicit_arg = 0; /* The sign of the numeric argument. */ int info_numeric_arg_sign = 1; /* The value of the argument itself. */ int info_numeric_arg = 1; /* Add the current digit to the argument in progress. */ DECLARE_INFO_COMMAND (info_add_digit_to_numeric_arg, _("Add this digit to the current numeric argument")) { info_numeric_arg_digit_loop (window, 0, key); } /* C-u, universal argument. Multiply the current argument by 4. Read a key. If the key has nothing to do with arguments, then dispatch on it. If the key is the abort character then abort. */ DECLARE_INFO_COMMAND (info_universal_argument, _("Start (or multiply by 4) the current numeric argument")) { info_numeric_arg *= 4; info_numeric_arg_digit_loop (window, 0, 0); } /* Create a default argument. */ void info_initialize_numeric_arg () { info_numeric_arg = info_numeric_arg_sign = 1; info_explicit_arg = 0; } DECLARE_INFO_COMMAND (info_numeric_arg_digit_loop, _("Internally used by \\[universal-argument]")) { unsigned char pure_key; Keymap keymap = window->keymap; while (1) { if (key) pure_key = key; else { if (display_was_interrupted_p && !info_any_buffered_input_p ()) display_update_display (windows); if (active_window != the_echo_area) display_cursor_at_point (active_window); pure_key = key = info_get_another_input_char (); if (Meta_p (key)) add_char_to_keyseq (ESC); add_char_to_keyseq (UnMeta (key)); } if (Meta_p (key)) key = UnMeta (key); if (keymap[key].type == ISFUNC && keymap[key].function == info_universal_argument) { info_numeric_arg *= 4; key = 0; continue; } if (isdigit (key)) { if (info_explicit_arg) info_numeric_arg = (info_numeric_arg * 10) + (key - '0'); else info_numeric_arg = (key - '0'); info_explicit_arg = 1; } else { if (key == '-' && !info_explicit_arg) { info_numeric_arg_sign = -1; info_numeric_arg = 1; } else { info_keyseq_index--; info_dispatch_on_key (pure_key, keymap); return; } } key = 0; } } /* **************************************************************** */ /* */ /* Input Character Buffering */ /* */ /* **************************************************************** */ /* Character waiting to be read next. */ static int pending_input_character = 0; /* How to make there be no pending input. */ static void info_clear_pending_input () { pending_input_character = 0; } /* How to set the pending input character. */ static void info_set_pending_input (key) unsigned char key; { pending_input_character = key; } /* How to see if there is any pending input. */ unsigned char info_input_pending_p () { return (pending_input_character); } /* Largest number of characters that we can read in advance. */ #define MAX_INFO_INPUT_BUFFERING 512 static int pop_index = 0, push_index = 0; static unsigned char info_input_buffer[MAX_INFO_INPUT_BUFFERING]; /* Add KEY to the buffer of characters to be read. */ static void info_push_typeahead (key) unsigned char key; { /* Flush all pending input in the case of C-g pressed. */ if (key == Control ('g')) { push_index = pop_index; info_set_pending_input (Control ('g')); } else { info_input_buffer[push_index++] = key; if (push_index >= sizeof (info_input_buffer)) push_index = 0; } } /* Return the amount of space available in INFO_INPUT_BUFFER for new chars. */ static int info_input_buffer_space_available () { if (pop_index > push_index) return (pop_index - push_index); else return (sizeof (info_input_buffer) - (push_index - pop_index)); } /* Get a key from the buffer of characters to be read. Return the key in KEY. Result is non-zero if there was a key, or 0 if there wasn't. */ static int info_get_key_from_typeahead (key) unsigned char *key; { if (push_index == pop_index) return (0); *key = info_input_buffer[pop_index++]; if (pop_index >= sizeof (info_input_buffer)) pop_index = 0; return (1); } int info_any_buffered_input_p () { info_gather_typeahead (); return (push_index != pop_index); } /* If characters are available to be read, then read them and stuff them into info_input_buffer. Otherwise, do nothing. */ void info_gather_typeahead () { register int i = 0; int tty, space_avail; long chars_avail; unsigned char input[MAX_INFO_INPUT_BUFFERING]; tty = fileno (info_input_stream); chars_avail = 0; space_avail = info_input_buffer_space_available (); /* If we can just find out how many characters there are to read, do so. */ #if defined (FIONREAD) { ioctl (tty, FIONREAD, &chars_avail); if (chars_avail > space_avail) chars_avail = space_avail; if (chars_avail) chars_avail = read (tty, &input[0], chars_avail); } #else /* !FIONREAD */ # if defined (O_NDELAY) { int flags; flags = fcntl (tty, F_GETFL, 0); fcntl (tty, F_SETFL, (flags | O_NDELAY)); chars_avail = read (tty, &input[0], space_avail); fcntl (tty, F_SETFL, flags); if (chars_avail == -1) chars_avail = 0; } # endif /* O_NDELAY */ #endif /* !FIONREAD */ while (i < chars_avail) { info_push_typeahead (input[i]); i++; } } /* How to read a single character. */ unsigned char info_get_input_char () { unsigned char keystroke; info_gather_typeahead (); if (pending_input_character) { keystroke = pending_input_character; pending_input_character = 0; } else if (info_get_key_from_typeahead (&keystroke) == 0) { int rawkey; unsigned char c; int tty = fileno (info_input_stream); /* Using stream I/O causes FIONREAD etc to fail to work so unless someone can find a portable way of finding out how many characters are currently buffered, we should stay with away from stream I/O. --Egil Kvaleberg , January 1997. */ #ifdef EINTR /* Keep reading if we got EINTR, so that we don't just exit. --Andreas Schwab , 22 Dec 1997. */ { int n; do n = read (tty, &c, 1); while (n == -1 && errno == EINTR); rawkey = n == 1 ? c : EOF; } #else rawkey = (read (tty, &c, 1) == 1) ? c : EOF; #endif keystroke = rawkey; if (rawkey == EOF) { if (info_input_stream != stdin) { fclose (info_input_stream); info_input_stream = stdin; display_inhibited = 0; display_update_display (windows); display_cursor_at_point (active_window); rawkey = (read (tty, &c, 1) == 1) ? c : EOF; keystroke = rawkey; } if (rawkey == EOF) { terminal_unprep_terminal (); close_dribble_file (); exit (0); } } } if (info_dribble_file) dribble (keystroke); return keystroke; } texinfo-3.12/info/session.h0000444000175000017500000001350306362741407013151 0ustar gg/* session.h -- Functions found in session.c. */ /* This file is part of GNU Info, a program for reading online documentation stored in Info format. Copyright (C) 1993 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ #if !defined (SESSION_H) #define SESSION_H #include "info.h" #include "dribble.h" /* All commands that can be invoked from within info_session () receive arguments in the same way. This simple define declares the header of a function named NAME, with associated documentation DOC. The documentation string is groveled out of the source files by the utility program `makedoc', which is also responsible for making the documentation/function-pointer maps. */ #define DECLARE_INFO_COMMAND(name, doc) \ void name (window, count, key) WINDOW *window; int count; unsigned char key; /* Variables found in session.h. */ extern VFunction *info_last_executed_command; /* Variable controlling the garbage collection of files briefly visited during searches. Such files are normally gc'ed, unless they were compressed to begin with. If this variable is non-zero, it says to gc even those file buffer contents which had to be uncompressed. */ extern int gc_compressed_files; /* When non-zero, tiling takes place automatically when info_split_window is called. */ extern int auto_tiling_p; /* Variable controlling the behaviour of default scrolling when you are already at the bottom of a node. */ extern int info_scroll_behaviour; extern char *info_scroll_choices[]; /* Values for info_scroll_behaviour. */ #define IS_Continuous 0 /* Try to get first menu item, or failing that, the "Next:" pointer, or failing that, the "Up:" and "Next:" of the up. */ #define IS_NextOnly 1 /* Try to get "Next:" menu item. */ #define IS_PageOnly 2 /* Simply give up at the bottom of a node. */ /* Utility functions found in session.c */ extern void info_dispatch_on_key (); extern unsigned char info_get_input_char (), info_get_another_input_char (); extern unsigned char info_input_pending_p (); extern void remember_window_and_node (), set_remembered_pagetop_and_point (); extern void set_window_pagetop (), info_set_node_of_window (); extern char *pretty_keyseq (); extern void initialize_keyseq (), add_char_to_keyseq (); extern void info_gather_typeahead (); extern FILE_BUFFER *file_buffer_of_window (); extern long info_search_in_node (), info_target_search_node (); extern void info_select_reference (); extern int info_any_buffered_input_p (); extern void print_node (); extern void dump_node_to_file (), dump_nodes_to_file (); /* Do the physical deletion of WINDOW, and forget this window and associated nodes. */ extern void info_delete_window_internal (); /* Tell Info that input is coming from the file FILENAME. */ extern void info_set_input_from_file (); #define return_if_control_g(val) \ do { \ info_gather_typeahead (); \ if (info_input_pending_p () == Control ('g')) \ return (val); \ } while (0) /* The names of the functions that run an info session. */ /* Starting an info session. */ extern void begin_multiple_window_info_session (), begin_info_session (); extern void begin_info_session_with_error (), info_session (); extern void info_read_and_dispatch (); /* Moving the point within a node. */ extern void info_next_line (), info_prev_line (); extern void info_end_of_line (), info_beginning_of_line (); extern void info_forward_char (), info_backward_char (); extern void info_forward_word (), info_backward_word (); extern void info_beginning_of_node (), info_end_of_node (); extern void info_move_to_prev_xref (), info_move_to_next_xref (); /* Scrolling text within a window. */ extern void info_scroll_forward (), info_scroll_backward (); extern void info_redraw_display (), info_toggle_wrap (); extern void info_move_to_window_line (); /* Manipulating multiple windows. */ extern void info_split_window (), info_delete_window (); extern void info_keep_one_window (), info_grow_window (); extern void info_scroll_other_window (), info_tile_windows (); extern void info_next_window (), info_prev_window (); /* Selecting nodes. */ extern void info_next_node (), info_prev_node (), info_up_node (); extern void info_last_node (), info_first_node (), info_history_node (); extern void info_goto_node (), info_top_node (), info_dir_node (); extern void info_global_next_node (), info_global_prev_node (); extern void info_kill_node (), info_view_file (); /* Selecting cross references. */ extern void info_menu_digit (), info_menu_item (), info_xref_item (); extern void info_find_menu (), info_select_reference_this_line (); /* Hacking numeric arguments. */ extern int info_explicit_arg, info_numeric_arg, info_numeric_arg_sign; extern void info_add_digit_to_numeric_arg (), info_universal_argument (); extern void info_initialize_numeric_arg (), info_numeric_arg_digit_loop (); /* Searching commands. */ extern void info_search (), isearch_forward (), isearch_backward (); /* Dumping and printing nodes. */ extern void info_print_node (); /* Miscellaneous commands. */ extern void info_abort_key (), info_quit (), info_do_lowercase_version (); #endif /* SESSION_H */ texinfo-3.12/info/terminal.h0000444000175000017500000001122706362741410013274 0ustar gg/* terminal.h -- The external interface to terminal I/O. */ /* This file is part of GNU Info, a program for reading online documentation stored in Info format. Copyright (C) 1993, 96, 97 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ #if !defined (TERMINAL_H) #define TERMINAL_H #include "info.h" /* For almost every function externally visible from terminal.c, there is a corresponding "hook" function which can be bound in order to replace the functionality of the one found in terminal.c. This is how we go about implemented X window display. */ /* The width and height of the terminal. */ extern int screenwidth, screenheight; /* Non-zero means this terminal can't really do anything. */ extern int terminal_is_dumb_p; /* Non-zero means that this terminal has a meta key. */ extern int terminal_has_meta_p; /* Non-zero means that this terminal can produce a visible bell. */ extern int terminal_has_visible_bell_p; /* Non-zero means to use that visible bell if at all possible. */ extern int terminal_use_visible_bell_p; /* Non-zero means that this terminal can scroll lines up and down. */ extern int terminal_can_scroll; /* Initialize the terminal which is known as TERMINAL_NAME. If this terminal doesn't have cursor addressability, TERMINAL_IS_DUMB_P becomes non-zero. The variables SCREENHEIGHT and SCREENWIDTH are set to the dimensions that this terminal actually has. The variable TERMINAL_HAS_META_P becomes non- zero if this terminal supports a Meta key. */ extern void terminal_initialize_terminal (); extern VFunction *terminal_initialize_terminal_hook; /* Return the current screen width and height in the variables SCREENWIDTH and SCREENHEIGHT. */ extern void terminal_get_screen_size (); extern VFunction *terminal_get_screen_size_hook; /* Save and restore tty settings. */ extern void terminal_prep_terminal (), terminal_unprep_terminal (); extern VFunction *terminal_prep_terminal_hook, *terminal_unprep_terminal_hook; /* Re-initialize the terminal to TERMINAL_NAME. */ extern void terminal_new_terminal (); extern VFunction *terminal_new_terminal_hook; /* Move the cursor to the terminal location of X and Y. */ extern void terminal_goto_xy (); extern VFunction *terminal_goto_xy_hook; /* Print STRING to the terminal at the current position. */ extern void terminal_put_text (); extern VFunction *terminal_put_text_hook; /* Print NCHARS from STRING to the terminal at the current position. */ extern void terminal_write_chars (); extern VFunction *terminal_write_chars_hook; /* Clear from the current position of the cursor to the end of the line. */ extern void terminal_clear_to_eol (); extern VFunction *terminal_clear_to_eol_hook; /* Clear the entire terminal screen. */ extern void terminal_clear_screen (); extern VFunction *terminal_clear_screen_hook; /* Move the cursor up one line. */ extern void terminal_up_line (); extern VFunction *terminal_up_line_hook; /* Move the cursor down one line. */ extern void terminal_down_line (); extern VFunction *terminal_down_line_hook; /* Turn on reverse video if possible. */ extern void terminal_begin_inverse (); extern VFunction *terminal_begin_inverse_hook; /* Turn off reverse video if possible. */ extern void terminal_end_inverse (); extern VFunction *terminal_end_inverse_hook; /* Scroll an area of the terminal, starting with the region from START to END, AMOUNT lines. If AMOUNT is negative, the lines are scrolled towards the top of the screen, else they are scrolled towards the bottom of the screen. */ extern void terminal_scroll_terminal (); extern VFunction *terminal_scroll_terminal_hook; /* Ring the terminal bell. The bell is run visibly if it both has one and terminal_use_visible_bell_p is non-zero. */ extern void terminal_ring_bell (); extern VFunction *terminal_ring_bell_hook; /* The key sequences output by the arrow keys, if this terminal has any. */ extern char *term_ku, *term_kd, *term_kr, *term_kl; extern char *term_kP, *term_kN; #endif /* !TERMINAL_H */ texinfo-3.12/info/man.c0000444000175000017500000003574606370222247012244 0ustar gg/* man.c: How to read and format man files. $Id: man.c,v 1.6 1997/07/31 23:49:59 karl Exp $ Copyright (C) 1995, 97 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, USA. Written by Brian Fox Thu May 4 09:17:52 1995 (bfox@ai.mit.edu). */ #include "info.h" #include #include "signals.h" #if defined (HAVE_SYS_TIME_H) #include #endif #if defined (HAVE_SYS_WAIT_H) #include #endif #include "tilde.h" #include "man.h" #if !defined (_POSIX_VERSION) #define pid_t int #endif #if defined (FD_SET) # if defined (hpux) # define fd_set_cast(x) (int *)(x) # else # define fd_set_cast(x) (fd_set *)(x) # endif /* !hpux */ #endif /* FD_SET */ static char *read_from_fd (); static void clean_manpage (); static NODE *manpage_node_of_file_buffer (); static char *get_manpage_contents (); NODE * make_manpage_node (pagename) char *pagename; { return (info_get_node (MANPAGE_FILE_BUFFER_NAME, pagename)); } NODE * get_manpage_node (file_buffer, pagename) FILE_BUFFER *file_buffer; char *pagename; { NODE *node; node = manpage_node_of_file_buffer (file_buffer, pagename); if (!node) { char *page; page = get_manpage_contents (pagename); if (page) { char header[1024]; long oldsize, newsize; int hlen, plen; sprintf (header, "\n\n%c\n%s %s, %s %s, %s (dir)\n\n", INFO_COOKIE, INFO_FILE_LABEL, file_buffer->filename, INFO_NODE_LABEL, pagename, INFO_UP_LABEL); oldsize = file_buffer->filesize; hlen = strlen (header); plen = strlen (page); newsize = (oldsize + hlen + plen); file_buffer->contents = (char *)xrealloc (file_buffer->contents, 1 + newsize); memcpy (file_buffer->contents + oldsize, header, hlen); oldsize += hlen; memcpy (file_buffer->contents + oldsize, page, plen); file_buffer->contents[newsize] = '\0'; file_buffer->filesize = newsize; file_buffer->finfo.st_size = newsize; build_tags_and_nodes (file_buffer); free (page); } node = manpage_node_of_file_buffer (file_buffer, pagename); } return (node); } FILE_BUFFER * create_manpage_file_buffer () { FILE_BUFFER *file_buffer = make_file_buffer (); file_buffer->filename = xstrdup (MANPAGE_FILE_BUFFER_NAME); file_buffer->fullpath = xstrdup (MANPAGE_FILE_BUFFER_NAME); file_buffer->finfo.st_size = 0; file_buffer->filesize = 0; file_buffer->contents = (char *)NULL; file_buffer->flags = (N_IsInternal | N_CannotGC | N_IsManPage); return (file_buffer); } /* Scan the list of directories in PATH looking for FILENAME. If we find one that is an executable file, return it as a new string. Otherwise, return a NULL pointer. */ static char * executable_file_in_path (filename, path) char *filename, *path; { struct stat finfo; char *temp_dirname; int statable, dirname_index; dirname_index = 0; while ((temp_dirname = extract_colon_unit (path, &dirname_index))) { char *temp; /* Expand a leading tilde if one is present. */ if (*temp_dirname == '~') { char *expanded_dirname; expanded_dirname = tilde_expand_word (temp_dirname); free (temp_dirname); temp_dirname = expanded_dirname; } temp = (char *)xmalloc (30 + strlen (temp_dirname) + strlen (filename)); strcpy (temp, temp_dirname); if (temp[(strlen (temp)) - 1] != '/') strcat (temp, "/"); strcat (temp, filename); free (temp_dirname); statable = (stat (temp, &finfo) == 0); /* If we have found a regular executable file, then use it. */ if ((statable) && (S_ISREG (finfo.st_mode)) && (access (temp, X_OK) == 0)) return (temp); else free (temp); } return ((char *)NULL); } /* Return the full pathname of the system man page formatter. */ static char * find_man_formatter () { return (executable_file_in_path ("man", (char *)getenv ("PATH"))); } static char *manpage_pagename = (char *)NULL; static char *manpage_section = (char *)NULL; static void get_page_and_section (pagename) char *pagename; { register int i; if (manpage_pagename) free (manpage_pagename); if (manpage_section) free (manpage_section); manpage_pagename = (char *)NULL; manpage_section = (char *)NULL; for (i = 0; pagename[i] != '\0' && pagename[i] != '('; i++); manpage_pagename = (char *)xmalloc (1 + i); strncpy (manpage_pagename, pagename, i); manpage_pagename[i] = '\0'; if (pagename[i] == '(') { int start; start = i + 1; for (i = start; pagename[i] != '\0' && pagename[i] != ')'; i++); manpage_section = (char *)xmalloc (1 + (i - start)); strncpy (manpage_section, pagename + start, (i - start)); manpage_section[i - start] = '\0'; } } static void reap_children (sig) int sig; { int status; wait (&status); } static char * get_manpage_contents (pagename) char *pagename; { static char *formatter_args[4] = { (char *)NULL }; int pipes[2]; pid_t child; char *formatted_page = (char *)NULL; int arg_index = 1; if (formatter_args[0] == (char *)NULL) formatter_args[0] = find_man_formatter (); if (formatter_args[0] == (char *)NULL) return ((char *)NULL); get_page_and_section (pagename); if (manpage_section != (char *)NULL) formatter_args[arg_index++] = manpage_section; formatter_args[arg_index++] = manpage_pagename; formatter_args[arg_index] = (char *)NULL; /* Open a pipe to this program, read the output, and save it away in FORMATTED_PAGE. The reader end of the pipe is pipes[0]; the writer end is pipes[1]. */ pipe (pipes); signal (SIGCHLD, reap_children); child = fork (); if (child == -1) return ((char *)NULL); if (child != 0) { /* In the parent, close the writing end of the pipe, and read from the exec'd child. */ close (pipes[1]); formatted_page = read_from_fd (pipes[0]); close (pipes[0]); } else { /* In the child, close the read end of the pipe, make the write end of the pipe be stdout, and execute the man page formatter. */ close (pipes[0]); close (fileno (stderr)); close (fileno (stdin)); /* Don't print errors. */ dup2 (pipes[1], fileno (stdout)); execv (formatter_args[0], formatter_args); /* If we get here, we couldn't exec, so close out the pipe and exit. */ close (pipes[1]); exit (0); } /* If we have the page, then clean it up. */ if (formatted_page) clean_manpage (formatted_page); return (formatted_page); } static void clean_manpage (manpage) char *manpage; { register int i, j; int newline_count = 0; char *newpage; newpage = (char *)xmalloc (1 + strlen (manpage)); for (i = 0, j = 0; (newpage[j] = manpage[i]); i++, j++) { if (manpage[i] == '\n') newline_count++; else newline_count = 0; if (newline_count == 3) { j--; newline_count--; } if (manpage[i] == '\b' || manpage[i] == '\f') j -= 2; } newpage[j++] = '\0'; strcpy (manpage, newpage); free (newpage); } static NODE * manpage_node_of_file_buffer (file_buffer, pagename) FILE_BUFFER *file_buffer; char *pagename; { NODE *node = (NODE *)NULL; TAG *tag = (TAG *)NULL; if (file_buffer->contents) { register int i; for (i = 0; (tag = file_buffer->tags[i]); i++) { if (strcasecmp (pagename, tag->nodename) == 0) break; } } if (tag) { node = (NODE *)xmalloc (sizeof (NODE)); node->filename = file_buffer->filename; node->nodename = tag->nodename; node->contents = file_buffer->contents + tag->nodestart; node->nodelen = tag->nodelen; node->flags = 0; node->parent = (char *)NULL; node->flags = (N_HasTagsTable | N_IsManPage); node->contents += skip_node_separator (node->contents); } return (node); } static char * read_from_fd (fd) int fd; { struct timeval timeout; char *buffer = (char *)NULL; int bsize = 0; int bindex = 0; int select_result; #if defined (FD_SET) fd_set read_fds; timeout.tv_sec = 15; timeout.tv_usec = 0; FD_ZERO (&read_fds); FD_SET (fd, &read_fds); select_result = select (fd + 1, fd_set_cast (&read_fds), 0, 0, &timeout); #else /* !FD_SET */ select_result = 1; #endif /* !FD_SET */ switch (select_result) { case 0: case -1: break; default: { int amount_read; int done = 0; while (!done) { while ((bindex + 1024) > (bsize)) buffer = (char *)xrealloc (buffer, (bsize += 1024)); buffer[bindex] = '\0'; amount_read = read (fd, buffer + bindex, 1023); if (amount_read < 0) { done = 1; } else { bindex += amount_read; buffer[bindex] = '\0'; if (amount_read == 0) done = 1; } } } } if ((buffer != (char *)NULL) && (*buffer == '\0')) { free (buffer); buffer = (char *)NULL; } return (buffer); } static char *reference_section_starters[] = { "\nRELATED INFORMATION", "\nRELATED\tINFORMATION", "RELATED INFORMATION\n", "RELATED\tINFORMATION\n", "\nSEE ALSO", "\nSEE\tALSO", "SEE ALSO\n", "SEE\tALSO\n", (char *)NULL }; static SEARCH_BINDING frs_binding; static SEARCH_BINDING * find_reference_section (node) NODE *node; { register int i; long position = -1; frs_binding.buffer = node->contents; frs_binding.start = 0; frs_binding.end = node->nodelen; frs_binding.flags = S_SkipDest; for (i = 0; reference_section_starters[i] != (char *)NULL; i++) { position = search_forward (reference_section_starters[i], &frs_binding); if (position != -1) break; } if (position == -1) return ((SEARCH_BINDING *)NULL); /* We found the start of the reference section, and point is right after the string which starts it. The text from here to the next header (or end of buffer) contains the only references in this manpage. */ frs_binding.start = position; for (i = frs_binding.start; i < frs_binding.end - 2; i++) { if ((frs_binding.buffer[i] == '\n') && (!whitespace (frs_binding.buffer[i + 1]))) { frs_binding.end = i; break; } } return (&frs_binding); } REFERENCE ** xrefs_of_manpage (node) NODE *node; { SEARCH_BINDING *reference_section; REFERENCE **refs = (REFERENCE **)NULL; int refs_index = 0; int refs_slots = 0; long position; reference_section = find_reference_section (node); if (reference_section == (SEARCH_BINDING *)NULL) return ((REFERENCE **)NULL); /* Grovel the reference section building a list of references found there. A reference is alphabetic characters followed by non-whitespace text within parenthesis. */ reference_section->flags = 0; while ((position = search_forward ("(", reference_section)) != -1) { register int start, end; for (start = position; start > reference_section->start; start--) if (whitespace (reference_section->buffer[start])) break; start++; for (end = position; end < reference_section->end; end++) { if (whitespace (reference_section->buffer[end])) { end = start; break; } if (reference_section->buffer[end] == ')') { end++; break; } } if (end != start) { REFERENCE *entry; int len = end - start; entry = (REFERENCE *)xmalloc (sizeof (REFERENCE)); entry->label = (char *)xmalloc (1 + len); strncpy (entry->label, (reference_section->buffer) + start, len); entry->label[len] = '\0'; entry->filename = xstrdup (node->filename); entry->nodename = xstrdup (entry->label); entry->start = start; entry->end = end; add_pointer_to_array (entry, refs_index, refs, refs_slots, 10, REFERENCE *); } reference_section->start = position + 1; } return (refs); } long locate_manpage_xref (node, start, dir) NODE *node; long start; int dir; { REFERENCE **refs; long position = -1; refs = xrefs_of_manpage (node); if (refs) { register int i, count; REFERENCE *entry; for (i = 0; refs[i]; i++); count = i; if (dir > 0) { for (i = 0; (entry = refs[i]); i++) if (entry->start > start) { position = entry->start; break; } } else { for (i = count - 1; i > -1; i--) { entry = refs[i]; if (entry->start < start) { position = entry->start; break; } } } info_free_references (refs); } return (position); } /* This one was a little tricky. The binding buffer that is passed in has a START and END value of 0 -- strlen (window-line-containing-point). The BUFFER is a pointer to the start of that line. */ REFERENCE ** manpage_xrefs_in_binding (node, binding) NODE *node; SEARCH_BINDING *binding; { register int i; REFERENCE **all_refs = xrefs_of_manpage (node); REFERENCE **brefs = (REFERENCE **)NULL; REFERENCE *entry; int brefs_index = 0; int brefs_slots = 0; int start, end; if (!all_refs) return ((REFERENCE **)NULL); start = binding->start + (binding->buffer - node->contents); end = binding->end + (binding->buffer - node->contents); for (i = 0; (entry = all_refs[i]); i++) { if ((entry->start > start) && (entry->end < end)) { add_pointer_to_array (entry, brefs_index, brefs, brefs_slots, 10, REFERENCE *); } else { maybe_free (entry->label); maybe_free (entry->filename); maybe_free (entry->nodename); free (entry); } } free (all_refs); return (brefs); } texinfo-3.12/info/dir.c0000444000175000017500000002172006366734400012236 0ustar gg/* dir.c -- How to build a special "dir" node from "localdir" files. $Id: dir.c,v 1.6 1997/07/27 21:09:20 karl Exp $ Copyright (C) 1993, 97 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ #include "info.h" #include "info-utils.h" #include "filesys.h" #include "tilde.h" /* The "dir" node can be built from the contents of a file called "dir", with the addition of the menus of every file named in the array dirs_to_add which are found in INFOPATH. */ static void add_menu_to_file_buffer (), insert_text_into_fb_at_binding (); static char *dirs_to_add[] = { "dir", "localdir", (char *)NULL }; /* Return zero if the file represented in the stat structure TEST has already been seen, nonzero else. */ typedef struct { unsigned long device; unsigned long inode; } dir_file_list_entry_type; static int new_dir_file_p (test) struct stat *test; { static unsigned dir_file_list_len = 0; static dir_file_list_entry_type *dir_file_list = NULL; unsigned i; for (i = 0; i < dir_file_list_len; i++) { dir_file_list_entry_type entry; entry = dir_file_list[i]; if (entry.device == test->st_dev && entry.inode == test->st_ino) return 0; } dir_file_list_len++; dir_file_list = xrealloc (dir_file_list, dir_file_list_len * sizeof (dir_file_list_entry_type)); dir_file_list[dir_file_list_len - 1].device = test->st_dev; dir_file_list[dir_file_list_len - 1].inode = test->st_ino; return 1; } void maybe_build_dir_node (dirname) char *dirname; { int path_index, update_tags; char *this_dir; FILE_BUFFER *dir_buffer = info_find_file (dirname); /* If there is no "dir" in the current info path, we cannot build one from nothing. */ if (!dir_buffer) return; /* If this directory has already been built, return now. */ if (dir_buffer->flags & N_CannotGC) return; /* Initialize the list we use to avoid reading the same dir file twice with the dir file just found. */ new_dir_file_p (&dir_buffer->finfo); path_index = update_tags = 0; /* Using each element of the path, check for one of the files in DIRS_TO_ADD. Do not check for "localdir.info.Z" or anything else. Only files explictly named are eligible. This is a design decision. There can be an info file name "localdir.info" which contains information on the setting up of "localdir" files. */ while ((this_dir = extract_colon_unit (infopath, &path_index))) { register int da_index; char *from_file; /* Expand a leading tilde if one is present. */ if (*this_dir == '~') { char *tilde_expanded_dirname; tilde_expanded_dirname = tilde_expand_word (this_dir); if (tilde_expanded_dirname != this_dir) { free (this_dir); this_dir = tilde_expanded_dirname; } } /* For every different file named in DIRS_TO_ADD found in the search path, add that file's menu to our "dir" node. */ for (da_index = 0; (from_file = dirs_to_add[da_index]); da_index++) { struct stat finfo; int statable; int namelen = strlen (from_file); char *fullpath = xmalloc (3 + strlen (this_dir) + namelen); strcpy (fullpath, this_dir); if (fullpath[strlen (fullpath) - 1] != '/') strcat (fullpath, "/"); strcat (fullpath, from_file); statable = (stat (fullpath, &finfo) == 0); /* Only add this file if we have not seen it before. */ if (statable && S_ISREG (finfo.st_mode) && new_dir_file_p (&finfo)) { long filesize; char *contents = filesys_read_info_file (fullpath, &filesize, &finfo); if (contents) { update_tags++; add_menu_to_file_buffer (contents, filesize, dir_buffer); free (contents); } } free (fullpath); } free (this_dir); } if (update_tags) build_tags_and_nodes (dir_buffer); /* Flag that the dir buffer has been built. */ dir_buffer->flags |= N_CannotGC; } /* Given CONTENTS and FB (a file buffer), add the menu found in CONTENTS to the menu found in FB->contents. Second argument SIZE is the total size of CONTENTS. */ static void add_menu_to_file_buffer (contents, size, fb) char *contents; long size; FILE_BUFFER *fb; { SEARCH_BINDING contents_binding, fb_binding; long contents_offset, fb_offset; contents_binding.buffer = contents; contents_binding.start = 0; contents_binding.end = size; contents_binding.flags = S_FoldCase | S_SkipDest; fb_binding.buffer = fb->contents; fb_binding.start = 0; fb_binding.end = fb->filesize; fb_binding.flags = S_FoldCase | S_SkipDest; /* Move to the start of the menus in CONTENTS and FB. */ contents_offset = search_forward (INFO_MENU_LABEL, &contents_binding); fb_offset = search_forward (INFO_MENU_LABEL, &fb_binding); /* If there is no menu in CONTENTS, quit now. */ if (contents_offset == -1) return; /* There is a menu in CONTENTS, and contents_offset points to the first character following the menu starter string. Skip all whitespace and newline characters. */ contents_offset += skip_whitespace_and_newlines (contents + contents_offset); /* If there is no menu in FB, make one. */ if (fb_offset == -1) { /* Find the start of the second node in this file buffer. If there is only one node, we will be adding the contents to the end of this node. */ fb_offset = find_node_separator (&fb_binding); /* If not even a single node separator, give up. */ if (fb_offset == -1) return; fb_binding.start = fb_offset; fb_binding.start += skip_node_separator (fb_binding.buffer + fb_binding.start); /* Try to find the next node separator. */ fb_offset = find_node_separator (&fb_binding); /* If found one, consider that the start of the menu. Otherwise, the start of this menu is the end of the file buffer (i.e., fb->size). */ if (fb_offset != -1) fb_binding.start = fb_offset; else fb_binding.start = fb_binding.end; insert_text_into_fb_at_binding (fb, &fb_binding, INFO_MENU_LABEL, strlen (INFO_MENU_LABEL)); fb_binding.buffer = fb->contents; fb_binding.start = 0; fb_binding.end = fb->filesize; fb_offset = search_forward (INFO_MENU_LABEL, &fb_binding); if (fb_offset == -1) abort (); } /* CONTENTS_OFFSET and FB_OFFSET point to the starts of the menus that appear in their respective buffers. Add the remainder of CONTENTS to the end of FB's menu. */ fb_binding.start = fb_offset; fb_offset = find_node_separator (&fb_binding); if (fb_offset != -1) fb_binding.start = fb_offset; else fb_binding.start = fb_binding.end; /* Leave exactly one blank line between directory entries. */ { int num_found = 0; while ((fb_binding.start > 0) && (whitespace_or_newline (fb_binding.buffer[fb_binding.start - 1]))) { num_found++; fb_binding.start--; } /* Optimize if possible. */ if (num_found >= 2) { fb_binding.buffer[fb_binding.start++] = '\n'; fb_binding.buffer[fb_binding.start++] = '\n'; } else { /* Do it the hard way. */ insert_text_into_fb_at_binding (fb, &fb_binding, "\n\n", 2); fb_binding.start += 2; } } /* Insert the new menu. */ insert_text_into_fb_at_binding (fb, &fb_binding, contents + contents_offset, size - contents_offset); } static void insert_text_into_fb_at_binding (fb, binding, text, textlen) FILE_BUFFER *fb; SEARCH_BINDING *binding; char *text; int textlen; { char *contents; long start, end; start = binding->start; end = fb->filesize; contents = (char *)xmalloc (fb->filesize + textlen + 1); memcpy (contents, fb->contents, start); memcpy (contents + start, text, textlen); memcpy (contents + start + textlen, fb->contents + start, end - start); free (fb->contents); fb->contents = contents; fb->filesize += textlen; fb->finfo.st_size = fb->filesize; } texinfo-3.12/info/Makefile.in0000664000175000017500000003454406477056746013412 0ustar gg# Makefile.in generated automatically by automake 1.2f from Makefile.am # Copyright (C) 1994, 1995, 1996, 1997, 1998 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. SHELL = /bin/sh srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ bindir = @bindir@ sbindir = @sbindir@ libexecdir = @libexecdir@ datadir = @datadir@ sysconfdir = @sysconfdir@ sharedstatedir = @sharedstatedir@ localstatedir = @localstatedir@ libdir = @libdir@ infodir = @infodir@ mandir = @mandir@ includedir = @includedir@ oldincludedir = /usr/include pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = .. ACLOCAL = @ACLOCAL@ AUTOCONF = @AUTOCONF@ AUTOMAKE = @AUTOMAKE@ AUTOHEADER = @AUTOHEADER@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : CATALOGS = @CATALOGS@ CATOBJEXT = @CATOBJEXT@ CC = @CC@ DATADIRNAME = @DATADIRNAME@ GENCAT = @GENCAT@ GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ GT_NO = @GT_NO@ GT_YES = @GT_YES@ INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@ INSTOBJEXT = @INSTOBJEXT@ INTLDEPS = @INTLDEPS@ INTLLIBS = @INTLLIBS@ INTLOBJS = @INTLOBJS@ MAKEINFO = @MAKEINFO@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ PACKAGE = @PACKAGE@ POFILES = @POFILES@ POSUB = @POSUB@ RANLIB = @RANLIB@ TERMLIBS = @TERMLIBS@ TEXCONFIG = @TEXCONFIG@ TEXMF = @TEXMF@ USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ l = @l@ noinst_PROGRAMS = makedoc # Use `ginfo' for building to avoid confusion with the standard `info' # target. The install rule removes the `g' before applying any # user-specified name transformations. bin_PROGRAMS = ginfo transform = s/ginfo/info/; @program_transform_name@ localedir = $(datadir)/locale # -I. for funs.h. # Automake puts -I.. and -I$(srcdir) into DEFS by default, but # we need to override it, so include them ourselves. INCLUDES = -I. -I$(top_srcdir)/lib -I../intl -I.. -I$(srcdir) DEFS = -DINFODIR=\"$(infodir)\" -DLOCALEDIR=\"$(localedir)\" @DEFS@ LDADD = ../lib/libtxi.a @TERMLIBS@ @INTLLIBS@ makedoc_SOURCES = makedoc.c ginfo_SOURCES = dir.c display.c display.h doc.c doc.h dribble.c dribble.h \ echo-area.c echo-area.h \ filesys.c filesys.h footnotes.c footnotes.h funs.h gc.c gc.h \ indices.c indices.h info-utils.c info-utils.h info.c info.h infodoc.c \ infomap.c infomap.h m-x.c man.c man.h nodemenu.c nodes.c nodes.h \ search.c search.h session.c session.h signals.c signals.h \ termdep.h terminal.c terminal.h tilde.c tilde.h \ variables.c variables.h window.c window.h EXTRA_DIST = README # The files `doc.c' and `funs.h' are created by ./makedoc run over the source # files which contain DECLARE_INFO_COMMAND. `funs.h' is a header file # listing the functions found. `doc.c' is a structure containing pointers # to those functions along with completable names and documentation strings. BUILT_SOURCES = doc.c funs.h cmd_sources = $(srcdir)/session.c $(srcdir)/echo-area.c $(srcdir)/infodoc.c \ $(srcdir)/m-x.c $(srcdir)/indices.c $(srcdir)/nodemenu.c \ $(srcdir)/footnotes.c $(srcdir)/variables.c mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = ../config.h CONFIG_CLEAN_FILES = PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ ginfo_OBJECTS = dir.o display.o doc.o dribble.o echo-area.o filesys.o \ footnotes.o gc.o indices.o info-utils.o info.o infodoc.o infomap.o \ m-x.o man.o nodemenu.o nodes.o search.o session.o signals.o terminal.o \ tilde.o variables.o window.o ginfo_LDADD = $(LDADD) ginfo_DEPENDENCIES = ../lib/libtxi.a ginfo_LDFLAGS = makedoc_OBJECTS = makedoc.o makedoc_LDADD = $(LDADD) makedoc_DEPENDENCIES = ../lib/libtxi.a makedoc_LDFLAGS = CFLAGS = @CFLAGS@ COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) LINK = $(CC) $(CFLAGS) $(LDFLAGS) -o $@ DIST_COMMON = README Makefile.am Makefile.in DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) TAR = tar GZIP = --best SOURCES = $(ginfo_SOURCES) $(makedoc_SOURCES) OBJECTS = $(ginfo_OBJECTS) $(makedoc_OBJECTS) default: all .SUFFIXES: .SUFFIXES: .S .c .o .s $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps info/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) \ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status mostlyclean-binPROGRAMS: clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) distclean-binPROGRAMS: maintainer-clean-binPROGRAMS: install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) $(mkinstalldirs) $(bindir) @list='$(bin_PROGRAMS)'; for p in $$list; do \ if test -f $$p; then \ echo " $(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p|sed '$(transform)'`"; \ $(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p|sed '$(transform)'`; \ else :; fi; \ done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) list='$(bin_PROGRAMS)'; for p in $$list; do \ rm -f $(bindir)/`echo $$p|sed '$(transform)'`; \ done mostlyclean-noinstPROGRAMS: clean-noinstPROGRAMS: -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) distclean-noinstPROGRAMS: maintainer-clean-noinstPROGRAMS: .c.o: $(COMPILE) -c $< .s.o: $(COMPILE) -c $< .S.o: $(COMPILE) -c $< mostlyclean-compile: -rm -f *.o core *.core clean-compile: distclean-compile: -rm -f *.tab.c maintainer-clean-compile: ginfo: $(ginfo_OBJECTS) $(ginfo_DEPENDENCIES) @rm -f ginfo $(LINK) $(ginfo_LDFLAGS) $(ginfo_OBJECTS) $(ginfo_LDADD) $(LIBS) makedoc: $(makedoc_OBJECTS) $(makedoc_DEPENDENCIES) @rm -f makedoc $(LINK) $(makedoc_LDFLAGS) $(makedoc_OBJECTS) $(makedoc_LDADD) $(LIBS) tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) here=`pwd` && cd $(srcdir) \ && mkid -f$$here/ID $(SOURCES) $(HEADERS) $(LISP) TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS)'; \ unique=`for i in $$list; do echo $$i; done | \ awk ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) mostlyclean-tags: clean-tags: distclean-tags: -rm -f TAGS ID maintainer-clean-tags: distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) subdir = info distdir: $(DISTFILES) @for file in $(DISTFILES); do \ d=$(srcdir); \ test -f $(distdir)/$$file \ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ || cp -p $$d/$$file $(distdir)/$$file; \ done dir.o: dir.c info.h ../lib/system.h ../config.h filesys.h display.h \ info-utils.h nodes.h window.h infomap.h search.h terminal.h \ session.h dribble.h echo-area.h doc.h footnotes.h gc.h tilde.h display.o: display.c info.h ../lib/system.h ../config.h filesys.h \ display.h info-utils.h nodes.h window.h infomap.h search.h \ terminal.h session.h dribble.h echo-area.h doc.h footnotes.h \ gc.h doc.o: doc.c doc.h info.h ../lib/system.h ../config.h filesys.h \ display.h info-utils.h nodes.h window.h infomap.h search.h \ terminal.h session.h dribble.h echo-area.h footnotes.h gc.h \ funs.h dribble.o: dribble.c info.h ../lib/system.h ../config.h filesys.h \ display.h info-utils.h nodes.h window.h infomap.h search.h \ terminal.h session.h dribble.h echo-area.h doc.h footnotes.h \ gc.h echo-area.o: echo-area.c info.h ../lib/system.h ../config.h filesys.h \ display.h info-utils.h nodes.h window.h infomap.h search.h \ terminal.h session.h dribble.h echo-area.h doc.h footnotes.h \ gc.h filesys.o: filesys.c info.h ../lib/system.h ../config.h filesys.h \ display.h info-utils.h nodes.h window.h infomap.h search.h \ terminal.h session.h dribble.h echo-area.h doc.h footnotes.h \ gc.h tilde.h footnotes.o: footnotes.c info.h ../lib/system.h ../config.h filesys.h \ display.h info-utils.h nodes.h window.h infomap.h search.h \ terminal.h session.h dribble.h echo-area.h doc.h footnotes.h \ gc.h gc.o: gc.c info.h ../lib/system.h ../config.h filesys.h display.h \ info-utils.h nodes.h window.h infomap.h search.h terminal.h \ session.h dribble.h echo-area.h doc.h footnotes.h gc.h indices.o: indices.c info.h ../lib/system.h ../config.h filesys.h \ display.h info-utils.h nodes.h window.h infomap.h search.h \ terminal.h session.h dribble.h echo-area.h doc.h footnotes.h \ gc.h indices.h info-utils.o: info-utils.c info.h ../lib/system.h ../config.h filesys.h \ display.h info-utils.h nodes.h window.h infomap.h search.h \ terminal.h session.h dribble.h echo-area.h doc.h footnotes.h \ gc.h man.h info.o: info.c info.h ../lib/system.h ../config.h filesys.h display.h \ info-utils.h nodes.h window.h infomap.h search.h terminal.h \ session.h dribble.h echo-area.h doc.h footnotes.h gc.h \ indices.h ../lib/getopt.h man.h infodoc.o: infodoc.c info.h ../lib/system.h ../config.h filesys.h \ display.h info-utils.h nodes.h window.h infomap.h search.h \ terminal.h session.h dribble.h echo-area.h doc.h footnotes.h \ gc.h infomap.o: infomap.c info.h ../lib/system.h ../config.h filesys.h \ display.h info-utils.h nodes.h window.h infomap.h search.h \ terminal.h session.h dribble.h echo-area.h doc.h footnotes.h \ gc.h funs.h m-x.o: m-x.c info.h ../lib/system.h ../config.h filesys.h display.h \ info-utils.h nodes.h window.h infomap.h search.h terminal.h \ session.h dribble.h echo-area.h doc.h footnotes.h gc.h makedoc.o: makedoc.c info.h ../lib/system.h ../config.h filesys.h \ display.h info-utils.h nodes.h window.h infomap.h search.h \ terminal.h session.h dribble.h echo-area.h doc.h footnotes.h \ gc.h man.o: man.c info.h ../lib/system.h ../config.h filesys.h display.h \ info-utils.h nodes.h window.h infomap.h search.h terminal.h \ session.h dribble.h echo-area.h doc.h footnotes.h gc.h \ signals.h tilde.h man.h nodemenu.o: nodemenu.c info.h ../lib/system.h ../config.h filesys.h \ display.h info-utils.h nodes.h window.h infomap.h search.h \ terminal.h session.h dribble.h echo-area.h doc.h footnotes.h \ gc.h nodes.o: nodes.c info.h ../lib/system.h ../config.h filesys.h display.h \ info-utils.h nodes.h window.h infomap.h search.h terminal.h \ session.h dribble.h echo-area.h doc.h footnotes.h gc.h man.h search.o: search.c info.h ../lib/system.h ../config.h filesys.h \ display.h info-utils.h nodes.h window.h infomap.h search.h \ terminal.h session.h dribble.h echo-area.h doc.h footnotes.h \ gc.h session.o: session.c info.h ../lib/system.h ../config.h filesys.h \ display.h info-utils.h nodes.h window.h infomap.h search.h \ terminal.h session.h dribble.h echo-area.h doc.h footnotes.h \ gc.h man.h signals.o: signals.c info.h ../lib/system.h ../config.h filesys.h \ display.h info-utils.h nodes.h window.h infomap.h search.h \ terminal.h session.h dribble.h echo-area.h doc.h footnotes.h \ gc.h signals.h terminal.o: terminal.c info.h ../lib/system.h ../config.h filesys.h \ display.h info-utils.h nodes.h window.h infomap.h search.h \ terminal.h session.h dribble.h echo-area.h doc.h footnotes.h \ gc.h termdep.h tilde.o: tilde.c info.h ../lib/system.h ../config.h filesys.h display.h \ info-utils.h nodes.h window.h infomap.h search.h terminal.h \ session.h dribble.h echo-area.h doc.h footnotes.h gc.h variables.o: variables.c info.h ../lib/system.h ../config.h filesys.h \ display.h info-utils.h nodes.h window.h infomap.h search.h \ terminal.h session.h dribble.h echo-area.h doc.h footnotes.h \ gc.h variables.h window.o: window.c info.h ../lib/system.h ../config.h filesys.h \ display.h info-utils.h nodes.h window.h infomap.h search.h \ terminal.h session.h dribble.h echo-area.h doc.h footnotes.h \ gc.h info: dvi: check: all $(MAKE) installcheck: install-exec: install-binPROGRAMS @$(NORMAL_INSTALL) install-data: @$(NORMAL_INSTALL) install: install-exec install-data all @: uninstall: uninstall-binPROGRAMS all: Makefile $(PROGRAMS) install-strip: $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install installdirs: $(mkinstalldirs) $(bindir) mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -rm -f Makefile $(DISTCLEANFILES) -rm -f config.cache config.log stamp-h stamp-h[0-9]* -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) mostlyclean: mostlyclean-binPROGRAMS mostlyclean-noinstPROGRAMS \ mostlyclean-compile mostlyclean-tags \ mostlyclean-generic clean: clean-binPROGRAMS clean-noinstPROGRAMS clean-compile clean-tags \ clean-generic mostlyclean distclean: distclean-binPROGRAMS distclean-noinstPROGRAMS \ distclean-compile distclean-tags distclean-generic \ clean -rm -f config.status maintainer-clean: maintainer-clean-binPROGRAMS \ maintainer-clean-noinstPROGRAMS \ maintainer-clean-compile maintainer-clean-tags \ maintainer-clean-generic distclean @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." .PHONY: default mostlyclean-binPROGRAMS distclean-binPROGRAMS \ clean-binPROGRAMS maintainer-clean-binPROGRAMS uninstall-binPROGRAMS \ install-binPROGRAMS mostlyclean-noinstPROGRAMS distclean-noinstPROGRAMS \ clean-noinstPROGRAMS maintainer-clean-noinstPROGRAMS \ mostlyclean-compile distclean-compile clean-compile \ maintainer-clean-compile tags mostlyclean-tags distclean-tags \ clean-tags maintainer-clean-tags distdir info dvi installcheck \ install-exec install-data install uninstall all installdirs \ mostlyclean-generic distclean-generic clean-generic \ maintainer-clean-generic clean mostlyclean distclean maintainer-clean $(BUILT_SOURCES): makedoc $(cmd_sources) ./makedoc $(cmd_sources) # 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: texinfo-3.12/info/termdep.h0000444000175000017500000000345606362741437013137 0ustar gg/* termdep.h -- System things that terminal.c depends on. $Id: termdep.h,v 1.3 1997/07/05 21:17:14 karl Exp $ This file is part of GNU Info, a program for reading online documentation stored in Info format. Copyright (C) 1993, 96, 97 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ #ifndef INFO_TERMDEP_H #define INFO_TERMDEP_H /* NeXT supplies but it is broken. Probably Autoconf should have a separate test, but anyway ... */ #ifdef NeXT #undef HAVE_TERMIOS_H #endif #ifdef HAVE_TERMIOS_H # include #else # if defined (HAVE_TERMIO_H) # include # if defined (HAVE_SYS_PTEM_H) # if defined (M_UNIX) || !defined (M_XENIX) # include # include # undef TIOCGETC # else /* M_XENIX */ # define tchars tc # endif /* M_XENIX */ # endif /* HAVE_SYS_PTEM_H */ # else /* !HAVE_TERMIO_H */ # include # endif /* !HAVE_TERMIO_H */ #endif /* !HAVE_TERMIOS_H */ #ifdef HAVE_SYS_TTOLD_H # include #endif /* HAVE_SYS_TTOLD_H */ #endif /* not INFO_TERMDEP_H */ texinfo-3.12/info/info-utils.c0000444000175000017500000004201306362741222013543 0ustar gg/* info-utils.c -- Useful functions for manipulating Info file quirks. */ /* This file is part of GNU Info, a program for reading online documentation stored in Info format. Copyright (C) 1993 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ #include "info.h" #include "info-utils.h" #if defined (HANDLE_MAN_PAGES) # include "man.h" #endif /* HANDLE_MAN_PAGES */ /* When non-zero, various display and input functions handle ISO Latin character sets correctly. */ int ISO_Latin_p = 0; /* Variable which holds the most recent filename parsed as a result of calling info_parse_xxx (). */ char *info_parsed_filename = (char *)NULL; /* Variable which holds the most recent nodename parsed as a result of calling info_parse_xxx (). */ char *info_parsed_nodename = (char *)NULL; /* Functions to remember a filename or nodename for later return. */ static void save_filename (), saven_filename (); static void save_nodename (), saven_nodename (); /* How to get a reference (either menu or cross). */ static REFERENCE **info_references_internal (); /* Parse the filename and nodename out of STRING. If STRING doesn't contain a filename (i.e., it is NOT (FILENAME)NODENAME) then set INFO_PARSED_FILENAME to NULL. If second argument NEWLINES_OKAY is non-zero, it says to allow the nodename specification to cross a newline boundary (i.e., only `,', `.', or `TAB' can end the spec). */ void info_parse_node (string, newlines_okay) char *string; int newlines_okay; { register int i = 0; /* Default the answer. */ save_filename ((char *)NULL); save_nodename ((char *)NULL); /* Special case of nothing passed. Return nothing. */ if (!string || !*string) return; string += skip_whitespace (string); /* Check for (FILENAME)NODENAME. */ if (*string == '(') { i = 0; /* Advance past the opening paren. */ string++; /* Find the closing paren. */ while (string[i] && string[i] != ')') i++; /* Remember parsed filename. */ saven_filename (string, i); /* Point directly at the nodename. */ string += i; if (*string) string++; } /* Parse out nodename. */ i = skip_node_characters (string, newlines_okay); saven_nodename (string, i); canonicalize_whitespace (info_parsed_nodename); if (info_parsed_nodename && !*info_parsed_nodename) { free (info_parsed_nodename); info_parsed_nodename = (char *)NULL; } } /* Return the node addressed by LABEL in NODE (usually one of "Prev:", "Next:", "Up:", "File:", or "Node:". After a call to this function, the global INFO_PARSED_NODENAME and INFO_PARSED_FILENAME contain the information. */ void info_parse_label (label, node) char *label; NODE *node; { register int i; char *nodeline; /* Default answer to failure. */ save_nodename ((char *)NULL); save_filename ((char *)NULL); /* Find the label in the first line of this node. */ nodeline = node->contents; i = string_in_line (label, nodeline); if (i == -1) return; nodeline += i; nodeline += skip_whitespace (nodeline); info_parse_node (nodeline, DONT_SKIP_NEWLINES); } /* **************************************************************** */ /* */ /* Finding and Building Menus */ /* */ /* **************************************************************** */ /* Return a NULL terminated array of REFERENCE * which represents the menu found in NODE. If there is no menu in NODE, just return a NULL pointer. */ REFERENCE ** info_menu_of_node (node) NODE *node; { long position; SEARCH_BINDING search; REFERENCE **menu = (REFERENCE **)NULL; search.buffer = node->contents; search.start = 0; search.end = node->nodelen; search.flags = S_FoldCase; /* Find the start of the menu. */ position = search_forward (INFO_MENU_LABEL, &search); if (position == -1) return ((REFERENCE **) NULL); /* We have the start of the menu now. Glean menu items from the rest of the node. */ search.start = position + strlen (INFO_MENU_LABEL); search.start += skip_line (search.buffer + search.start); search.start--; menu = info_menu_items (&search); return (menu); } /* Return a NULL terminated array of REFERENCE * which represents the cross refrences found in NODE. If there are no cross references in NODE, just return a NULL pointer. */ REFERENCE ** info_xrefs_of_node (node) NODE *node; { SEARCH_BINDING search; #if defined (HANDLE_MAN_PAGES) if (node->flags & N_IsManPage) return (xrefs_of_manpage (node)); #endif search.buffer = node->contents; search.start = 0; search.end = node->nodelen; search.flags = S_FoldCase; return (info_xrefs (&search)); } /* Glean menu entries from BINDING->buffer + BINDING->start until we have looked at the entire contents of BINDING. Return an array of REFERENCE * that represents each menu item in this range. */ REFERENCE ** info_menu_items (binding) SEARCH_BINDING *binding; { return (info_references_internal (INFO_MENU_ENTRY_LABEL, binding)); } /* Glean cross references from BINDING->buffer + BINDING->start until BINDING->end. Return an array of REFERENCE * that represents each cross reference in this range. */ REFERENCE ** info_xrefs (binding) SEARCH_BINDING *binding; { return (info_references_internal (INFO_XREF_LABEL, binding)); } /* Glean cross references or menu items from BINDING. Return an array of REFERENCE * that represents the items found. */ static REFERENCE ** info_references_internal (label, binding) char *label; SEARCH_BINDING *binding; { SEARCH_BINDING search; REFERENCE **refs = (REFERENCE **)NULL; int refs_index = 0, refs_slots = 0; int searching_for_menu_items = 0; long position; search.buffer = binding->buffer; search.start = binding->start; search.end = binding->end; search.flags = S_FoldCase | S_SkipDest; searching_for_menu_items = (strcasecmp (label, INFO_MENU_ENTRY_LABEL) == 0); while ((position = search_forward (label, &search)) != -1) { int offset, start; char *refdef; REFERENCE *entry; search.start = position; search.start += skip_whitespace (search.buffer + search.start); start = search.start - binding->start; refdef = search.buffer + search.start; offset = string_in_line (":", refdef); /* When searching for menu items, if no colon, there is no menu item on this line. */ if (offset == -1) { if (searching_for_menu_items) continue; else { int temp; temp = skip_line (refdef); offset = string_in_line (":", refdef + temp); if (offset == -1) continue; /* Give up? */ else offset += temp; } } entry = (REFERENCE *)xmalloc (sizeof (REFERENCE)); entry->filename = (char *)NULL; entry->nodename = (char *)NULL; entry->label = (char *)xmalloc (offset); strncpy (entry->label, refdef, offset - 1); entry->label[offset - 1] = '\0'; canonicalize_whitespace (entry->label); refdef += offset; entry->start = start; entry->end = refdef - binding->buffer; /* If this reference entry continues with another ':' then the nodename is the same as the label. */ if (*refdef == ':') { entry->nodename = xstrdup (entry->label); } else { /* This entry continues with a specific nodename. Parse the nodename from the specification. */ refdef += skip_whitespace_and_newlines (refdef); if (searching_for_menu_items) info_parse_node (refdef, DONT_SKIP_NEWLINES); else info_parse_node (refdef, SKIP_NEWLINES); if (info_parsed_filename) entry->filename = xstrdup (info_parsed_filename); if (info_parsed_nodename) entry->nodename = xstrdup (info_parsed_nodename); } add_pointer_to_array (entry, refs_index, refs, refs_slots, 50, REFERENCE *); } return (refs); } /* Get the entry associated with LABEL in MENU. Return a pointer to the REFERENCE if found, or NULL. */ REFERENCE * info_get_labeled_reference (label, references) char *label; REFERENCE **references; { register int i; REFERENCE *entry; for (i = 0; references && (entry = references[i]); i++) { if (strcmp (label, entry->label) == 0) return (entry); } return ((REFERENCE *)NULL); } /* A utility function for concatenating REFERENCE **. Returns a new REFERENCE ** which is the concatenation of REF1 and REF2. The REF1 and REF2 arrays are freed, but their contents are not. */ REFERENCE ** info_concatenate_references (ref1, ref2) REFERENCE **ref1, **ref2; { register int i, j; REFERENCE **result; int size; /* With one argument passed as NULL, simply return the other arg. */ if (!ref1) return (ref2); else if (!ref2) return (ref1); /* Get the total size of the slots that we will need. */ for (i = 0; ref1[i]; i++); size = i; for (i = 0; ref2[i]; i++); size += i; result = (REFERENCE **)xmalloc ((1 + size) * sizeof (REFERENCE *)); /* Copy the contents over. */ for (i = 0; ref1[i]; i++) result[i] = ref1[i]; j = i; for (i = 0; ref2[i]; i++) result[j++] = ref2[i]; result[j] = (REFERENCE *)NULL; free (ref1); free (ref2); return (result); } /* Free the data associated with REFERENCES. */ void info_free_references (references) REFERENCE **references; { register int i; REFERENCE *entry; if (references) { for (i = 0; references && (entry = references[i]); i++) { maybe_free (entry->label); maybe_free (entry->filename); maybe_free (entry->nodename); free (entry); } free (references); } } /* Search for sequences of whitespace or newlines in STRING, replacing all such sequences with just a single space. Remove whitespace from start and end of string. */ void canonicalize_whitespace (string) char *string; { register int i, j; int len, whitespace_found, whitespace_loc; char *temp; if (!string) return; len = strlen (string); temp = (char *)xmalloc (1 + len); /* Search for sequences of whitespace or newlines. Replace all such sequences in the string with just a single space. */ whitespace_found = 0; for (i = 0, j = 0; string[i]; i++) { if (whitespace_or_newline (string[i])) { whitespace_found++; whitespace_loc = i; continue; } else { if (whitespace_found && whitespace_loc) { whitespace_found = 0; /* Suppress whitespace at start of string. */ if (j) temp[j++] = ' '; } temp[j++] = string[i]; } } /* Kill trailing whitespace. */ if (j && whitespace (temp[j - 1])) j--; temp[j] = '\0'; strcpy (string, temp); free (temp); } /* String representation of a char returned by printed_representation (). */ static char the_rep[10]; /* Return a pointer to a string which is the printed representation of CHARACTER if it were printed at HPOS. */ char * printed_representation (character, hpos) unsigned char character; int hpos; { register int i = 0; int printable_limit; if (ISO_Latin_p) printable_limit = 160; else printable_limit = 127; if (character == '\177') { the_rep[i++] = '^'; the_rep[i++] = '?'; } else if (iscntrl (character)) { switch (character) { case '\r': case '\n': the_rep[i++] = character; break; case '\t': { int tw; tw = ((hpos + 8) & 0xf8) - hpos; while (i < tw) the_rep[i++] = ' '; } break; default: the_rep[i++] = '^'; the_rep[i++] = (character | 0x40); } } else if (character > printable_limit) { sprintf (the_rep + i, "\\%0o", character); i = strlen (the_rep); } else the_rep[i++] = character; the_rep[i] = '\0'; return (the_rep); } /* **************************************************************** */ /* */ /* Functions Static To This File */ /* */ /* **************************************************************** */ /* Amount of space allocated to INFO_PARSED_FILENAME via xmalloc (). */ static int parsed_filename_size = 0; /* Amount of space allocated to INFO_PARSED_NODENAME via xmalloc (). */ static int parsed_nodename_size = 0; static void save_string (), saven_string (); /* Remember FILENAME in PARSED_FILENAME. An empty FILENAME is translated to a NULL pointer in PARSED_FILENAME. */ static void save_filename (filename) char *filename; { save_string (filename, &info_parsed_filename, &parsed_filename_size); } /* Just like save_filename (), but you pass the length of the string. */ static void saven_filename (filename, len) char *filename; int len; { saven_string (filename, len, &info_parsed_filename, &parsed_filename_size); } /* Remember NODENAME in PARSED_NODENAME. An empty NODENAME is translated to a NULL pointer in PARSED_NODENAME. */ static void save_nodename (nodename) char *nodename; { save_string (nodename, &info_parsed_nodename, &parsed_nodename_size); } /* Just like save_nodename (), but you pass the length of the string. */ static void saven_nodename (nodename, len) char *nodename; int len; { saven_string (nodename, len, &info_parsed_nodename, &parsed_nodename_size); } /* Remember STRING in STRING_P. STRING_P should currently have STRING_SIZE_P bytes allocated to it. An empty STRING is translated to a NULL pointer in STRING_P. */ static void save_string (string, string_p, string_size_p) char *string; char **string_p; int *string_size_p; { if (!string || !*string) { if (*string_p) free (*string_p); *string_p = (char *)NULL; *string_size_p = 0; } else { if (strlen (string) >= *string_size_p) *string_p = (char *)xrealloc (*string_p, (*string_size_p = 1 + strlen (string))); strcpy (*string_p, string); } } /* Just like save_string (), but you also pass the length of STRING. */ static void saven_string (string, len, string_p, string_size_p) char *string; int len; char **string_p; int *string_size_p; { if (!string) { if (*string_p) free (*string_p); *string_p = (char *)NULL; *string_size_p = 0; } else { if (len >= *string_size_p) *string_p = (char *)xrealloc (*string_p, (*string_size_p = 1 + len)); strncpy (*string_p, string, len); (*string_p)[len] = '\0'; } } /* Return a pointer to the part of PATHNAME that simply defines the file. */ char * filename_non_directory (pathname) char *pathname; { char *filename; filename = (char *) strrchr (pathname, '/'); if (filename) filename++; else filename = pathname; return (filename); } /* Return non-zero if NODE is one especially created by Info. */ int internal_info_node_p (node) NODE *node; { #if defined (NEVER) if (node && (node->filename && !*node->filename) && !node->parent && node->nodename) return (1); else return (0); #else return ((node != (NODE *)NULL) && ((node->flags & N_IsInternal) != 0)); #endif /* !NEVER */ } /* Make NODE appear to be one especially created by Info. */ void name_internal_node (node, name) NODE *node; char *name; { if (!node) return; node->filename = ""; node->parent = (char *)NULL; node->nodename = name; node->flags |= N_IsInternal; } /* Return the window displaying NAME, the name of an internally created Info window. */ WINDOW * get_internal_info_window (name) char *name; { WINDOW *win; for (win = windows; win; win = win->next) if (internal_info_node_p (win->node) && (strcmp (win->node->nodename, name) == 0)) break; return (win); } texinfo-3.12/info/makedoc.c0000444000175000017500000003014006362741423013056 0ustar gg/* makedoc.c -- Make doc.c and funs.h from input files. $Id: makedoc.c,v 1.4 1997/07/15 18:35:59 karl Exp $ This file is part of GNU Info, a program for reading online documentation stored in Info format. Copyright (C) 1993, 97 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ /* This program grovels the contents of the source files passed as arguments and writes out a file of function pointers and documentation strings, and a header file which describes the contents. This only does the functions declared with DECLARE_INFO_COMMAND. */ #include "info.h" static void fatal_file_error (); /* Name of the header file which receives the declarations of functions. */ static char *funs_filename = "funs.h"; /* Name of the documentation to function pointer file. */ static char *doc_filename = "doc.c"; static char *doc_header[] = { "/* doc.c -- Generated structure containing function names and doc strings.", "", " This file was automatically made from various source files with the", " command \"%s\". DO NOT EDIT THIS FILE, only \"%s.c\".", (char *)NULL }; static char *doc_header_1[] = { " An entry in the array FUNCTION_DOC_ARRAY is made for each command", " found in the above files; each entry consists of a function pointer,", #if defined (NAMED_FUNCTIONS) " a string which is the user-visible name of the function,", #endif /* NAMED_FUNCTIONS */ " and a string which documents its purpose. */", "", "#include \"doc.h\"", "#include \"funs.h\"", "", "FUNCTION_DOC function_doc_array[] = {", "", (char *)NULL }; /* How to remember the locations of the functions found so that Emacs can use the information in a tag table. */ typedef struct { char *name; /* Name of the tag. */ int line; /* Line number at which it appears. */ long char_offset; /* Character offset at which it appears. */ } EMACS_TAG; typedef struct { char *filename; /* Name of the file containing entries. */ long entrylen; /* Total number of characters in tag block. */ EMACS_TAG **entries; /* Entries found in FILENAME. */ int entries_index; int entries_slots; } EMACS_TAG_BLOCK; EMACS_TAG_BLOCK **emacs_tags = (EMACS_TAG_BLOCK **)NULL; int emacs_tags_index = 0; int emacs_tags_slots = 0; #define DECLARATION_STRING "\nDECLARE_INFO_COMMAND" static void process_one_file (); static void maybe_dump_tags (); static FILE *must_fopen (); int main (argc, argv) int argc; char **argv; { register int i; int tags_only = 0; FILE *funs_stream, *doc_stream; for (i = 1; i < argc; i++) if (strcmp (argv[i], "-tags") == 0) { tags_only++; break; } if (tags_only) { funs_filename = "/dev/null"; doc_filename = "/dev/null"; } funs_stream = must_fopen (funs_filename, "w"); doc_stream = must_fopen (doc_filename, "w"); fprintf (funs_stream, "/* %s -- Generated declarations for Info commands. */\n", funs_filename); for (i = 0; doc_header[i]; i++) { fprintf (doc_stream, doc_header[i], argv[0], argv[0]); fprintf (doc_stream, "\n"); } fprintf (doc_stream, _(" Source files groveled to make this file include:\n\n")); for (i = 1; i < argc; i++) fprintf (doc_stream, "\t%s\n", argv[i]); fprintf (doc_stream, "\n"); for (i = 0; doc_header_1[i]; i++) fprintf (doc_stream, "%s\n", doc_header_1[i]); for (i = 1; i < argc; i++) { char *curfile; curfile = argv[i]; if (*curfile == '-') continue; fprintf (doc_stream, "/* Commands found in \"%s\". */\n", curfile); fprintf (funs_stream, "\n/* Functions declared in \"%s\". */\n", curfile); process_one_file (curfile, doc_stream, funs_stream); } fprintf (doc_stream, " { (VFunction *)NULL, (char *)NULL, (char *)NULL }\n};\n"); fclose (funs_stream); fclose (doc_stream); if (tags_only) maybe_dump_tags (stdout); exit (0); } /* Dumping out the contents of an Emacs tags table. */ static void maybe_dump_tags (stream) FILE *stream; { register int i; /* Print out the information for each block. */ for (i = 0; i < emacs_tags_index; i++) { register int j; register EMACS_TAG_BLOCK *block; register EMACS_TAG *etag; long block_len; block_len = 0; block = emacs_tags[i]; /* Calculate the length of the dumped block first. */ for (j = 0; j < block->entries_index; j++) { char digits[30]; etag = block->entries[j]; block_len += 3 + strlen (etag->name); sprintf (digits, "%d,%ld", etag->line, etag->char_offset); block_len += strlen (digits); } /* Print out the defining line. */ fprintf (stream, "\f\n%s,%ld\n", block->filename, block_len); /* Print out the individual tags. */ for (j = 0; j < block->entries_index; j++) { etag = block->entries[j]; fprintf (stream, "%s,\177%d,%ld\n", etag->name, etag->line, etag->char_offset); } } } /* Keeping track of names, line numbers and character offsets of functions found in source files. */ static EMACS_TAG_BLOCK * make_emacs_tag_block (filename) char *filename; { EMACS_TAG_BLOCK *block; block = (EMACS_TAG_BLOCK *)xmalloc (sizeof (EMACS_TAG_BLOCK)); block->filename = xstrdup (filename); block->entrylen = 0; block->entries = (EMACS_TAG **)NULL; block->entries_index = 0; block->entries_slots = 0; return (block); } static void add_tag_to_block (block, name, line, char_offset) EMACS_TAG_BLOCK *block; char *name; int line; long char_offset; { EMACS_TAG *tag; tag = (EMACS_TAG *)xmalloc (sizeof (EMACS_TAG)); tag->name = name; tag->line = line; tag->char_offset = char_offset; add_pointer_to_array (tag, block->entries_index, block->entries, block->entries_slots, 50, EMACS_TAG *); } /* Read the file represented by FILENAME into core, and search it for Info function declarations. Output the declarations in various forms to the DOC_STREAM and FUNS_STREAM. */ static void process_one_file (filename, doc_stream, funs_stream) char *filename; FILE *doc_stream, *funs_stream; { int descriptor, decl_len; char *buffer, *decl_str; struct stat finfo; long offset; long file_size; EMACS_TAG_BLOCK *block; if (stat (filename, &finfo) == -1) fatal_file_error (filename); descriptor = open (filename, O_RDONLY, 0666); if (descriptor == -1) fatal_file_error (filename); file_size = (long) finfo.st_size; buffer = (char *)xmalloc (1 + file_size); read (descriptor, buffer, file_size); close (descriptor); offset = 0; decl_str = DECLARATION_STRING; decl_len = strlen (decl_str); block = make_emacs_tag_block (filename); while (1) { long point = 0; long line_start = 0; int line_number = 0; char *func, *doc; #if defined (NAMED_FUNCTIONS) char *func_name; #endif /* NAMED_FUNCTIONS */ for (; offset < (file_size - decl_len); offset++) { if (buffer[offset] == '\n') { line_number++; line_start = offset + 1; } if (strncmp (buffer + offset, decl_str, decl_len) == 0) { offset += decl_len; point = offset; break; } } if (!point) break; /* Skip forward until we find the open paren. */ while (point < file_size) { if (buffer[point] == '\n') { line_number++; line_start = point + 1; } else if (buffer[point] == '(') break; point++; } while (point++ < file_size) { if (!whitespace_or_newline (buffer[point])) break; else if (buffer[point] == '\n') { line_number++; line_start = point + 1; } } if (point >= file_size) break; /* Now looking at name of function. Get it. */ for (offset = point; buffer[offset] != ','; offset++); func = (char *)xmalloc (1 + (offset - point)); strncpy (func, buffer + point, offset - point); func[offset - point] = '\0'; /* Remember this tag in the current block. */ { char *tag_name; tag_name = (char *)xmalloc (1 + (offset - line_start)); strncpy (tag_name, buffer + line_start, offset - line_start); tag_name[offset - line_start] = '\0'; add_tag_to_block (block, tag_name, line_number, point); } #if defined (NAMED_FUNCTIONS) /* Generate the user-visible function name from the function's name. */ { register int i; char *name_start; name_start = func; if (strncmp (name_start, "info_", 5) == 0) name_start += 5; func_name = xstrdup (name_start); /* Fix up "ea" commands. */ if (strncmp (func_name, "ea_", 3) == 0) { char *temp_func_name; temp_func_name = (char *)xmalloc (10 + strlen (func_name)); strcpy (temp_func_name, "echo_area_"); strcat (temp_func_name, func_name + 3); free (func_name); func_name = temp_func_name; } for (i = 0; func_name[i]; i++) if (func_name[i] == '_') func_name[i] = '-'; } #endif /* NAMED_FUNCTIONS */ /* Find doc string. */ point = offset + 1; while (point < file_size) { if (buffer[point] == '\n') { line_number++; line_start = point + 1; } if (buffer[point] == '"') break; else point++; } offset = point + 1; while (offset < file_size) { if (buffer[offset] == '\n') { line_number++; line_start = offset + 1; } if (buffer[offset] == '\\') offset += 2; else if (buffer[offset] == '"') break; else offset++; } offset++; if (offset >= file_size) break; doc = (char *)xmalloc (1 + (offset - point)); strncpy (doc, buffer + point, offset - point); doc[offset - point] = '\0'; #if defined (NAMED_FUNCTIONS) fprintf (doc_stream, " { %s, \"%s\", %s },\n", func, func_name, doc); free (func_name); #else /* !NAMED_FUNCTIONS */ fprintf (doc_stream, " { %s, %s },\n", func, doc); #endif /* !NAMED_FUNCTIONS */ fprintf (funs_stream, "extern void %s ();\n", func); free (func); free (doc); } free (buffer); /* If we created any tags, remember this file on our global list. Otherwise, free the memory already allocated to it. */ if (block->entries) add_pointer_to_array (block, emacs_tags_index, emacs_tags, emacs_tags_slots, 10, EMACS_TAG_BLOCK *); else { free (block->filename); free (block); } } static void fatal_file_error (filename) char *filename; { fprintf (stderr, _("Couldn't manipulate the file %s.\n"), filename); exit (2); } static FILE * must_fopen (filename, mode) char *filename, *mode; { FILE *stream; stream = fopen (filename, mode); if (!stream) fatal_file_error (filename); return (stream); } texinfo-3.12/info/signals.h0000444000175000017500000000571506362741437013137 0ustar gg/* signals.h -- Header to include system dependent signal definitions. $Id: signals.h,v 1.3 1997/07/15 18:35:59 karl Exp $ This file is part of GNU Info, a program for reading online documentation stored in Info format. Copyright (C) 1993, 94, 95, 97 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ #ifndef INFO_SIGNALS_H #define INFO_SIGNALS_H #include #include /* For sysV68 --phdm@info.ucl.ac.be. */ #if !defined (SIGCHLD) && defined (SIGCLD) #define SIGCHLD SIGCLD #endif #if !defined (HAVE_SIGPROCMASK) && !defined (sigmask) # define sigmask(x) (1 << ((x)-1)) #endif /* !HAVE_SIGPROCMASK && !sigmask */ #if !defined (HAVE_SIGPROCMASK) # if !defined (SIG_BLOCK) # define SIG_UNBLOCK 1 # define SIG_BLOCK 2 # define SIG_SETMASK 3 # endif /* SIG_BLOCK */ /* Type of a signal set. */ # define sigset_t int /* Make SET have no signals in it. */ # define sigemptyset(set) (*(set) = (sigset_t)0x0) /* Make SET have the full range of signal specifications possible. */ # define sigfillset(set) (*(set) = (sigset_t)0xffffffffff) /* Add SIG to the contents of SET. */ # define sigaddset(set, sig) *(set) |= sigmask (sig) /* Delete SIG from the contents of SET. */ # define sigdelset(set, sig) *(set) &= ~(sigmask (sig)) /* Tell if SET contains SIG. */ # define sigismember(set, sig) (*(set) & (sigmask (sig))) /* Suspend the process until the reception of one of the signals not present in SET. */ # define sigsuspend(set) sigpause (*(set)) #endif /* !HAVE_SIGPROCMASK */ #if defined (HAVE_SIGPROCMASK) || defined (HAVE_SIGSETMASK) /* These definitions are used both in POSIX and non-POSIX implementations. */ #define BLOCK_SIGNAL(sig) \ do { \ sigset_t nvar, ovar; \ sigemptyset (&nvar); \ sigemptyset (&ovar); \ sigaddset (&nvar, sig); \ sigprocmask (SIG_BLOCK, &nvar, &ovar); \ } while (0) #define UNBLOCK_SIGNAL(sig) \ do { \ sigset_t nvar, ovar; \ sigemptyset (&ovar); \ sigemptyset (&nvar); \ sigaddset (&nvar, sig); \ sigprocmask (SIG_UNBLOCK, &nvar, &ovar); \ } while (0) #else /* !HAVE_SIGPROCMASK && !HAVE_SIGSETMASK */ # define BLOCK_SIGNAL(sig) # define UNBLOCK_SIGNAL(sig) #endif /* !HAVE_SIGPROCMASK && !HAVE_SIGSETMASK */ #endif /* not INFO_SIGNALS_H */ texinfo-3.12/info/man.h0000444000175000017500000000304306362742260012235 0ustar gg/* man.h: Defines and external function declarations for man.c. $Id: man.h,v 1.2 1997/07/15 18:42:56 karl Exp $ This file is part of GNU Info, a program for reading online documentation stored in Info format. Copyright (C) 1993, 97 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, USA. Author: Brian J. Fox (bfox@ai.mit.edu) Sat May 6 16:19:13 1995. */ #ifndef INFO_MAN_H #define INFO_MAN_H #define MANPAGE_FILE_BUFFER_NAME "*manpages*" extern NODE *make_manpage_node (/* char *pagename */); extern NODE *get_manpage_node (/* FILE_BUFFER *file_buffer, char *pagename */); extern FILE_BUFFER *create_manpage_file_buffer (/* void */); extern long locate_manpage_xref (/* NODE *node, long start, int dir */); extern REFERENCE **xrefs_of_manpage (/* NODE *node */); extern REFERENCE **manpage_xrefs_in_binding (/* NODE *node, SEARCH_BINDING *binding */); #endif /* INFO_MAN_H */ texinfo-3.12/info/gc.c0000444000175000017500000000575506365746555012100 0ustar gg/* gc.c -- Functions to remember and garbage collect unused node contents. */ /* This file is part of GNU Info, a program for reading online documentation stored in Info format. Copyright (C) 1993 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ #include "info.h" /* Array of pointers to the contents of gc-able nodes. A pointer on this list can be garbage collected when no info window contains a node whose contents member match the pointer. */ static char **gcable_pointers = (char **)NULL; static int gcable_pointers_index = 0; static int gcable_pointers_slots = 0; /* Add POINTER to the list of garbage collectible pointers. A pointer is not actually garbage collected until no info window contains a node whose contents member is equal to the pointer. */ void add_gcable_pointer (pointer) char *pointer; { gc_pointers (); add_pointer_to_array (pointer, gcable_pointers_index, gcable_pointers, gcable_pointers_slots, 10, char *); } /* Grovel the list of info windows and gc-able pointers finding those node->contents which are collectible, and free them. */ void gc_pointers () { register int i, j, k; INFO_WINDOW *iw; char **new = (char **)NULL; int new_index = 0; int new_slots = 0; if (!info_windows || !gcable_pointers_index) return; for (i = 0; (iw = info_windows[i]); i++) { for (j = 0; j < iw->nodes_index; j++) { NODE *node = iw->nodes[j]; /* If this node->contents appears in our list of gcable_pointers, it is not gc-able, so save it. */ for (k = 0; k < gcable_pointers_index; k++) if (gcable_pointers[k] == node->contents) { add_pointer_to_array (node->contents, new_index, new, new_slots, 10, char *); break; } } } /* We have gathered all of the pointers which need to be saved. Free any of the original pointers which do not appear in the new list. */ for (i = 0; i < gcable_pointers_index; i++) { for (j = 0; j < new_index; j++) if (gcable_pointers[i] == new[j]) break; /* If we got all the way through the new list, then the old pointer can be garbage collected. */ if (new && !new[j]) free (gcable_pointers[i]); } free (gcable_pointers); gcable_pointers = new; gcable_pointers_slots = new_slots; gcable_pointers_index = new_index; } texinfo-3.12/info/dribble.c0000444000175000017500000000414006362741066013062 0ustar gg/* dribble.c -- Dribble files for Info. */ /* This file is part of GNU Info, a program for reading online documentation stored in Info format. Copyright (C) 1993 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ #include "info.h" #include "dribble.h" /* When non-zero, it is a stream to write all input characters to for the duration of this info session. */ FILE *info_dribble_file = (FILE *)NULL; /* Open a dribble file named NAME, perhaps closing an already open one. This sets the global variable INFO_DRIBBLE_FILE to the open stream. */ void open_dribble_file (name) char *name; { /* Perhaps close existing dribble file. */ close_dribble_file (); info_dribble_file = fopen (name, "w"); #if defined (HAVE_SETVBUF) if (info_dribble_file) # if defined (SETVBUF_REVERSED) setvbuf (info_dribble_file, _IONBF, (char *)NULL, 1); # else setvbuf (info_dribble_file, (char *)NULL, _IONBF, 1); # endif /* !SETVBUF_REVERSED */ #endif /* HAVE_SETVBUF */ } /* If there is a dribble file already open, close it. */ void close_dribble_file () { if (info_dribble_file) { fflush (info_dribble_file); fclose (info_dribble_file); info_dribble_file = (FILE *)NULL; } } /* Write some output to our existing dribble file. */ void dribble (byte) unsigned char byte; { if (info_dribble_file) fwrite (&byte, sizeof (unsigned char), 1, info_dribble_file); } texinfo-3.12/info/terminal.c0000444000175000017500000005302706473665673013316 0ustar gg/* terminal.c -- How to handle the physical terminal for Info. $Id: terminal.c,v 1.9 1998/02/22 00:05:15 karl Exp $ Copyright (C) 1988, 89, 90, 91, 92, 93, 96, 97, 98 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ #include "info.h" #include "terminal.h" #include "termdep.h" #include #include /* The Unix termcap interface code. */ #ifdef HAVE_NCURSES_TERMCAP_H #include #else #ifdef HAVE_TERMCAP_H #include #else /* On Solaris2, sys/types.h #includes sys/reg.h, which #defines PC. Unfortunately, PC is a global variable used by the termcap library. */ #undef PC /* Termcap requires these variables, whether we access them or not. */ char *BC, *UP; char PC; /* Pad character */ short ospeed; /* Terminal output baud rate */ extern int tgetnum (), tgetflag (), tgetent (); extern char *tgetstr (), *tgoto (); extern void tputs (); #endif /* not HAVE_TERMCAP_H */ #endif /* not HAVE_NCURSES_TERMCAP_H */ /* Function "hooks". If you make one of these point to a function, that function is called when appropriate instead of its namesake. Your function is called with exactly the same arguments that were passed to the namesake function. */ VFunction *terminal_begin_inverse_hook = (VFunction *)NULL; VFunction *terminal_end_inverse_hook = (VFunction *)NULL; VFunction *terminal_prep_terminal_hook = (VFunction *)NULL; VFunction *terminal_unprep_terminal_hook = (VFunction *)NULL; VFunction *terminal_up_line_hook = (VFunction *)NULL; VFunction *terminal_down_line_hook = (VFunction *)NULL; VFunction *terminal_clear_screen_hook = (VFunction *)NULL; VFunction *terminal_clear_to_eol_hook = (VFunction *)NULL; VFunction *terminal_get_screen_size_hook = (VFunction *)NULL; VFunction *terminal_goto_xy_hook = (VFunction *)NULL; VFunction *terminal_initialize_terminal_hook = (VFunction *)NULL; VFunction *terminal_new_terminal_hook = (VFunction *)NULL; VFunction *terminal_put_text_hook = (VFunction *)NULL; VFunction *terminal_ring_bell_hook = (VFunction *)NULL; VFunction *terminal_write_chars_hook = (VFunction *)NULL; VFunction *terminal_scroll_terminal_hook = (VFunction *)NULL; /* **************************************************************** */ /* */ /* Terminal and Termcap */ /* */ /* **************************************************************** */ /* A buffer which holds onto the current terminal description, and a pointer used to float within it. */ static char *term_buffer = (char *)NULL; static char *term_string_buffer = (char *)NULL; /* Some strings to control terminal actions. These are output by tputs (). */ static char *term_goto, *term_clreol, *term_cr, *term_clrpag; static char *term_begin_use, *term_end_use; static char *term_AL, *term_DL, *term_al, *term_dl; static char *term_keypad_on, *term_keypad_off; /* How to go up a line. */ static char *term_up; /* How to go down a line. */ static char *term_dn; /* An audible bell, if the terminal can be made to make noise. */ static char *audible_bell; /* A visible bell, if the terminal can be made to flash the screen. */ static char *visible_bell; /* The string to write to turn on the meta key, if this term has one. */ static char *term_mm; /* The string to write to turn off the meta key, if this term has one. */ static char *term_mo; /* The string to turn on inverse mode, if this term has one. */ static char *term_invbeg; /* The string to turn off inverse mode, if this term has one. */ static char *term_invend; /* Although I can't find any documentation that says this is supposed to return its argument, all the code I've looked at (termutils, less) does so, so fine. */ static int output_character_function (c) int c; { putc (c, stdout); return c; } /* Macro to send STRING to the terminal. */ #define send_to_terminal(string) \ do { \ if (string) \ tputs (string, 1, output_character_function); \ } while (0) /* Tell the terminal that we will be doing cursor addressable motion. */ static void terminal_begin_using_terminal () { RETSIGTYPE (*sigsave) (); if (term_keypad_on) send_to_terminal (term_keypad_on); if (!term_begin_use || !*term_begin_use) return; #ifdef SIGWINCH sigsave = signal (SIGWINCH, SIG_IGN); #endif send_to_terminal (term_begin_use); /* Without this fflush and sleep, running info in a shelltool or cmdtool (TERM=sun-cmd) with scrollbars loses -- the scrollbars are not restored properly. From: strube@physik3.gwdg.de (Hans Werner Strube). */ fflush (stdout); sleep (1); #ifdef SIGWINCH signal (SIGWINCH, sigsave); #endif } /* Tell the terminal that we will not be doing any more cursor addressable motion. */ static void terminal_end_using_terminal () { RETSIGTYPE (*sigsave) (); if (term_keypad_off) send_to_terminal (term_keypad_off); if (!term_end_use || !*term_end_use) return; #ifdef SIGWINCH sigsave = signal (SIGWINCH, SIG_IGN); #endif send_to_terminal (term_end_use); fflush (stdout); sleep (1); #ifdef SIGWINCH signal (SIGWINCH, sigsave); #endif } /* **************************************************************** */ /* */ /* Necessary Terminal Functions */ /* */ /* **************************************************************** */ /* The functions and variables on this page implement the user visible portion of the terminal interface. */ /* The width and height of the terminal. */ int screenwidth, screenheight; /* Non-zero means this terminal can't really do anything. */ int terminal_is_dumb_p = 0; /* Non-zero means that this terminal has a meta key. */ int terminal_has_meta_p = 0; /* Non-zero means that this terminal can produce a visible bell. */ int terminal_has_visible_bell_p = 0; /* Non-zero means to use that visible bell if at all possible. */ int terminal_use_visible_bell_p = 0; /* Non-zero means that the terminal can do scrolling. */ int terminal_can_scroll = 0; /* The key sequences output by the arrow keys, if this terminal has any. */ char *term_ku = (char *)NULL; char *term_kd = (char *)NULL; char *term_kr = (char *)NULL; char *term_kl = (char *)NULL; char *term_kP = (char *)NULL; /* page-up */ char *term_kN = (char *)NULL; /* page-down */ /* Move the cursor to the terminal location of X and Y. */ void terminal_goto_xy (x, y) int x, y; { if (terminal_goto_xy_hook) (*terminal_goto_xy_hook) (x, y); else { if (term_goto) tputs (tgoto (term_goto, x, y), 1, output_character_function); } } /* Print STRING to the terminal at the current position. */ void terminal_put_text (string) char *string; { if (terminal_put_text_hook) (*terminal_put_text_hook) (string); else { printf ("%s", string); } } /* Print NCHARS from STRING to the terminal at the current position. */ void terminal_write_chars (string, nchars) char *string; int nchars; { if (terminal_write_chars_hook) (*terminal_write_chars_hook) (string, nchars); else { if (nchars) fwrite (string, 1, nchars, stdout); } } /* Clear from the current position of the cursor to the end of the line. */ void terminal_clear_to_eol () { if (terminal_clear_to_eol_hook) (*terminal_clear_to_eol_hook) (); else { send_to_terminal (term_clreol); } } /* Clear the entire terminal screen. */ void terminal_clear_screen () { if (terminal_clear_screen_hook) (*terminal_clear_screen_hook) (); else { send_to_terminal (term_clrpag); } } /* Move the cursor up one line. */ void terminal_up_line () { if (terminal_up_line_hook) (*terminal_up_line_hook) (); else { send_to_terminal (term_up); } } /* Move the cursor down one line. */ void terminal_down_line () { if (terminal_down_line_hook) (*terminal_down_line_hook) (); else { send_to_terminal (term_dn); } } /* Turn on reverse video if possible. */ void terminal_begin_inverse () { if (terminal_begin_inverse_hook) (*terminal_begin_inverse_hook) (); else { send_to_terminal (term_invbeg); } } /* Turn off reverse video if possible. */ void terminal_end_inverse () { if (terminal_end_inverse_hook) (*terminal_end_inverse_hook) (); else { send_to_terminal (term_invend); } } /* Ring the terminal bell. The bell is run visibly if it both has one and terminal_use_visible_bell_p is non-zero. */ void terminal_ring_bell () { if (terminal_ring_bell_hook) (*terminal_ring_bell_hook) (); else { if (terminal_has_visible_bell_p && terminal_use_visible_bell_p) send_to_terminal (visible_bell); else send_to_terminal (audible_bell); } } /* At the line START, delete COUNT lines from the terminal display. */ static void terminal_delete_lines (start, count) int start, count; { int lines; /* Normalize arguments. */ if (start < 0) start = 0; lines = screenheight - start; terminal_goto_xy (0, start); if (term_DL) tputs (tgoto (term_DL, 0, count), lines, output_character_function); else { while (count--) tputs (term_dl, lines, output_character_function); } fflush (stdout); } /* At the line START, insert COUNT lines in the terminal display. */ static void terminal_insert_lines (start, count) int start, count; { int lines; /* Normalize arguments. */ if (start < 0) start = 0; lines = screenheight - start; terminal_goto_xy (0, start); if (term_AL) tputs (tgoto (term_AL, 0, count), lines, output_character_function); else { while (count--) tputs (term_al, lines, output_character_function); } fflush (stdout); } /* Scroll an area of the terminal, starting with the region from START to END, AMOUNT lines. If AMOUNT is negative, the lines are scrolled towards the top of the screen, else they are scrolled towards the bottom of the screen. */ void terminal_scroll_terminal (start, end, amount) int start, end, amount; { if (!terminal_can_scroll) return; /* Any scrolling at all? */ if (amount == 0) return; if (terminal_scroll_terminal_hook) (*terminal_scroll_terminal_hook) (start, end, amount); else { /* If we are scrolling down, delete AMOUNT lines at END. Then insert AMOUNT lines at START. */ if (amount > 0) { terminal_delete_lines (end, amount); terminal_insert_lines (start, amount); } /* If we are scrolling up, delete AMOUNT lines before START. This actually does the upwards scroll. Then, insert AMOUNT lines after the already scrolled region (i.e., END - AMOUNT). */ if (amount < 0) { int abs_amount = -amount; terminal_delete_lines (start - abs_amount, abs_amount); terminal_insert_lines (end - abs_amount, abs_amount); } } } /* Re-initialize the terminal considering that the TERM/TERMCAP variable has changed. */ void terminal_new_terminal (terminal_name) char *terminal_name; { if (terminal_new_terminal_hook) (*terminal_new_terminal_hook) (terminal_name); else { terminal_initialize_terminal (terminal_name); } } /* Set the global variables SCREENWIDTH and SCREENHEIGHT. */ void terminal_get_screen_size () { if (terminal_get_screen_size_hook) (*terminal_get_screen_size_hook) (); else { screenwidth = screenheight = 0; #if defined (TIOCGWINSZ) { struct winsize window_size; if (ioctl (fileno (stdout), TIOCGWINSZ, &window_size) == 0) { screenwidth = (int) window_size.ws_col; screenheight = (int) window_size.ws_row; } } #endif /* TIOCGWINSZ */ /* Environment variable COLUMNS overrides setting of "co". */ if (screenwidth <= 0) { char *sw = getenv ("COLUMNS"); if (sw) screenwidth = atoi (sw); if (screenwidth <= 0) screenwidth = tgetnum ("co"); } /* Environment variable LINES overrides setting of "li". */ if (screenheight <= 0) { char *sh = getenv ("LINES"); if (sh) screenheight = atoi (sh); if (screenheight <= 0) screenheight = tgetnum ("li"); } /* If all else fails, default to 80x24 terminal. */ if (screenwidth <= 0) screenwidth = 80; if (screenheight <= 0) screenheight = 24; } } /* Initialize the terminal which is known as TERMINAL_NAME. If this terminal doesn't have cursor addressability, `terminal_is_dumb_p' becomes nonzero. The variables SCREENHEIGHT and SCREENWIDTH are set to the dimensions that this terminal actually has. The variable TERMINAL_HAS_META_P becomes nonzero if this terminal supports a Meta key. Finally, the terminal screen is cleared. */ void terminal_initialize_terminal (terminal_name) char *terminal_name; { char *term, *buffer; terminal_is_dumb_p = 0; if (terminal_initialize_terminal_hook) { (*terminal_initialize_terminal_hook) (terminal_name); return; } term = terminal_name ? terminal_name : getenv ("TERM"); if (!term_string_buffer) term_string_buffer = (char *)xmalloc (2048); if (!term_buffer) term_buffer = (char *)xmalloc (2048); buffer = term_string_buffer; term_clrpag = term_cr = term_clreol = (char *)NULL; if (!term) term = "dumb"; if (tgetent (term_buffer, term) <= 0) { terminal_is_dumb_p = 1; screenwidth = 80; screenheight = 24; term_cr = "\r"; term_up = term_dn = audible_bell = visible_bell = (char *)NULL; term_ku = term_kd = term_kl = term_kr = (char *)NULL; term_kP = term_kN = (char *)NULL; return; } BC = tgetstr ("pc", &buffer); PC = BC ? *BC : 0; #if defined (TIOCGETP) { struct sgttyb sg; if (ioctl (fileno (stdout), TIOCGETP, &sg) != -1) ospeed = sg.sg_ospeed; else ospeed = B9600; } #else ospeed = B9600; #endif /* !TIOCGETP */ term_cr = tgetstr ("cr", &buffer); term_clreol = tgetstr ("ce", &buffer); term_clrpag = tgetstr ("cl", &buffer); term_goto = tgetstr ("cm", &buffer); /* Find out about this terminals scrolling capability. */ term_AL = tgetstr ("AL", &buffer); term_DL = tgetstr ("DL", &buffer); term_al = tgetstr ("al", &buffer); term_dl = tgetstr ("dl", &buffer); terminal_can_scroll = ((term_AL || term_al) && (term_DL || term_dl)); term_invbeg = tgetstr ("mr", &buffer); if (term_invbeg) term_invend = tgetstr ("me", &buffer); else term_invend = (char *)NULL; if (!term_cr) term_cr = "\r"; terminal_get_screen_size (); term_up = tgetstr ("up", &buffer); term_dn = tgetstr ("dn", &buffer); visible_bell = tgetstr ("vb", &buffer); terminal_has_visible_bell_p = (visible_bell != (char *)NULL); audible_bell = tgetstr ("bl", &buffer); if (!audible_bell) audible_bell = "\007"; term_begin_use = tgetstr ("ti", &buffer); term_end_use = tgetstr ("te", &buffer); term_keypad_on = tgetstr ("ks", &buffer); term_keypad_off = tgetstr ("ke", &buffer); /* Check to see if this terminal has a meta key. */ terminal_has_meta_p = (tgetflag ("km") || tgetflag ("MT")); if (terminal_has_meta_p) { term_mm = tgetstr ("mm", &buffer); term_mo = tgetstr ("mo", &buffer); } else { term_mm = (char *)NULL; term_mo = (char *)NULL; } /* Attempt to find the arrow keys. */ term_ku = tgetstr ("ku", &buffer); term_kd = tgetstr ("kd", &buffer); term_kr = tgetstr ("kr", &buffer); term_kl = tgetstr ("kl", &buffer); term_kP = tgetstr ("kP", &buffer); term_kN = tgetstr ("kN", &buffer); /* If this terminal is not cursor addressable, then it is really dumb. */ if (!term_goto) terminal_is_dumb_p = 1; } /* **************************************************************** */ /* */ /* How to Read Characters From the Terminal */ /* */ /* **************************************************************** */ #if defined (TIOCGETC) /* A buffer containing the terminal interrupt characters upon entry to Info. */ struct tchars original_tchars; #endif #if defined (TIOCGLTC) /* A buffer containing the local terminal mode characters upon entry to Info. */ struct ltchars original_ltchars; #endif #if defined (HAVE_TERMIOS_H) struct termios original_termios, ttybuff; #else # if defined (HAVE_TERMIO_H) /* A buffer containing the terminal mode flags upon entry to info. */ struct termio original_termio, ttybuff; # else /* !HAVE_TERMIO_H */ /* Buffers containing the terminal mode flags upon entry to info. */ int original_tty_flags = 0; int original_lmode; struct sgttyb ttybuff; # endif /* !HAVE_TERMIO_H */ #endif /* !HAVE_TERMIOS_H */ /* Prepare to start using the terminal to read characters singly. */ void terminal_prep_terminal () { int tty; if (terminal_prep_terminal_hook) { (*terminal_prep_terminal_hook) (); return; } terminal_begin_using_terminal (); tty = fileno (stdin); #if defined (HAVE_TERMIOS_H) tcgetattr (tty, &original_termios); tcgetattr (tty, &ttybuff); #else # if defined (HAVE_TERMIO_H) ioctl (tty, TCGETA, &original_termio); ioctl (tty, TCGETA, &ttybuff); # endif #endif #if defined (HAVE_TERMIOS_H) || defined (HAVE_TERMIO_H) ttybuff.c_iflag &= (~ISTRIP & ~INLCR & ~IGNCR & ~ICRNL & ~IXON); /* These output flags are not part of POSIX, so only use them if they are defined. */ #ifdef ONLCR ttybuff.c_oflag &= ~ONLCR ; #endif #ifdef OCRNL ttybuff.c_oflag &= ~OCRNL; #endif ttybuff.c_lflag &= (~ICANON & ~ECHO); ttybuff.c_cc[VMIN] = 1; ttybuff.c_cc[VTIME] = 0; if (ttybuff.c_cc[VINTR] == '\177') ttybuff.c_cc[VINTR] = -1; if (ttybuff.c_cc[VQUIT] == '\177') ttybuff.c_cc[VQUIT] = -1; #ifdef VLNEXT if (ttybuff.c_cc[VLNEXT] == '\026') ttybuff.c_cc[VLNEXT] = -1; #endif /* VLNEXT */ #endif /* TERMIOS or TERMIO */ #if defined (HAVE_TERMIOS_H) tcsetattr (tty, TCSANOW, &ttybuff); #else # if defined (HAVE_TERMIO_H) ioctl (tty, TCSETA, &ttybuff); # endif #endif #if !defined (HAVE_TERMIOS_H) && !defined (HAVE_TERMIO_H) ioctl (tty, TIOCGETP, &ttybuff); if (!original_tty_flags) original_tty_flags = ttybuff.sg_flags; /* Make this terminal pass 8 bits around while we are using it. */ # if defined (PASS8) ttybuff.sg_flags |= PASS8; # endif /* PASS8 */ # if defined (TIOCLGET) && defined (LPASS8) { int flags; ioctl (tty, TIOCLGET, &flags); original_lmode = flags; flags |= LPASS8; ioctl (tty, TIOCLSET, &flags); } # endif /* TIOCLGET && LPASS8 */ # if defined (TIOCGETC) { struct tchars temp; ioctl (tty, TIOCGETC, &original_tchars); temp = original_tchars; /* C-s and C-q. */ temp.t_startc = temp.t_stopc = -1; /* Often set to C-d. */ temp.t_eofc = -1; /* If the a quit or interrupt character conflicts with one of our commands, then make it go away. */ if (temp.t_intrc == '\177') temp.t_intrc = -1; if (temp.t_quitc == '\177') temp.t_quitc = -1; ioctl (tty, TIOCSETC, &temp); } # endif /* TIOCGETC */ # if defined (TIOCGLTC) { struct ltchars temp; ioctl (tty, TIOCGLTC, &original_ltchars); temp = original_ltchars; /* Make the interrupt keys go away. Just enough to make people happy. */ temp.t_lnextc = -1; /* C-v. */ temp.t_dsuspc = -1; /* C-y. */ temp.t_flushc = -1; /* C-o. */ ioctl (tty, TIOCSLTC, &temp); } # endif /* TIOCGLTC */ ttybuff.sg_flags &= ~ECHO; ttybuff.sg_flags |= CBREAK; ioctl (tty, TIOCSETN, &ttybuff); #endif /* !HAVE_TERMIOS_H && !HAVE_TERMIO_H */ } /* Restore the tty settings back to what they were before we started using this terminal. */ void terminal_unprep_terminal () { int tty; if (terminal_unprep_terminal_hook) { (*terminal_unprep_terminal_hook) (); return; } tty = fileno (stdin); #if defined (HAVE_TERMIOS_H) tcsetattr (tty, TCSANOW, &original_termios); #else # if defined (HAVE_TERMIO_H) ioctl (tty, TCSETA, &original_termio); # else /* !HAVE_TERMIO_H */ ioctl (tty, TIOCGETP, &ttybuff); ttybuff.sg_flags = original_tty_flags; ioctl (tty, TIOCSETN, &ttybuff); # if defined (TIOCGETC) ioctl (tty, TIOCSETC, &original_tchars); # endif /* TIOCGETC */ # if defined (TIOCGLTC) ioctl (tty, TIOCSLTC, &original_ltchars); # endif /* TIOCGLTC */ # if defined (TIOCLGET) && defined (LPASS8) ioctl (tty, TIOCLSET, &original_lmode); # endif /* TIOCLGET && LPASS8 */ # endif /* !HAVE_TERMIO_H */ #endif /* !HAVE_TERMIOS_H */ terminal_end_using_terminal (); } texinfo-3.12/info/indices.c0000444000175000017500000005042506365744142013105 0ustar gg/* indices.c -- Commands for dealing with an Info file Index. $Id: indices.c,v 1.6 1997/07/24 21:25:53 karl Exp $ Copyright (C) 1993, 97 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ #include "info.h" #include "indices.h" /* User-visible variable controls the output of info-index-next. */ int show_index_match = 1; /* In the Info sense, an index is a menu. This variable holds the last parsed index. */ static REFERENCE **index_index = (REFERENCE **)NULL; /* The offset of the most recently selected index element. */ static int index_offset = 0; /* Variable which holds the last string searched for. */ static char *index_search = (char *)NULL; /* A couple of "globals" describing where the initial index was found. */ static char *initial_index_filename = (char *)NULL; static char *initial_index_nodename = (char *)NULL; /* A structure associating index names with index offset ranges. */ typedef struct { char *name; /* The nodename of this index. */ int first; /* The index in our list of the first entry. */ int last; /* The index in our list of the last entry. */ } INDEX_NAME_ASSOC; /* An array associating index nodenames with index offset ranges. */ static INDEX_NAME_ASSOC **index_nodenames = (INDEX_NAME_ASSOC **)NULL; static int index_nodenames_index = 0; static int index_nodenames_slots = 0; /* Add the name of NODE, and the range of the associated index elements (passed in ARRAY) to index_nodenames. */ static void add_index_to_index_nodenames (array, node) REFERENCE **array; NODE *node; { register int i, last; INDEX_NAME_ASSOC *assoc; for (last = 0; array[last]; last++); assoc = (INDEX_NAME_ASSOC *)xmalloc (sizeof (INDEX_NAME_ASSOC)); assoc->name = xstrdup (node->nodename); if (!index_nodenames_index) { assoc->first = 0; assoc->last = last; } else { for (i = 0; index_nodenames[i + 1]; i++); assoc->first = 1 + index_nodenames[i]->last; assoc->last = assoc->first + last; } add_pointer_to_array (assoc, index_nodenames_index, index_nodenames, index_nodenames_slots, 10, INDEX_NAME_ASSOC *); } /* Find and return the indices of WINDOW's file. The indices are defined as the first node in the file containing the word "Index" and any immediately following nodes whose names also contain "Index". All such indices are concatenated and the result returned. If WINDOW's info file doesn't have any indices, a NULL pointer is returned. */ REFERENCE ** info_indices_of_window (window) WINDOW *window; { FILE_BUFFER *fb; fb = file_buffer_of_window (window); return (info_indices_of_file_buffer (fb)); } REFERENCE ** info_indices_of_file_buffer (file_buffer) FILE_BUFFER *file_buffer; { register int i; REFERENCE **result = (REFERENCE **)NULL; /* No file buffer, no indices. */ if (!file_buffer) return ((REFERENCE **)NULL); /* Reset globals describing where the index was found. */ maybe_free (initial_index_filename); maybe_free (initial_index_nodename); initial_index_filename = (char *)NULL; initial_index_nodename = (char *)NULL; if (index_nodenames) { for (i = 0; index_nodenames[i]; i++) { free (index_nodenames[i]->name); free (index_nodenames[i]); } index_nodenames_index = 0; index_nodenames[0] = (INDEX_NAME_ASSOC *)NULL; } /* Grovel the names of the nodes found in this file. */ if (file_buffer->tags) { TAG *tag; for (i = 0; (tag = file_buffer->tags[i]); i++) { if (string_in_line ("Index", tag->nodename) != -1) { NODE *node; REFERENCE **menu; /* Found one. Get its menu. */ node = info_get_node (tag->filename, tag->nodename); if (!node) continue; /* Remember the filename and nodename of this index. */ initial_index_filename = xstrdup (file_buffer->filename); initial_index_nodename = xstrdup (tag->nodename); menu = info_menu_of_node (node); /* If we have a menu, add this index's nodename and range to our list of index_nodenames. */ if (menu) { add_index_to_index_nodenames (menu, node); /* Concatenate the references found so far. */ result = info_concatenate_references (result, menu); } free (node); } } } /* If there is a result, clean it up so that every entry has a filename. */ for (i = 0; result && result[i]; i++) if (!result[i]->filename) result[i]->filename = xstrdup (file_buffer->filename); return (result); } DECLARE_INFO_COMMAND (info_index_search, _("Look up a string in the index for this file")) { do_info_index_search (window, count, 0); } /* Look up SEARCH_STRING in the index for this file. If SEARCH_STRING is NULL, prompt user for input. */ void do_info_index_search (window, count, search_string) WINDOW *window; int count; char *search_string; { FILE_BUFFER *fb; char *line; /* Reset the index offset, since this is not the info-index-next command. */ index_offset = 0; /* The user is selecting a new search string, so flush the old one. */ maybe_free (index_search); index_search = (char *)NULL; /* If this window's file is not the same as the one that we last built an index for, build and remember an index now. */ fb = file_buffer_of_window (window); if (!initial_index_filename || (strcmp (initial_index_filename, fb->filename) != 0)) { info_free_references (index_index); window_message_in_echo_area (_("Finding index entries...")); index_index = info_indices_of_file_buffer (fb); } /* If there is no index, quit now. */ if (!index_index) { info_error (_("No indices found.")); return; } /* Okay, there is an index. Look for SEARCH_STRING, or, if it is empty, prompt for one. */ if (search_string && *search_string) line = xstrdup (search_string); else { line = info_read_maybe_completing (window, _("Index entry: "), index_index); window = active_window; /* User aborted? */ if (!line) { info_abort_key (active_window, 1, 0); return; } /* Empty line means move to the Index node. */ if (!*line) { free (line); if (initial_index_filename && initial_index_nodename) { NODE *node; node = info_get_node (initial_index_filename, initial_index_nodename); set_remembered_pagetop_and_point (window); window_set_node_of_window (window, node); remember_window_and_node (window, node); window_clear_echo_area (); return; } } } /* The user typed either a completed index label, or a partial string. Find an exact match, or, failing that, the first index entry containing the partial string. So, we just call info_next_index_match () with minor manipulation of INDEX_OFFSET. */ { int old_offset; /* Start the search right after/before this index. */ if (count < 0) { register int i; for (i = 0; index_index[i]; i++); index_offset = i; } else index_offset = -1; old_offset = index_offset; /* The "last" string searched for is this one. */ index_search = line; /* Find it, or error. */ info_next_index_match (window, count, 0); /* If the search failed, return the index offset to where it belongs. */ if (index_offset == old_offset) index_offset = 0; } } int index_entry_exists (window, string) WINDOW *window; char *string; { register int i; FILE_BUFFER *fb; /* If there is no previous search string, the user hasn't built an index yet. */ if (!string) return 0; fb = file_buffer_of_window (window); if (!initial_index_filename || (strcmp (initial_index_filename, fb->filename) != 0)) { info_free_references (index_index); index_index = info_indices_of_file_buffer (fb); } /* If there is no index, that is an error. */ if (!index_index) return 0; for (i = 0; (i > -1) && (index_index[i]); i++) if (strcmp (string, index_index[i]->label) == 0) break; /* If that failed, look for the next substring match. */ if ((i < 0) || (!index_index[i])) { for (i = 0; (i > -1) && (index_index[i]); i++) if (string_in_line (string, index_index[i]->label) != -1) break; if ((i > -1) && (index_index[i])) string_in_line (string, index_index[i]->label); } /* If that failed, return 0. */ if ((i < 0) || (!index_index[i])) return 0; return 1; } DECLARE_INFO_COMMAND (info_next_index_match, _("Go to the next matching index item from the last `\\[index-search]' command")) { register int i; int partial, dir; NODE *node; /* If there is no previous search string, the user hasn't built an index yet. */ if (!index_search) { info_error (_("No previous index search string.")); return; } /* If there is no index, that is an error. */ if (!index_index) { info_error (_("No index entries.")); return; } /* The direction of this search is controlled by the value of the numeric argument. */ if (count < 0) dir = -1; else dir = 1; /* Search for the next occurence of index_search. First try to find an exact match. */ partial = 0; for (i = index_offset + dir; (i > -1) && (index_index[i]); i += dir) if (strcmp (index_search, index_index[i]->label) == 0) break; /* If that failed, look for the next substring match. */ if ((i < 0) || (!index_index[i])) { for (i = index_offset + dir; (i > -1) && (index_index[i]); i += dir) if (string_in_line (index_search, index_index[i]->label) != -1) break; if ((i > -1) && (index_index[i])) partial = string_in_line (index_search, index_index[i]->label); } /* If that failed, print an error. */ if ((i < 0) || (!index_index[i])) { info_error (_("No %sindex entries containing \"%s\"."), index_offset > 0 ? _("more ") : "", index_search); return; } /* Okay, we found the next one. Move the offset to the current entry. */ index_offset = i; /* Report to the user on what we have found. */ { register int j; char *name = _("CAN'T SEE THIS"); char *match; for (j = 0; index_nodenames[j]; j++) { if ((i >= index_nodenames[j]->first) && (i <= index_nodenames[j]->last)) { name = index_nodenames[j]->name; break; } } /* If we had a partial match, indicate to the user which part of the string matched. */ match = xstrdup (index_index[i]->label); if (partial && show_index_match) { int j, ls, start, upper; ls = strlen (index_search); start = partial - ls; upper = isupper (match[start]) ? 1 : 0; for (j = 0; j < ls; j++) if (upper) match[j + start] = info_tolower (match[j + start]); else match[j + start] = info_toupper (match[j + start]); } { char *format; format = replace_in_documentation (_("Found \"%s\" in %s. (`\\[next-index-match]' tries to find next.)")); window_message_in_echo_area (format, match, name); } free (match); } /* Select the node corresponding to this index entry. */ node = info_get_node (index_index[i]->filename, index_index[i]->nodename); if (!node) { info_error (CANT_FILE_NODE, index_index[i]->filename, index_index[i]->nodename); return; } set_remembered_pagetop_and_point (window); window_set_node_of_window (window, node); remember_window_and_node (window, node); /* Try to find an occurence of LABEL in this node. */ { long start, loc; start = window->line_starts[1] - window->node->contents; loc = info_target_search_node (node, index_index[i]->label, start); if (loc != -1) { window->point = loc; window_adjust_pagetop (window); } } } /* **************************************************************** */ /* */ /* Info APROPOS: Search every known index. */ /* */ /* **************************************************************** */ /* For every menu item in DIR, search the indices of that file for SEARCH_STRING. */ REFERENCE ** apropos_in_all_indices (search_string, inform) char *search_string; int inform; { register int i, dir_index; REFERENCE **all_indices = (REFERENCE **)NULL; REFERENCE **dir_menu = (REFERENCE **)NULL; NODE *dir_node; dir_node = info_get_node ("dir", "Top"); if (dir_node) dir_menu = info_menu_of_node (dir_node); if (!dir_menu) return NULL; /* For every menu item in DIR, get the associated node's file buffer and read the indices of that file buffer. Gather all of the indices into one large one. */ for (dir_index = 0; dir_menu[dir_index]; dir_index++) { REFERENCE **this_index, *this_item; NODE *this_node; FILE_BUFFER *this_fb; this_item = dir_menu[dir_index]; if (!this_item->filename) { if (dir_node->parent) this_item->filename = xstrdup (dir_node->parent); else this_item->filename = xstrdup (dir_node->filename); } /* Find this node. If we cannot find it, try using the label of the entry as a file (i.e., "(LABEL)Top"). */ this_node = info_get_node (this_item->filename, this_item->nodename); if (!this_node && this_item->nodename && (strcmp (this_item->label, this_item->nodename) == 0)) this_node = info_get_node (this_item->label, "Top"); if (!this_node) continue; /* Get the file buffer associated with this node. */ { char *files_name; files_name = this_node->parent; if (!files_name) files_name = this_node->filename; this_fb = info_find_file (files_name); if (this_fb && inform) message_in_echo_area (_("Scanning indices of \"%s\"..."), files_name); this_index = info_indices_of_file_buffer (this_fb); free (this_node); if (this_fb && inform) unmessage_in_echo_area (); } if (this_index) { /* Remember the filename which contains this set of references. */ for (i = 0; this_index && this_index[i]; i++) if (!this_index[i]->filename) this_index[i]->filename = xstrdup (this_fb->filename); /* Concatenate with the other indices. */ all_indices = info_concatenate_references (all_indices, this_index); } } info_free_references (dir_menu); /* Build a list of the references which contain SEARCH_STRING. */ if (all_indices) { REFERENCE *entry, **apropos_list = (REFERENCE **)NULL; int apropos_list_index = 0; int apropos_list_slots = 0; for (i = 0; (entry = all_indices[i]); i++) { if (string_in_line (search_string, entry->label) != -1) { add_pointer_to_array (entry, apropos_list_index, apropos_list, apropos_list_slots, 100, REFERENCE *); } else { maybe_free (entry->label); maybe_free (entry->filename); maybe_free (entry->nodename); free (entry); } } free (all_indices); all_indices = apropos_list; } return (all_indices); } #define APROPOS_NONE \ _("No available info files reference \"%s\" in their indices.") void info_apropos (string) char *string; { REFERENCE **apropos_list; apropos_list = apropos_in_all_indices (string, 0); if (!apropos_list) { info_error (APROPOS_NONE, string); } else { register int i; REFERENCE *entry; for (i = 0; (entry = apropos_list[i]); i++) fprintf (stderr, "\"(%s)%s\" -- %s\n", entry->filename, entry->nodename, entry->label); } info_free_references (apropos_list); } static char *apropos_list_nodename = "*Apropos*"; DECLARE_INFO_COMMAND (info_index_apropos, _("Grovel all known info file's indices for a string and build a menu")) { char *line; line = info_read_in_echo_area (window, _("Index apropos: ")); window = active_window; /* User aborted? */ if (!line) { info_abort_key (window, 1, 1); return; } /* User typed something? */ if (*line) { REFERENCE **apropos_list; NODE *apropos_node; apropos_list = apropos_in_all_indices (line, 1); if (!apropos_list) { info_error (APROPOS_NONE, line); } else { register int i; char *line_buffer; initialize_message_buffer (); printf_to_message_buffer (_("\n* Menu: Nodes whoses indices contain \"%s\":\n"), line); line_buffer = (char *)xmalloc (500); for (i = 0; apropos_list[i]; i++) { int len; sprintf (line_buffer, "* (%s)%s::", apropos_list[i]->filename, apropos_list[i]->nodename); len = pad_to (36, line_buffer); sprintf (line_buffer + len, "%s", apropos_list[i]->label); printf_to_message_buffer ("%s\n", line_buffer); } free (line_buffer); } apropos_node = message_buffer_to_node (); add_gcable_pointer (apropos_node->contents); name_internal_node (apropos_node, apropos_list_nodename); /* Even though this is an internal node, we don't want the window system to treat it specially. So we turn off the internalness of it here. */ apropos_node->flags &= ~N_IsInternal; /* Find/Create a window to contain this node. */ { WINDOW *new; NODE *node; set_remembered_pagetop_and_point (window); /* If a window is visible and showing an apropos list already, re-use it. */ for (new = windows; new; new = new->next) { node = new->node; if (internal_info_node_p (node) && (strcmp (node->nodename, apropos_list_nodename) == 0)) break; } /* If we couldn't find an existing window, try to use the next window in the chain. */ if (!new && window->next) new = window->next; /* If we still don't have a window, make a new one to contain the list. */ if (!new) { WINDOW *old_active; old_active = active_window; active_window = window; new = window_make_window ((NODE *)NULL); active_window = old_active; } /* If we couldn't make a new window, use this one. */ if (!new) new = window; /* Lines do not wrap in this window. */ new->flags |= W_NoWrap; window_set_node_of_window (new, apropos_node); remember_window_and_node (new, apropos_node); active_window = new; } info_free_references (apropos_list); } free (line); if (!info_error_was_printed) window_clear_echo_area (); } texinfo-3.12/info/funs.h0000664000175000017500000000675106477046146012461 0ustar gg/* funs.h -- Generated declarations for Info commands. */ /* Functions declared in "./session.c". */ extern void info_next_line (); extern void info_prev_line (); extern void info_end_of_line (); extern void info_beginning_of_line (); extern void info_forward_char (); extern void info_backward_char (); extern void info_forward_word (); extern void info_backward_word (); extern void info_global_next_node (); extern void info_global_prev_node (); extern void info_scroll_forward (); extern void info_scroll_backward (); extern void info_beginning_of_node (); extern void info_end_of_node (); extern void info_next_window (); extern void info_prev_window (); extern void info_split_window (); extern void info_delete_window (); extern void info_keep_one_window (); extern void info_scroll_other_window (); extern void info_grow_window (); extern void info_tile_windows (); extern void info_toggle_wrap (); extern void info_next_node (); extern void info_prev_node (); extern void info_up_node (); extern void info_last_node (); extern void info_first_node (); extern void info_last_menu_item (); extern void info_menu_digit (); extern void info_menu_item (); extern void info_xref_item (); extern void info_find_menu (); extern void info_visit_menu (); extern void info_goto_node (); extern void info_man (); extern void info_top_node (); extern void info_dir_node (); extern void info_history_node (); extern void info_kill_node (); extern void info_view_file (); extern void info_print_node (); extern void info_search (); extern void isearch_forward (); extern void isearch_backward (); extern void info_move_to_prev_xref (); extern void info_move_to_next_xref (); extern void info_select_reference_this_line (); extern void info_abort_key (); extern void info_move_to_window_line (); extern void info_redraw_display (); extern void info_quit (); extern void info_do_lowercase_version (); extern void info_add_digit_to_numeric_arg (); extern void info_universal_argument (); extern void info_numeric_arg_digit_loop (); /* Functions declared in "./echo-area.c". */ extern void ea_forward (); extern void ea_backward (); extern void ea_beg_of_line (); extern void ea_end_of_line (); extern void ea_forward_word (); extern void ea_backward_word (); extern void ea_delete (); extern void ea_rubout (); extern void ea_abort (); extern void ea_newline (); extern void ea_quoted_insert (); extern void ea_insert (); extern void ea_tab_insert (); extern void ea_transpose_chars (); extern void ea_yank (); extern void ea_yank_pop (); extern void ea_kill_line (); extern void ea_backward_kill_line (); extern void ea_kill_word (); extern void ea_backward_kill_word (); extern void ea_possible_completions (); extern void ea_complete (); extern void ea_scroll_completions_window (); /* Functions declared in "./infodoc.c". */ extern void info_get_help_window (); extern void info_get_info_help_node (); extern void describe_key (); extern void info_where_is (); /* Functions declared in "./m-x.c". */ extern void describe_command (); extern void info_execute_command (); extern void set_screen_height (); /* Functions declared in "./indices.c". */ extern void info_index_search (); extern void info_next_index_match (); extern void info_index_apropos (); /* Functions declared in "./nodemenu.c". */ extern void list_visited_nodes (); extern void select_visited_node (); /* Functions declared in "./footnotes.c". */ extern void info_show_footnotes (); /* Functions declared in "./variables.c". */ extern void describe_variable (); extern void set_variable (); texinfo-3.12/info/window.h0000444000175000017500000002375706362742533013012 0ustar gg/* window.h -- Structure and flags used in manipulating Info windows. $Id: window.h,v 1.4 1997/07/15 18:45:47 karl Exp $ This file is part of GNU Info, a program for reading online documentation stored in Info format. Copyright (C) 1993, 97 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ #ifndef INFO_WINDOW_H #define INFO_WINDOW_H #include "nodes.h" #include "infomap.h" /* Smallest number of visible lines in a window. The actual height is always one more than this number because each window has a modeline. */ #define WINDOW_MIN_HEIGHT 2 /* Smallest number of screen lines that can be used to fully present a window. This number includes the modeline of the window. */ #define WINDOW_MIN_SIZE (WINDOW_MIN_HEIGHT + 1) /* The exact same elements are used within the WINDOW_STATE structure and a subsection of the WINDOW structure. We could define a structure which contains this elements, and include that structure in each of WINDOW_STATE and WINDOW. But that would lead references in the code such as window->state->node which we would like to avoid. Instead, we #define the elements here, and simply include the define in both data structures. Thus, if you need to change window state information, here is where you would do it. NB> The last element does NOT end with a semi-colon. */ #define WINDOW_STATE_DECL \ NODE *node; /* The node displayed in this window. */ \ int pagetop; /* LINE_STARTS[PAGETOP] is first line in WINDOW. */ \ long point /* Offset within NODE of the cursor position. */ /* Structure which defines a window. Windows are doubly linked, next and prev. The list of windows is kept on WINDOWS. The structure member window->height is the total height of the window. The position location (0, window->height + window->first_row) is the first character of this windows modeline. The number of lines that can be displayed in a window is equal to window->height - 1. */ typedef struct window_struct { struct window_struct *next; /* Next window in this chain. */ struct window_struct *prev; /* Previous window in this chain. */ int width; /* Width of this window. */ int height; /* Height of this window. */ int first_row; /* Offset of the first line in the_screen. */ int goal_column; /* The column we would like the cursor to appear in. */ Keymap keymap; /* Keymap used to read commands in this window. */ WINDOW_STATE_DECL; /* Node, pagetop and point. */ char *modeline; /* Calculated text of the modeline for this window. */ char **line_starts; /* Array of printed line starts for this node. */ int line_count; /* Number of lines appearing in LINE_STARTS. */ int flags; /* See below for details. */ } WINDOW; typedef struct { WINDOW_STATE_DECL; /* What gets saved. */ } WINDOW_STATE; #define W_UpdateWindow 0x01 /* WINDOW needs updating. */ #define W_WindowIsPerm 0x02 /* This WINDOW is a permanent object. */ #define W_WindowVisible 0x04 /* This WINDOW is currently visible. */ #define W_InhibitMode 0x08 /* This WINDOW has no modeline. */ #define W_NoWrap 0x10 /* Lines do not wrap in this window. */ #define W_InputWindow 0x20 /* Window accepts input. */ #define W_TempWindow 0x40 /* Window is less important. */ extern WINDOW *windows; /* List of visible Info windows. */ extern WINDOW *active_window; /* The currently active window. */ extern WINDOW *the_screen; /* The Info screen is just another window. */ extern WINDOW *the_echo_area; /* THE_ECHO_AREA is a window in THE_SCREEN. */ /* Global variable control redisplay of scrolled windows. If non-zero, it is the desired number of lines to scroll the window in order to make point visible. A user might set this to 1 for smooth scrolling. If set to zero, the line containing point is centered within the window. */ extern int window_scroll_step; /* Make the modeline member for WINDOW. */ extern void window_make_modeline (); /* Initalize the window system by creating THE_SCREEN and THE_ECHO_AREA. Create the first window ever, and make it permanent. You pass WIDTH and HEIGHT; the dimensions of the total screen size. */ extern void window_initialize_windows (); /* Make a new window showing NODE, and return that window structure. The new window is made to be the active window. If NODE is passed as NULL, then show the node showing in the active window. If the window could not be made return a NULL pointer. The active window is not changed.*/ extern WINDOW *window_make_window (); /* Delete WINDOW from the list of known windows. If this window was the active window, make the next window in the chain be the active window, or the previous window in the chain if there is no next window. */ extern void window_delete_window (); /* A function to call when the screen changes size, and some windows have to get deleted. The function is called with the window to be deleted as an argument, and it can't do anything about the window getting deleted; it can only clean up dangling references to that window. */ extern VFunction *window_deletion_notifier; /* Set WINDOW to display NODE. */ extern void window_set_node_of_window (); /* Tell the window system that the size of the screen has changed. This causes lots of interesting things to happen. The permanent windows are resized, as well as every visible window. You pass WIDTH and HEIGHT; the dimensions of the total screen size. */ extern void window_new_screen_size (); /* Change the height of WINDOW by AMOUNT. This also automagically adjusts the previous and next windows in the chain. If there is only one user window, then no change takes place. */ extern void window_change_window_height (); /* Adjust the pagetop of WINDOW such that the cursor point will be visible. */ extern void window_adjust_pagetop (); /* Tile all of the windows currently displayed in the global variable WINDOWS. If argument DO_INTERNALS is non-zero, tile windows displaying internal nodes as well. */ #define DONT_TILE_INTERNALS 0 #define TILE_INTERNALS 1 extern void window_tile_windows (); /* Toggle the state of line wrapping in WINDOW. This can do a bit of fancy redisplay. */ extern void window_toggle_wrap (); /* For every window in CHAIN, set the flags member to have FLAG set. */ extern void window_mark_chain (); /* For every window in CHAIN, clear the flags member of FLAG. */ extern void window_unmark_chain (); /* Make WINDOW start displaying at PERCENT percentage of its node. */ extern void window_goto_percentage (); /* Build a new node which has FORMAT printed with ARG1 and ARG2 as the contents. */ extern NODE *build_message_node (); /* Useful functions can be called from outside of window.c. */ extern void initialize_message_buffer (); /* Print FORMAT with ARG1,2 to the end of the current message buffer. */ extern void printf_to_message_buffer (); /* Convert the contents of the message buffer to a node. */ extern NODE *message_buffer_to_node (); /* Return the length of the most recently printed line in message buffer. */ extern int message_buffer_length_this_line (); /* Pad STRING to COUNT characters by inserting blanks. */ extern int pad_to (); /* Make a message appear in the echo area, built from FORMAT, ARG1 and ARG2. The arguments are treated similar to printf () arguments, but not all of printf () hair is present. The message appears immediately. If there was already a message appearing in the echo area, it is removed. */ extern void window_message_in_echo_area (); /* Place a temporary message in the echo area built from FORMAT, ARG1 and ARG2. The message appears immediately, but does not destroy any existing message. A future call to unmessage_in_echo_area () restores the old contents. */ extern void message_in_echo_area (); extern void unmessage_in_echo_area (); /* Clear the echo area, removing any message that is already present. The echo area is cleared immediately. */ extern void window_clear_echo_area (); /* Quickly guess the approximate number of lines to that NODE would take to display. This really only counts carriage returns. */ extern int window_physical_lines (); /* Calculate a list of line starts for the node belonging to WINDOW. The line starts are pointers to the actual text within WINDOW->NODE. */ extern void calculate_line_starts (); /* Given WINDOW, recalculate the line starts for the node it displays. */ extern void recalculate_line_starts (); /* Return the number of characters it takes to display CHARACTER on the screen at HPOS. */ extern int character_width (); /* Return the number of characters it takes to display STRING on the screen at HPOS. */ extern int string_width (); /* Return the index of the line containing point. */ extern int window_line_of_point (); /* Get and return the goal column for this window. */ extern int window_get_goal_column (); /* Get and return the printed column offset of the cursor in this window. */ extern int window_get_cursor_column (); /* Get and Set the node, pagetop, and point of WINDOW. */ extern void window_get_state (), window_set_state (); /* Count the number of characters in LINE that precede the printed column offset of GOAL. */ extern int window_chars_to_goal (); #endif /* not INFO_WINDOW_H */ texinfo-3.12/info/variables.h0000444000175000017500000000500706362742407013437 0ustar gg/* variables.h -- Description of user visible variables in Info. $Id: variables.h,v 1.3 1997/07/15 18:44:23 karl Exp $ This file is part of GNU Info, a program for reading online documentation stored in Info format. Copyright (C) 1993, 97 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ #ifndef INFO_VARIABLES_H #define INFO_VARIABLES_H /* A variable (in the Info sense) is an integer value with a user-visible name. You may supply an array of strings to complete over when the variable is set; in that case, the variable is set to the index of the string that the user chose. If you supply a null list, the user can set the variable to a numeric value. */ /* Structure describing a user visible variable. */ typedef struct { char *name; /* Polite name. */ char *doc; /* Documentation string. */ int *value; /* Address of value. */ char **choices; /* Array of strings or NULL if numeric only. */ } VARIABLE_ALIST; /* Read the name of an Info variable in the echo area and return the address of a VARIABLE_ALIST member. A return value of NULL indicates that no variable could be read. */ extern VARIABLE_ALIST *read_variable_name (); /* Make an array of REFERENCE which actually contains the names of the variables available in Info. */ extern REFERENCE **make_variable_completions_array (); /* Set the value of an info variable. */ extern void set_variable (); /* The list of user-visible variables. */ extern int auto_footnotes_p; extern int auto_tiling_p; extern int terminal_use_visible_bell_p; extern int info_error_rings_bell_p; extern int gc_compressed_files; extern int show_index_match; extern int info_scroll_behaviour; extern int window_scroll_step; extern int ISO_Latin_p; #endif /* not INFO_VARIABLES_H */ texinfo-3.12/info/info-utils.h0000444000175000017500000001264306362742214013560 0ustar gg/* info-utils.h -- Exported functions and variables from info-util.c. $Id: info-utils.h,v 1.3 1997/07/15 18:42:20 karl Exp $ This file is part of GNU Info, a program for reading online documentation stored in Info format. Copyright (C) 1993, 96 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ #ifndef INFO_UTILS_H #define INFO_UTILS_H #if !defined (HAVE_STRCHR) # undef strchr # undef strrchr # define strchr index # define strrchr rindex #endif /* !HAVE_STRCHR */ #include "nodes.h" #include "window.h" #include "search.h" /* Structure which describes a node reference, such as a menu entry or cross reference. Arrays of such references can be built by calling info_menus_of_node () or info_xrefs_of_node (). */ typedef struct { char *label; /* User Label. */ char *filename; /* File where this node can be found. */ char *nodename; /* Name of the node. */ int start, end; /* Offsets within the containing node of LABEL. */ } REFERENCE; /* When non-zero, various display and input functions handle ISO Latin character sets correctly. */ extern int ISO_Latin_p; /* Variable which holds the most recent filename parsed as a result of calling info_parse_xxx (). */ extern char *info_parsed_filename; /* Variable which holds the most recent nodename parsed as a result of calling info_parse_xxx (). */ extern char *info_parsed_nodename; /* Parse the filename and nodename out of STRING. If STRING doesn't contain a filename (i.e., it is NOT (FILENAME)NODENAME) then set INFO_PARSED_FILENAME to NULL. If second argument NEWLINES_OKAY is non-zero, it says to allow the nodename specification to cross a newline boundary (i.e., only `,', `.', or `TAB' can end the spec). */ void info_parse_node (); /* Return a NULL terminated array of REFERENCE * which represents the menu found in NODE. If there is no menu in NODE, just return a NULL pointer. */ extern REFERENCE **info_menu_of_node (); /* Return a NULL terminated array of REFERENCE * which represents the cross refrences found in NODE. If there are no cross references in NODE, just return a NULL pointer. */ extern REFERENCE **info_xrefs_of_node (); /* Glean cross references from BINDING->buffer + BINDING->start until BINDING->end. Return an array of REFERENCE * that represents each cross reference in this range. */ extern REFERENCE **info_xrefs (); /* Get the entry associated with LABEL in REFERENCES. Return a pointer to the reference if found, or NULL. */ extern REFERENCE *info_get_labeled_reference (); /* Glean menu entries from BINDING->buffer + BINDING->start until we have looked at the entire contents of BINDING. Return an array of REFERENCE * that represents each menu item in this range. */ extern REFERENCE **info_menu_items (); /* A utility function for concatenating REFERENCE **. Returns a new REFERENCE ** which is the concatenation of REF1 and REF2. The REF1 and REF2 arrays are freed, but their contents are not. */ REFERENCE **info_concatenate_references (); /* Free the data associated with REFERENCES. */ extern void info_free_references (); /* Search for sequences of whitespace or newlines in STRING, replacing all such sequences with just a single space. Remove whitespace from start and end of string. */ void canonicalize_whitespace (); /* Return a pointer to a string which is the printed representation of CHARACTER if it were printed at HPOS. */ extern char *printed_representation (); /* Return a pointer to the part of PATHNAME that simply defines the file. */ extern char *filename_non_directory (); /* Return non-zero if NODE is one especially created by Info. */ extern int internal_info_node_p (); /* Make NODE appear to be one especially created by Info, and give it NAME. */ extern void name_internal_node (); /* Return the window displaying NAME, the name of an internally created Info window. */ extern WINDOW *get_internal_info_window (); /* Return the node addressed by LABEL in NODE (usually one of "Prev:", "Next:", "Up:", "File:", or "Node:". After a call to this function, the global INFO_PARSED_NODENAME and INFO_PARSED_FILENAME contain the information. */ extern void info_parse_label (/* label, node */); #define info_label_was_found \ (info_parsed_nodename != NULL || info_parsed_filename != NULL) #define info_file_label_of_node(n) info_parse_label (INFO_FILE_LABEL, n) #define info_next_label_of_node(n) info_parse_label (INFO_NEXT_LABEL, n) #define info_up_label_of_node(n) info_parse_label (INFO_UP_LABEL, n) #define info_prev_label_of_node(n) \ do { \ info_parse_label (INFO_PREV_LABEL, n); \ if (!info_label_was_found) \ info_parse_label (INFO_ALTPREV_LABEL, n); \ } while (0) #endif /* not INFO_UTILS_H */ texinfo-3.12/info/infomap.h0000444000175000017500000000500506362741227013115 0ustar gg/* infomap.h -- Description of a keymap in Info and related functions. */ /* This file is part of GNU Info, a program for reading online documentation stored in Info format. Copyright (C) 1993 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ #ifndef INFOMAP_H #define INFOMAP_H #include "info.h" #define ESC '\033' #define DEL '\177' #define TAB '\011' #define RET '\r' #define LFD '\n' #define SPC ' ' #define meta_character_threshold (DEL + 1) #define control_character_threshold (SPC) #define meta_character_bit 0x80 #define control_character_bit 0x40 #define Meta_p(c) (((c) > meta_character_threshold)) #define Control_p(c) ((c) < control_character_threshold) #define Meta(c) ((c) | (meta_character_bit)) #define UnMeta(c) ((c) & (~meta_character_bit)) #define Control(c) ((toupper (c)) & (~control_character_bit)) #define UnControl(c) (tolower ((c) | control_character_bit)) /* A keymap contains one entry for each key in the ASCII set. Each entry consists of a type and a pointer. FUNCTION is the address of a function to run, or the address of a keymap to indirect through. TYPE says which kind of thing FUNCTION is. */ typedef struct { char type; VFunction *function; } KEYMAP_ENTRY; typedef KEYMAP_ENTRY *Keymap; /* The values that TYPE can have in a keymap entry. */ #define ISFUNC 0 #define ISKMAP 1 extern Keymap info_keymap; extern Keymap echo_area_keymap; /* Return a new keymap which has all the uppercase letters mapped to run the function info_do_lowercase_version (). */ extern Keymap keymap_make_keymap (); /* Return a new keymap which is a copy of MAP. */ extern Keymap keymap_copy_keymap (); /* Free MAP and it's descendents. */ extern void keymap_discard_keymap (); /* Initialize the info keymaps. */ extern void initialize_info_keymaps (); #endif /* not INFOMAP_H */ texinfo-3.12/info/echo-area.c0000444000175000017500000012474206475370347013323 0ustar gg/* echo-area.c -- How to read a line in the echo area. $Id: echo-area.c,v 1.10 1998/02/26 22:47:02 karl Exp $ Copyright (C) 1993, 97, 98 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ #include "info.h" #if defined (FD_SET) # if defined (hpux) # define fd_set_cast(x) (int *)(x) # else # define fd_set_cast(x) (fd_set *)(x) # endif /* !hpux */ #endif /* FD_SET */ /* Non-zero means that C-g was used to quit reading input. */ int info_aborted_echo_area = 0; /* Non-zero means that the echo area is being used to read input. */ int echo_area_is_active = 0; /* The address of the last command executed in the echo area. */ VFunction *ea_last_executed_command = (VFunction *)NULL; /* Non-zero means that the last command executed while reading input killed some text. */ int echo_area_last_command_was_kill = 0; /* Variables which hold on to the current state of the input line. */ static char input_line[1 + EA_MAX_INPUT]; static char *input_line_prompt; static int input_line_point; static int input_line_beg; static int input_line_end; static NODE input_line_node = { (char *)NULL, (char *)NULL, (char *)NULL, input_line, EA_MAX_INPUT, 0 }; static void echo_area_initialize_node (); static void push_echo_area (), pop_echo_area (); static int echo_area_stack_contains_completions_p (); static void ea_kill_text (); /* Non-zero means we force the user to complete. */ static int echo_area_must_complete_p = 0; static int completions_window_p (); /* If non-null, this is a window which was specifically created to display possible completions output. We remember it so we can delete it when appropriate. */ static WINDOW *echo_area_completions_window = (WINDOW *)NULL; /* Variables which keep track of the window which was active prior to entering the echo area. */ static WINDOW *calling_window = (WINDOW *)NULL; static NODE *calling_window_node = (NODE *)NULL; static long calling_window_point = 0; static long calling_window_pagetop = 0; /* Remember the node and pertinent variables of the calling window. */ static void remember_calling_window (window) WINDOW *window; { /* Only do this if the calling window is not the completions window, or, if it is the completions window and there is no other window. */ if (!completions_window_p (window) || ((window == windows) && !(window->next))) { calling_window = window; calling_window_node = window->node; calling_window_point = window->point; calling_window_pagetop = window->pagetop; } } /* Restore the caller's window so that it shows the node that it was showing on entry to info_read_xxx_echo_area (). */ static void restore_calling_window () { register WINDOW *win, *compwin = (WINDOW *)NULL; /* If the calling window is still visible, and it is the window that we used for completions output, then restore the calling window. */ for (win = windows; win; win = win->next) { if (completions_window_p (win)) compwin = win; if (win == calling_window && win == compwin) { window_set_node_of_window (calling_window, calling_window_node); calling_window->point = calling_window_point; calling_window->pagetop = calling_window_pagetop; compwin = (WINDOW *)NULL; break; } } /* Delete the completions window if it is still present, it isn't the last window on the screen, and there aren't any prior echo area reads pending which created a completions window. */ if (compwin) { if ((compwin != windows || windows->next) && !echo_area_stack_contains_completions_p ()) { WINDOW *next; int pagetop, start, end, amount; next = compwin->next; if (next) { start = next->first_row; end = start + next->height; amount = - (compwin->height + 1); pagetop = next->pagetop; } info_delete_window_internal (compwin); /* This is not necessary because info_delete_window_internal () calls echo_area_inform_of_deleted_window (), which does the right thing. */ #if defined (UNNECESSARY) echo_area_completions_window = (WINDOW *)NULL; #endif /* UNNECESSARY */ if (next) { display_scroll_display (start, end, amount); next->pagetop = pagetop; display_update_display (windows); } } } } /* Set up a new input line with PROMPT. */ static void initialize_input_line (prompt) char *prompt; { input_line_prompt = prompt; if (prompt) strcpy (input_line, prompt); else input_line[0] = '\0'; input_line_beg = input_line_end = input_line_point = strlen (prompt); } static char * echo_area_after_read () { char *return_value; if (info_aborted_echo_area) { info_aborted_echo_area = 0; return_value = (char *)NULL; } else { if (input_line_beg == input_line_end) return_value = xstrdup (""); else { int line_len = input_line_end - input_line_beg; return_value = (char *) xmalloc (1 + line_len); strncpy (return_value, &input_line[input_line_beg], line_len); return_value[line_len] = '\0'; } } return (return_value); } /* Read a line of text in the echo area. Return a malloc ()'ed string, or NULL if the user aborted out of this read. WINDOW is the currently active window, so that we can restore it when we need to. PROMPT, if non-null, is a prompt to print before reading the line. */ char * info_read_in_echo_area (window, prompt) WINDOW *window; char *prompt; { char *line; /* If the echo area is already active, remember the current state. */ if (echo_area_is_active) push_echo_area (); /* Initialize our local variables. */ initialize_input_line (prompt); /* Initialize the echo area for the first (but maybe not the last) time. */ echo_area_initialize_node (); /* Save away the original node of this window, and the window itself, so echo area commands can temporarily use this window. */ remember_calling_window (window); /* Let the rest of Info know that the echo area is active. */ echo_area_is_active++; active_window = the_echo_area; /* Read characters in the echo area. */ info_read_and_dispatch (); echo_area_is_active--; /* Restore the original active window and show point in it. */ active_window = calling_window; restore_calling_window (); display_cursor_at_point (active_window); fflush (stdout); /* Get the value of the line. */ line = echo_area_after_read (); /* If there is a previous loop waiting for us, restore it now. */ if (echo_area_is_active) pop_echo_area (); /* Return the results to the caller. */ return (line); } /* (re) Initialize the echo area node. */ static void echo_area_initialize_node () { register int i; for (i = input_line_end; i < sizeof (input_line); i++) input_line[i] = ' '; input_line[i - 1] = '\n'; window_set_node_of_window (the_echo_area, &input_line_node); input_line[input_line_end] = '\n'; } /* Prepare to read characters in the echo area. This can initialize the echo area node, but its primary purpose is to side effect the input line buffer contents. */ void echo_area_prep_read () { if (the_echo_area->node != &input_line_node) echo_area_initialize_node (); the_echo_area->point = input_line_point; input_line[input_line_end] = '\n'; display_update_one_window (the_echo_area); display_cursor_at_point (active_window); } /* **************************************************************** */ /* */ /* Echo Area Movement Commands */ /* */ /* **************************************************************** */ DECLARE_INFO_COMMAND (ea_forward, _("Move forward a character")) { if (count < 0) ea_backward (window, -count, key); else { input_line_point += count; if (input_line_point > input_line_end) input_line_point = input_line_end; } } DECLARE_INFO_COMMAND (ea_backward, _("Move backward a character")) { if (count < 0) ea_forward (window, -count, key); else { input_line_point -= count; if (input_line_point < input_line_beg) input_line_point = input_line_beg; } } DECLARE_INFO_COMMAND (ea_beg_of_line, _("Move to the start of this line")) { input_line_point = input_line_beg; } DECLARE_INFO_COMMAND (ea_end_of_line, _("Move to the end of this line")) { input_line_point = input_line_end; } #define alphabetic(c) (islower (c) || isupper (c) || isdigit (c)) /* Move forward a word in the input line. */ DECLARE_INFO_COMMAND (ea_forward_word, _("Move forward a word")) { int c; if (count < 0) ea_backward_word (window, -count, key); else { while (count--) { if (input_line_point == input_line_end) return; /* If we are not in a word, move forward until we are in one. Then, move forward until we hit a non-alphabetic character. */ c = input_line[input_line_point]; if (!alphabetic (c)) { while (++input_line_point < input_line_end) { c = input_line[input_line_point]; if (alphabetic (c)) break; } } if (input_line_point == input_line_end) return; while (++input_line_point < input_line_end) { c = input_line[input_line_point]; if (!alphabetic (c)) break; } } } } DECLARE_INFO_COMMAND (ea_backward_word, _("Move backward a word")) { int c; if (count < 0) ea_forward_word (window, -count, key); else { while (count--) { if (input_line_point == input_line_beg) return; /* Like ea_forward_word (), except that we look at the characters just before point. */ c = input_line[input_line_point - 1]; if (!alphabetic (c)) { while ((--input_line_point) != input_line_beg) { c = input_line[input_line_point - 1]; if (alphabetic (c)) break; } } while (input_line_point != input_line_beg) { c = input_line[input_line_point - 1]; if (!alphabetic (c)) break; else --input_line_point; } } } } DECLARE_INFO_COMMAND (ea_delete, _("Delete the character under the cursor")) { register int i; if (count < 0) ea_rubout (window, -count, key); else { if (input_line_point == input_line_end) return; if (info_explicit_arg || count > 1) { int orig_point; orig_point = input_line_point; ea_forward (window, count, key); ea_kill_text (orig_point, input_line_point); input_line_point = orig_point; } else { for (i = input_line_point; i < input_line_end; i++) input_line[i] = input_line[i + 1]; input_line_end--; } } } DECLARE_INFO_COMMAND (ea_rubout, _("Delete the character behind the cursor")) { if (count < 0) ea_delete (window, -count, key); else { int start; if (input_line_point == input_line_beg) return; start = input_line_point; ea_backward (window, count, key); if (info_explicit_arg || count > 1) ea_kill_text (start, input_line_point); else ea_delete (window, count, key); } } DECLARE_INFO_COMMAND (ea_abort, _("Cancel or quit operation")) { /* If any text, just discard it, and restore the calling window's node. If no text, quit. */ if (input_line_end != input_line_beg) { terminal_ring_bell (); input_line_end = input_line_point = input_line_beg; if (calling_window->node != calling_window_node) restore_calling_window (); } else info_aborted_echo_area = 1; } DECLARE_INFO_COMMAND (ea_newline, _("Accept (or force completion of) this line")) { /* Stub does nothing. Simply here to see if it has been executed. */ } DECLARE_INFO_COMMAND (ea_quoted_insert, _("Insert next character verbatim")) { unsigned char character; character = info_get_another_input_char (); ea_insert (window, count, character); } DECLARE_INFO_COMMAND (ea_insert, _("Insert this character")) { register int i; if ((input_line_end + 1) == EA_MAX_INPUT) { terminal_ring_bell (); return; } for (i = input_line_end + 1; i != input_line_point; i--) input_line[i] = input_line[i - 1]; input_line[input_line_point] = key; input_line_point++; input_line_end++; } DECLARE_INFO_COMMAND (ea_tab_insert, _("Insert a TAB character")) { ea_insert (window, count, '\t'); } /* Transpose the characters at point. If point is at the end of the line, then transpose the characters before point. */ DECLARE_INFO_COMMAND (ea_transpose_chars, _("Transpose characters at point")) { /* Handle conditions that would make it impossible to transpose characters. */ if (!count || !input_line_point || (input_line_end - input_line_beg) < 2) return; while (count) { int t; if (input_line_point == input_line_end) { t = input_line[input_line_point - 1]; input_line[input_line_point - 1] = input_line[input_line_point - 2]; input_line[input_line_point - 2] = t; } else { t = input_line[input_line_point]; input_line[input_line_point] = input_line[input_line_point - 1]; input_line[input_line_point - 1] = t; if (count < 0 && input_line_point != input_line_beg) input_line_point--; else input_line_point++; } if (count < 0) count++; else count--; } } /* **************************************************************** */ /* */ /* Echo Area Killing and Yanking */ /* */ /* **************************************************************** */ static char **kill_ring = (char **)NULL; static int kill_ring_index = 0; /* Number of kills appearing in KILL_RING. */ static int kill_ring_slots = 0; /* Number of slots allocated to KILL_RING. */ static int kill_ring_loc = 0; /* Location of current yank pointer. */ /* The largest number of kills that we remember at one time. */ static int max_retained_kills = 15; DECLARE_INFO_COMMAND (ea_yank, _("Yank back the contents of the last kill")) { register int i; register char *text; if (!kill_ring_index) { inform_in_echo_area (_("Kill ring is empty")); return; } text = kill_ring[kill_ring_loc]; for (i = 0; text[i]; i++) ea_insert (window, 1, text[i]); } /* If the last command was yank, or yank_pop, and the text just before point is identical to the current kill item, then delete that text from the line, rotate the index down, and yank back some other text. */ DECLARE_INFO_COMMAND (ea_yank_pop, _("Yank back a previous kill")) { register int len; if (((ea_last_executed_command != ea_yank) && (ea_last_executed_command != ea_yank_pop)) || (kill_ring_index == 0)) return; len = strlen (kill_ring[kill_ring_loc]); /* Delete the last yanked item from the line. */ { register int i, counter; counter = input_line_end - input_line_point; for (i = input_line_point - len; counter; i++, counter--) input_line[i] = input_line[i + len]; input_line_end -= len; input_line_point -= len; } /* Get a previous kill, and yank that. */ kill_ring_loc--; if (kill_ring_loc < 0) kill_ring_loc = kill_ring_index - 1; ea_yank (window, count, key); } /* Delete the text from point to end of line. */ DECLARE_INFO_COMMAND (ea_kill_line, _("Kill to the end of the line")) { if (count < 0) { ea_kill_text (input_line_point, input_line_beg); input_line_point = input_line_beg; } else ea_kill_text (input_line_point, input_line_end); } /* Delete the text from point to beg of line. */ DECLARE_INFO_COMMAND (ea_backward_kill_line, _("Kill to the beginning of the line")) { if (count < 0) ea_kill_text (input_line_point, input_line_end); else { ea_kill_text (input_line_point, input_line_beg); input_line_point = input_line_beg; } } /* Delete from point to the end of the current word. */ DECLARE_INFO_COMMAND (ea_kill_word, _("Kill the word following the cursor")) { int orig_point = input_line_point; if (count < 0) ea_backward_kill_word (window, -count, key); else { ea_forward_word (window, count, key); if (input_line_point != orig_point) ea_kill_text (orig_point, input_line_point); input_line_point = orig_point; } } /* Delete from point to the start of the current word. */ DECLARE_INFO_COMMAND (ea_backward_kill_word, _("Kill the word preceding the cursor")) { int orig_point = input_line_point; if (count < 0) ea_kill_word (window, -count, key); else { ea_backward_word (window, count, key); if (input_line_point != orig_point) ea_kill_text (orig_point, input_line_point); } } /* The way to kill something. This appends or prepends to the last kill, if the last command was a kill command. If FROM is less than TO, then the killed text is appended to the most recent kill, otherwise it is prepended. If the last command was not a kill command, then a new slot is made for this kill. */ static void ea_kill_text (from, to) int from, to; { register int i, counter, distance; int killing_backwards, slot; char *killed_text; killing_backwards = (from > to); /* If killing backwards, reverse the values of FROM and TO. */ if (killing_backwards) { int temp = from; from = to; to = temp; } /* Remember the text that we are about to delete. */ distance = to - from; killed_text = (char *)xmalloc (1 + distance); strncpy (killed_text, &input_line[from], distance); killed_text[distance] = '\0'; /* Actually delete the text from the line. */ counter = input_line_end - to; for (i = from; counter; i++, counter--) input_line[i] = input_line[i + distance]; input_line_end -= distance; /* If the last command was a kill, append or prepend the killed text to the last command's killed text. */ if (echo_area_last_command_was_kill) { char *old, *new; slot = kill_ring_loc; old = kill_ring[slot]; new = (char *)xmalloc (1 + strlen (old) + strlen (killed_text)); if (killing_backwards) { /* Prepend TEXT to current kill. */ strcpy (new, killed_text); strcat (new, old); } else { /* Append TEXT to current kill. */ strcpy (new, old); strcat (new, killed_text); } free (old); free (killed_text); kill_ring[slot] = new; } else { /* Try to store the kill in a new slot, unless that would cause there to be too many remembered kills. */ slot = kill_ring_index; if (slot == max_retained_kills) slot = 0; if (slot + 1 > kill_ring_slots) kill_ring = (char **) xrealloc (kill_ring, (kill_ring_slots += max_retained_kills) * sizeof (char *)); if (slot != kill_ring_index) free (kill_ring[slot]); else kill_ring_index++; kill_ring[slot] = killed_text; kill_ring_loc = slot; } /* Notice that the last command was a kill. */ echo_area_last_command_was_kill++; } /* **************************************************************** */ /* */ /* Echo Area Completion */ /* */ /* **************************************************************** */ /* Pointer to an array of REFERENCE to complete over. */ static REFERENCE **echo_area_completion_items = (REFERENCE **)NULL; /* Sorted array of REFERENCE * which is the possible completions found in the variable echo_area_completion_items. If there is only one element, it is the only possible completion. */ static REFERENCE **completions_found = (REFERENCE **)NULL; static int completions_found_index = 0; static int completions_found_slots = 0; /* The lowest common denominator found while completing. */ static REFERENCE *LCD_completion; /* Internal functions used by the user calls. */ static void build_completions (), completions_must_be_rebuilt (); /* Variable which holds the output of completions. */ static NODE *possible_completions_output_node = (NODE *)NULL; static char *compwin_name = "*Completions*"; /* Return non-zero if WINDOW is a window used for completions output. */ static int completions_window_p (window) WINDOW *window; { int result = 0; if (internal_info_node_p (window->node) && (strcmp (window->node->nodename, compwin_name) == 0)) result = 1; return (result); } /* Workhorse for completion readers. If FORCE is non-zero, the user cannot exit unless the line read completes, or is empty. */ char * info_read_completing_internal (window, prompt, completions, force) WINDOW *window; char *prompt; REFERENCE **completions; int force; { char *line; /* If the echo area is already active, remember the current state. */ if (echo_area_is_active) push_echo_area (); echo_area_must_complete_p = force; /* Initialize our local variables. */ initialize_input_line (prompt); /* Initialize the echo area for the first (but maybe not the last) time. */ echo_area_initialize_node (); /* Save away the original node of this window, and the window itself, so echo area commands can temporarily use this window. */ remember_calling_window (window); /* Save away the list of items to complete over. */ echo_area_completion_items = completions; completions_must_be_rebuilt (); active_window = the_echo_area; echo_area_is_active++; /* Read characters in the echo area. */ while (1) { info_read_and_dispatch (); line = echo_area_after_read (); /* Force the completion to take place if the user hasn't accepted a default or aborted, and if FORCE is active. */ if (force && line && *line && completions) { register int i; build_completions (); /* If there is only one completion, then make the line be that completion. */ if (completions_found_index == 1) { free (line); line = xstrdup (completions_found[0]->label); break; } /* If one of the completions matches exactly, then that is okay, so return the current line. */ for (i = 0; i < completions_found_index; i++) if (strcasecmp (completions_found[i]->label, line) == 0) { free (line); line = xstrdup (completions_found[i]->label); break; } /* If no match, go back and try again. */ if (i == completions_found_index) { inform_in_echo_area (_("Not complete")); continue; } } break; } echo_area_is_active--; /* Restore the original active window and show point in it. */ active_window = calling_window; restore_calling_window (); display_cursor_at_point (active_window); fflush (stdout); echo_area_completion_items = (REFERENCE **)NULL; completions_must_be_rebuilt (); /* If there is a previous loop waiting for us, restore it now. */ if (echo_area_is_active) pop_echo_area (); return (line); } /* Read a line in the echo area with completion over COMPLETIONS. */ char * info_read_completing_in_echo_area (window, prompt, completions) WINDOW *window; char *prompt; REFERENCE **completions; { return (info_read_completing_internal (window, prompt, completions, 1)); } /* Read a line in the echo area allowing completion over COMPLETIONS, but not requiring it. */ char * info_read_maybe_completing (window, prompt, completions) WINDOW *window; char *prompt; REFERENCE **completions; { return (info_read_completing_internal (window, prompt, completions, 0)); } DECLARE_INFO_COMMAND (ea_possible_completions, _("List possible completions")) { if (!echo_area_completion_items) { ea_insert (window, count, key); return; } build_completions (); if (!completions_found_index) { terminal_ring_bell (); inform_in_echo_area (_("No completions")); } else if ((completions_found_index == 1) && (key != '?')) { inform_in_echo_area (_("Sole completion")); } else { register int i, l; int limit, count, max_label = 0; initialize_message_buffer (); printf_to_message_buffer (completions_found_index == 1 ? _("One completion:\n") : _("%d completions:\n")); /* Find the maximum length of a label. */ for (i = 0; i < completions_found_index; i++) { int len = strlen (completions_found[i]->label); if (len > max_label) max_label = len; } max_label += 4; /* Find out how many columns we should print in. */ limit = calling_window->width / max_label; if (limit != 1 && (limit * max_label == calling_window->width)) limit--; /* Avoid a possible floating exception. If max_label > width then the limit will be 0 and a divide-by-zero fault will result. */ if (limit == 0) limit = 1; /* How many iterations of the printing loop? */ count = (completions_found_index + (limit - 1)) / limit; /* Watch out for special case. If the number of completions is less than LIMIT, then just do the inner printing loop. */ if (completions_found_index < limit) count = 1; /* Print the sorted items, up-and-down alphabetically. */ for (i = 0; i < count; i++) { register int j; for (j = 0, l = i; j < limit; j++) { if (l >= completions_found_index) break; else { char *label; int printed_length, k; label = completions_found[l]->label; printed_length = strlen (label); printf_to_message_buffer ("%s", label); if (j + 1 < limit) { for (k = 0; k < max_label - printed_length; k++) printf_to_message_buffer (" "); } } l += count; } printf_to_message_buffer ("\n"); } /* Make a new node to hold onto possible completions. Don't destroy dangling pointers. */ { NODE *temp; temp = message_buffer_to_node (); add_gcable_pointer (temp->contents); name_internal_node (temp, compwin_name); possible_completions_output_node = temp; } /* Find a suitable window for displaying the completions output. First choice is an existing window showing completions output. If there is only one window, and it is large, make another (smaller) window, and use that one. Otherwise, use the caller's window. */ { WINDOW *compwin; compwin = get_internal_info_window (compwin_name); if (!compwin) { /* If we can split the window to display most of the completion items, then do so. */ if (calling_window->height > (count * 2) && calling_window->height / 2 >= WINDOW_MIN_SIZE) { int start, pagetop; #ifdef SPLIT_BEFORE_ACTIVE int end; #endif active_window = calling_window; /* Perhaps we can scroll this window on redisplay. */ start = calling_window->first_row; pagetop = calling_window->pagetop; compwin = window_make_window (possible_completions_output_node); active_window = the_echo_area; window_change_window_height (compwin, -(compwin->height - (count + 2))); window_adjust_pagetop (calling_window); remember_calling_window (calling_window); #if defined (SPLIT_BEFORE_ACTIVE) /* If the pagetop hasn't changed, scrolling the calling window is a reasonable thing to do. */ if (pagetop == calling_window->pagetop) { end = start + calling_window->height; display_scroll_display (start, end, calling_window->prev->height + 1); } #else /* !SPLIT_BEFORE_ACTIVE */ /* If the pagetop has changed, set the new pagetop here. */ if (pagetop != calling_window->pagetop) { int newtop = calling_window->pagetop; calling_window->pagetop = pagetop; set_window_pagetop (calling_window, newtop); } #endif /* !SPLIT_BEFORE_ACTIVE */ echo_area_completions_window = compwin; remember_window_and_node (compwin, compwin->node); } else compwin = calling_window; } if (compwin->node != possible_completions_output_node) { window_set_node_of_window (compwin, possible_completions_output_node); remember_window_and_node (compwin, compwin->node); } display_update_display (windows); } } } DECLARE_INFO_COMMAND (ea_complete, _("Insert completion")) { if (!echo_area_completion_items) { ea_insert (window, count, key); return; } /* If KEY is SPC, and we are not forcing completion to take place, simply insert the key. */ if (!echo_area_must_complete_p && key == SPC) { ea_insert (window, count, key); return; } if (ea_last_executed_command == ea_complete) { /* If the keypress is a SPC character, and we have already tried completing once, and there are several completions, then check the batch of completions to see if any continue with a space. If there are some, insert the space character and continue. */ if (key == SPC && completions_found_index > 1) { register int i, offset; offset = input_line_end - input_line_beg; for (i = 0; i < completions_found_index; i++) if (completions_found[i]->label[offset] == ' ') break; if (completions_found[i]) ea_insert (window, 1, ' '); else { ea_possible_completions (window, count, key); return; } } else { ea_possible_completions (window, count, key); return; } } input_line_point = input_line_end; build_completions (); if (!completions_found_index) terminal_ring_bell (); else if (LCD_completion->label[0] == '\0') ea_possible_completions (window, count, key); else { register int i; input_line_point = input_line_end = input_line_beg; for (i = 0; LCD_completion->label[i]; i++) ea_insert (window, 1, LCD_completion->label[i]); } } /* Utility REFERENCE used to store possible LCD. */ static REFERENCE LCD_reference = { (char *)NULL, (char *)NULL, (char *)NULL }; static void remove_completion_duplicates (); /* Variables which remember the state of the most recent call to build_completions (). */ static char *last_completion_request = (char *)NULL; static REFERENCE **last_completion_items = (REFERENCE **)NULL; /* How to tell the completion builder to reset internal state. */ static void completions_must_be_rebuilt () { maybe_free (last_completion_request); last_completion_request = (char *)NULL; last_completion_items = (REFERENCE **)NULL; } /* Build a list of possible completions from echo_area_completion_items, and the contents of input_line. */ static void build_completions () { register int i, len; register REFERENCE *entry; char *request; int informed_of_lengthy_job = 0; /* If there are no items to complete over, exit immediately. */ if (!echo_area_completion_items) { completions_found_index = 0; LCD_completion = (REFERENCE *)NULL; return; } /* Check to see if this call to build completions is the same as the last call to build completions. */ len = input_line_end - input_line_beg; request = (char *)xmalloc (1 + len); strncpy (request, &input_line[input_line_beg], len); request[len] = '\0'; if (last_completion_request && last_completion_items && last_completion_items == echo_area_completion_items && (strcmp (last_completion_request, request) == 0)) { free (request); return; } maybe_free (last_completion_request); last_completion_request = request; last_completion_items = echo_area_completion_items; /* Always start at the beginning of the list. */ completions_found_index = 0; LCD_completion = (REFERENCE *)NULL; for (i = 0; (entry = echo_area_completion_items[i]); i++) { if (strncasecmp (request, entry->label, len) == 0) add_pointer_to_array (entry, completions_found_index, completions_found, completions_found_slots, 20, REFERENCE *); if (!informed_of_lengthy_job && completions_found_index > 100) { informed_of_lengthy_job = 1; window_message_in_echo_area (_("Building completions...")); } } if (!completions_found_index) return; /* Sort and prune duplicate entries from the completions array. */ remove_completion_duplicates (); /* If there is only one completion, just return that. */ if (completions_found_index == 1) { LCD_completion = completions_found[0]; return; } /* Find the least common denominator. */ { long shortest = 100000; for (i = 1; i < completions_found_index; i++) { register int j; int c1, c2; for (j = 0; (c1 = info_tolower (completions_found[i - 1]->label[j])) && (c2 = info_tolower (completions_found[i]->label[j])); j++) if (c1 != c2) break; if (shortest > j) shortest = j; } maybe_free (LCD_reference.label); LCD_reference.label = (char *)xmalloc (1 + shortest); strncpy (LCD_reference.label, completions_found[0]->label, shortest); LCD_reference.label[shortest] = '\0'; LCD_completion = &LCD_reference; } if (informed_of_lengthy_job) echo_area_initialize_node (); } /* Function called by qsort. */ static int compare_references (entry1, entry2) REFERENCE **entry1, **entry2; { return (strcasecmp ((*entry1)->label, (*entry2)->label)); } /* Prune duplicate entries from COMPLETIONS_FOUND. */ static void remove_completion_duplicates () { register int i, j; REFERENCE **temp; int newlen; if (!completions_found_index) return; /* Sort the items. */ qsort (completions_found, completions_found_index, sizeof (REFERENCE *), compare_references); for (i = 0, newlen = 1; i < completions_found_index - 1; i++) { if (strcmp (completions_found[i]->label, completions_found[i + 1]->label) == 0) completions_found[i] = (REFERENCE *)NULL; else newlen++; } /* We have marked all the dead slots. It is faster to copy the live slots twice than to prune the dead slots one by one. */ temp = (REFERENCE **)xmalloc ((1 + newlen) * sizeof (REFERENCE *)); for (i = 0, j = 0; i < completions_found_index; i++) if (completions_found[i]) temp[j++] = completions_found[i]; for (i = 0; i < newlen; i++) completions_found[i] = temp[i]; completions_found[i] = (REFERENCE *)NULL; completions_found_index = newlen; free (temp); } /* Scroll the "other" window. If there is a window showing completions, scroll that one, otherwise scroll the window which was active on entering the read function. */ DECLARE_INFO_COMMAND (ea_scroll_completions_window, _("Scroll the completions window")) { WINDOW *compwin; int old_pagetop; compwin = get_internal_info_window (compwin_name); if (!compwin) compwin = calling_window; old_pagetop = compwin->pagetop; /* Let info_scroll_forward () do the work, and print any messages that need to be displayed. */ info_scroll_forward (compwin, count, key); } /* Function which gets called when an Info window is deleted while the echo area is active. WINDOW is the window which has just been deleted. */ void echo_area_inform_of_deleted_window (window) WINDOW *window; { /* If this is the calling_window, forget what we remembered about it. */ if (window == calling_window) { if (active_window != the_echo_area) remember_calling_window (active_window); else remember_calling_window (windows); } /* If this window was the echo_area_completions_window, then notice that the window has been deleted. */ if (window == echo_area_completions_window) echo_area_completions_window = (WINDOW *)NULL; } /* **************************************************************** */ /* */ /* Pushing and Popping the Echo Area */ /* */ /* **************************************************************** */ /* Push and Pop the echo area. */ typedef struct { char *line; char *prompt; REFERENCE **comp_items; int point, beg, end; int must_complete; NODE node; WINDOW *compwin; } PUSHED_EA; static PUSHED_EA **pushed_echo_areas = (PUSHED_EA **)NULL; static int pushed_echo_areas_index = 0; static int pushed_echo_areas_slots = 0; /* Pushing the echo_area has a side effect of zeroing the completion_items. */ static void push_echo_area () { PUSHED_EA *pushed; pushed = (PUSHED_EA *)xmalloc (sizeof (PUSHED_EA)); pushed->line = xstrdup (input_line); pushed->prompt = input_line_prompt; pushed->point = input_line_point; pushed->beg = input_line_beg; pushed->end = input_line_end; pushed->node = input_line_node; pushed->comp_items = echo_area_completion_items; pushed->must_complete = echo_area_must_complete_p; pushed->compwin = echo_area_completions_window; add_pointer_to_array (pushed, pushed_echo_areas_index, pushed_echo_areas, pushed_echo_areas_slots, 4, PUSHED_EA *); echo_area_completion_items = (REFERENCE **)NULL; } static void pop_echo_area () { PUSHED_EA *popped; popped = pushed_echo_areas[--pushed_echo_areas_index]; strcpy (input_line, popped->line); free (popped->line); input_line_prompt = popped->prompt; input_line_point = popped->point; input_line_beg = popped->beg; input_line_end = popped->end; input_line_node = popped->node; echo_area_completion_items = popped->comp_items; echo_area_must_complete_p = popped->must_complete; echo_area_completions_window = popped->compwin; completions_must_be_rebuilt (); /* If the completion window no longer exists, forget about it. */ if (echo_area_completions_window) { register WINDOW *win; for (win = windows; win; win = win->next) if (echo_area_completions_window == win) break; /* If the window wasn't found, then it has already been deleted. */ if (!win) echo_area_completions_window = (WINDOW *)NULL; } free (popped); } /* Returns non-zero if any of the prior stacked calls to read in the echo area produced a completions window. */ static int echo_area_stack_contains_completions_p () { register int i; for (i = 0; i < pushed_echo_areas_index; i++) if (pushed_echo_areas[i]->compwin) return (1); return (0); } /* **************************************************************** */ /* */ /* Error Messages While Reading in Echo Area */ /* */ /* **************************************************************** */ #if defined (HAVE_SYS_TIME_H) # include # define HAVE_STRUCT_TIMEVAL #endif /* HAVE_SYS_TIME_H */ static void pause_or_input () { #if defined (FD_SET) struct timeval timer; fd_set readfds; int ready; FD_ZERO (&readfds); FD_SET (fileno (stdin), &readfds); timer.tv_sec = 2; timer.tv_usec = 750; ready = select (fileno (stdin) + 1, &readfds, (fd_set *) NULL, (fd_set *) NULL, &timer); #endif /* FD_SET */ } /* Print MESSAGE right after the end of the current line, and wait for input or 2.75 seconds, whichever comes first. Then flush the informational message that was printed. */ void inform_in_echo_area (message) char *message; { register int i; char *text; text = xstrdup (message); for (i = 0; text[i] && text[i] != '\n'; i++); text[i] = '\0'; echo_area_initialize_node (); sprintf (&input_line[input_line_end], "%s[%s]\n", echo_area_is_active ? " ": "", text); free (text); the_echo_area->point = input_line_point; display_update_one_window (the_echo_area); display_cursor_at_point (active_window); fflush (stdout); pause_or_input (); echo_area_initialize_node (); } texinfo-3.12/info/tilde.c0000444000175000017500000002345106474127272012567 0ustar gg/* tilde.c -- Tilde expansion code (~/foo := $HOME/foo). $Id: tilde.c,v 1.9 1998/02/22 23:03:21 karl Exp $ This file is part of GNU Info, a program for reading online documentation stored in Info format. Copyright (C) 1988, 89, 90, 91, 92, 93, 96, 98 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ /* Indent #pragma so that older Cpp's don't try to parse it. */ #ifdef _AIX #pragma alloca #endif /* _AIX */ /* Include config.h before doing alloca. */ #include "info.h" #ifdef __GNUC__ # undef alloca # define alloca __builtin_alloca #else # ifdef HAVE_ALLOCA_H # include # else # ifndef _AIX char *alloca (); # endif # endif #endif #if defined (TEST) || defined (STATIC_MALLOC) static void *xmalloc (), *xrealloc (); #endif /* TEST || STATIC_MALLOC */ /* The default value of tilde_additional_prefixes. This is set to whitespace preceding a tilde so that simple programs which do not perform any word separation get desired behaviour. */ static char *default_prefixes[] = { " ~", "\t~", (char *)NULL }; /* The default value of tilde_additional_suffixes. This is set to whitespace or newline so that simple programs which do not perform any word separation get desired behaviour. */ static char *default_suffixes[] = { " ", "\n", (char *)NULL }; /* If non-null, this contains the address of a function to call if the standard meaning for expanding a tilde fails. The function is called with the text (sans tilde, as in "foo"), and returns a malloc()'ed string which is the expansion, or a NULL pointer if there is no expansion. */ CFunction *tilde_expansion_failure_hook = (CFunction *)NULL; /* When non-null, this is a NULL terminated array of strings which are duplicates for a tilde prefix. Bash uses this to expand `=~' and `:~'. */ char **tilde_additional_prefixes = default_prefixes; /* When non-null, this is a NULL terminated array of strings which match the end of a username, instead of just "/". Bash sets this to `:' and `=~'. */ char **tilde_additional_suffixes = default_suffixes; /* Find the start of a tilde expansion in STRING, and return the index of the tilde which starts the expansion. Place the length of the text which identified this tilde starter in LEN, excluding the tilde itself. */ static int tilde_find_prefix (string, len) char *string; int *len; { register int i, j, string_len; register char **prefixes = tilde_additional_prefixes; string_len = strlen (string); *len = 0; if (!*string || *string == '~') return (0); if (prefixes) { for (i = 0; i < string_len; i++) { for (j = 0; prefixes[j]; j++) { if (strncmp (string + i, prefixes[j], strlen (prefixes[j])) == 0) { *len = strlen (prefixes[j]) - 1; return (i + *len); } } } } return (string_len); } /* Find the end of a tilde expansion in STRING, and return the index of the character which ends the tilde definition. */ static int tilde_find_suffix (string) char *string; { register int i, j, string_len; register char **suffixes = tilde_additional_suffixes; string_len = strlen (string); for (i = 0; i < string_len; i++) { if (string[i] == '/' || !string[i]) break; for (j = 0; suffixes && suffixes[j]; j++) { if (strncmp (string + i, suffixes[j], strlen (suffixes[j])) == 0) return (i); } } return (i); } /* Return a new string which is the result of tilde expanding STRING. */ char * tilde_expand (string) char *string; { char *result, *tilde_expand_word (); int result_size, result_index; result_size = result_index = 0; result = (char *)NULL; /* Scan through STRING expanding tildes as we come to them. */ while (1) { register int start, end; char *tilde_word, *expansion; int len; /* Make START point to the tilde which starts the expansion. */ start = tilde_find_prefix (string, &len); /* Copy the skipped text into the result. */ if ((result_index + start + 1) > result_size) result = (char *)xrealloc (result, 1 + (result_size += (start + 20))); strncpy (result + result_index, string, start); result_index += start; /* Advance STRING to the starting tilde. */ string += start; /* Make END be the index of one after the last character of the username. */ end = tilde_find_suffix (string); /* If both START and END are zero, we are all done. */ if (!start && !end) break; /* Expand the entire tilde word, and copy it into RESULT. */ tilde_word = (char *)xmalloc (1 + end); strncpy (tilde_word, string, end); tilde_word[end] = '\0'; string += end; expansion = tilde_expand_word (tilde_word); free (tilde_word); len = strlen (expansion); if ((result_index + len + 1) > result_size) result = (char *)xrealloc (result, 1 + (result_size += (len + 20))); strcpy (result + result_index, expansion); result_index += len; free (expansion); } result[result_index] = '\0'; return (result); } /* Do the work of tilde expansion on FILENAME. FILENAME starts with a tilde. If there is no expansion, call tilde_expansion_failure_hook. */ char * tilde_expand_word (filename) char *filename; { char *dirname; dirname = filename ? xstrdup (filename) : (char *)NULL; if (dirname && *dirname == '~') { char *temp_name; if (!dirname[1] || dirname[1] == '/') { /* Prepend $HOME to the rest of the string. */ char *temp_home = getenv ("HOME"); /* If there is no HOME variable, look up the directory in the password database. */ if (!temp_home) { struct passwd *entry; entry = (struct passwd *) getpwuid (getuid ()); if (entry) temp_home = entry->pw_dir; } temp_name = (char *) alloca (1 + strlen (&dirname[1]) + (temp_home ? strlen (temp_home) : 0)); temp_name[0] = '\0'; if (temp_home) strcpy (temp_name, temp_home); strcat (temp_name, &dirname[1]); free (dirname); dirname = xstrdup (temp_name); } else { struct passwd *user_entry; char *username = (char *)alloca (257); int i, c; for (i = 1; (c = dirname[i]); i++) { if (c == '/') break; else username[i - 1] = c; } username[i - 1] = '\0'; if (!(user_entry = (struct passwd *) getpwnam (username))) { /* If the calling program has a special syntax for expanding tildes, and we couldn't find a standard expansion, then let them try. */ if (tilde_expansion_failure_hook) { char *expansion; expansion = (*tilde_expansion_failure_hook) (username); if (expansion) { temp_name = (char *)alloca (1 + strlen (expansion) + strlen (&dirname[i])); strcpy (temp_name, expansion); strcat (temp_name, &dirname[i]); free (expansion); goto return_name; } } /* We shouldn't report errors. */ } else { temp_name = (char *)alloca (1 + strlen (user_entry->pw_dir) + strlen (&dirname[i])); strcpy (temp_name, user_entry->pw_dir); strcat (temp_name, &dirname[i]); return_name: free (dirname); dirname = xstrdup (temp_name); } endpwent (); } } return (dirname); } #if defined (TEST) #undef NULL #include main (argc, argv) int argc; char **argv; { char *result, line[512]; int done = 0; while (!done) { printf ("~expand: "); fflush (stdout); if (!gets (line)) strcpy (line, "done"); if ((strcmp (line, "done") == 0) || (strcmp (line, "quit") == 0) || (strcmp (line, "exit") == 0)) { done = 1; break; } result = tilde_expand (line); printf (" --> %s\n", result); free (result); } exit (0); } static void memory_error_and_abort (); static void * xmalloc (bytes) int bytes; { void *temp = (void *)malloc (bytes); if (!temp) memory_error_and_abort (); return (temp); } static void * xrealloc (pointer, bytes) void *pointer; int bytes; { void *temp; if (!pointer) temp = (char *)malloc (bytes); else temp = (char *)realloc (pointer, bytes); if (!temp) memory_error_and_abort (); return (temp); } static void memory_error_and_abort () { fprintf (stderr, _("readline: Out of virtual memory!\n")); abort (); } #endif /* TEST */ texinfo-3.12/info/filesys.c0000444000175000017500000003637706473655277013171 0ustar gg/* filesys.c -- File system specific functions for hacking this system. $Id: filesys.c,v 1.6 1998/02/21 22:52:46 karl Exp $ Copyright (C) 1993, 97, 98 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ #include "info.h" #include "tilde.h" #include "filesys.h" /* Local to this file. */ static char *info_file_in_path (), *lookup_info_filename (); static void remember_info_filename (), maybe_initialize_infopath (); typedef struct { char *suffix; char *decompressor; } COMPRESSION_ALIST; static char *info_suffixes[] = { "", ".info", "-info", "/index", (char *)NULL }; static COMPRESSION_ALIST compress_suffixes[] = { { ".Z", "uncompress" }, { ".Y", "unyabba" }, { ".z", "gunzip" }, { ".gz", "gunzip" }, { (char *)NULL, (char *)NULL } }; /* The path on which we look for info files. You can initialize this from the environment variable INFOPATH if there is one, or you can call info_add_path () to add paths to the beginning or end of it. You can call zap_infopath () to make the path go away. */ char *infopath = (char *)NULL; static int infopath_size = 0; /* Expand the filename in PARTIAL to make a real name for this operating system. This looks in INFO_PATHS in order to find the correct file. If it can't find the file, it returns NULL. */ static char *local_temp_filename = (char *)NULL; static int local_temp_filename_size = 0; char * info_find_fullpath (partial) char *partial; { int initial_character; char *temp; filesys_error_number = 0; maybe_initialize_infopath (); if (partial && (initial_character = *partial)) { char *expansion; expansion = lookup_info_filename (partial); if (expansion) return (expansion); /* If we have the full path to this file, we still may have to add various extensions to it. I guess we have to stat this file after all. */ if (initial_character == '/') temp = info_file_in_path (partial + 1, "/"); else if (initial_character == '~') { expansion = tilde_expand_word (partial); if (*expansion == '/') { temp = info_file_in_path (expansion + 1, "/"); free (expansion); } else temp = expansion; } else if (initial_character == '.' && (partial[1] == '/' || (partial[1] == '.' && partial[2] == '/'))) { if (local_temp_filename_size < 1024) local_temp_filename = (char *)xrealloc (local_temp_filename, (local_temp_filename_size = 1024)); #if defined (HAVE_GETCWD) if (!getcwd (local_temp_filename, local_temp_filename_size)) #else /* !HAVE_GETCWD */ if (!getwd (local_temp_filename)) #endif /* !HAVE_GETCWD */ { filesys_error_number = errno; return (partial); } strcat (local_temp_filename, "/"); strcat (local_temp_filename, partial); return (local_temp_filename); } else temp = info_file_in_path (partial, infopath); if (temp) { remember_info_filename (partial, temp); if (strlen (temp) > local_temp_filename_size) local_temp_filename = (char *) xrealloc (local_temp_filename, (local_temp_filename_size = (50 + strlen (temp)))); strcpy (local_temp_filename, temp); free (temp); return (local_temp_filename); } } return (partial); } /* Scan the list of directories in PATH looking for FILENAME. If we find one that is a regular file, return it as a new string. Otherwise, return a NULL pointer. */ static char * info_file_in_path (filename, path) char *filename, *path; { struct stat finfo; char *temp_dirname; int statable, dirname_index; dirname_index = 0; while ((temp_dirname = extract_colon_unit (path, &dirname_index))) { register int i, pre_suffix_length; char *temp; /* Expand a leading tilde if one is present. */ if (*temp_dirname == '~') { char *expanded_dirname; expanded_dirname = tilde_expand_word (temp_dirname); free (temp_dirname); temp_dirname = expanded_dirname; } temp = (char *)xmalloc (30 + strlen (temp_dirname) + strlen (filename)); strcpy (temp, temp_dirname); if (temp[(strlen (temp)) - 1] != '/') strcat (temp, "/"); strcat (temp, filename); pre_suffix_length = strlen (temp); free (temp_dirname); for (i = 0; info_suffixes[i]; i++) { strcpy (temp + pre_suffix_length, info_suffixes[i]); statable = (stat (temp, &finfo) == 0); /* If we have found a regular file, then use that. Else, if we have found a directory, look in that directory for this file. */ if (statable) { if (S_ISREG (finfo.st_mode)) { return (temp); } else if (S_ISDIR (finfo.st_mode)) { char *newpath, *filename_only, *newtemp; newpath = xstrdup (temp); filename_only = filename_non_directory (filename); newtemp = info_file_in_path (filename_only, newpath); free (newpath); if (newtemp) { free (temp); return (newtemp); } } } else { /* Add various compression suffixes to the name to see if the file is present in compressed format. */ register int j, pre_compress_suffix_length; pre_compress_suffix_length = strlen (temp); for (j = 0; compress_suffixes[j].suffix; j++) { strcpy (temp + pre_compress_suffix_length, compress_suffixes[j].suffix); statable = (stat (temp, &finfo) == 0); if (statable && (S_ISREG (finfo.st_mode))) return (temp); } } } free (temp); } return ((char *)NULL); } /* Given a string containing units of information separated by colons, return the next one pointed to by IDX, or NULL if there are no more. Advance IDX to the character after the colon. */ char * extract_colon_unit (string, idx) char *string; int *idx; { register int i, start; i = start = *idx; if ((i >= strlen (string)) || !string) return ((char *) NULL); while (string[i] && string[i] != ':') i++; if (i == start) { return ((char *) NULL); } else { char *value; value = (char *) xmalloc (1 + (i - start)); strncpy (value, &string[start], (i - start)); value[i - start] = '\0'; if (string[i]) ++i; *idx = i; return (value); } } /* A structure which associates a filename with its expansion. */ typedef struct { char *filename; char *expansion; } FILENAME_LIST; /* An array of remembered arguments and results. */ static FILENAME_LIST **names_and_files = (FILENAME_LIST **)NULL; static int names_and_files_index = 0; static int names_and_files_slots = 0; /* Find the result for having already called info_find_fullpath () with FILENAME. */ static char * lookup_info_filename (filename) char *filename; { if (filename && names_and_files) { register int i; for (i = 0; names_and_files[i]; i++) { if (strcmp (names_and_files[i]->filename, filename) == 0) return (names_and_files[i]->expansion); } } return (char *)NULL;; } /* Add a filename and its expansion to our list. */ static void remember_info_filename (filename, expansion) char *filename, *expansion; { FILENAME_LIST *new; if (names_and_files_index + 2 > names_and_files_slots) { int alloc_size; names_and_files_slots += 10; alloc_size = names_and_files_slots * sizeof (FILENAME_LIST *); names_and_files = (FILENAME_LIST **) xrealloc (names_and_files, alloc_size); } new = (FILENAME_LIST *)xmalloc (sizeof (FILENAME_LIST)); new->filename = xstrdup (filename); new->expansion = expansion ? xstrdup (expansion) : (char *)NULL; names_and_files[names_and_files_index++] = new; names_and_files[names_and_files_index] = (FILENAME_LIST *)NULL; } static void maybe_initialize_infopath () { if (!infopath_size) { infopath = (char *) xmalloc (infopath_size = (1 + strlen (DEFAULT_INFOPATH))); strcpy (infopath, DEFAULT_INFOPATH); } } /* Add PATH to the list of paths found in INFOPATH. 2nd argument says whether to put PATH at the front or end of INFOPATH. */ void info_add_path (path, where) char *path; int where; { int len; if (!infopath) { infopath = (char *)xmalloc (infopath_size = 200 + strlen (path)); infopath[0] = '\0'; } len = strlen (path) + strlen (infopath); if (len + 2 >= infopath_size) infopath = (char *)xrealloc (infopath, (infopath_size += (2 * len) + 2)); if (!*infopath) strcpy (infopath, path); else if (where == INFOPATH_APPEND) { strcat (infopath, ":"); strcat (infopath, path); } else if (where == INFOPATH_PREPEND) { char *temp = xstrdup (infopath); strcpy (infopath, path); strcat (infopath, ":"); strcat (infopath, temp); free (temp); } } /* Make INFOPATH have absolutely nothing in it. */ void zap_infopath () { if (infopath) free (infopath); infopath = (char *)NULL; infopath_size = 0; } /* Read the contents of PATHNAME, returning a buffer with the contents of that file in it, and returning the size of that buffer in FILESIZE. FINFO is a stat struct which has already been filled in by the caller. If the file cannot be read, return a NULL pointer. */ char * filesys_read_info_file (pathname, filesize, finfo) char *pathname; long *filesize; struct stat *finfo; { long st_size; *filesize = filesys_error_number = 0; if (compressed_filename_p (pathname)) return (filesys_read_compressed (pathname, filesize, finfo)); else { int descriptor; char *contents; descriptor = open (pathname, O_RDONLY, 0666); /* If the file couldn't be opened, give up. */ if (descriptor < 0) { filesys_error_number = errno; return ((char *)NULL); } /* Try to read the contents of this file. */ st_size = (long) finfo->st_size; contents = (char *)xmalloc (1 + st_size); if ((read (descriptor, contents, st_size)) != st_size) { filesys_error_number = errno; close (descriptor); free (contents); return ((char *)NULL); } close (descriptor); *filesize = st_size; return (contents); } } /* Typically, pipe buffers are 4k. */ #define BASIC_PIPE_BUFFER (4 * 1024) /* We use some large multiple of that. */ #define FILESYS_PIPE_BUFFER_SIZE (16 * BASIC_PIPE_BUFFER) char * filesys_read_compressed (pathname, filesize, finfo) char *pathname; long *filesize; struct stat *finfo; { FILE *stream; char *command, *decompressor; char *contents = (char *)NULL; *filesize = filesys_error_number = 0; decompressor = filesys_decompressor_for_file (pathname); if (!decompressor) return ((char *)NULL); command = (char *)xmalloc (10 + strlen (pathname) + strlen (decompressor)); sprintf (command, "%s < %s", decompressor, pathname); #if !defined (BUILDING_LIBRARY) if (info_windows_initialized_p) { char *temp; temp = (char *)xmalloc (5 + strlen (command)); sprintf (temp, "%s...", command); message_in_echo_area ("%s", temp); free (temp); } #endif /* !BUILDING_LIBRARY */ stream = popen (command, "r"); free (command); /* Read chunks from this file until there are none left to read. */ if (stream) { int offset, size; char *chunk; offset = size = 0; chunk = (char *)xmalloc (FILESYS_PIPE_BUFFER_SIZE); while (1) { int bytes_read; bytes_read = fread (chunk, 1, FILESYS_PIPE_BUFFER_SIZE, stream); if (bytes_read + offset >= size) contents = (char *)xrealloc (contents, size += (2 * FILESYS_PIPE_BUFFER_SIZE)); memcpy (contents + offset, chunk, bytes_read); offset += bytes_read; if (bytes_read != FILESYS_PIPE_BUFFER_SIZE) break; } free (chunk); pclose (stream); contents = (char *)xrealloc (contents, offset + 1); *filesize = offset; } else { filesys_error_number = errno; } #if !defined (BUILDING_LIBARARY) if (info_windows_initialized_p) unmessage_in_echo_area (); #endif /* !BUILDING_LIBRARY */ return (contents); } /* Return non-zero if FILENAME belongs to a compressed file. */ int compressed_filename_p (filename) char *filename; { char *decompressor; /* Find the final extension of this filename, and see if it matches one of our known ones. */ decompressor = filesys_decompressor_for_file (filename); if (decompressor) return (1); else return (0); } /* Return the command string that would be used to decompress FILENAME. */ char * filesys_decompressor_for_file (filename) char *filename; { register int i; char *extension = (char *)NULL; /* Find the final extension of FILENAME, and see if it appears in our list of known compression extensions. */ for (i = strlen (filename) - 1; i > 0; i--) if (filename[i] == '.') { extension = filename + i; break; } if (!extension) return ((char *)NULL); for (i = 0; compress_suffixes[i].suffix; i++) if (strcmp (extension, compress_suffixes[i].suffix) == 0) return (compress_suffixes[i].decompressor); return ((char *)NULL); } /* The number of the most recent file system error. */ int filesys_error_number = 0; /* A function which returns a pointer to a static buffer containing an error message for FILENAME and ERROR_NUM. */ static char *errmsg_buf = (char *)NULL; static int errmsg_buf_size = 0; char * filesys_error_string (filename, error_num) char *filename; int error_num; { int len; char *result; if (error_num == 0) return ((char *)NULL); result = strerror (error_num); len = 4 + strlen (filename) + strlen (result); if (len >= errmsg_buf_size) errmsg_buf = (char *)xrealloc (errmsg_buf, (errmsg_buf_size = 2 + len)); sprintf (errmsg_buf, "%s: %s", filename, result); return (errmsg_buf); } texinfo-3.12/info/dribble.h0000444000175000017500000000277606362741067013105 0ustar gg/* dribble.h -- Functions and vars declared in dribble.c. */ /* This file is part of GNU Info, a program for reading online documentation stored in Info format. Copyright (C) 1993 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ #if !defined (_DRIBBLE_H_) #define _DRIBBLE_H_ /* When non-zero, it is a stream to write all input characters to for the duration of this info session. */ extern FILE *info_dribble_file; /* Open a dribble file named NAME, perhaps closing an already open one. This sets the global variable INFO_DRIBBLE_FILE to the open stream. */ extern void open_dribble_file (); /* If there is a dribble file already open, close it. */ extern void close_dribble_file (); /* Write some output to our existing dribble file. */ extern void dribble (); #endif /* !_DRIBBLE_H_ */ texinfo-3.12/info/indices.h0000444000175000017500000000307606362741253013107 0ustar gg/* indices.h -- Functions defined in indices.c. $Id: indices.h,v 1.2 1997/07/06 20:50:29 karl Exp $ This file is part of GNU Info, a program for reading online documentation stored in Info format. Copyright (C) 1993, 97 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ #ifndef INFO_INDICES_H #define INFO_INDICES_H /* User-visible variable controls the output of info-index-next. */ extern int show_index_match; extern REFERENCE **info_indices_of_window (), **info_indices_of_file_buffer (); extern void info_apropos (); /* For every menu item in DIR, search the indices of that file for STRING. */ REFERENCE **apropos_in_all_indices (); /* User visible functions declared in indices.c. */ extern void info_index_search (), info_next_index_match (); extern void do_info_index_search (); extern int index_intry_exists (); #endif /* not INFO_INDICES_H */ texinfo-3.12/info/echo-area.h0000444000175000017500000000524706362741636013324 0ustar gg/* echo-area.h -- Functions used in reading information from the echo area. $Id: echo-area.h,v 1.3 1997/07/15 18:38:21 karl Exp $ This file is part of GNU Info, a program for reading online documentation stored in Info format. Copyright (C) 1993, 97 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ #ifndef INFO_ECHO_AREA_H #define INFO_ECHO_AREA_H #define EA_MAX_INPUT 256 extern int echo_area_is_active, info_aborted_echo_area; /* Non-zero means that the last command executed while reading input killed some text. */ extern int echo_area_last_command_was_kill; extern void inform_in_echo_area (), echo_area_inform_of_deleted_window (); extern void echo_area_prep_read (); extern VFunction *ea_last_executed_command; /* Read a line of text in the echo area. Return a malloc ()'ed string, or NULL if the user aborted out of this read. WINDOW is the currently active window, so that we can restore it when we need to. PROMPT, if non-null, is a prompt to print before reading the line. */ extern char *info_read_in_echo_area (); /* Read a line in the echo area with completion over COMPLETIONS. Takes arguments of WINDOW, PROMPT, and COMPLETIONS, a REFERENCE **. */ char *info_read_completing_in_echo_area (); /* Read a line in the echo area allowing completion over COMPLETIONS, but not requiring it. Takes arguments of WINDOW, PROMPT, and COMPLETIONS, a REFERENCE **. */ extern char *info_read_maybe_completing (); extern void ea_insert (), ea_quoted_insert (); extern void ea_beg_of_line (), ea_backward (), ea_delete (), ea_end_of_line (); extern void ea_forward (), ea_abort (), ea_rubout (), ea_complete (); extern void ea_newline (), ea_kill_line (), ea_transpose_chars (); extern void ea_yank (), ea_tab_insert (), ea_possible_completions (); extern void ea_backward_word (), ea_kill_word (), ea_forward_word (); extern void ea_yank_pop (), ea_backward_kill_word (); extern void ea_scroll_completions_window (); #endif /* not INFO_ECHO_AREA_H */ texinfo-3.12/info/m-x.c0000444000175000017500000001164206365744340012166 0ustar gg/* m-x.c -- Meta-X minibuffer reader. $Id: m-x.c,v 1.5 1997/07/24 21:28:00 karl Exp $ Copyright (C) 1993, 97 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ #include "info.h" /* **************************************************************** */ /* */ /* Reading Named Commands */ /* */ /* **************************************************************** */ /* Read the name of an Info function in the echo area and return the name. A return value of NULL indicates that no function name could be read. */ char * read_function_name (prompt, window) char *prompt; WINDOW *window; { register int i; char *line; REFERENCE **array = (REFERENCE **)NULL; int array_index = 0, array_slots = 0; /* Make an array of REFERENCE which actually contains the names of the functions available in Info. */ for (i = 0; function_doc_array[i].func; i++) { REFERENCE *entry; entry = (REFERENCE *)xmalloc (sizeof (REFERENCE)); entry->label = xstrdup (function_doc_array[i].func_name); entry->nodename = (char *)NULL; entry->filename = (char *)NULL; add_pointer_to_array (entry, array_index, array, array_slots, 200, REFERENCE *); } line = info_read_completing_in_echo_area (window, prompt, array); info_free_references (array); if (!echo_area_is_active) window_clear_echo_area (); return (line); } DECLARE_INFO_COMMAND (describe_command, _("Read the name of an Info command and describe it")) { char *line; line = read_function_name (_("Describe command: "), window); if (!line) { info_abort_key (active_window, count, key); return; } /* Describe the function named in "LINE". */ if (*line) { VFunction *fun = named_function (line); if (!fun) return; window_message_in_echo_area ("%s: %s.", line, function_documentation (fun)); } free (line); } DECLARE_INFO_COMMAND (info_execute_command, _("Read a command name in the echo area and execute it")) { char *line; /* Ask the completer to read a reference for us. */ if (info_explicit_arg || count != 1) { char *prompt; prompt = (char *)xmalloc (20); sprintf (prompt, "%d M-x ", count); line = read_function_name (prompt, window); } else line = read_function_name ("M-x ", window); /* User aborted? */ if (!line) { info_abort_key (active_window, count, key); return; } /* User accepted "default"? (There is none.) */ if (!*line) { free (line); return; } /* User wants to execute a named command. Do it. */ { VFunction *function; if ((active_window != the_echo_area) && (strncmp (line, "echo-area-", 10) == 0)) { free (line); info_error (_("Cannot execute an `echo-area' command here.")); return; } function = named_function (line); free (line); if (!function) return; (*function) (active_window, count, 0); } } /* Okay, now that we have M-x, let the user set the screen height. */ DECLARE_INFO_COMMAND (set_screen_height, _("Set the height of the displayed window")) { int new_height; if (info_explicit_arg || count != 1) new_height = count; else { char prompt[80]; char *line; new_height = screenheight; sprintf (prompt, _("Set screen height to (%d): "), new_height); line = info_read_in_echo_area (window, prompt); /* If the user aborted, do that now. */ if (!line) { info_abort_key (active_window, count, 0); return; } /* Find out what the new height is supposed to be. */ if (*line) new_height = atoi (line); /* Clear the echo area if it isn't active. */ if (!echo_area_is_active) window_clear_echo_area (); free (line); } terminal_clear_screen (); display_clear_display (the_display); screenheight = new_height; display_initialize_display (screenwidth, screenheight); window_new_screen_size (screenwidth, screenheight); } texinfo-3.12/info/signals.c0000444000175000017500000001247606362741407013131 0ustar gg/* signals.c -- Install and maintain Info signal handlers. */ /* This file is part of GNU Info, a program for reading online documentation stored in Info format. Copyright (C) 1993, 1994, 1995 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ #include "info.h" #include "signals.h" /* **************************************************************** */ /* */ /* Pretending That We Have POSIX Signals */ /* */ /* **************************************************************** */ #if !defined (HAVE_SIGPROCMASK) && defined (HAVE_SIGSETMASK) /* Perform OPERATION on NEWSET, perhaps leaving information in OLDSET. */ static void sigprocmask (operation, newset, oldset) int operation, *newset, *oldset; { switch (operation) { case SIG_UNBLOCK: sigsetmask (sigblock (0) & ~(*newset)); break; case SIG_BLOCK: *oldset = sigblock (*newset); break; case SIG_SETMASK: sigsetmask (*newset); break; default: abort (); } } #endif /* !HAVE_SIGPROCMASK && HAVE_SIGSETMASK */ /* **************************************************************** */ /* */ /* Signal Handling for Info */ /* */ /* **************************************************************** */ typedef RETSIGTYPE signal_handler (); static RETSIGTYPE info_signal_handler (); static signal_handler *old_TSTP, *old_TTOU, *old_TTIN; static signal_handler *old_WINCH, *old_INT; void initialize_info_signal_handler () { #if defined (SIGTSTP) old_TSTP = (signal_handler *) signal (SIGTSTP, info_signal_handler); old_TTOU = (signal_handler *) signal (SIGTTOU, info_signal_handler); old_TTIN = (signal_handler *) signal (SIGTTIN, info_signal_handler); #endif /* SIGTSTP */ #if defined (SIGWINCH) old_WINCH = (signal_handler *) signal (SIGWINCH, info_signal_handler); #endif #if defined (SIGINT) old_INT = (signal_handler *) signal (SIGINT, info_signal_handler); #endif } static void redisplay_after_signal () { terminal_clear_screen (); display_clear_display (the_display); window_mark_chain (windows, W_UpdateWindow); display_update_display (windows); display_cursor_at_point (active_window); fflush (stdout); } static RETSIGTYPE info_signal_handler (sig) int sig; { signal_handler **old_signal_handler; switch (sig) { #if defined (SIGTSTP) case SIGTSTP: case SIGTTOU: case SIGTTIN: #endif #if defined (SIGINT) case SIGINT: #endif { #if defined (SIGTSTP) if (sig == SIGTSTP) old_signal_handler = &old_TSTP; if (sig == SIGTTOU) old_signal_handler = &old_TTOU; if (sig == SIGTTIN) old_signal_handler = &old_TTIN; #endif /* SIGTSTP */ if (sig == SIGINT) old_signal_handler = &old_INT; /* For stop signals, restore the terminal IO, leave the cursor at the bottom of the window, and stop us. */ terminal_goto_xy (0, screenheight - 1); terminal_clear_to_eol (); fflush (stdout); terminal_unprep_terminal (); signal (sig, *old_signal_handler); UNBLOCK_SIGNAL (sig); kill (getpid (), sig); /* The program is returning now. Restore our signal handler, turn on terminal handling, redraw the screen, and place the cursor where it belongs. */ terminal_prep_terminal (); *old_signal_handler = (signal_handler *) signal (sig, info_signal_handler); redisplay_after_signal (); fflush (stdout); } break; #if defined (SIGWINCH) case SIGWINCH: { /* Turn off terminal IO, tell our parent that the window has changed, then reinitialize the terminal and rebuild our windows. */ old_signal_handler = &old_WINCH; terminal_goto_xy (0, 0); fflush (stdout); terminal_unprep_terminal (); signal (sig, *old_signal_handler); UNBLOCK_SIGNAL (sig); kill (getpid (), sig); /* After our old signal handler returns... */ terminal_get_screen_size (); terminal_prep_terminal (); display_initialize_display (screenwidth, screenheight); window_new_screen_size (screenwidth, screenheight, (VFunction *)NULL); *old_signal_handler = (signal_handler *) signal (sig, info_signal_handler); redisplay_after_signal (); } break; #endif /* SIGWINCH */ } } texinfo-3.12/info/info.c0000444000175000017500000004650606475631027012426 0ustar gg/* info.c -- Display nodes of Info files in multiple windows. $Id: info.c,v 1.18 1998/02/27 21:37:27 karl Exp $ Copyright (C) 1993, 96, 97, 98 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ #include "info.h" #include "indices.h" #include "dribble.h" #include "getopt.h" #if defined (HANDLE_MAN_PAGES) # include "man.h" #endif /* HANDLE_MAN_PAGES */ /* The version numbers of this version of Info. */ int info_major_version = 2; int info_minor_version = 18; /* basename (argv[0]) */ static char *program_name = NULL; /* Non-zero means search all indices for APROPOS_SEARCH_STRING. */ static int apropos_p = 0; /* Variable containing the string to search for when apropos_p is non-zero. */ static char *apropos_search_string = (char *)NULL; /* Non-zero means search all indices for INDEX_SEARCH_STRING. Unlike apropos, this puts the user at the node, running info. */ static int index_search_p = 0; /* Variable containing the string to search for when index_search_p is non-zero. */ static char *index_search_string = (char *)NULL; /* Non-zero means print version info only. */ static int print_version_p = 0; /* Non-zero means print a short description of the options. */ static int print_help_p = 0; /* Array of the names of nodes that the user specified with "--node" on the command line. */ static char **user_nodenames = (char **)NULL; static int user_nodenames_index = 0; static int user_nodenames_slots = 0; /* String specifying the first file to load. This string can only be set by the user specifying "--file" on the command line. */ static char *user_filename = (char *)NULL; /* String specifying the name of the file to dump nodes to. This value is filled if the user speficies "--output" on the command line. */ static char *user_output_filename = (char *)NULL; /* Non-zero indicates that when "--output" is specified, all of the menu items of the specified nodes (and their subnodes as well) should be dumped in the order encountered. This basically can print a book. */ int dump_subnodes = 0; /* Structure describing the options that Info accepts. We pass this structure to getopt_long (). If you add or otherwise change this structure, you must also change the string which follows it. */ #define APROPOS_OPTION 1 #define DRIBBLE_OPTION 2 #define RESTORE_OPTION 3 #define IDXSRCH_OPTION 4 static struct option long_options[] = { { "apropos", 1, 0, APROPOS_OPTION }, { "directory", 1, 0, 'd' }, { "node", 1, 0, 'n' }, { "file", 1, 0, 'f' }, { "subnodes", 0, &dump_subnodes, 1 }, { "output", 1, 0, 'o' }, { "help", 0, &print_help_p, 1 }, { "version", 0, &print_version_p, 1 }, { "dribble", 1, 0, DRIBBLE_OPTION }, { "restore", 1, 0, RESTORE_OPTION }, { "index-search", 1, 0, IDXSRCH_OPTION }, {NULL, 0, NULL, 0} }; /* String describing the shorthand versions of the long options found above. */ static char *short_options = "d:n:f:o:s"; /* When non-zero, the Info window system has been initialized. */ int info_windows_initialized_p = 0; /* Some "forward" declarations. */ static void info_short_help (), remember_info_program_name (); /* **************************************************************** */ /* */ /* Main Entry Point to the Info Program */ /* */ /* **************************************************************** */ int main (argc, argv) int argc; char **argv; { int getopt_long_index; /* Index returned by getopt_long (). */ NODE *initial_node; /* First node loaded by Info. */ remember_info_program_name (argv[0]); #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 option_character; option_character = getopt_long (argc, argv, short_options, long_options, &getopt_long_index); /* getopt_long () returns EOF when there are no more long options. */ if (option_character == EOF) break; /* If this is a long option, then get the short version of it. */ if (option_character == 0 && long_options[getopt_long_index].flag == 0) option_character = long_options[getopt_long_index].val; /* Case on the option that we have received. */ switch (option_character) { case 0: break; /* User wants to add a directory. */ case 'd': info_add_path (optarg, INFOPATH_PREPEND); break; /* User is specifying a particular node. */ case 'n': add_pointer_to_array (optarg, user_nodenames_index, user_nodenames, user_nodenames_slots, 10, char *); break; /* User is specifying a particular Info file. */ case 'f': if (user_filename) free (user_filename); user_filename = xstrdup (optarg); break; /* User is specifying the name of a file to output to. */ case 'o': if (user_output_filename) free (user_output_filename); user_output_filename = xstrdup (optarg); break; /* User is specifying that she wishes to dump the subnodes of the node that she is dumping. */ case 's': dump_subnodes = 1; break; /* User has specified a string to search all indices for. */ case APROPOS_OPTION: apropos_p = 1; maybe_free (apropos_search_string); apropos_search_string = xstrdup (optarg); break; /* User has specified a dribble file to receive keystrokes. */ case DRIBBLE_OPTION: close_dribble_file (); open_dribble_file (optarg); break; /* User has specified an alternate input stream. */ case RESTORE_OPTION: info_set_input_from_file (optarg); break; /* User has specified a string to search all indices for. */ case IDXSRCH_OPTION: index_search_p = 1; maybe_free (index_search_string); index_search_string = xstrdup (optarg); break; default: fprintf (stderr, _("Try --help for more information.")); exit (1); } } /* If the output device is not a terminal, and no output filename has been specified, make user_output_filename be "-", so that the info is written to stdout, and turn on the dumping of subnodes. */ if ((!isatty (fileno (stdout))) && (user_output_filename == (char *)NULL)) { user_output_filename = xstrdup ("-"); dump_subnodes = 1; } /* If the user specified --version, then show the version and exit. */ if (print_version_p) { printf ("%s (GNU %s %s) %s\n", program_name, PACKAGE, VERSION, version_string ()); printf (_("Copyright (C) %s Free Software Foundation, Inc.\n\ 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"), "1998"); exit (0); } /* If the `--help' option was present, show the help and exit. */ if (print_help_p) { info_short_help (); exit (0); } /* If the user hasn't specified a path for Info files, default it. Lowest priority is our messy hardwired list in filesys.h. Then comes the user's INFODIR from the Makefile. Highest priority is the environment variable, if set. */ if (!infopath) { char *path_from_env = getenv ("INFOPATH"); if (path_from_env) { unsigned len = strlen (path_from_env); /* Trailing : on INFOPATH means insert the default path. */ if (len && path_from_env[len - 1] == ':') { path_from_env[len - 1] = 0; info_add_path (DEFAULT_INFOPATH, INFOPATH_PREPEND); } #ifdef INFODIR /* from the Makefile */ info_add_path (INFODIR, INFOPATH_PREPEND); #endif info_add_path (path_from_env, INFOPATH_PREPEND); } else { info_add_path (DEFAULT_INFOPATH, INFOPATH_PREPEND); #ifdef INFODIR /* from the Makefile */ info_add_path (INFODIR, INFOPATH_PREPEND); #endif } } /* If the user specified a particular filename, add the path of that file to the contents of INFOPATH. */ if (user_filename) { char *directory_name = xstrdup (user_filename); char *temp = filename_non_directory (directory_name); if (temp != directory_name) { *temp = 0; info_add_path (directory_name, INFOPATH_PREPEND); } free (directory_name); } /* If the user wants to search every known index for a given string, do that now, and report the results. */ if (apropos_p) { info_apropos (apropos_search_string); exit (0); } /* Get the initial Info node. It is either "(dir)Top", or what the user specifed with values in user_filename and user_nodenames. */ initial_node = info_get_node (user_filename, user_nodenames ? user_nodenames[0] : NULL); /* If we couldn't get the initial node, this user is in trouble. */ if (!initial_node) { if (info_recent_file_error) info_error (info_recent_file_error); else info_error (CANT_FIND_NODE, user_nodenames ? user_nodenames[0] : "Top"); exit (1); } /* Special cases for when the user specifies multiple nodes. If we are dumping to an output file, dump all of the nodes specified. Otherwise, attempt to create enough windows to handle the nodes that this user wants displayed. */ if (user_nodenames_index > 1) { free (initial_node); if (user_output_filename) dump_nodes_to_file (user_filename, user_nodenames, user_output_filename, dump_subnodes); else begin_multiple_window_info_session (user_filename, user_nodenames); exit (0); } /* If the user specified `--index-search=STRING', start the info session in the node corresponding to the first match. */ if (index_search_p) { int status = 0; initialize_info_session (initial_node, 0); if (index_entry_exists (windows, index_search_string)) { terminal_clear_screen (); terminal_prep_terminal (); display_update_display (windows); info_last_executed_command = (VFunction *)NULL; do_info_index_search (windows, 0, index_search_string); info_read_and_dispatch (); terminal_unprep_terminal (); /* On program exit, leave the cursor at the bottom of the window, and restore the terminal IO. */ terminal_goto_xy (0, screenheight - 1); terminal_clear_to_eol (); fflush (stdout); } else { fputs (_("no entries found\n"), stderr); status = 2; } close_dribble_file (); exit (status); } /* If there are arguments remaining, they are the names of menu items in sequential info files starting from the first one loaded. That file name is either "dir", or the contents of user_filename if one was specified. */ while (optind != argc) { REFERENCE **menu; REFERENCE *entry; NODE *node; char *arg; static char *first_arg = (char *)NULL; /* Remember the name of the menu entry we want. */ arg = argv[optind++]; if (!first_arg) first_arg = arg; /* Build and return a list of the menu items in this node. */ menu = info_menu_of_node (initial_node); /* If there wasn't a menu item in this node, stop here, but let the user continue to use Info. Perhaps they wanted this node and didn't realize it. */ if (!menu) { #if defined (HANDLE_MAN_PAGES) if (first_arg == arg) { node = make_manpage_node (first_arg); if (node) goto maybe_got_node; } #endif /* HANDLE_MAN_PAGES */ begin_info_session_with_error (initial_node, _("There is no menu in this node.")); exit (0); } /* Find the specified menu item. */ entry = info_get_labeled_reference (arg, menu); /* If the item wasn't found, search the list sloppily. Perhaps this user typed "buffer" when they really meant "Buffers". */ if (!entry) { register int i; int best_guess = -1; for (i = 0; (entry = menu[i]); i++) { if (strcasecmp (entry->label, arg) == 0) break; else if (strncasecmp (entry->label, arg, strlen (arg)) == 0) best_guess = i; } if (!entry && best_guess != -1) entry = menu[best_guess]; } /* If we failed to find the reference, start Info with the current node anyway. It is probably a misspelling. */ if (!entry) { char *error_message = _("There is no menu item \"%s\" in this node."); #if defined (HANDLE_MAN_PAGES) if (first_arg == arg) { node = make_manpage_node (first_arg); if (node) goto maybe_got_node; } #endif /* HANDLE_MAN_PAGES */ info_free_references (menu); /* If we were supposed to dump this node, complain. */ if (user_output_filename) info_error (error_message, arg); else begin_info_session_with_error (initial_node, error_message, arg); exit (0); } /* We have found the reference that the user specified. Clean it up a little bit. */ if (!entry->filename) { if (initial_node->parent) entry->filename = xstrdup (initial_node->parent); else entry->filename = xstrdup (initial_node->filename); } /* Find this node. If we can find it, then turn the initial_node into this one. If we cannot find it, try using the label of the entry as a file (i.e., "(LABEL)Top"). Otherwise the Info file is malformed in some way, and we will just use the current value of initial node. */ node = info_get_node (entry->filename, entry->nodename); #if defined (HANDLE_MAN_PAGES) if ((first_arg == arg) && !node) { node = make_manpage_node (first_arg); if (node) goto maybe_got_node; } #endif /* HANDLE_MAN_PAGES */ if (!node && entry->nodename && (strcmp (entry->label, entry->nodename) == 0)) node = info_get_node (entry->label, "Top"); maybe_got_node: if (node) { free (initial_node); initial_node = node; info_free_references (menu); } else { char *temp = xstrdup (entry->label); char *error_message; error_message = _("Unable to find the node referenced by \"%s\"."); info_free_references (menu); /* If we were trying to dump the node, then give up. Otherwise, start the session with an error message. */ if (user_output_filename) info_error (error_message, temp); else begin_info_session_with_error (initial_node, error_message, temp); exit (0); } } /* If the user specified that this node should be output, then do that now. Otherwise, start the Info session with this node. */ if (user_output_filename) dump_node_to_file (initial_node, user_output_filename, dump_subnodes); else begin_info_session (initial_node); exit (0); } /* Return a string describing the current version of Info. */ char * version_string () { static char *vstring = (char *)NULL; if (!vstring) { vstring = (char *)xmalloc (50); sprintf (vstring, "%d.%d", info_major_version, info_minor_version); } return (vstring); } /* Error handling. */ static void remember_info_program_name (fullpath) char *fullpath; { char *filename; filename = filename_non_directory (fullpath); program_name = xstrdup (filename); } /* Non-zero if an error has been signalled. */ int info_error_was_printed = 0; /* Non-zero means ring terminal bell on errors. */ int info_error_rings_bell_p = 1; /* Print FORMAT with ARG1 and ARG2. If the window system was initialized, then the message is printed in the echo area. Otherwise, a message is output to stderr. */ void info_error (format, arg1, arg2) char *format; void *arg1, *arg2; { info_error_was_printed = 1; if (!info_windows_initialized_p || display_inhibited) { fprintf (stderr, "%s: ", program_name); fprintf (stderr, format, arg1, arg2); fprintf (stderr, "\n"); fflush (stderr); } else { if (!echo_area_is_active) { if (info_error_rings_bell_p) terminal_ring_bell (); window_message_in_echo_area (format, arg1, arg2); } else { NODE *temp; temp = build_message_node (format, arg1, arg2); if (info_error_rings_bell_p) terminal_ring_bell (); inform_in_echo_area (temp->contents); free (temp->contents); free (temp); } } } /* Produce a scaled down description of the available options to Info. */ static void info_short_help () { printf (_("\ Usage: %s [OPTION]... [INFO-FILE [MENU-ITEM...]]\n\ \n\ Read documentation in Info format.\n\ For more complete documentation on how to use Info, run `info info options'.\n\ \n\ Options:\n\ --directory DIR add DIR to INFOPATH.\n\ --dribble FILENAME remember user keystrokes in FILENAME.\n\ --file FILENAME specify Info file to visit.\n\ --node NODENAME specify nodes in first visited Info file.\n\ --output FILENAME output selected nodes to FILENAME.\n\ --restore FILENAME read initial keystrokes from FILENAME.\n\ --subnodes recursively output menu items.\n\ --help display this help and exit.\n\ --version display version information and exit.\n\ \n\ The first argument, if present, is the name of the Info file to read.\n\ Any remaining arguments are treated as the names of menu\n\ items in the initial node visited. For example, `info emacs buffers'\n\ moves to the node `buffers' in the info file `emacs'.\n\ \n\ Email bug reports to bug-texinfo@gnu.org."), program_name); exit (0); } texinfo-3.12/info/nodemenu.c0000444000175000017500000002157706365744566013321 0ustar gg/* nodemenu.c -- Produce a menu of all visited nodes. $Id: nodemenu.c,v 1.7 1997/07/24 21:30:30 karl Exp $ Copyright (C) 1993, 97 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ #include "info.h" /* Return a line describing the format of a node information line. */ static char * nodemenu_format_info () { return (_("\n\ * Menu:\n\ (File)Node Lines Size Containing File\n\ ---------- ----- ---- ---------------")); } /* Produce a formatted line of information about NODE. Here is what we want the output listing to look like: * Menu: (File)Node Lines Size Containing File ---------- ----- ---- --------------- * (emacs)Buffers:: 48 2230 /usr/gnu/info/emacs/emacs-1 * (autoconf)Writing configure.in:: 123 58789 /usr/gnu/info/autoconf/autoconf-1 * (dir)Top:: 40 589 /usr/gnu/info/dir */ static char * format_node_info (node) NODE *node; { register int i, len; char *parent, *containing_file; static char *line_buffer = (char *)NULL; if (!line_buffer) line_buffer = (char *)xmalloc (1000); if (node->parent) { parent = filename_non_directory (node->parent); if (!parent) parent = node->parent; } else parent = (char *)NULL; containing_file = node->filename; if (!parent && !*containing_file) sprintf (line_buffer, "* %s::", node->nodename); else { char *file = (char *)NULL; if (parent) file = parent; else file = filename_non_directory (containing_file); if (!file) file = containing_file; if (!*file) file = "dir"; sprintf (line_buffer, "* (%s)%s::", file, node->nodename); } len = pad_to (36, line_buffer); { int lines = 1; for (i = 0; i < node->nodelen; i++) if (node->contents[i] == '\n') lines++; sprintf (line_buffer + len, "%d", lines); } len = pad_to (44, line_buffer); sprintf (line_buffer + len, "%ld", node->nodelen); if (node->filename && *(node->filename)) { len = pad_to (51, line_buffer); sprintf (line_buffer + len, node->filename); } return xstrdup (line_buffer); } /* Little string comparison routine for qsort (). */ static int compare_strings (string1, string2) char **string1, **string2; { return (strcasecmp (*string1, *string2)); } /* The name of the nodemenu node. */ static char *nodemenu_nodename = "*Node Menu*"; /* Produce an informative listing of all the visited nodes, and return it in a node. If FILTER_FUNC is non-null, it is a function which filters which nodes will appear in the listing. FILTER_FUNC takes an argument of NODE, and returns non-zero if the node should appear in the listing. */ NODE * get_visited_nodes (filter_func) Function *filter_func; { register int i, iw_index; INFO_WINDOW *info_win; NODE *node; char **lines = (char **)NULL; int lines_index = 0, lines_slots = 0; if (!info_windows) return ((NODE *)NULL); for (iw_index = 0; (info_win = info_windows[iw_index]); iw_index++) { for (i = 0; i < info_win->nodes_index; i++) { node = info_win->nodes[i]; /* We skip mentioning "*Node Menu*" nodes. */ if (internal_info_node_p (node) && (strcmp (node->nodename, nodemenu_nodename) == 0)) continue; if (node && (!filter_func || (*filter_func) (node))) { char *line; line = format_node_info (node); add_pointer_to_array (line, lines_index, lines, lines_slots, 20, char *); } } } /* Sort the array of information lines, if there are any. */ if (lines) { register int j, newlen; char **temp; qsort (lines, lines_index, sizeof (char *), compare_strings); /* Delete duplicates. */ for (i = 0, newlen = 1; i < lines_index - 1; i++) { if (strcmp (lines[i], lines[i + 1]) == 0) { free (lines[i]); lines[i] = (char *)NULL; } else newlen++; } /* We have free ()'d and marked all of the duplicate slots. Copy the live slots rather than pruning the dead slots. */ temp = (char **)xmalloc ((1 + newlen) * sizeof (char *)); for (i = 0, j = 0; i < lines_index; i++) if (lines[i]) temp[j++] = lines[i]; temp[j] = (char *)NULL; free (lines); lines = temp; lines_index = newlen; } initialize_message_buffer (); printf_to_message_buffer ("%s", replace_in_documentation (_("Here is the menu of nodes you have recently visited.\n\ Select one from this menu, or use `\\[history-node]' in another window.\n"))); printf_to_message_buffer ("%s\n", nodemenu_format_info ()); for (i = 0; (lines != (char **)NULL) && (i < lines_index); i++) { printf_to_message_buffer ("%s\n", lines[i]); free (lines[i]); } if (lines) free (lines); node = message_buffer_to_node (); add_gcable_pointer (node->contents); return (node); } DECLARE_INFO_COMMAND (list_visited_nodes, _("Make a window containing a menu of all of the currently visited nodes")) { WINDOW *new; NODE *node; set_remembered_pagetop_and_point (window); /* If a window is visible and showing the buffer list already, re-use it. */ for (new = windows; new; new = new->next) { node = new->node; if (internal_info_node_p (node) && (strcmp (node->nodename, nodemenu_nodename) == 0)) break; } /* If we couldn't find an existing window, try to use the next window in the chain. */ if (!new) { if (window->next) new = window->next; /* If there is more than one window, wrap around. */ else if (window != windows) new = windows; } /* If we still don't have a window, make a new one to contain the list. */ if (!new) { WINDOW *old_active; old_active = active_window; active_window = window; new = window_make_window ((NODE *)NULL); active_window = old_active; } /* If we couldn't make a new window, use this one. */ if (!new) new = window; /* Lines do not wrap in this window. */ new->flags |= W_NoWrap; node = get_visited_nodes ((Function *)NULL); name_internal_node (node, nodemenu_nodename); #if 0 /* Even if this is an internal node, we don't want the window system to treat it specially. So we turn off the internalness of it here. */ /* Why? We depend on internal_info_node_p returning true, so we must not remove the flag. Otherwise, the *Node Menu* nodes themselves appear in the node menu. --Andreas Schwab . */ node->flags &= ~N_IsInternal; #endif /* If this window is already showing a node menu, reuse the existing node slot. */ { int remember_me = 1; #if defined (NOTDEF) if (internal_info_node_p (new->node) && (strcmp (new->node->nodename, nodemenu_nodename) == 0)) remember_me = 0; #endif /* NOTDEF */ window_set_node_of_window (new, node); if (remember_me) remember_window_and_node (new, node); } active_window = new; } DECLARE_INFO_COMMAND (select_visited_node, _("Select a node which has been previously visited in a visible window")) { char *line; NODE *node; REFERENCE **menu; node = get_visited_nodes ((Function *)NULL); menu = info_menu_of_node (node); free (node); line = info_read_completing_in_echo_area (window, _("Select visited node: "), menu); window = active_window; /* User aborts, just quit. */ if (!line) { info_abort_key (window, 0, 0); info_free_references (menu); return; } if (*line) { REFERENCE *entry; /* Find the selected label in the references. */ entry = info_get_labeled_reference (line, menu); if (!entry) info_error (_("The reference disappeared! (%s)."), line); else info_select_reference (window, entry); } free (line); info_free_references (menu); if (!info_error_was_printed) window_clear_echo_area (); } texinfo-3.12/info/search.c0000444000175000017500000003456406362741406012737 0ustar gg/* search.c -- How to search large bodies of text. */ /* This file is part of GNU Info, a program for reading online documentation stored in Info format. Copyright (C) 1993, 97 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ #include "info.h" #include "search.h" #include "nodes.h" /* The search functions take two arguments: 1) a string to search for, and 2) a pointer to a SEARCH_BINDING which contains the buffer, start, and end of the search. They return a long, which is the offset from the start of the buffer at which the match was found. An offset of -1 indicates failure. */ /* A function which makes a binding with buffer and bounds. */ SEARCH_BINDING * make_binding (buffer, start, end) char *buffer; long start, end; { SEARCH_BINDING *binding; binding = (SEARCH_BINDING *)xmalloc (sizeof (SEARCH_BINDING)); binding->buffer = buffer; binding->start = start; binding->end = end; binding->flags = 0; return (binding); } /* Make a copy of BINDING without duplicating the data. */ SEARCH_BINDING * copy_binding (binding) SEARCH_BINDING *binding; { SEARCH_BINDING *copy; copy = make_binding (binding->buffer, binding->start, binding->end); copy->flags = binding->flags; return (copy); } /* **************************************************************** */ /* */ /* The Actual Searching Functions */ /* */ /* **************************************************************** */ /* Search forwards or backwards for the text delimited by BINDING. The search is forwards if BINDING->start is greater than BINDING->end. */ long search (string, binding) char *string; SEARCH_BINDING *binding; { long result; /* If the search is backwards, then search backwards, otherwise forwards. */ if (binding->start > binding->end) result = search_backward (string, binding); else result = search_forward (string, binding); return (result); } /* Search forwards for STRING through the text delimited in BINDING. */ long search_forward (string, binding) char *string; SEARCH_BINDING *binding; { register int c, i, len; register char *buff, *end; char *alternate = (char *)NULL; len = strlen (string); /* We match characters in the search buffer against STRING and ALTERNATE. ALTERNATE is a case reversed version of STRING; this is cheaper than case folding each character before comparison. Alternate is only used if the case folding bit is turned on in the passed BINDING. */ if (binding->flags & S_FoldCase) { alternate = xstrdup (string); for (i = 0; i < len; i++) { if (islower (alternate[i])) alternate[i] = toupper (alternate[i]); else if (isupper (alternate[i])) alternate[i] = tolower (alternate[i]); } } buff = binding->buffer + binding->start; end = binding->buffer + binding->end + 1; while (buff < (end - len)) { for (i = 0; i < len; i++) { c = buff[i]; if ((c != string[i]) && (!alternate || c != alternate[i])) break; } if (!string[i]) { if (alternate) free (alternate); if (binding->flags & S_SkipDest) buff += len; return ((long) (buff - binding->buffer)); } buff++; } if (alternate) free (alternate); return ((long) -1); } /* Search for STRING backwards through the text delimited in BINDING. */ long search_backward (input_string, binding) char *input_string; SEARCH_BINDING *binding; { register int c, i, len; register char *buff, *end; char *string; char *alternate = (char *)NULL; len = strlen (input_string); /* Reverse the characters in the search string. */ string = (char *)xmalloc (1 + len); for (c = 0, i = len - 1; input_string[c]; c++, i--) string[i] = input_string[c]; string[c] = '\0'; /* We match characters in the search buffer against STRING and ALTERNATE. ALTERNATE is a case reversed version of STRING; this is cheaper than case folding each character before comparison. ALTERNATE is only used if the case folding bit is turned on in the passed BINDING. */ if (binding->flags & S_FoldCase) { alternate = xstrdup (string); for (i = 0; i < len; i++) { if (islower (alternate[i])) alternate[i] = toupper (alternate[i]); else if (isupper (alternate[i])) alternate[i] = tolower (alternate[i]); } } buff = binding->buffer + binding->start - 1; end = binding->buffer + binding->end; while (buff > (end + len)) { for (i = 0; i < len; i++) { c = *(buff - i); if (c != string[i] && (alternate && c != alternate[i])) break; } if (!string[i]) { free (string); if (alternate) free (alternate); if (binding->flags & S_SkipDest) buff -= len; return ((long) (1 + (buff - binding->buffer))); } buff--; } free (string); if (alternate) free (alternate); return ((long) -1); } /* Find STRING in LINE, returning the offset of the end of the string. Return an offset of -1 if STRING does not appear in LINE. The search is bound by the end of the line (i.e., either NEWLINE or 0). */ int string_in_line (string, line) char *string, *line; { register int end; SEARCH_BINDING binding; /* Find the end of the line. */ for (end = 0; line[end] && line[end] != '\n'; end++); /* Search for STRING within these confines. */ binding.buffer = line; binding.start = 0; binding.end = end; binding.flags = S_FoldCase | S_SkipDest; return (search_forward (string, &binding)); } /* Return non-zero if STRING is the first text to appear at BINDING. */ int looking_at (string, binding) char *string; SEARCH_BINDING *binding; { long search_end; search_end = search (string, binding); /* If the string was not found, SEARCH_END is -1. If the string was found, but not right away, SEARCH_END is != binding->start. Otherwise, the string was found at binding->start. */ return (search_end == binding->start); } /* **************************************************************** */ /* */ /* Small String Searches */ /* */ /* **************************************************************** */ /* Function names that start with "skip" are passed a string, and return an offset from the start of that string. Function names that start with "find" are passed a SEARCH_BINDING, and return an absolute position marker of the item being searched for. "Find" functions return a value of -1 if the item being looked for couldn't be found. */ /* Return the index of the first non-whitespace character in STRING. */ int skip_whitespace (string) char *string; { register int i; for (i = 0; string && whitespace (string[i]); i++); return (i); } /* Return the index of the first non-whitespace or newline character in STRING. */ int skip_whitespace_and_newlines (string) char *string; { register int i; for (i = 0; string && (whitespace (string[i]) || string[i] == '\n'); i++); return (i); } /* Return the index of the first whitespace character in STRING. */ int skip_non_whitespace (string) char *string; { register int i; for (i = 0; string && !whitespace (string[i]); i++); return (i); } /* Return the index of the first non-node character in STRING. Note that this function contains quite a bit of hair to ignore periods in some special cases. This is because we here at GNU ship some info files which contain nodenames that contain periods. No such nodename can start with a period, or continue with whitespace, newline, or ')' immediately following the period. If second argument NEWLINES_OKAY is non-zero, newlines should be skipped while parsing out the nodename specification. */ int skip_node_characters (string, newlines_okay) char *string; int newlines_okay; { register int c, i = 0; int paren_seen = 0; int paren = 0; /* Handle special case. This is when another function has parsed out the filename component of the node name, and we just want to parse out the nodename proper. In that case, a period at the start of the nodename indicates an empty nodename. */ if (string && *string == '.') return (0); if (string && *string == '(') { paren++; paren_seen++; i++; } for (; string && (c = string[i]); i++) { if (paren) { if (c == '(') paren++; else if (c == ')') paren--; continue; } /* If the character following the close paren is a space or period, then this node name has no more characters associated with it. */ if (c == '\t' || c == ',' || c == INFO_TAGSEP || ((!newlines_okay) && (c == '\n')) || ((paren_seen && string[i - 1] == ')') && (c == ' ' || c == '.')) || (c == '.' && ( #if 0 /* This test causes a node name ending in a period, like `This.', not to be found. The trailing . is stripped. This occurs in the jargon file (`I see no X here.' is a node name). */ (!string[i + 1]) || #endif (whitespace_or_newline (string[i + 1])) || (string[i + 1] == ')')))) break; } return (i); } /* **************************************************************** */ /* */ /* Searching FILE_BUFFER's */ /* */ /* **************************************************************** */ /* Return the absolute position of the first occurence of a node separator in BINDING-buffer. The search starts at BINDING->start. Return -1 if no node separator was found. */ long find_node_separator (binding) SEARCH_BINDING *binding; { register long i; char *body; body = binding->buffer; /* A node is started by [^L]^_[^L]\n. That is to say, the C-l's are optional, but the DELETE and NEWLINE are not. This separator holds true for all separated elements in an Info file, including the tags table (if present) and the indirect tags table (if present). */ for (i = binding->start; i < binding->end - 1; i++) if (((body[i] == INFO_FF && body[i + 1] == INFO_COOKIE) && (body[i + 2] == '\n' || (body[i + 2] == INFO_FF && body[i + 3] == '\n'))) || ((body[i] == INFO_COOKIE) && (body[i + 1] == '\n' || (body[i + 1] == INFO_FF && body[i + 2] == '\n')))) return (i); return (-1); } /* Return the length of the node separator characters that BODY is currently pointing at. */ int skip_node_separator (body) char *body; { register int i; i = 0; if (body[i] == INFO_FF) i++; if (body[i++] != INFO_COOKIE) return (0); if (body[i] == INFO_FF) i++; if (body[i++] != '\n') return (0); return (i); } /* Return the number of characters from STRING to the start of the next line. */ int skip_line (string) char *string; { register int i; for (i = 0; string && string[i] && string[i] != '\n'; i++); if (string[i] == '\n') i++; return (i); } /* Return the absolute position of the beginning of a tags table in this binding starting the search at binding->start. */ long find_tags_table (binding) SEARCH_BINDING *binding; { SEARCH_BINDING search; long position; search.buffer = binding->buffer; search.start = binding->start; search.end = binding->end; search.flags = S_FoldCase; while ((position = find_node_separator (&search)) != -1 ) { search.start = position; search.start += skip_node_separator (search.buffer + search.start); if (looking_at (TAGS_TABLE_BEG_LABEL, &search)) return (position); } return (-1); } /* Return the absolute position of the node named NODENAME in BINDING. This is a brute force search, and we wish to avoid it when possible. This function is called when a tag (indirect or otherwise) doesn't really point to the right node. It returns the absolute position of the separator preceding the node. */ long find_node_in_binding (nodename, binding) char *nodename; SEARCH_BINDING *binding; { long position; int offset, namelen; SEARCH_BINDING search; namelen = strlen (nodename); search.buffer = binding->buffer; search.start = binding->start; search.end = binding->end; search.flags = 0; while ((position = find_node_separator (&search)) != -1) { search.start = position; search.start += skip_node_separator (search.buffer + search.start); offset = string_in_line (INFO_NODE_LABEL, search.buffer + search.start); if (offset == -1) continue; search.start += offset; search.start += skip_whitespace (search.buffer + search.start); offset = skip_node_characters (search.buffer + search.start, DONT_SKIP_NEWLINES); /* Notice that this is an exact match. You cannot grovel through the buffer with this function looking for random nodes. */ if ((offset == namelen) && (search.buffer[search.start] == nodename[0]) && (strncmp (search.buffer + search.start, nodename, offset) == 0)) return (position); } return (-1); } texinfo-3.12/info/Makefile.am0000444000175000017500000000351506474126360013352 0ustar gg## Makefile.am for texinfo/info. ## $Id: Makefile.am,v 1.11 1998/02/22 22:55:44 karl Exp $ ## Run automake in .. to produce Makefile.in from this. noinst_PROGRAMS = makedoc # Use `ginfo' for building to avoid confusion with the standard `info' # target. The install rule removes the `g' before applying any # user-specified name transformations. bin_PROGRAMS = ginfo transform = s/ginfo/info/; @program_transform_name@ localedir = $(datadir)/locale # -I. for funs.h. # Automake puts -I.. and -I$(srcdir) into DEFS by default, but # we need to override it, so include them ourselves. INCLUDES = -I. -I$(top_srcdir)/lib -I../intl -I.. -I$(srcdir) DEFS = -DINFODIR=\"$(infodir)\" -DLOCALEDIR=\"$(localedir)\" @DEFS@ LDADD = ../lib/libtxi.a @TERMLIBS@ @INTLLIBS@ makedoc_SOURCES = makedoc.c ginfo_SOURCES = dir.c display.c display.h doc.c doc.h dribble.c dribble.h \ echo-area.c echo-area.h \ filesys.c filesys.h footnotes.c footnotes.h funs.h gc.c gc.h \ indices.c indices.h info-utils.c info-utils.h info.c info.h infodoc.c \ infomap.c infomap.h m-x.c man.c man.h nodemenu.c nodes.c nodes.h \ search.c search.h session.c session.h signals.c signals.h \ termdep.h terminal.c terminal.h tilde.c tilde.h \ variables.c variables.h window.c window.h EXTRA_DIST = README # The files `doc.c' and `funs.h' are created by ./makedoc run over the source # files which contain DECLARE_INFO_COMMAND. `funs.h' is a header file # listing the functions found. `doc.c' is a structure containing pointers # to those functions along with completable names and documentation strings. BUILT_SOURCES = doc.c funs.h cmd_sources = $(srcdir)/session.c $(srcdir)/echo-area.c $(srcdir)/infodoc.c \ $(srcdir)/m-x.c $(srcdir)/indices.c $(srcdir)/nodemenu.c \ $(srcdir)/footnotes.c $(srcdir)/variables.c $(BUILT_SOURCES): makedoc $(cmd_sources) ./makedoc $(cmd_sources) texinfo-3.12/info/tilde.h0000444000175000017500000000430506362741411012562 0ustar gg/* tilde.h: Externally available variables and function in libtilde.a. */ /* This file is part of GNU Info, a program for reading online documentation stored in Info format. This file has appeared in prior works by the Free Software Foundation; thus it carries copyright dates from 1988 through 1993. Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ #ifndef TILDE_H #define TILDE_H #include "info.h" /* If non-null, this contains the address of a function to call if the standard meaning for expanding a tilde fails. The function is called with the text (sans tilde, as in "foo"), and returns a malloc()'ed string which is the expansion, or a NULL pointer if there is no expansion. */ extern CFunction *tilde_expansion_failure_hook; /* When non-null, this is a NULL terminated array of strings which are duplicates for a tilde prefix. Bash uses this to expand `=~' and `:~'. */ extern char **tilde_additional_prefixes; /* When non-null, this is a NULL terminated array of strings which match the end of a username, instead of just "/". Bash sets this to `:' and `=~'. */ extern char **tilde_additional_suffixes; /* Return a new string which is the result of tilde expanding STRING. */ extern char *tilde_expand (); /* Do the work of tilde expansion on FILENAME. FILENAME starts with a tilde. If there is no expansion, call tilde_expansion_failure_hook. */ extern char *tilde_expand_word (); #endif /* not TILDE_H */ texinfo-3.12/info/nodes.h0000444000175000017500000002034406363677310012601 0ustar gg/* nodes.h -- How we represent nodes internally. $Id: nodes.h,v 1.5 1997/07/18 14:33:44 karl Exp $ This file is part of GNU Info, a program for reading online documentation stored in Info format. Copyright (C) 1993, 97 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ #if !defined (NODES_H) #define NODES_H #include "info.h" /* **************************************************************** */ /* */ /* User Code Interface */ /* */ /* **************************************************************** */ /* Callers generally only want the node itself. This structure is used to pass node information around. None of the information in this structure should ever be directly freed. The structure itself can be passed to free (). Note that NODE->parent is non-null if this node's file is a subfile. In that case, NODE->parent is the logical name of the file containing this node. Both names are given as full paths, so you might have: node->filename = "/usr/gnu/info/emacs-1", with node->parent = "/usr/gnu/info/emacs". */ typedef struct { char *filename; /* The physical file containing this node. */ char *parent; /* Non-null is the logical file name. */ char *nodename; /* The name of this node. */ char *contents; /* Characters appearing in this node. */ long nodelen; /* The length of the CONTENTS member. */ int flags; /* See immediately below. */ } NODE; /* Defines that can appear in NODE->flags. All informative. */ #define N_HasTagsTable 0x01 /* This node was found through a tags table. */ #define N_TagsIndirect 0x02 /* The tags table was an indirect one. */ #define N_UpdateTags 0x04 /* The tags table is out of date. */ #define N_IsCompressed 0x08 /* The file is compressed on disk. */ #define N_IsInternal 0x10 /* This node was made by Info. */ #define N_CannotGC 0x20 /* File buffer cannot be gc'ed. */ #define N_IsManPage 0x40 /* This node is a Un*x manpage. */ /* **************************************************************** */ /* */ /* Internal Data Structures */ /* */ /* **************************************************************** */ /* Some defines describing details about Info file contents. */ /* String Constants. */ #define INFO_FILE_LABEL "File:" #define INFO_NODE_LABEL "Node:" #define INFO_PREV_LABEL "Prev:" #define INFO_ALTPREV_LABEL "Previous:" #define INFO_NEXT_LABEL "Next:" #define INFO_UP_LABEL "Up:" #define INFO_MENU_LABEL "\n* Menu:" #define INFO_MENU_ENTRY_LABEL "\n* " #define INFO_XREF_LABEL "*Note" #define TAGS_TABLE_END_LABEL "\nEnd Tag Table" #define TAGS_TABLE_BEG_LABEL "Tag Table:\n" #define INDIRECT_TAGS_TABLE_LABEL "Indirect:\n" #define TAGS_TABLE_IS_INDIRECT_LABEL "(Indirect)" /* Character Constants. */ #define INFO_COOKIE '\037' #define INFO_FF '\014' #define INFO_TAGSEP '\177' /* For each logical file that we have loaded, we keep a list of the names of the nodes that are found in that file. A pointer to a node in an info file is called a "tag". For split files, the tag pointer is "indirect"; that is, the pointer also contains the name of the split file where the node can be found. For non-split files, the filename member in the structure below simply contains the name of the current file. The following structure describes a single node within a file. */ typedef struct { char *filename; /* The file where this node can be found. */ char *nodename; /* The node pointed to by this tag. */ long nodestart; /* The offset of the start of this node. */ long nodelen; /* The length of this node. */ } TAG; /* The following structure is used to remember information about the contents of Info files that we have loaded at least once before. The FINFO member is present so that we can reload the file if it has been modified since last being loaded. All of the arrays appearing within this structure are NULL terminated, and each array which can change size has a corresponding SLOTS member which says how many slots have been allocated (with malloc ()) for this array. */ typedef struct { char *filename; /* The filename used to find this file. */ char *fullpath; /* The full pathname of this info file. */ struct stat finfo; /* Information about this file. */ char *contents; /* The contents of this particular file. */ long filesize; /* The number of bytes this file expands to. */ char **subfiles; /* If non-null, the list of subfiles. */ TAG **tags; /* If non-null, the indirect tags table. */ int tags_slots; /* Number of slots allocated for TAGS. */ int flags; /* Various flags. Mimics of N_* flags. */ } FILE_BUFFER; /* **************************************************************** */ /* */ /* Externally Visible Functions */ /* */ /* **************************************************************** */ /* Array of FILE_BUFFER * which represents the currently loaded info files. */ extern FILE_BUFFER **info_loaded_files; /* The number of slots currently allocated to INFO_LOADED_FILES. */ extern int info_loaded_files_slots; /* Locate the file named by FILENAME, and return the information structure describing this file. The file may appear in our list of loaded files already, or it may not. If it does not already appear, find the file, and add it to the list of loaded files. If the file cannot be found, return a NULL FILE_BUFFER *. */ extern FILE_BUFFER *info_find_file (); /* Force load the file named FILENAME, and return the information structure describing this file. Even if the file was already loaded, this loads a new buffer, rebuilds tags and nodes, and returns a new FILE_BUFFER *. */ extern FILE_BUFFER *info_load_file (); /* Return a pointer to a NODE structure for the Info node (FILENAME)NODENAME. FILENAME can be passed as NULL, in which case the filename of "dir" is used. NODENAME can be passed as NULL, in which case the nodename of "Top" is used. If the node cannot be found, return a NULL pointer. */ extern NODE *info_get_node (); /* Return a pointer to a NODE structure for the Info node NODENAME in FILE_BUFFER. NODENAME can be passed as NULL, in which case the nodename of "Top" is used. If the node cannot be found, return a NULL pointer. */ extern NODE *info_get_node_of_file_buffer (); /* Grovel FILE_BUFFER->contents finding tags and nodes, and filling in the various slots. This can also be used to rebuild a tag or node table. */ extern void build_tags_and_nodes (); /* When non-zero, this is a string describing the most recent file error. */ extern char *info_recent_file_error; /* Create a new, empty file buffer. */ extern FILE_BUFFER *make_file_buffer (); #endif /* !NODES_H */ texinfo-3.12/info/footnotes.c0000444000175000017500000001727106365743725013517 0ustar gg/* footnotes.c -- Some functions for manipulating footnotes. $Id: footnotes.c,v 1.4 1997/07/24 21:23:33 karl Exp $ Copyright (C) 1993, 97 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ #include "info.h" /* Non-zero means attempt to show footnotes when displaying a new window. */ int auto_footnotes_p = 1; static char *footnote_nodename = "*Footnotes*"; #define FOOTNOTE_HEADER_FORMAT \ "*** Footnotes appearing in the node \"%s\" ***\n" /* Find the window currently showing footnotes. */ static WINDOW * find_footnotes_window () { WINDOW *win; /* Try to find an existing window first. */ for (win = windows; win; win = win->next) if (internal_info_node_p (win->node) && (strcmp (win->node->nodename, footnote_nodename) == 0)) break; return (win); } /* Manufacture a node containing the footnotes of this node, and return the manufactured node. If NODE has no footnotes, return a NULL pointer. */ NODE * make_footnotes_node (node) NODE *node; { NODE *fn_node, *result = (NODE *)NULL; long fn_start; /* Make the initial assumption that the footnotes appear as simple text within this windows node. */ fn_node = node; /* See if this node contains the magic footnote label. */ fn_start = info_search_in_node (FOOTNOTE_LABEL, node, 0, (WINDOW *)NULL, 1); /* If it doesn't, check to see if it has an associated footnotes node. */ if (fn_start == -1) { REFERENCE **refs; refs = info_xrefs_of_node (node); if (refs) { register int i; char *refname; refname = (char *)xmalloc (1 + strlen ("-Footnotes") + strlen (node->nodename)); strcpy (refname, node->nodename); strcat (refname, "-Footnotes"); for (i = 0; refs[i]; i++) if ((refs[i]->nodename != (char *)NULL) && (strcmp (refs[i]->nodename, refname) == 0)) { char *filename; filename = node->parent; if (!filename) filename = node->filename; fn_node = info_get_node (filename, refname); if (fn_node) fn_start = 0; break; } free (refname); info_free_references (refs); } } /* If we never found the start of a footnotes area, quit now. */ if (fn_start == -1) return ((NODE *)NULL); /* Make the new node. */ result = (NODE *)xmalloc (sizeof (NODE)); result->flags = 0; /* Get the size of the footnotes appearing within this node. */ { char *header; long text_start = fn_start; header = (char *)xmalloc (1 + strlen (node->nodename) + strlen (FOOTNOTE_HEADER_FORMAT)); sprintf (header, FOOTNOTE_HEADER_FORMAT, node->nodename); /* Move the start of the displayed text to right after the first line. This effectively skips either "---- footno...", or "File: foo...". */ while (text_start < fn_node->nodelen) if (fn_node->contents[text_start++] == '\n') break; result->nodelen = strlen (header) + fn_node->nodelen - text_start; /* Set the contents of this node. */ result->contents = (char *)xmalloc (1 + result->nodelen); sprintf (result->contents, "%s", header); memcpy (result->contents + strlen (header), fn_node->contents + text_start, fn_node->nodelen - text_start); name_internal_node (result, footnote_nodename); free (header); } #if defined (NOTDEF) /* If the footnotes were gleaned from the node that we were called with, shorten the calling node's display length. */ if (fn_node == node) narrow_node (node, 0, fn_start); #endif /* NOTDEF */ return (result); } /* Create or delete the footnotes window depending on whether footnotes exist in WINDOW's node or not. Returns FN_FOUND if footnotes were found and displayed. Returns FN_UNFOUND if there were no footnotes found in WINDOW's node. Returns FN_UNABLE if there were footnotes, but the window to show them couldn't be made. */ int info_get_or_remove_footnotes (window) WINDOW *window; { WINDOW *fn_win; NODE *new_footnotes; fn_win = find_footnotes_window (); /* If we are in the footnotes window, change nothing. */ if (fn_win == window) return (FN_FOUND); /* Try to find footnotes for this window's node. */ new_footnotes = make_footnotes_node (window->node); /* If there was a window showing footnotes, and there are no footnotes for the current window, delete the old footnote window. */ if (fn_win && !new_footnotes) { if (windows->next) info_delete_window_internal (fn_win); } /* If there are footnotes for this window's node, but no window around showing footnotes, try to make a new window. */ if (new_footnotes && !fn_win) { WINDOW *old_active; WINDOW *last, *win; /* Always make this window be the last one appearing in the list. Find the last window in the chain. */ for (win = windows, last = windows; win; last = win, win = win->next); /* Try to split this window, and make the split window the one to contain the footnotes. */ old_active = active_window; active_window = last; fn_win = window_make_window (new_footnotes); active_window = old_active; if (!fn_win) { free (new_footnotes->contents); free (new_footnotes); /* If we are hacking automatic footnotes, and there are footnotes but we couldn't display them, print a message to that effect. */ if (auto_footnotes_p) inform_in_echo_area (_("Footnotes could not be displayed")); return (FN_UNABLE); } } /* If there are footnotes, and there is a window to display them, make that window be the number of lines appearing in the footnotes. */ if (new_footnotes && fn_win) { window_set_node_of_window (fn_win, new_footnotes); window_change_window_height (fn_win, fn_win->line_count - fn_win->height); remember_window_and_node (fn_win, new_footnotes); add_gcable_pointer (new_footnotes->contents); } if (!new_footnotes) return (FN_UNFOUND); else return (FN_FOUND); } /* Show the footnotes associated with this node in another window. */ DECLARE_INFO_COMMAND (info_show_footnotes, _("Show the footnotes associated with this node in another window")) { /* A negative argument means just make the window go away. */ if (count < 0) { WINDOW *fn_win = find_footnotes_window (); /* If there is an old footnotes window, and it isn't the only window on the screen, delete it. */ if (fn_win && windows->next) info_delete_window_internal (fn_win); } else { int result; result = info_get_or_remove_footnotes (window); switch (result) { case FN_UNFOUND: info_error (NO_FOOT_NODE); break; case FN_UNABLE: info_error (WIN_TOO_SMALL); break; } } } texinfo-3.12/info/footnotes.h0000444000175000017500000000337306362742033013506 0ustar gg/* footnotes.h -- Some functions for manipulating footnotes. $Id: footnotes.h,v 1.3 1997/07/15 18:40:27 karl Exp $ This file is part of GNU Info, a program for reading online documentation stored in Info format. Copyright (C) 1993, 97 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ #ifndef INFO_FOOTNOTES_H #define INFO_FOOTNOTES_H /* Magic string which indicates following text is footnotes. */ #define FOOTNOTE_LABEL _("---------- Footnotes ----------") #define FN_FOUND 0 #define FN_UNFOUND 1 #define FN_UNABLE 2 /* Create or delete the footnotes window depending on whether footnotes exist in WINDOW's node or not. Returns FN_FOUND if footnotes were found and displayed. Returns FN_UNFOUND if there were no footnotes found in WINDOW's node. Returns FN_UNABLE if there were footnotes, but the window to show them couldn't be made. */ extern int info_get_or_remove_footnotes (); /* Non-zero means attempt to show footnotes when displaying a new window. */ extern int auto_footnotes_p; #endif /* not INFO_FOOTNOTES_H */ texinfo-3.12/info/filesys.h0000444000175000017500000000713106371434717013147 0ustar gg/* filesys.h -- External declarations of functions and vars in filesys.c. $Id: filesys.h,v 1.3 1997/07/15 18:39:08 karl Exp $ This file is part of GNU Info, a program for reading online documentation stored in Info format. Copyright (C) 1993, 97 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ #ifndef INFO_FILESYS_H #define INFO_FILESYS_H /* The path on which we look for info files. You can initialize this from the environment variable INFOPATH if there is one, or you can call info_add_path () to add paths to the beginning or end of it. */ extern char *infopath; /* Make INFOPATH have absolutely nothing in it. */ extern void zap_infopath (); /* Add PATH to the list of paths found in INFOPATH. 2nd argument says whether to put PATH at the front or end of INFOPATH. */ extern void info_add_path (); /* Defines that are passed along with the pathname to info_add_path (). */ #define INFOPATH_PREPEND 0 #define INFOPATH_APPEND 1 /* Expand the filename in PARTIAL to make a real name for this operating system. This looks in INFO_PATHS in order to find the correct file. If it can't find the file, it returns NULL. */ extern char *info_find_fullpath (); /* Read the contents of PATHNAME, returning a buffer with the contents of that file in it, and returning the size of that buffer in FILESIZE. FINFO is a stat struct which has already been filled in by the caller. If the file cannot be read, return a NULL pointer. */ extern char *filesys_read_info_file (); extern char *filesys_read_compressed (); /* Return the command string that would be used to decompress FILENAME. */ extern char *filesys_decompressor_for_file (); extern int compressed_filename_p (); /* A function which returns a pointer to a static buffer containing an error message for FILENAME and ERROR_NUM. */ extern char *filesys_error_string (); /* The number of the most recent file system error. */ extern int filesys_error_number; /* Given a string containing units of information separated by colons, return the next one pointed to by IDX, or NULL if there are no more. Advance IDX to the character after the colon. */ extern char *extract_colon_unit (); /* The default value of INFOPATH. */ #if !defined (DEFAULT_INFOPATH) # define DEFAULT_INFOPATH "/usr/local/info:/usr/info:/usr/local/lib/info:/usr/lib/info:/usr/local/gnu/info:/usr/local/gnu/lib/info:/usr/gnu/info:/usr/gnu/lib/info:/opt/gnu/info:/usr/share/info:/usr/share/lib/info:/usr/local/share/info:/usr/local/share/lib/info:/usr/gnu/lib/emacs/info:/usr/local/gnu/lib/emacs/info:/usr/local/lib/emacs/info:/usr/local/emacs/info:." #endif /* !DEFAULT_INFOPATH */ #if !defined (S_ISREG) && defined (S_IFREG) # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) #endif /* !S_ISREG && S_IFREG */ #if !defined (S_ISDIR) && defined (S_IFDIR) # define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) #endif /* !S_ISDIR && S_IFDIR */ #endif /* not INFO_FILESYS_H */ texinfo-3.12/info/display.c0000444000175000017500000004406206365742570013137 0ustar gg/* display.c -- How to display Info windows. $Id: display.c,v 1.6 1997/07/24 21:13:27 karl Exp $ Copyright (C) 1993, 97 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ #include "info.h" #include "display.h" extern int info_any_buffered_input_p (); /* Found in session.c. */ static void free_display (); static DISPLAY_LINE **make_display (); /* An array of display lines which tell us what is currently visible on the display. */ DISPLAY_LINE **the_display = (DISPLAY_LINE **)NULL; /* Non-zero means do no output. */ int display_inhibited = 0; /* Initialize THE_DISPLAY to WIDTH and HEIGHT, with nothing in it. */ void display_initialize_display (width, height) int width, height; { free_display (the_display); the_display = make_display (width, height); display_clear_display (the_display); } /* Clear all of the lines in DISPLAY making the screen blank. */ void display_clear_display (display) DISPLAY_LINE **display; { register int i; register DISPLAY_LINE *display_line; for (i = 0; (display_line = display[i]); i++) { display[i]->text[0] = '\0'; display[i]->textlen = 0; display[i]->inverse = 0; } } /* Non-zero if we didn't completely redisplay a window. */ int display_was_interrupted_p = 0; /* Update the windows pointed to by WINDOW in the_display. This actually writes the text on the screen. */ void display_update_display (window) WINDOW *window; { register WINDOW *win; display_was_interrupted_p = 0; /* For every window in the list, check contents against the display. */ for (win = window; win; win = win->next) { /* Only re-display visible windows which need updating. */ if (((win->flags & W_WindowVisible) == 0) || ((win->flags & W_UpdateWindow) == 0) || (win->height == 0)) continue; display_update_one_window (win); if (display_was_interrupted_p) break; } /* Always update the echo area. */ display_update_one_window (the_echo_area); } /* Display WIN on the_display. Unlike display_update_display (), this function only does one window. */ void display_update_one_window (win) WINDOW *win; { register char *nodetext; /* Current character to display. */ register char *last_node_char; /* Position of the last character in node. */ register int i; /* General use index. */ char *printed_line; /* Buffer for a printed line. */ int pl_index = 0; /* Index into PRINTED_LINE. */ int line_index = 0; /* Number of lines done so far. */ DISPLAY_LINE **display = the_display; /* If display is inhibited, that counts as an interrupted display. */ if (display_inhibited) display_was_interrupted_p = 1; /* If the window has no height, or display is inhibited, quit now. */ if (!win->height || display_inhibited) return; /* If the window's first row doesn't appear in the_screen, then it cannot be displayed. This can happen when the_echo_area is the window to be displayed, and the screen has shrunk to less than one line. */ if ((win->first_row < 0) || (win->first_row > the_screen->height)) return; /* Print each line in the window into our local buffer, and then check the contents of that buffer against the display. If they differ, update the display. */ printed_line = (char *)xmalloc (1 + win->width); if (!win->node || !win->line_starts) goto done_with_node_display; nodetext = win->line_starts[win->pagetop]; last_node_char = win->node->contents + win->node->nodelen; for (; nodetext < last_node_char; nodetext++) { char *rep, *rep_carried_over, rep_temp[2]; int replen; if (isprint (*nodetext)) { rep_temp[0] = *nodetext; replen = 1; rep_temp[1] = '\0'; rep = rep_temp; } else { if (*nodetext == '\r' || *nodetext == '\n') { replen = win->width - pl_index; } else { rep = printed_representation (*nodetext, pl_index); replen = strlen (rep); } } /* If this character can be printed without passing the width of the line, then stuff it into the line. */ if (replen + pl_index < win->width) { /* Optimize if possible. */ if (replen == 1) { printed_line[pl_index++] = *rep; } else { for (i = 0; i < replen; i++) printed_line[pl_index++] = rep[i]; } } else { DISPLAY_LINE *entry; /* If this character cannot be printed in this line, we have found the end of this line as it would appear on the screen. Carefully print the end of the line, and then compare. */ if (*nodetext == '\n' || *nodetext == '\r' || *nodetext == '\t') { printed_line[pl_index] = '\0'; rep_carried_over = (char *)NULL; } else { /* The printed representation of this character extends into the next line. Remember the offset of the last character printed out of REP so that we can carry the character over to the next line. */ for (i = 0; pl_index < (win->width - 1);) printed_line[pl_index++] = rep[i++]; rep_carried_over = rep + i; /* If printing the last character in this window couldn't possibly cause the screen to scroll, place a backslash in the rightmost column. */ if (1 + line_index + win->first_row < the_screen->height) { if (win->flags & W_NoWrap) printed_line[pl_index++] = '$'; else printed_line[pl_index++] = '\\'; } printed_line[pl_index] = '\0'; } /* We have the exact line as it should appear on the screen. Check to see if this line matches the one already appearing on the screen. */ entry = display[line_index + win->first_row]; /* If the screen line is inversed, then we have to clear the line from the screen first. Why, I don't know. */ if (entry->inverse) { terminal_goto_xy (0, line_index + win->first_row); terminal_clear_to_eol (); entry->inverse = 0; entry->text[0] = '\0'; entry->textlen = 0; } /* Find the offset where these lines differ. */ for (i = 0; i < pl_index; i++) if (printed_line[i] != entry->text[i]) break; /* If the lines are not the same length, or if they differed at all, we must do some redrawing. */ if ((i != pl_index) || (pl_index != entry->textlen)) { /* Move to the proper point on the terminal. */ terminal_goto_xy (i, line_index + win->first_row); /* If there is any text to print, print it. */ if (i != pl_index) terminal_put_text (printed_line + i); /* If the printed text didn't extend all the way to the edge of the window, and text was appearing between here and the edge of the window, clear from here to the end of the line. */ if ((pl_index < win->width && pl_index < entry->textlen) || (entry->inverse)) terminal_clear_to_eol (); fflush (stdout); /* Update the display text buffer. */ strcpy (entry->text + i, printed_line + i); entry->textlen = pl_index; /* Lines showing node text are not in inverse. Only modelines have that distinction. */ entry->inverse = 0; } /* We have done at least one line. Increment our screen line index, and check against the bottom of the window. */ if (++line_index == win->height) break; /* A line has been displayed, and the screen reflects that state. If there is typeahead pending, then let that typeahead be read now, instead of continuing with the display. */ if (info_any_buffered_input_p ()) { free (printed_line); display_was_interrupted_p = 1; return; } /* Reset PL_INDEX to the start of the line. */ pl_index = 0; /* If there are characters from REP left to print, stuff them into the buffer now. */ if (rep_carried_over) for (; rep[pl_index]; pl_index++) printed_line[pl_index] = rep[pl_index]; /* If this window has chosen not to wrap lines, skip to the end of the physical line in the buffer, and start a new line here. */ if (pl_index && (win->flags & W_NoWrap)) { char *begin; pl_index = 0; printed_line[0] = '\0'; begin = nodetext; while ((nodetext < last_node_char) && (*nodetext != '\n')) nodetext++; } } } done_with_node_display: /* We have reached the end of the node or the end of the window. If it is the end of the node, then clear the lines of the window from here to the end of the window. */ for (; line_index < win->height; line_index++) { DISPLAY_LINE *entry = display[line_index + win->first_row]; /* If this line has text on it then make it go away. */ if (entry && entry->textlen) { entry->textlen = 0; entry->text[0] = '\0'; terminal_goto_xy (0, line_index + win->first_row); terminal_clear_to_eol (); } } /* Finally, if this window has a modeline it might need to be redisplayed. Check the window's modeline against the one in the display, and update if necessary. */ if ((win->flags & W_InhibitMode) == 0) { window_make_modeline (win); line_index = win->first_row + win->height; /* This display line must both be in inverse, and have the same contents. */ if ((!display[line_index]->inverse) || (strcmp (display[line_index]->text, win->modeline) != 0)) { terminal_goto_xy (0, line_index); terminal_begin_inverse (); terminal_put_text (win->modeline); terminal_end_inverse (); strcpy (display[line_index]->text, win->modeline); display[line_index]->inverse = 1; display[line_index]->textlen = strlen (win->modeline); fflush (stdout); } } /* Okay, this window doesn't need updating anymore. */ win->flags &= ~W_UpdateWindow; free (printed_line); fflush (stdout); } /* Scroll the region of the_display starting at START, ending at END, and moving the lines AMOUNT lines. If AMOUNT is less than zero, the lines are moved up in the screen, otherwise down. Actually, it is possible for no scrolling to take place in the case that the terminal doesn't support it. This doesn't matter to us. */ void display_scroll_display (start, end, amount) int start, end, amount; { register int i, last; DISPLAY_LINE *temp; /* If this terminal cannot do scrolling, give up now. */ if (!terminal_can_scroll) return; /* If there isn't anything displayed on the screen because it is too small, quit now. */ if (!the_display[0]) return; /* If there is typeahead pending, then don't actually do any scrolling. */ if (info_any_buffered_input_p ()) return; /* Do it on the screen. */ terminal_scroll_terminal (start, end, amount); /* Now do it in the display buffer so our contents match the screen. */ if (amount > 0) { last = end + amount; /* Shift the lines to scroll right into place. */ for (i = 0; i < (end - start); i++) { temp = the_display[last - i]; the_display[last - i] = the_display[end - i]; the_display[end - i] = temp; } /* The lines have been shifted down in the buffer. Clear all of the lines that were vacated. */ for (i = start; i != (start + amount); i++) { the_display[i]->text[0] = '\0'; the_display[i]->textlen = 0; the_display[i]->inverse = 0; } } if (amount < 0) { last = start + amount; for (i = 0; i < (end - start); i++) { temp = the_display[last + i]; the_display[last + i] = the_display[start + i]; the_display[start + i] = temp; } /* The lines have been shifted up in the buffer. Clear all of the lines that are left over. */ for (i = end + amount; i != end; i++) { the_display[i]->text[0] = '\0'; the_display[i]->textlen = 0; the_display[i]->inverse = 0; } } } /* Try to scroll lines in WINDOW. OLD_PAGETOP is the pagetop of WINDOW before having had its line starts recalculated. OLD_STARTS is the list of line starts that used to appear in this window. OLD_COUNT is the number of lines that appear in the OLD_STARTS array. */ void display_scroll_line_starts (window, old_pagetop, old_starts, old_count) WINDOW *window; int old_pagetop, old_count; char **old_starts; { register int i, old, new; /* Indices into the line starts arrays. */ int last_new, last_old; /* Index of the last visible line. */ int old_first, new_first; /* Index of the first changed line. */ int unchanged_at_top = 0; int already_scrolled = 0; /* Locate the first line which was displayed on the old window. */ old_first = old_pagetop; new_first = window->pagetop; /* Find the last line currently visible in this window. */ last_new = window->pagetop + (window->height - 1); if (last_new > window->line_count) last_new = window->line_count - 1; /* Find the last line which used to be currently visible in this window. */ last_old = old_pagetop + (window->height - 1); if (last_old > old_count) last_old = old_count - 1; for (old = old_first, new = new_first; old < last_old && new < last_new; old++, new++) if (old_starts[old] != window->line_starts[new]) break; else unchanged_at_top++; /* Loop through the old lines looking for a match in the new lines. */ for (old = old_first + unchanged_at_top; old < last_old; old++) { for (new = new_first; new < last_new; new++) if (old_starts[old] == window->line_starts[new]) { /* Find the extent of the matching lines. */ for (i = 0; (old + i) < last_old; i++) if (old_starts[old + i] != window->line_starts[new + i]) break; /* Scroll these lines if there are enough of them. */ { int start, end, amount; start = (window->first_row + ((old + already_scrolled) - old_pagetop)); amount = new - (old + already_scrolled); end = window->first_row + window->height; /* If we are shifting the block of lines down, then the last AMOUNT lines will become invisible. Thus, don't bother scrolling them. */ if (amount > 0) end -= amount; if ((end - start) > 0) { display_scroll_display (start, end, amount); /* Some lines have been scrolled. Simulate the scrolling by offsetting the value of the old index. */ old += i; already_scrolled += amount; } } } } } /* Move the screen cursor to directly over the current character in WINDOW. */ void display_cursor_at_point (window) WINDOW *window; { int vpos, hpos; vpos = window_line_of_point (window) - window->pagetop + window->first_row; hpos = window_get_cursor_column (window); terminal_goto_xy (hpos, vpos); fflush (stdout); } /* **************************************************************** */ /* */ /* Functions Static to this File */ /* */ /* **************************************************************** */ /* Make a DISPLAY_LINE ** with width and height. */ static DISPLAY_LINE ** make_display (width, height) int width, height; { register int i; DISPLAY_LINE **display; display = (DISPLAY_LINE **)xmalloc ((1 + height) * sizeof (DISPLAY_LINE *)); for (i = 0; i < height; i++) { display[i] = (DISPLAY_LINE *)xmalloc (sizeof (DISPLAY_LINE)); display[i]->text = (char *)xmalloc (1 + width); display[i]->textlen = 0; display[i]->inverse = 0; } display[i] = (DISPLAY_LINE *)NULL; return (display); } /* Free the storage allocated to DISPLAY. */ static void free_display (display) DISPLAY_LINE **display; { register int i; register DISPLAY_LINE *display_line; if (!display) return; for (i = 0; (display_line = display[i]); i++) { free (display_line->text); free (display_line); } free (display); } texinfo-3.12/info/search.h0000444000175000017500000000572206362742345012741 0ustar gg/* search.h -- Structure used to search large bodies of text, with bounds. $Id: search.h,v 1.3 1997/07/15 18:43:49 karl Exp $ This file is part of GNU Info, a program for reading online documentation stored in Info format. Copyright (C) 1993, 97 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ /* The search functions take two arguments: 1) a string to search for, and 2) a pointer to a SEARCH_BINDING which contains the buffer, start, and end of the search. They return a long, which is the offset from the start of the buffer at which the match was found. An offset of -1 indicates failure. */ #ifndef INFO_SEARCH_H #define INFO_SEARCH_H typedef struct { char *buffer; /* The buffer of text to search. */ long start; /* Offset of the start of the search. */ long end; /* Offset of the end of the searh. */ int flags; /* Flags controlling the type of search. */ } SEARCH_BINDING; #define S_FoldCase 0x01 /* Set means fold case in searches. */ #define S_SkipDest 0x02 /* Set means return pointing after the dest. */ SEARCH_BINDING *make_binding (), *copy_binding (); extern long search_forward (), search_backward (), search (); extern int looking_at (); /* Note that STRING_IN_LINE () always returns the offset of the 1st character after the string. */ extern int string_in_line (); /* Some unixes don't have strcasecmp or strncasecmp. */ #if !defined (HAVE_STRCASECMP) extern int strcasecmp (), strncasecmp (); #endif /* !HAVE_STRCASECMP */ /* Function names that start with "skip" are passed a string, and return an offset from the start of that string. Function names that start with "find" are passed a SEARCH_BINDING, and return an absolute position marker of the item being searched for. "Find" functions return a value of -1 if the item being looked for couldn't be found. */ extern int skip_whitespace (), skip_non_whitespace (); extern int skip_whitespace_and_newlines (), skip_line (); extern int skip_node_characters (), skip_node_separator (); #define DONT_SKIP_NEWLINES 0 #define SKIP_NEWLINES 1 extern long find_node_separator (), find_tags_table (); extern long find_node_in_binding (); #endif /* not INFO_SEARCH_H */ texinfo-3.12/info/doc.h0000444000175000017500000000314506362741064012233 0ustar gg/* doc.h -- Structure associating function pointers with documentation. */ /* This file is part of GNU Info, a program for reading online documentation stored in Info format. Copyright (C) 1993 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ #if !defined (DOC_H) #define DOC_H #include "info.h" /* for NAMED_FUNCTIONS, VFunction, etc. */ typedef struct { VFunction *func; #if defined (NAMED_FUNCTIONS) char *func_name; #endif /* NAMED_FUNCTIONS */ char *doc; } FUNCTION_DOC; extern FUNCTION_DOC function_doc_array[]; extern char *function_documentation (); extern char *key_documentation (); extern char *pretty_keyname (); extern char *replace_in_documentation (); extern void info_document_key (); extern void dump_map_to_message_buffer (); #if defined (NAMED_FUNCTIONS) extern char *function_name (); extern VFunction *named_function (); #endif /* NAMED_FUNCTIONS */ #endif /* !DOC_H */ texinfo-3.12/info/window.c0000444000175000017500000012330006474375632012774 0ustar gg/* window.c -- Windows in Info. $Id: window.c,v 1.5 1998/02/23 22:43:38 karl Exp $ This file is part of GNU Info, a program for reading online documentation stored in Info format. Copyright (C) 1993, 97 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ #include "info.h" #include "nodes.h" #include "window.h" #include "display.h" #include "info-utils.h" #include "infomap.h" /* The window which describes the screen. */ WINDOW *the_screen = (WINDOW *)NULL; /* The window which describes the echo area. */ WINDOW *the_echo_area = (WINDOW *)NULL; /* The list of windows in Info. */ WINDOW *windows = (WINDOW *)NULL; /* Pointer to the active window in WINDOW_LIST. */ WINDOW *active_window = (WINDOW *)NULL; /* The size of the echo area in Info. It never changes, irregardless of the size of the screen. */ #define ECHO_AREA_HEIGHT 1 /* Macro returns the amount of space that the echo area truly requires relative to the entire screen. */ #define echo_area_required (1 + the_echo_area->height) /* Initalize the window system by creating THE_SCREEN and THE_ECHO_AREA. Create the first window ever. You pass the dimensions of the total screen size. */ void window_initialize_windows (width, height) int width, height; { the_screen = (WINDOW *)xmalloc (sizeof (WINDOW)); the_echo_area = (WINDOW *)xmalloc (sizeof (WINDOW)); windows = (WINDOW *)xmalloc (sizeof (WINDOW)); active_window = windows; zero_mem (the_screen, sizeof (WINDOW)); zero_mem (the_echo_area, sizeof (WINDOW)); zero_mem (active_window, sizeof (WINDOW)); /* None of these windows has a goal column yet. */ the_echo_area->goal_column = -1; active_window->goal_column = -1; the_screen->goal_column = -1; /* The active and echo_area windows are visible. The echo_area is permanent. The screen is permanent. */ active_window->flags = W_WindowVisible; the_echo_area->flags = W_WindowIsPerm | W_InhibitMode | W_WindowVisible; the_screen->flags = W_WindowIsPerm; /* The height of the echo area never changes. It is statically set right here, and it must be at least 1 line for display. The size of the initial window cannot be the same size as the screen, since the screen includes the echo area. So, we make the height of the initial window equal to the screen's displayable region minus the height of the echo area. */ the_echo_area->height = ECHO_AREA_HEIGHT; active_window->height = the_screen->height - 1 - the_echo_area->height; window_new_screen_size (width, height, (VFunction *)NULL); /* The echo area uses a different keymap than normal info windows. */ the_echo_area->keymap = echo_area_keymap; active_window->keymap = info_keymap; } /* Given that the size of the screen has changed to WIDTH and HEIGHT from whatever it was before (found in the_screen->height, ->width), change the size (and possibly location) of each window in the screen. If a window would become too small, call the function DELETER on it, after deleting the window from our chain of windows. If DELETER is NULL, nothing extra is done. The last window can never be deleted, but it can become invisible. */ /* If non-null, a function to call with WINDOW as argument when the function window_new_screen_size () has deleted WINDOW. */ VFunction *window_deletion_notifier = (VFunction *)NULL; void window_new_screen_size (width, height) int width, height; { register WINDOW *win; int delta_height, delta_each, delta_leftover; int numwins; /* If no change, do nothing. */ if (width == the_screen->width && height == the_screen->height) return; /* If the new window height is too small, make it be zero. */ if (height < (WINDOW_MIN_SIZE + the_echo_area->height)) height = 0; if (width < 0) width = 0; /* Find out how many windows will change. */ for (numwins = 0, win = windows; win; win = win->next, numwins++); /* See if some windows will need to be deleted. This is the case if the screen is getting smaller, and the available space divided by the number of windows is less than WINDOW_MIN_SIZE. In that case, delete some windows and try again until there is either enough space to divy up among the windows, or until there is only one window left. */ while ((height - echo_area_required) / numwins <= WINDOW_MIN_SIZE) { /* If only one window, make the size of it be zero, and return immediately. */ if (!windows->next) { windows->height = 0; maybe_free (windows->line_starts); windows->line_starts = (char **)NULL; windows->line_count = 0; break; } /* If we have some temporary windows, delete one of them. */ for (win = windows; win; win = win->next) if (win->flags & W_TempWindow) break; /* Otherwise, delete the first window, and try again. */ if (!win) win = windows; if (window_deletion_notifier) (*window_deletion_notifier) (win); window_delete_window (win); numwins--; } /* The screen has changed height and width. */ delta_height = height - the_screen->height; /* This is how much. */ the_screen->height = height; /* This is the new height. */ the_screen->width = width; /* This is the new width. */ /* Set the start of the echo area. */ the_echo_area->first_row = height - the_echo_area->height; the_echo_area->width = width; /* Check to see if the screen can really be changed this way. */ if ((!windows->next) && ((windows->height == 0) && (delta_height < 0))) return; /* Divide the change in height among the available windows. */ delta_each = delta_height / numwins; delta_leftover = delta_height - (delta_each * numwins); /* Change the height of each window in the chain by delta_each. Change the height of the last window in the chain by delta_each and by the leftover amount of change. Change the width of each window to be WIDTH. */ for (win = windows; win; win = win->next) { if ((win->width != width) && ((win->flags & W_InhibitMode) == 0)) { win->width = width; maybe_free (win->modeline); win->modeline = (char *)xmalloc (1 + width); } win->height += delta_each; /* If the previous height of this window was zero, it was the only window, and it was not visible. Thus we need to compensate for the echo_area. */ if (win->height == delta_each) win->height -= (1 + the_echo_area->height); /* If this is not the first window in the chain, then change the first row of it. We cannot just add delta_each to the first row, since this window's first row is the sum of the collective increases that have gone before it. So we just add one to the location of the previous window's modeline. */ if (win->prev) win->first_row = (win->prev->first_row + win->prev->height) + 1; /* The last window in the chain gets the extra space (or shrinkage). */ if (!win->next) win->height += delta_leftover; if (win->node) recalculate_line_starts (win); win->flags |= W_UpdateWindow; } /* If the screen got smaller, check over the windows just shrunk to keep them within bounds. Some of the windows may have gotten smaller than WINDOW_MIN_HEIGHT in which case some of the other windows are larger than the available display space in the screen. Because of our intial test above, we know that there is enough space for all of the windows. */ if ((delta_each < 0) && ((windows->height != 0) && windows->next)) { int avail; avail = the_screen->height - (numwins + the_echo_area->height); win = windows; while (win) { if ((win->height < WINDOW_MIN_HEIGHT) || (win->height > avail)) { WINDOW *lastwin; /* Split the space among the available windows. */ delta_each = avail / numwins; delta_leftover = avail - (delta_each * numwins); for (win = windows; win; win = win->next) { lastwin = win; if (win->prev) win->first_row = (win->prev->first_row + win->prev->height) + 1; win->height = delta_each; } /* Give the leftover space (if any) to the last window. */ lastwin->height += delta_leftover; break; } else win= win->next; } } } /* Make a new window showing NODE, and return that window structure. If NODE is passed as NULL, then show the node showing in the active window. If the window could not be made return a NULL pointer. The active window is not changed.*/ WINDOW * window_make_window (node) NODE *node; { WINDOW *window; if (!node) node = active_window->node; /* If there isn't enough room to make another window, return now. */ if ((active_window->height / 2) < WINDOW_MIN_SIZE) return ((WINDOW *)NULL); /* Make and initialize the new window. The fudging about with -1 and +1 is because the following window in the chain cannot start at window->height, since that is where the modeline for the previous window is displayed. The inverse adjustment is made in window_delete_window (). */ window = (WINDOW *)xmalloc (sizeof (WINDOW)); window->width = the_screen->width; window->height = (active_window->height / 2) - 1; #if defined (SPLIT_BEFORE_ACTIVE) window->first_row = active_window->first_row; #else window->first_row = active_window->first_row + (active_window->height - window->height); #endif window->keymap = info_keymap; window->goal_column = -1; window->modeline = (char *)xmalloc (1 + window->width); window->line_starts = (char **)NULL; window->flags = W_UpdateWindow | W_WindowVisible; window_set_node_of_window (window, node); /* Adjust the height of the old active window. */ active_window->height -= (window->height + 1); #if defined (SPLIT_BEFORE_ACTIVE) active_window->first_row += (window->height + 1); #endif active_window->flags |= W_UpdateWindow; /* Readjust the new and old windows so that their modelines and contents will be displayed correctly. */ #if defined (NOTDEF) /* We don't have to do this for WINDOW since window_set_node_of_window () already did. */ window_adjust_pagetop (window); window_make_modeline (window); #endif /* NOTDEF */ /* We do have to readjust the existing active window. */ window_adjust_pagetop (active_window); window_make_modeline (active_window); #if defined (SPLIT_BEFORE_ACTIVE) /* This window is just before the active one. The active window gets bumped down one. The active window is not changed. */ window->next = active_window; window->prev = active_window->prev; active_window->prev = window; if (window->prev) window->prev->next = window; else windows = window; #else /* This window is just after the active one. Which window is active is not changed. */ window->prev = active_window; window->next = active_window->next; active_window->next = window; if (window->next) window->next->prev = window; #endif /* !SPLIT_BEFORE_ACTIVE */ return (window); } /* These useful macros make it possible to read the code in window_change_window_height (). */ #define grow_me_shrinking_next(me, next, diff) \ do { \ me->height += diff; \ next->height -= diff; \ next->first_row += diff; \ window_adjust_pagetop (next); \ } while (0) #define grow_me_shrinking_prev(me, prev, diff) \ do { \ me->height += diff; \ prev->height -= diff; \ me->first_row -=diff; \ window_adjust_pagetop (prev); \ } while (0) #define shrink_me_growing_next(me, next, diff) \ do { \ me->height -= diff; \ next->height += diff; \ next->first_row -= diff; \ window_adjust_pagetop (next); \ } while (0) #define shrink_me_growing_prev(me, prev, diff) \ do { \ me->height -= diff; \ prev->height += diff; \ me->first_row += diff; \ window_adjust_pagetop (prev); \ } while (0) /* Change the height of WINDOW by AMOUNT. This also automagically adjusts the previous and next windows in the chain. If there is only one user window, then no change takes place. */ void window_change_window_height (window, amount) WINDOW *window; int amount; { register WINDOW *win, *prev, *next; /* If there is only one window, or if the amount of change is zero, return immediately. */ if (!windows->next || amount == 0) return; /* Find this window in our chain. */ for (win = windows; win; win = win->next) if (win == window) break; /* If the window is isolated (i.e., doesn't appear in our window list, then quit now. */ if (!win) return; /* Change the height of this window by AMOUNT, if that is possible. It can be impossible if there isn't enough available room on the screen, or if the resultant window would be too small. */ prev = window->prev; next = window->next; /* WINDOW decreasing in size? */ if (amount < 0) { int abs_amount = -amount; /* It is easier to deal with this way. */ /* If the resultant window would be too small, stop here. */ if ((window->height - abs_amount) < WINDOW_MIN_HEIGHT) return; /* If we have two neighboring windows, choose the smaller one to get larger. */ if (next && prev) { if (prev->height < next->height) shrink_me_growing_prev (window, prev, abs_amount); else shrink_me_growing_next (window, next, abs_amount); } else if (next) shrink_me_growing_next (window, next, abs_amount); else shrink_me_growing_prev (window, prev, abs_amount); } /* WINDOW increasing in size? */ if (amount > 0) { int total_avail, next_avail = 0, prev_avail = 0; if (next) next_avail = next->height - WINDOW_MIN_SIZE; if (prev) prev_avail = prev->height - WINDOW_MIN_SIZE; total_avail = next_avail + prev_avail; /* If there isn't enough space available to grow this window, give up. */ if (amount > total_avail) return; /* If there aren't two neighboring windows, or if one of the neighbors is larger than the other one by at least AMOUNT, grow that one. */ if ((next && !prev) || ((next_avail - amount) >= prev_avail)) grow_me_shrinking_next (window, next, amount); else if ((prev && !next) || ((prev_avail - amount) >= next_avail)) grow_me_shrinking_prev (window, prev, amount); else { int change; /* This window has two neighbors. They both must be shrunk in to make enough space for WINDOW to grow. Make them both the same size. */ if (prev_avail > next_avail) { change = prev_avail - next_avail; grow_me_shrinking_prev (window, prev, change); amount -= change; } else { change = next_avail - prev_avail; grow_me_shrinking_next (window, next, change); amount -= change; } /* Both neighbors are the same size. Split the difference in AMOUNT between them. */ while (amount) { window->height++; amount--; /* Odd numbers grow next, even grow prev. */ if (amount & 1) { prev->height--; window->first_row--; } else { next->height--; next->first_row++; } } window_adjust_pagetop (prev); window_adjust_pagetop (next); } } if (prev) prev->flags |= W_UpdateWindow; if (next) next->flags |= W_UpdateWindow; window->flags |= W_UpdateWindow; window_adjust_pagetop (window); } /* Tile all of the windows currently displayed in the global variable WINDOWS. If argument STYLE is TILE_INTERNALS, tile windows displaying internal nodes as well, otherwise do not change the height of such windows. */ void window_tile_windows (style) int style; { WINDOW *win, *last_adjusted; int numwins, avail, per_win_height, leftover; int do_internals; numwins = avail = 0; do_internals = (style == TILE_INTERNALS); for (win = windows; win; win = win->next) if (do_internals || !win->node || (win->node->flags & N_IsInternal) == 0) { avail += win->height; numwins++; } if (numwins <= 1 || !the_screen->height) return; /* Find the size for each window. Divide the size of the usable portion of the screen by the number of windows. */ per_win_height = avail / numwins; leftover = avail - (per_win_height * numwins); last_adjusted = (WINDOW *)NULL; for (win = windows; win; win = win->next) { if (do_internals || !win->node || (win->node->flags & N_IsInternal) == 0) { last_adjusted = win; win->height = per_win_height; } } if (last_adjusted) last_adjusted->height += leftover; /* Readjust the first_row of every window in the chain. */ for (win = windows; win; win = win->next) { if (win->prev) win->first_row = win->prev->first_row + win->prev->height + 1; window_adjust_pagetop (win); win->flags |= W_UpdateWindow; } } /* Toggle the state of line wrapping in WINDOW. This can do a bit of fancy redisplay. */ void window_toggle_wrap (window) WINDOW *window; { if (window->flags & W_NoWrap) window->flags &= ~W_NoWrap; else window->flags |= W_NoWrap; if (window != the_echo_area) { char **old_starts; int old_lines, old_pagetop; old_starts = window->line_starts; old_lines = window->line_count; old_pagetop = window->pagetop; calculate_line_starts (window); /* Make sure that point appears within this window. */ window_adjust_pagetop (window); /* If the pagetop hasn't changed maybe we can do some scrolling now to speed up the display. Many of the line starts will be the same, so scrolling here is a very good optimization.*/ if (old_pagetop == window->pagetop) display_scroll_line_starts (window, old_pagetop, old_starts, old_lines); maybe_free (old_starts); } window->flags |= W_UpdateWindow; } /* Set WINDOW to display NODE. */ void window_set_node_of_window (window, node) WINDOW *window; NODE *node; { window->node = node; window->pagetop = 0; window->point = 0; recalculate_line_starts (window); window->flags |= W_UpdateWindow; window_adjust_pagetop (window); window_make_modeline (window); } /* Delete WINDOW from the list of known windows. If this window was the active window, make the next window in the chain be the active window. If the active window is the next or previous window, choose that window as the recipient of the extra space. Otherwise, prefer the next window. */ void window_delete_window (window) WINDOW *window; { WINDOW *next, *prev, *window_to_fix; next = window->next; prev = window->prev; /* You cannot delete the only window or a permanent window. */ if ((!next && !prev) || (window->flags & W_WindowIsPerm)) return; if (next) next->prev = prev; if (!prev) windows = next; else prev->next = next; if (window->line_starts) free (window->line_starts); if (window->modeline) free (window->modeline); if (window == active_window) { /* If there isn't a next window, then there must be a previous one, since we cannot delete the last window. If there is a next window, prefer to use that as the active window. */ if (next) active_window = next; else active_window = prev; } if (next && active_window == next) window_to_fix = next; else if (prev && active_window == prev) window_to_fix = prev; else if (next) window_to_fix = next; else if (prev) window_to_fix = prev; else window_to_fix = windows; if (window_to_fix->first_row > window->first_row) { int diff; /* Try to adjust the visible part of the node so that as little text as possible has to move. */ diff = window_to_fix->first_row - window->first_row; window_to_fix->first_row = window->first_row; window_to_fix->pagetop -= diff; if (window_to_fix->pagetop < 0) window_to_fix->pagetop = 0; } /* The `+ 1' is to offset the difference between the first_row locations. See the code in window_make_window (). */ window_to_fix->height += window->height + 1; window_to_fix->flags |= W_UpdateWindow; free (window); } /* For every window in CHAIN, set the flags member to have FLAG set. */ void window_mark_chain (chain, flag) WINDOW *chain; int flag; { register WINDOW *win; for (win = chain; win; win = win->next) win->flags |= flag; } /* For every window in CHAIN, clear the flags member of FLAG. */ void window_unmark_chain (chain, flag) WINDOW *chain; int flag; { register WINDOW *win; for (win = chain; win; win = win->next) win->flags &= ~flag; } /* Return the number of characters it takes to display CHARACTER on the screen at HPOS. */ int character_width (character, hpos) int character, hpos; { int printable_limit = 127; int width = 1; if (ISO_Latin_p) printable_limit = 255; if (character > printable_limit) width = 3; else if (iscntrl (character)) { switch (character) { case '\r': case '\n': width = the_screen->width - hpos; break; case '\t': width = ((hpos + 8) & 0xf8) - hpos; break; default: width = 2; } } else if (character == DEL) width = 2; return (width); } /* Return the number of characters it takes to display STRING on the screen at HPOS. */ int string_width (string, hpos) char *string; int hpos; { register int i, width, this_char_width; for (width = 0, i = 0; string[i]; i++) { this_char_width = character_width (string[i], hpos); width += this_char_width; hpos += this_char_width; } return (width); } /* Quickly guess the approximate number of lines to that NODE would take to display. This really only counts carriage returns. */ int window_physical_lines (node) NODE *node; { register int i, lines; char *contents; if (!node) return (0); contents = node->contents; for (i = 0, lines = 1; i < node->nodelen; i++) if (contents[i] == '\n') lines++; return (lines); } /* Calculate a list of line starts for the node belonging to WINDOW. The line starts are pointers to the actual text within WINDOW->NODE. */ void calculate_line_starts (window) WINDOW *window; { register int i, hpos; char **line_starts = (char **)NULL; int line_starts_index = 0, line_starts_slots = 0; int bump_index; NODE *node; window->line_starts = (char **)NULL; window->line_count = 0; node = window->node; if (!node) return; /* Grovel the node starting at the top, and for each line calculate the width of the characters appearing in that line. Add each line start to our array. */ i = 0; hpos = 0; bump_index = 0; while (i < node->nodelen) { char *line = node->contents + i; unsigned int cwidth, c; add_pointer_to_array (line, line_starts_index, line_starts, line_starts_slots, 100, char *); if (bump_index) { i++; bump_index = 0; } while (1) { c = node->contents[i]; cwidth = character_width (c, hpos); /* If this character fits within this line, just do the next one. */ if ((hpos + cwidth) < window->width) { i++; hpos += cwidth; continue; } else { /* If this character would position the cursor at the start of the next printed screen line, then do the next line. */ if (c == '\n' || c == '\r' || c == '\t') { i++; hpos = 0; break; } else { /* This character passes the window width border. Postion the cursor after the printed character, but remember this line start as where this character is. A bit tricky. */ /* If this window doesn't wrap lines, proceed to the next physical line here. */ if (window->flags & W_NoWrap) { hpos = 0; while (i < node->nodelen && node->contents[i] != '\n') i++; if (node->contents[i] == '\n') i++; } else { hpos = the_screen->width - hpos; bump_index++; } break; } } } } window->line_starts = line_starts; window->line_count = line_starts_index; } /* Given WINDOW, recalculate the line starts for the node it displays. */ void recalculate_line_starts (window) WINDOW *window; { maybe_free (window->line_starts); calculate_line_starts (window); } /* Global variable control redisplay of scrolled windows. If non-zero, it is the desired number of lines to scroll the window in order to make point visible. A user might set this to 1 for smooth scrolling. If set to zero, the line containing point is centered within the window. */ int window_scroll_step = 0; /* Adjust the pagetop of WINDOW such that the cursor point will be visible. */ void window_adjust_pagetop (window) WINDOW *window; { register int line = 0; char *contents; if (!window->node) return; contents = window->node->contents; /* Find the first printed line start which is after WINDOW->point. */ for (line = 0; line < window->line_count; line++) { char *line_start; line_start = window->line_starts[line]; if ((line_start - contents) > window->point) break; } /* The line index preceding the line start which is past point is the one containing point. */ line--; /* If this line appears in the current displayable page, do nothing. Otherwise, adjust the top of the page to make this line visible. */ if ((line < window->pagetop) || (line - window->pagetop > (window->height - 1))) { /* The user-settable variable "scroll-step" is used to attempt to make point visible, iff it is non-zero. If that variable is zero, then the line containing point is centered within the window. */ if (window_scroll_step < window->height) { if ((line < window->pagetop) && ((window->pagetop - window_scroll_step) <= line)) window->pagetop -= window_scroll_step; else if ((line - window->pagetop > (window->height - 1)) && ((line - (window->pagetop + window_scroll_step) < window->height))) window->pagetop += window_scroll_step; else window->pagetop = line - ((window->height - 1) / 2); } else window->pagetop = line - ((window->height - 1) / 2); if (window->pagetop < 0) window->pagetop = 0; window->flags |= W_UpdateWindow; } } /* Return the index of the line containing point. */ int window_line_of_point (window) WINDOW *window; { register int i, start = 0; /* Try to optimize. Check to see if point is past the pagetop for this window, and if so, start searching forward from there. */ if ((window->pagetop > -1 && window->pagetop < window->line_count) && (window->line_starts[window->pagetop] - window->node->contents) <= window->point) start = window->pagetop; for (i = start; i < window->line_count; i++) { if ((window->line_starts[i] - window->node->contents) > window->point) break; } return (i - 1); } /* Get and return the goal column for this window. */ int window_get_goal_column (window) WINDOW *window; { if (!window->node) return (-1); if (window->goal_column != -1) return (window->goal_column); /* Okay, do the work. Find the printed offset of the cursor in this window. */ return (window_get_cursor_column (window)); } /* Get and return the printed column offset of the cursor in this window. */ int window_get_cursor_column (window) WINDOW *window; { int i, hpos, end; char *line; i = window_line_of_point (window); if (i < 0) return (-1); line = window->line_starts[i]; end = window->point - (line - window->node->contents); for (hpos = 0, i = 0; i < end; i++) hpos += character_width (line[i], hpos); return (hpos); } /* Count the number of characters in LINE that precede the printed column offset of GOAL. */ int window_chars_to_goal (line, goal) char *line; int goal; { register int i, check, hpos; for (hpos = 0, i = 0; line[i] != '\n'; i++) { check = hpos + character_width (line[i], hpos); if (check > goal) break; hpos = check; } return (i); } /* Create a modeline for WINDOW, and store it in window->modeline. */ void window_make_modeline (window) WINDOW *window; { register int i; char *modeline; char location_indicator[4]; int lines_remaining; /* Only make modelines for those windows which have one. */ if (window->flags & W_InhibitMode) return; /* Find the number of lines actually displayed in this window. */ lines_remaining = window->line_count - window->pagetop; if (window->pagetop == 0) { if (lines_remaining <= window->height) strcpy (location_indicator, "All"); else strcpy (location_indicator, "Top"); } else { if (lines_remaining <= window->height) strcpy (location_indicator, "Bot"); else { float pt, lc; int percentage; pt = (float)window->pagetop; lc = (float)window->line_count; percentage = 100 * (pt / lc); sprintf (location_indicator, "%2d%%", percentage); } } /* Calculate the maximum size of the information to stick in MODELINE. */ { int modeline_len = 0; char *parent = (char *)NULL, *filename = "*no file*"; char *nodename = "*no node*"; char *update_message = (char *)NULL; NODE *node = window->node; if (node) { if (node->nodename) nodename = node->nodename; if (node->parent) { parent = filename_non_directory (node->parent); modeline_len += strlen ("Subfile: ") + strlen (node->filename); } if (node->filename) filename = filename_non_directory (node->filename); if (node->flags & N_UpdateTags) update_message = _("--*** Tags out of Date ***"); } if (update_message) modeline_len += strlen (update_message); modeline_len += strlen (filename); modeline_len += strlen (nodename); modeline_len += 4; /* strlen (location_indicator). */ /* 10 for the decimal representation of the number of lines in this node, and the remainder of the text that can appear in the line. */ modeline_len += 10 + strlen (_("-----Info: (), lines ----, ")); modeline_len += window->width; modeline = (char *)xmalloc (1 + modeline_len); /* Special internal windows have no filename. */ if (!parent && !*filename) sprintf (modeline, _("-%s---Info: %s, %d lines --%s--"), (window->flags & W_NoWrap) ? "$" : "-", nodename, window->line_count, location_indicator); else sprintf (modeline, _("-%s%s-Info: (%s)%s, %d lines --%s--"), (window->flags & W_NoWrap) ? "$" : "-", (node && (node->flags & N_IsCompressed)) ? "zz" : "--", parent ? parent : filename, nodename, window->line_count, location_indicator); if (parent) sprintf (modeline + strlen (modeline), _(" Subfile: %s"), filename); if (update_message) sprintf (modeline + strlen (modeline), "%s", update_message); i = strlen (modeline); if (i >= window->width) modeline[window->width] = '\0'; else { while (i < window->width) modeline[i++] = '-'; modeline[i] = '\0'; } strcpy (window->modeline, modeline); free (modeline); } } /* Make WINDOW start displaying at PERCENT percentage of its node. */ void window_goto_percentage (window, percent) WINDOW *window; int percent; { int desired_line; if (!percent) desired_line = 0; else desired_line = (int) ((float)window->line_count * ((float)percent / 100.0)); window->pagetop = desired_line; window->point = window->line_starts[window->pagetop] - window->node->contents; window->flags |= W_UpdateWindow; window_make_modeline (window); } /* Get the state of WINDOW, and save it in STATE. */ void window_get_state (window, state) WINDOW *window; WINDOW_STATE *state; { state->node = window->node; state->pagetop = window->pagetop; state->point = window->point; } /* Set the node, pagetop, and point of WINDOW. */ void window_set_state (window, state) WINDOW *window; WINDOW_STATE *state; { if (window->node != state->node) window_set_node_of_window (window, state->node); window->pagetop = state->pagetop; window->point = state->point; } /* **************************************************************** */ /* */ /* Manipulating Home-Made Nodes */ /* */ /* **************************************************************** */ /* A place to buffer echo area messages. */ static NODE *echo_area_node = (NODE *)NULL; /* Make the node of the_echo_area be an empty one. */ static void free_echo_area () { if (echo_area_node) { maybe_free (echo_area_node->contents); free (echo_area_node); } echo_area_node = (NODE *)NULL; window_set_node_of_window (the_echo_area, echo_area_node); } /* Clear the echo area, removing any message that is already present. The echo area is cleared immediately. */ void window_clear_echo_area () { free_echo_area (); display_update_one_window (the_echo_area); } /* Make a message appear in the echo area, built from FORMAT, ARG1 and ARG2. The arguments are treated similar to printf () arguments, but not all of printf () hair is present. The message appears immediately. If there was already a message appearing in the echo area, it is removed. */ void window_message_in_echo_area (format, arg1, arg2) char *format; void *arg1, *arg2; { free_echo_area (); echo_area_node = build_message_node (format, arg1, arg2); window_set_node_of_window (the_echo_area, echo_area_node); display_update_one_window (the_echo_area); } /* Place a temporary message in the echo area built from FORMAT, ARG1 and ARG2. The message appears immediately, but does not destroy any existing message. A future call to unmessage_in_echo_area () restores the old contents. */ static NODE **old_echo_area_nodes = (NODE **)NULL; static int old_echo_area_nodes_index = 0; static int old_echo_area_nodes_slots = 0; void message_in_echo_area (format, arg1, arg2) char *format; void *arg1, *arg2; { if (echo_area_node) { add_pointer_to_array (echo_area_node, old_echo_area_nodes_index, old_echo_area_nodes, old_echo_area_nodes_slots, 4, NODE *); } echo_area_node = (NODE *)NULL; window_message_in_echo_area (format, arg1, arg2); } void unmessage_in_echo_area () { free_echo_area (); if (old_echo_area_nodes_index) echo_area_node = old_echo_area_nodes[--old_echo_area_nodes_index]; window_set_node_of_window (the_echo_area, echo_area_node); display_update_one_window (the_echo_area); } /* A place to build a message. */ static char *message_buffer = (char *)NULL; static int message_buffer_index = 0; static int message_buffer_size = 0; /* Ensure that there is enough space to stuff LENGTH characters into MESSAGE_BUFFER. */ static void message_buffer_resize (length) int length; { if (!message_buffer) { message_buffer_size = length + 1; message_buffer = (char *)xmalloc (message_buffer_size); message_buffer_index = 0; } while (message_buffer_size <= message_buffer_index + length) message_buffer = (char *) xrealloc (message_buffer, message_buffer_size += 100 + (2 * length)); } /* Format MESSAGE_BUFFER with the results of printing FORMAT with ARG1 and ARG2. */ static void build_message_buffer (format, arg1, arg2) char *format; void *arg1, *arg2; { register int i, len; void *args[2]; int arg_index = 0; args[0] = arg1; args[1] = arg2; len = strlen (format); message_buffer_resize (len); for (i = 0; format[i]; i++) { if (format[i] != '%') { message_buffer[message_buffer_index++] = format[i]; len--; } else { char c; c = format[++i]; switch (c) { case '%': /* Insert a percent sign. */ message_buffer_resize (len + 1); message_buffer[message_buffer_index++] = '%'; break; case 's': /* Insert the current arg as a string. */ { char *string; int string_len; string = (char *)args[arg_index++]; string_len = strlen (string); message_buffer_resize (len + string_len); sprintf (message_buffer + message_buffer_index, "%s", string); message_buffer_index += string_len; } break; case 'd': /* Insert the current arg as an integer. */ { long long_val; int integer; long_val = (long)args[arg_index++]; integer = (int)long_val; message_buffer_resize (len + 32); sprintf (message_buffer + message_buffer_index, "%d", integer); message_buffer_index = strlen (message_buffer); } break; case 'c': /* Insert the current arg as a character. */ { long long_val; int character; long_val = (long)args[arg_index++]; character = (int)long_val; message_buffer_resize (len + 1); message_buffer[message_buffer_index++] = character; } break; default: abort (); } } } message_buffer[message_buffer_index] = '\0'; } /* Build a new node which has FORMAT printed with ARG1 and ARG2 as the contents. */ NODE * build_message_node (format, arg1, arg2) char *format; void *arg1, *arg2; { NODE *node; message_buffer_index = 0; build_message_buffer (format, arg1, arg2); node = message_buffer_to_node (); return (node); } /* Convert the contents of the message buffer to a node. */ NODE * message_buffer_to_node () { NODE *node; node = (NODE *)xmalloc (sizeof (NODE)); node->filename = (char *)NULL; node->parent = (char *)NULL; node->nodename = (char *)NULL; node->flags = 0; /* Make sure that this buffer ends with a newline. */ node->nodelen = 1 + strlen (message_buffer); node->contents = (char *)xmalloc (1 + node->nodelen); strcpy (node->contents, message_buffer); node->contents[node->nodelen - 1] = '\n'; node->contents[node->nodelen] = '\0'; return (node); } /* Useful functions can be called from outside of window.c. */ void initialize_message_buffer () { message_buffer_index = 0; } /* Print FORMAT with ARG1,2 to the end of the current message buffer. */ void printf_to_message_buffer (format, arg1, arg2) char *format; void *arg1, *arg2; { build_message_buffer (format, arg1, arg2); } /* Return the current horizontal position of the "cursor" on the most recently output message buffer line. */ int message_buffer_length_this_line () { register int i; if (!message_buffer_index) return (0); for (i = message_buffer_index; i && message_buffer[i - 1] != '\n'; i--); return (string_width (message_buffer + i, 0)); } /* Pad STRING to COUNT characters by inserting blanks. */ int pad_to (count, string) int count; char *string; { register int i; i = strlen (string); if (i >= count) string[i++] = ' '; else { while (i < count) string[i++] = ' '; } string[i] = '\0'; return (i); } texinfo-3.12/info/README0000664000175000017500000000237606475365561012217 0ustar ggInfo 2.0 is a complete rewrite of the original standalone Info I wrote in 1987, the first program I wrote for rms. That program was something like my second Unix program ever, and my die-hard machine language coding habits tended to show through. I found the original Info hard to read and maintain, and thus decided to write this one. The rewrite consists of about 12,000 lines of code written in about 12 days. I believe this version of Info to be in much better shape than the original Info. Info 2.0 is substantially different from its original standalone predecessor. It appears almost identical to the GNU Emacs version, but has the advantages of smaller size, ease of portability, and a built in library which can be used in other programs (to get or display documentation from Info files, for example). I eagerly await responses to this newer version of Info; comments on its portability, ease of use and user interface, code quality, and general usefulness are all of interest to me, and I will appreciate any comments that you would care to make. A full listing of the commands available in Info can be gotten by typing `?' while within an Info window. This produces a node in a window which can be viewed just like any Info node. --Brian Fox texinfo-3.12/info/info.h0000444000175000017500000001416006475630704012423 0ustar gg/* info.h -- Header file which includes all of the other headers. $Id: info.h,v 1.7 1998/02/27 21:36:04 karl Exp $ This file is part of GNU Info, a program for reading online documentation stored in Info format. Copyright (C) 1993, 97, 98 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ #if !defined (INFO_H) #define INFO_H /* We always want these, so why clutter up the compile command? */ #define HANDLE_MAN_PAGES #define NAMED_FUNCTIONS /* System dependencies. */ #include "system.h" /* Some of our other include files use these. */ typedef int Function (); typedef void VFunction (); typedef char *CFunction (); #include "filesys.h" #include "display.h" #include "session.h" #include "echo-area.h" #include "doc.h" #include "footnotes.h" #include "gc.h" #define info_toupper(x) (islower (x) ? toupper (x) : x) #define info_tolower(x) (isupper (x) ? tolower (x) : x) #if !defined (whitespace) # define whitespace(c) ((c == ' ') || (c == '\t')) #endif /* !whitespace */ #if !defined (whitespace_or_newline) # define whitespace_or_newline(c) (whitespace (c) || (c == '\n')) #endif /* !whitespace_or_newline */ /* Add POINTER to the list of pointers found in ARRAY. SLOTS is the number of slots that have already been allocated. INDEX is the index into the array where POINTER should be added. GROW is the number of slots to grow ARRAY by, in the case that it needs growing. TYPE is a cast of the type of object stored in ARRAY (e.g., NODE_ENTRY *. */ #define add_pointer_to_array(pointer, idx, array, slots, grow, type) \ do { \ if (idx + 2 >= slots) \ array = (type *)(xrealloc (array, (slots += grow) * sizeof (type))); \ array[idx++] = (type)pointer; \ array[idx] = (type)NULL; \ } while (0) #define maybe_free(x) do { if (x) free (x); } while (0) #if !defined (zero_mem) && defined (HAVE_MEMSET) # define zero_mem(mem, length) memset (mem, 0, length) #endif /* !zero_mem && HAVE_MEMSET */ #if !defined (zero_mem) && defined (HAVE_BZERO) # define zero_mem(mem, length) bzero (mem, length) #endif /* !zero_mem && HAVE_BZERO */ #if !defined (zero_mem) # define zero_mem(mem, length) \ do { \ register int zi; \ register unsigned char *place; \ \ place = (unsigned char *)mem; \ for (zi = 0; zi < length; zi++) \ place[zi] = 0; \ } while (0) #endif /* !zero_mem */ /* A structure associating the nodes visited in a particular window. */ typedef struct { WINDOW *window; /* The window that this list is attached to. */ NODE **nodes; /* Array of nodes visited in this window. */ int *pagetops; /* For each node in NODES, the pagetop. */ long *points; /* For each node in NODES, the point. */ int current; /* Index in NODES of the current node. */ int nodes_index; /* Index where to add the next node. */ int nodes_slots; /* Number of slots allocated to NODES. */ } INFO_WINDOW; /* Array of structures describing for each window which nodes have been visited in that window. */ extern INFO_WINDOW **info_windows; /* For handling errors. If you initialize the window system, you should also set info_windows_initialized_p to non-zero. It is used by the info_error () function to determine how to format and output errors. */ extern int info_windows_initialized_p; /* Non-zero if an error message has been printed. */ extern int info_error_was_printed; /* Non-zero means ring terminal bell on errors. */ extern int info_error_rings_bell_p; /* Print FORMAT with ARG1 and ARG2. If the window system was initialized, then the message is printed in the echo area. Otherwise, a message is output to stderr. */ extern void info_error (); /* The version numbers of Info. */ extern int info_major_version, info_minor_version; /* How to get the version string for this version of Info. Returns something similar to "2.11". */ extern char *version_string (); /* Error message defines. */ #define CANT_FIND_NODE _("Cannot find the node \"%s\".") #define CANT_FILE_NODE _("Cannot find the node \"(%s)%s\".") #define CANT_FIND_WIND _("Cannot find a window!") #define CANT_FIND_POINT _("Point doesn't appear within this window's node!") #define CANT_KILL_LAST _("Cannot delete the last window.") #define NO_MENU_NODE _("No menu in this node.") #define NO_FOOT_NODE _("No footnotes in this node.") #define NO_XREF_NODE _("No cross references in this node.") #define NO_POINTER _("No \"%s\" pointer for this node.") #define UNKNOWN_COMMAND _("Unknown Info command `%c'. `?' for help.") #define TERM_TOO_DUMB _("Terminal type \"%s\" is not smart enough to run Info.") #define AT_NODE_BOTTOM _("You are already at the last page of this node.") #define AT_NODE_TOP _("You are already at the first page of this node.") #define ONE_WINDOW _("Only one window.") #define WIN_TOO_SMALL _("Resulting window would be too small.") #define CANT_MAKE_HELP \ _("There isn't enough room to make a help window. Please delete a window.") /* Found in info-utils.c. */ extern char *filename_non_directory (); #if !defined (BUILDING_LIBRARY) /* Found in session.c */ extern int info_windows_initialized_p; /* Found in window.c. */ extern void message_in_echo_area (), unmessage_in_echo_area (); #endif /* !BUILDING_LIBRARY */ #endif /* !INFO_H */ texinfo-3.12/info/variables.c0000444000175000017500000001771206363677360013446 0ustar gg/* variables.c -- How to manipulate user visible variables in Info. $Id: variables.c,v 1.5 1997/07/18 14:34:23 karl Exp $ This file is part of GNU Info, a program for reading online documentation stored in Info format. Copyright (C) 1993, 97 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ #include "info.h" #include "variables.h" /* **************************************************************** */ /* */ /* User Visible Variables in Info */ /* */ /* **************************************************************** */ /* Choices used by the completer when reading a zero/non-zero value for a variable. */ static char *on_off_choices[] = { "Off", "On", (char *)NULL }; VARIABLE_ALIST info_variables[] = { { "automatic-footnotes", N_("When \"On\", footnotes appear and disappear automatically"), &auto_footnotes_p, (char **)on_off_choices }, { "automatic-tiling", N_("When \"On\", creating or deleting a window resizes other windows"), &auto_tiling_p, (char **)on_off_choices }, { "visible-bell", N_("When \"On\", flash the screen instead of ringing the bell"), &terminal_use_visible_bell_p, (char **)on_off_choices }, { "errors-ring-bell", N_("When \"On\", errors cause the bell to ring"), &info_error_rings_bell_p, (char **)on_off_choices }, { "gc-compressed-files", N_("When \"On\", Info garbage collects files which had to be uncompressed"), &gc_compressed_files, (char **)on_off_choices }, { "show-index-match", N_("When \"On\", the portion of the matched search string is highlighted"), &show_index_match, (char **)on_off_choices }, { "scroll-behaviour", N_("Controls what happens when scrolling is requested at the end of a node"), &info_scroll_behaviour, (char **)info_scroll_choices }, { "scroll-step", N_("The number lines to scroll when the cursor moves out of the window"), &window_scroll_step, (char **)NULL }, { "ISO-Latin", N_("When \"On\", Info accepts and displays ISO Latin characters"), &ISO_Latin_p, (char **)on_off_choices }, { (char *)NULL, (char *)NULL, (int *)NULL, (char **)NULL } }; DECLARE_INFO_COMMAND (describe_variable, _("Explain the use of a variable")) { VARIABLE_ALIST *var; char *description; /* Get the variable's name. */ var = read_variable_name (_("Describe variable: "), window); if (!var) return; description = (char *)xmalloc (20 + strlen (var->name) + strlen (_(var->doc))); if (var->choices) sprintf (description, "%s (%s): %s.", var->name, var->choices[*(var->value)], _(var->doc)); else sprintf (description, "%s (%d): %s.", var->name, *(var->value), _(var->doc)); window_message_in_echo_area ("%s", description); free (description); } DECLARE_INFO_COMMAND (set_variable, _("Set the value of an Info variable")) { VARIABLE_ALIST *var; char *line; /* Get the variable's name and value. */ var = read_variable_name (_("Set variable: "), window); if (!var) return; /* Read a new value for this variable. */ { char prompt[100]; if (!var->choices) { int potential_value; if (info_explicit_arg || count != 1) potential_value = count; else potential_value = *(var->value); sprintf (prompt, _("Set %s to value (%d): "), var->name, potential_value); line = info_read_in_echo_area (active_window, prompt); /* If no error was printed, clear the echo area. */ if (!info_error_was_printed) window_clear_echo_area (); /* User aborted? */ if (!line) return; /* If the user specified a value, get that, otherwise, we are done. */ canonicalize_whitespace (line); if (*line) *(var->value) = atoi (line); else *(var->value) = potential_value; free (line); } else { register int i; REFERENCE **array = (REFERENCE **)NULL; int array_index = 0; int array_slots = 0; for (i = 0; var->choices[i]; i++) { REFERENCE *entry; entry = (REFERENCE *)xmalloc (sizeof (REFERENCE)); entry->label = xstrdup (var->choices[i]); entry->nodename = (char *)NULL; entry->filename = (char *)NULL; add_pointer_to_array (entry, array_index, array, array_slots, 10, REFERENCE *); } sprintf (prompt, _("Set %s to value (%s): "), var->name, var->choices[*(var->value)]); /* Ask the completer to read a variable value for us. */ line = info_read_completing_in_echo_area (window, prompt, array); info_free_references (array); if (!echo_area_is_active) window_clear_echo_area (); /* User aborted? */ if (!line) { info_abort_key (active_window, 0, 0); return; } /* User accepted default choice? If so, no change. */ if (!*line) { free (line); return; } /* Find the choice in our list of choices. */ for (i = 0; var->choices[i]; i++) if (strcmp (var->choices[i], line) == 0) break; if (var->choices[i]) *(var->value) = i; } } } /* Read the name of an Info variable in the echo area and return the address of a VARIABLE_ALIST member. A return value of NULL indicates that no variable could be read. */ VARIABLE_ALIST * read_variable_name (prompt, window) char *prompt; WINDOW *window; { register int i; char *line; REFERENCE **variables; /* Get the completion array of variable names. */ variables = make_variable_completions_array (); /* Ask the completer to read a variable for us. */ line = info_read_completing_in_echo_area (window, prompt, variables); info_free_references (variables); if (!echo_area_is_active) window_clear_echo_area (); /* User aborted? */ if (!line) { info_abort_key (active_window, 0, 0); return ((VARIABLE_ALIST *)NULL); } /* User accepted "default"? (There is none.) */ if (!*line) { free (line); return ((VARIABLE_ALIST *)NULL); } /* Find the variable in our list of variables. */ for (i = 0; info_variables[i].name; i++) if (strcmp (info_variables[i].name, line) == 0) break; if (!info_variables[i].name) return ((VARIABLE_ALIST *)NULL); else return (&(info_variables[i])); } /* Make an array of REFERENCE which actually contains the names of the variables available in Info. */ REFERENCE ** make_variable_completions_array () { register int i; REFERENCE **array = (REFERENCE **)NULL; int array_index = 0, array_slots = 0; for (i = 0; info_variables[i].name; i++) { REFERENCE *entry; entry = (REFERENCE *) xmalloc (sizeof (REFERENCE)); entry->label = xstrdup (info_variables[i].name); entry->nodename = (char *)NULL; entry->filename = (char *)NULL; add_pointer_to_array (entry, array_index, array, array_slots, 200, REFERENCE *); } return (array); } texinfo-3.12/info/infodoc.c0000444000175000017500000005435306366212731013107 0ustar gg/* infodoc.c -- Functions which build documentation nodes. $Id: infodoc.c,v 1.4 1997/07/25 21:08:40 karl Exp $ Copyright (C) 1993, 97 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ #include "info.h" /* Normally we do not define HELP_NODE_GETS_REGENERATED because the contents of the help node currently can never change once an info session has been started. You should consider defining this in the case that you place information about dynamic variables in the help text. When that happens, the contents of the help node will change dependent on the value of those variables, and the user will expect to see those changes. */ /* #define HELP_NODE_GETS_REGENERATED 1 */ /* **************************************************************** */ /* */ /* Info Help Windows */ /* */ /* **************************************************************** */ /* The name of the node used in the help window. */ static char *info_help_nodename = "*Info Help*"; /* A node containing printed key bindings and their documentation. */ static NODE *internal_info_help_node = (NODE *)NULL; /* A pointer to the contents of the help node. */ static char *internal_info_help_node_contents = (char *)NULL; /* The static text which appears in the internal info help node. */ static char *info_internal_help_text[] = { N_ ("Basic Commands in Info Windows"), "******************************", "", " h Invoke the Info tutorial.", " CTRL-x 0 Quit this help.", " q Quit Info altogether.", "", "Selecting other nodes:", "----------------------", " n Move to the \"next\" node of this node.", " p Move to the \"previous\" node of this node.", " u Move \"up\" from this node.", " m Pick menu item specified by name.", " Picking a menu item causes another node to be selected.", " f Follow a cross reference. Reads name of reference.", " l Move to the last node seen in this window.", " d Move to the `directory' node. Equivalent to `g(DIR)'.", "", "Moving within a node:", "---------------------", " SPC Scroll forward a page.", " DEL Scroll backward a page.", " b Go to the beginning of this node.", " e Go to the end of this node.", "", "Other commands:", "--------------------", " 1 Pick first item in node's menu.", " 2-9 Pick second ... ninth item in node's menu.", " 0 Pick last item in node's menu.", " g Move to node specified by name.", " You may include a filename as well, as in (FILENAME)NODENAME.", " s Search through this Info file for a specified string,", " and select the node in which the next occurrence is found.", NULL }; static char *where_is (), *where_is_internal (); void dump_map_to_message_buffer (prefix, map) char *prefix; Keymap map; { register int i; for (i = 0; i < 256; i++) { if (map[i].type == ISKMAP) { char *new_prefix, *keyname; keyname = pretty_keyname (i); new_prefix = (char *) xmalloc (3 + strlen (prefix) + strlen (keyname)); sprintf (new_prefix, "%s%s%s ", prefix, *prefix ? " " : "", keyname); dump_map_to_message_buffer (new_prefix, (Keymap)map[i].function); free (new_prefix); } else if (map[i].function) { register int last; char *doc, *name; doc = function_documentation (map[i].function); name = function_name (map[i].function); if (!*doc) continue; /* Find out if there is a series of identical functions, as in ea_insert (). */ for (last = i + 1; last < 256; last++) if ((map[last].type != ISFUNC) || (map[last].function != map[i].function)) break; if (last - 1 != i) { printf_to_message_buffer ("%s%s .. ", prefix, pretty_keyname (i)); printf_to_message_buffer ("%s%s\t", prefix, pretty_keyname (last - 1)); i = last - 1; } else printf_to_message_buffer ("%s%s\t", prefix, pretty_keyname (i)); #if defined (NAMED_FUNCTIONS) /* Print the name of the function, and some padding before the documentation string is printed. */ { int length_so_far; int desired_doc_start = 40; /* Must be multiple of 8. */ printf_to_message_buffer ("(%s)", name); length_so_far = message_buffer_length_this_line (); if ((desired_doc_start + strlen (doc)) >= the_screen->width) printf_to_message_buffer ("\n "); else { while (length_so_far < desired_doc_start) { printf_to_message_buffer ("\t"); length_so_far += character_width ('\t', length_so_far); } } } #endif /* NAMED_FUNCTIONS */ printf_to_message_buffer ("%s\n", doc); } } } /* How to create internal_info_help_node. */ static void create_internal_info_help_node () { register int i; char *contents = (char *)NULL; NODE *node; #if !defined (HELP_NODE_GETS_REGENERATED) if (internal_info_help_node_contents) contents = internal_info_help_node_contents; #endif /* !HELP_NODE_GETS_REGENERATED */ if (!contents) { int printed_one_mx = 0; initialize_message_buffer (); for (i = 0; info_internal_help_text[i]; i++) printf_to_message_buffer ("%s\n", info_internal_help_text[i]); printf_to_message_buffer ("---------------------\n\n"); printf_to_message_buffer ("The current search path is:\n"); printf_to_message_buffer (" \"%s\"\n", infopath); printf_to_message_buffer ("---------------------\n\n"); printf_to_message_buffer ("Commands available in Info windows:\n\n"); dump_map_to_message_buffer ("", info_keymap); printf_to_message_buffer ("---------------------\n\n"); printf_to_message_buffer ("Commands available in the echo area:\n\n"); dump_map_to_message_buffer ("", echo_area_keymap); #if defined (NAMED_FUNCTIONS) /* Get a list of the M-x commands which have no keystroke equivs. */ for (i = 0; function_doc_array[i].func; i++) { VFunction *func = function_doc_array[i].func; if ((!where_is_internal (info_keymap, func)) && (!where_is_internal (echo_area_keymap, func))) { if (!printed_one_mx) { printf_to_message_buffer ("---------------------\n\n"); printf_to_message_buffer (_("The following commands can only be invoked via M-x:\n\n")); printed_one_mx = 1; } printf_to_message_buffer ("M-x %s\n %s\n", function_doc_array[i].func_name, replace_in_documentation (function_doc_array[i].doc)); } } if (printed_one_mx) printf_to_message_buffer ("\n"); #endif /* NAMED_FUNCTIONS */ printf_to_message_buffer ("%s", replace_in_documentation (_("--- Use `\\[history-node]' or `\\[kill-node]' to exit ---\n"))); node = message_buffer_to_node (); internal_info_help_node_contents = node->contents; } else { /* We already had the right contents, so simply use them. */ node = build_message_node ("", 0, 0); free (node->contents); node->contents = contents; node->nodelen = 1 + strlen (contents); } internal_info_help_node = node; /* Do not GC this node's contents. It never changes, and we never need to delete it once it is made. If you change some things (such as placing information about dynamic variables in the help text) then you will need to allow the contents to be gc'd, and you will have to arrange to always regenerate the help node. */ #if defined (HELP_NODE_GETS_REGENERATED) add_gcable_pointer (internal_info_help_node->contents); #endif name_internal_node (internal_info_help_node, info_help_nodename); /* Even though this is an internal node, we don't want the window system to treat it specially. So we turn off the internalness of it here. */ internal_info_help_node->flags &= ~N_IsInternal; } /* Return a window which is the window showing help in this Info. */ static WINDOW * info_find_or_create_help_window () { WINDOW *help_window, *eligible, *window; eligible = (WINDOW *)NULL; help_window = get_internal_info_window (info_help_nodename); /* If we couldn't find the help window, then make it. */ if (!help_window) { int max = 0; for (window = windows; window; window = window->next) { if (window->height > max) { max = window->height; eligible = window; } } if (!eligible) return ((WINDOW *)NULL); } #if !defined (HELP_NODE_GETS_REGENERATED) else return (help_window); #endif /* !HELP_NODE_GETS_REGENERATED */ /* Make sure that we have a node containing the help text. */ create_internal_info_help_node (); /* Either use the existing window to display the help node, or create a new window if there was no existing help window. */ if (!help_window) { /* Split the largest window into 2 windows, and show the help text in that window. */ if (eligible->height > 30) { active_window = eligible; help_window = window_make_window (internal_info_help_node); } else { set_remembered_pagetop_and_point (active_window); window_set_node_of_window (active_window, internal_info_help_node); help_window = active_window; } } else { /* Case where help node always gets regenerated, and we have an existing window in which to place the node. */ if (active_window != help_window) { set_remembered_pagetop_and_point (active_window); active_window = help_window; } window_set_node_of_window (active_window, internal_info_help_node); } remember_window_and_node (help_window, help_window->node); return (help_window); } /* Create or move to the help window. */ DECLARE_INFO_COMMAND (info_get_help_window, _("Display help message")) { WINDOW *help_window; help_window = info_find_or_create_help_window (); if (help_window) { active_window = help_window; active_window->flags |= W_UpdateWindow; } else { info_error (CANT_MAKE_HELP); } } /* Show the Info help node. This means that the "info" file is installed where it can easily be found on your system. */ DECLARE_INFO_COMMAND (info_get_info_help_node, _("Visit Info node `(info)Help'")) { NODE *node; char *nodename; /* If there is a window on the screen showing the node "(info)Help" or the node "(info)Help-Small-Screen", simply select that window. */ { WINDOW *win; for (win = windows; win; win = win->next) { if (win->node && win->node->filename && (strcasecmp (filename_non_directory (win->node->filename), "info") == 0) && ((strcmp (win->node->nodename, "Help") == 0) || (strcmp (win->node->nodename, "Help-Small-Screen") == 0))) { active_window = win; return; } } } /* If the current window is small, show the small screen help. */ if (active_window->height < 24) nodename = "Help-Small-Screen"; else nodename = "Help"; /* Try to get the info file for Info. */ node = info_get_node ("Info", nodename); if (!node) { if (info_recent_file_error) info_error (info_recent_file_error); else info_error (CANT_FILE_NODE, "Info", nodename); } else { /* If the current window is very large (greater than 45 lines), then split it and show the help node in another window. Otherwise, use the current window. */ if (active_window->height > 45) active_window = window_make_window (node); else { set_remembered_pagetop_and_point (active_window); window_set_node_of_window (active_window, node); } remember_window_and_node (active_window, node); } } /* **************************************************************** */ /* */ /* Groveling Info Keymaps and Docs */ /* */ /* **************************************************************** */ /* Return the documentation associated with the Info command FUNCTION. */ char * function_documentation (function) VFunction *function; { register int i; for (i = 0; function_doc_array[i].func; i++) if (function == function_doc_array[i].func) break; return (replace_in_documentation (function_doc_array[i].doc)); } #if defined (NAMED_FUNCTIONS) /* Return the user-visible name of the function associated with the Info command FUNCTION. */ char * function_name (function) VFunction *function; { register int i; for (i = 0; function_doc_array[i].func; i++) if (function == function_doc_array[i].func) break; return (function_doc_array[i].func_name); } /* Return a pointer to the function named NAME. */ VFunction * named_function (name) char *name; { register int i; for (i = 0; function_doc_array[i].func; i++) if (strcmp (function_doc_array[i].func_name, name) == 0) break; return (function_doc_array[i].func); } #endif /* NAMED_FUNCTIONS */ /* Return the documentation associated with KEY in MAP. */ char * key_documentation (key, map) char key; Keymap map; { VFunction *function = map[key].function; if (function) return (function_documentation (function)); else return ((char *)NULL); } DECLARE_INFO_COMMAND (describe_key, _("Print documentation for KEY")) { char keyname[50]; int keyname_index = 0; unsigned char keystroke; char *rep; Keymap map; keyname[0] = '\0'; map = window->keymap; while (1) { message_in_echo_area (_("Describe key: %s"), keyname); keystroke = info_get_input_char (); unmessage_in_echo_area (); if (Meta_p (keystroke) && (!ISO_Latin_p || key < 160)) { if (map[ESC].type != ISKMAP) { window_message_in_echo_area (_("ESC %s is undefined."), pretty_keyname (UnMeta (keystroke))); return; } strcpy (keyname + keyname_index, "ESC "); keyname_index = strlen (keyname); keystroke = UnMeta (keystroke); map = (Keymap)map[ESC].function; } /* Add the printed representation of KEYSTROKE to our keyname. */ rep = pretty_keyname (keystroke); strcpy (keyname + keyname_index, rep); keyname_index = strlen (keyname); if (map[keystroke].function == (VFunction *)NULL) { message_in_echo_area (_("%s is undefined."), keyname); return; } else if (map[keystroke].type == ISKMAP) { map = (Keymap)map[keystroke].function; strcat (keyname, " "); keyname_index = strlen (keyname); continue; } else { char *message, *fundoc, *funname = ""; #if defined (NAMED_FUNCTIONS) funname = function_name (map[keystroke].function); #endif /* NAMED_FUNCTIONS */ fundoc = function_documentation (map[keystroke].function); message = (char *)xmalloc (10 + strlen (keyname) + strlen (fundoc) + strlen (funname)); #if defined (NAMED_FUNCTIONS) sprintf (message, "%s (%s): %s.", keyname, funname, fundoc); #else sprintf (message, _("%s is defined to %s."), keyname, fundoc); #endif /* !NAMED_FUNCTIONS */ window_message_in_echo_area ("%s", message); free (message); break; } } } /* How to get the pretty printable name of a character. */ static char rep_buffer[30]; char * pretty_keyname (key) unsigned char key; { char *rep; if (Meta_p (key)) { char temp[20]; rep = pretty_keyname (UnMeta (key)); sprintf (temp, "ESC %s", rep); strcpy (rep_buffer, temp); rep = rep_buffer; } else if (Control_p (key)) { switch (key) { case '\n': rep = "LFD"; break; case '\t': rep = "TAB"; break; case '\r': rep = "RET"; break; case ESC: rep = "ESC"; break; default: sprintf (rep_buffer, "C-%c", UnControl (key)); rep = rep_buffer; } } else { switch (key) { case ' ': rep = "SPC"; break; case DEL: rep = "DEL"; break; default: rep_buffer[0] = key; rep_buffer[1] = '\0'; rep = rep_buffer; } } return (rep); } /* Replace the names of functions with the key that invokes them. */ char * replace_in_documentation (string) char *string; { register int i, start, next; static char *result = (char *)NULL; maybe_free (result); result = (char *)xmalloc (1 + strlen (string)); i = next = start = 0; /* Skip to the beginning of a replaceable function. */ for (i = start; string[i]; i++) { /* Is this the start of a replaceable function name? */ if (string[i] == '\\' && string[i + 1] == '[') { char *fun_name, *rep; VFunction *function; /* Copy in the old text. */ strncpy (result + next, string + start, i - start); next += (i - start); start = i + 2; /* Move to the end of the function name. */ for (i = start; string[i] && (string[i] != ']'); i++); fun_name = (char *)xmalloc (1 + i - start); strncpy (fun_name, string + start, i - start); fun_name[i - start] = '\0'; /* Find a key which invokes this function in the info_keymap. */ function = named_function (fun_name); /* If the internal documentation string fails, there is a serious problem with the associated command's documentation. We croak so that it can be fixed immediately. */ if (!function) abort (); rep = where_is (info_keymap, function); strcpy (result + next, rep); next = strlen (result); start = i; if (string[i]) start++; } } strcpy (result + next, string + start); return (result); } /* Return a string of characters which could be typed from the keymap MAP to invoke FUNCTION. */ static char *where_is_rep = (char *)NULL; static int where_is_rep_index = 0; static int where_is_rep_size = 0; static char * where_is (map, function) Keymap map; VFunction *function; { char *rep; if (!where_is_rep_size) where_is_rep = (char *)xmalloc (where_is_rep_size = 100); where_is_rep_index = 0; rep = where_is_internal (map, function); /* If it couldn't be found, return "M-x Foo". */ if (!rep) { char *name; name = function_name (function); if (name) sprintf (where_is_rep, "M-x %s", name); rep = where_is_rep; } return (rep); } /* Return the printed rep of FUNCTION as found in MAP, or NULL. */ static char * where_is_internal (map, function) Keymap map; VFunction *function; { register int i; /* If the function is directly invokable in MAP, return the representation of that keystroke. */ for (i = 0; i < 256; i++) if ((map[i].type == ISFUNC) && map[i].function == function) { sprintf (where_is_rep + where_is_rep_index, "%s", pretty_keyname (i)); return (where_is_rep); } /* Okay, search subsequent maps for this function. */ for (i = 0; i < 256; i++) { if (map[i].type == ISKMAP) { int saved_index = where_is_rep_index; char *rep; sprintf (where_is_rep + where_is_rep_index, "%s ", pretty_keyname (i)); where_is_rep_index = strlen (where_is_rep); rep = where_is_internal ((Keymap)map[i].function, function); if (rep) return (where_is_rep); where_is_rep_index = saved_index; } } return ((char *)NULL); } extern char *read_function_name (); DECLARE_INFO_COMMAND (info_where_is, "Show what to type to execute a given command") { char *command_name; command_name = read_function_name (_("Where is command: "), window); if (!command_name) { info_abort_key (active_window, count, key); return; } if (*command_name) { VFunction *function; function = named_function (command_name); if (function) { char *location; location = where_is (active_window->keymap, function); if (!location) { info_error (_("`%s' is not on any keys"), command_name); } else { if (strncmp (location, "M-x ", 4) == 0) window_message_in_echo_area (_("%s can only be invoked via %s."), command_name, location); else window_message_in_echo_area (_("%s can be invoked via %s."), command_name, location); } } else info_error (_("There is no function named `%s'"), command_name); } free (command_name); } texinfo-3.12/info/doc.c0000664000175000017500000002112506477046146012236 0ustar gg/* doc.c -- Generated structure containing function names and doc strings. This file was automatically made from various source files with the command "./makedoc". DO NOT EDIT THIS FILE, only "./makedoc.c". Source files groveled to make this file include: ./session.c ./echo-area.c ./infodoc.c ./m-x.c ./indices.c ./nodemenu.c ./footnotes.c ./variables.c An entry in the array FUNCTION_DOC_ARRAY is made for each command found in the above files; each entry consists of a function pointer, a string which is the user-visible name of the function, and a string which documents its purpose. */ #include "doc.h" #include "funs.h" FUNCTION_DOC function_doc_array[] = { /* Commands found in "./session.c". */ { info_next_line, "next-line", "Move down to the next line" }, { info_prev_line, "prev-line", "Move up to the previous line" }, { info_end_of_line, "end-of-line", "Move to the end of the line" }, { info_beginning_of_line, "beginning-of-line", "Move to the start of the line" }, { info_forward_char, "forward-char", "Move forward a character" }, { info_backward_char, "backward-char", "Move backward a character" }, { info_forward_word, "forward-word", "Move forward a word" }, { info_backward_word, "backward-word", "Move backward a word" }, { info_global_next_node, "global-next-node", "Move forwards or down through node structure" }, { info_global_prev_node, "global-prev-node", "Move backwards or up through node structure" }, { info_scroll_forward, "scroll-forward", "Scroll forward in this window" }, { info_scroll_backward, "scroll-backward", "Scroll backward in this window" }, { info_beginning_of_node, "beginning-of-node", "Move to the start of this node" }, { info_end_of_node, "end-of-node", "Move to the end of this node" }, { info_next_window, "next-window", "Select the next window" }, { info_prev_window, "prev-window", "Select the previous window" }, { info_split_window, "split-window", "Split the current window" }, { info_delete_window, "delete-window", "Delete the current window" }, { info_keep_one_window, "keep-one-window", "Delete all other windows" }, { info_scroll_other_window, "scroll-other-window", "Scroll the other window" }, { info_grow_window, "grow-window", "Grow (or shrink) this window" }, { info_tile_windows, "tile-windows", "Divide the available screen space among the visible windows" }, { info_toggle_wrap, "toggle-wrap", "Toggle the state of line wrapping in the current window" }, { info_next_node, "next-node", "Select the `Next' node" }, { info_prev_node, "prev-node", "Select the `Prev' node" }, { info_up_node, "up-node", "Select the `Up' node" }, { info_last_node, "last-node", "Select the last node in this file" }, { info_first_node, "first-node", "Select the first node in this file" }, { info_last_menu_item, "last-menu-item", "Select the last item in this node's menu" }, { info_menu_digit, "menu-digit", "Select this menu item" }, { info_menu_item, "menu-item", "Read a menu item and select its node" }, { info_xref_item, "xref-item", "Read a footnote or cross reference and select its node" }, { info_find_menu, "find-menu", "Move to the start of this node's menu" }, { info_visit_menu, "visit-menu", "Visit as many menu items at once as possible" }, { info_goto_node, "goto-node", "Read a node name and select it" }, { info_man, "man", "Read a manpage reference and select it" }, { info_top_node, "top-node", "Select the node `Top' in this file" }, { info_dir_node, "dir-node", "Select the node `(dir)'" }, { info_history_node, "history-node", "Select the most recently selected node" }, { info_kill_node, "kill-node", "Kill this node" }, { info_view_file, "view-file", "Read the name of a file and select it" }, { info_print_node, "print-node", "Pipe the contents of this node through INFO_PRINT_COMMAND" }, { info_search, "search", "Read a string and search for it" }, { isearch_forward, "isearch-forward", "Search interactively for a string as you type it" }, { isearch_backward, "isearch-backward", "Search interactively for a string as you type it" }, { info_move_to_prev_xref, "move-to-prev-xref", "Move to the previous cross reference" }, { info_move_to_next_xref, "move-to-next-xref", "Move to the next cross reference" }, { info_select_reference_this_line, "select-reference-this-line", "Select reference or menu item appearing on this line" }, { info_abort_key, "abort-key", "Cancel current operation" }, { info_move_to_window_line, "move-to-window-line", "Move to the cursor to a specific line of the window" }, { info_redraw_display, "redraw-display", "Redraw the display" }, { info_quit, "quit", "Quit using Info" }, { info_do_lowercase_version, "do-lowercase-version", "" }, { info_add_digit_to_numeric_arg, "add-digit-to-numeric-arg", "Add this digit to the current numeric argument" }, { info_universal_argument, "universal-argument", "Start (or multiply by 4) the current numeric argument" }, { info_numeric_arg_digit_loop, "numeric-arg-digit-loop", "Internally used by \\[universal-argument]" }, /* Commands found in "./echo-area.c". */ { ea_forward, "echo-area-forward", "Move forward a character" }, { ea_backward, "echo-area-backward", "Move backward a character" }, { ea_beg_of_line, "echo-area-beg-of-line", "Move to the start of this line" }, { ea_end_of_line, "echo-area-end-of-line", "Move to the end of this line" }, { ea_forward_word, "echo-area-forward-word", "Move forward a word" }, { ea_backward_word, "echo-area-backward-word", "Move backward a word" }, { ea_delete, "echo-area-delete", "Delete the character under the cursor" }, { ea_rubout, "echo-area-rubout", "Delete the character behind the cursor" }, { ea_abort, "echo-area-abort", "Cancel or quit operation" }, { ea_newline, "echo-area-newline", "Accept (or force completion of) this line" }, { ea_quoted_insert, "echo-area-quoted-insert", "Insert next character verbatim" }, { ea_insert, "echo-area-insert", "Insert this character" }, { ea_tab_insert, "echo-area-tab-insert", "Insert a TAB character" }, { ea_transpose_chars, "echo-area-transpose-chars", "Transpose characters at point" }, { ea_yank, "echo-area-yank", "Yank back the contents of the last kill" }, { ea_yank_pop, "echo-area-yank-pop", "Yank back a previous kill" }, { ea_kill_line, "echo-area-kill-line", "Kill to the end of the line" }, { ea_backward_kill_line, "echo-area-backward-kill-line", "Kill to the beginning of the line" }, { ea_kill_word, "echo-area-kill-word", "Kill the word following the cursor" }, { ea_backward_kill_word, "echo-area-backward-kill-word", "Kill the word preceding the cursor" }, { ea_possible_completions, "echo-area-possible-completions", "List possible completions" }, { ea_complete, "echo-area-complete", "Insert completion" }, { ea_scroll_completions_window, "echo-area-scroll-completions-window", "Scroll the completions window" }, /* Commands found in "./infodoc.c". */ { info_get_help_window, "get-help-window", "Display help message" }, { info_get_info_help_node, "get-info-help-node", "Visit Info node `(info)Help'" }, { describe_key, "describe-key", "Print documentation for KEY" }, { info_where_is, "where-is", "Show what to type to execute a given command" }, /* Commands found in "./m-x.c". */ { describe_command, "describe-command", "Read the name of an Info command and describe it" }, { info_execute_command, "execute-command", "Read a command name in the echo area and execute it" }, { set_screen_height, "set-screen-height", "Set the height of the displayed window" }, /* Commands found in "./indices.c". */ { info_index_search, "index-search", "Look up a string in the index for this file" }, { info_next_index_match, "next-index-match", "Go to the next matching index item from the last `\\[index-search]' command" }, { info_index_apropos, "index-apropos", "Grovel all known info file's indices for a string and build a menu" }, /* Commands found in "./nodemenu.c". */ { list_visited_nodes, "list-visited-nodes", "Make a window containing a menu of all of the currently visited nodes" }, { select_visited_node, "select-visited-node", "Select a node which has been previously visited in a visible window" }, /* Commands found in "./footnotes.c". */ { info_show_footnotes, "show-footnotes", "Show the footnotes associated with this node in another window" }, /* Commands found in "./variables.c". */ { describe_variable, "describe-variable", "Explain the use of a variable" }, { set_variable, "set-variable", "Set the value of an Info variable" }, { (VFunction *)NULL, (char *)NULL, (char *)NULL } }; texinfo-3.12/info/infomap.c0000444000175000017500000003030206370173615013105 0ustar gg/* infomap.c -- Keymaps for Info. $Id: infomap.c,v 1.7 1997/07/31 20:37:32 karl Exp $ Copyright (C) 1993, 97 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ #include "info.h" #include "infomap.h" #include "funs.h" #include "terminal.h" /* Return a new keymap which has all the uppercase letters mapped to run the function info_do_lowercase_version (). */ Keymap keymap_make_keymap () { register int i; Keymap keymap; keymap = (Keymap)xmalloc (256 * sizeof (KEYMAP_ENTRY)); for (i = 0; i < 256; i++) { keymap[i].type = ISFUNC; keymap[i].function = (VFunction *)NULL; } for (i = 'A'; i < ('Z' + 1); i++) { keymap[i].type = ISFUNC; keymap[i].function = info_do_lowercase_version; } return (keymap); } /* Return a new keymap which is a copy of MAP. */ Keymap keymap_copy_keymap (map) Keymap map; { register int i; Keymap keymap; keymap = keymap_make_keymap (); for (i = 0; i < 256; i++) { keymap[i].type = map[i].type; keymap[i].function = map[i].function; } return (keymap); } /* Free the keymap and it's descendents. */ void keymap_discard_keymap (map) Keymap (map); { register int i; if (!map) return; for (i = 0; i < 256; i++) { switch (map[i].type) { case ISFUNC: break; case ISKMAP: keymap_discard_keymap ((Keymap)map[i].function); break; } } } /* Conditionally bind key sequence. */ int keymap_bind_keyseq (map, keyseq, keyentry) Keymap map; const unsigned char *keyseq; KEYMAP_ENTRY *keyentry; { register Keymap m = map; register const unsigned char *s = keyseq; register int c; if (s == NULL || *s == '\0') return 0; while ((c = *s++) != '\0') { switch (m[c].type) { case ISFUNC: if (!(m[c].function == NULL || (m != map && m[c].function == info_do_lowercase_version))) return 0; if (*s != '\0') { m[c].type = ISKMAP; m[c].function = (VFunction *)keymap_make_keymap (); } break; case ISKMAP: if (*s == '\0') return 0; break; } if (*s != '\0') { m = (Keymap)m[c].function; } else { m[c] = *keyentry; } } return 1; } /* Initialize the standard info keymaps. */ Keymap info_keymap = (Keymap)NULL; Keymap echo_area_keymap = (Keymap)NULL; void initialize_info_keymaps () { register int i; Keymap map; if (!info_keymap) { info_keymap = keymap_make_keymap (); info_keymap[ESC].type = ISKMAP; info_keymap[ESC].function = (VFunction *)keymap_make_keymap (); info_keymap[Control ('x')].type = ISKMAP; info_keymap[Control ('x')].function = (VFunction *)keymap_make_keymap (); echo_area_keymap = keymap_make_keymap (); echo_area_keymap[ESC].type = ISKMAP; echo_area_keymap[ESC].function = (VFunction *)keymap_make_keymap (); echo_area_keymap[Control ('x')].type = ISKMAP; echo_area_keymap[Control ('x')].function = (VFunction *)keymap_make_keymap (); } /* Bind numeric arg functions for both echo area and info window maps. */ for (i = '0'; i < '9' + 1; i++) { ((Keymap) info_keymap[ESC].function)[i].function = ((Keymap) echo_area_keymap[ESC].function)[i].function = info_add_digit_to_numeric_arg; } ((Keymap) info_keymap[ESC].function)['-'].function = ((Keymap) echo_area_keymap[ESC].function)['-'].function = info_add_digit_to_numeric_arg; /* Bind the echo area routines. */ map = echo_area_keymap; /* Bind the echo area insert routines. */ for (i = 0; i < 160; i++) if (isprint (i)) map[i].function = ea_insert; map[Control ('a')].function = ea_beg_of_line; map[Control ('b')].function = ea_backward; map[Control ('d')].function = ea_delete; map[Control ('e')].function = ea_end_of_line; map[Control ('f')].function = ea_forward; map[Control ('g')].function = ea_abort; map[Control ('h')].function = ea_rubout; map[Control ('k')].function = ea_kill_line; map[Control ('l')].function = info_redraw_display; map[Control ('q')].function = ea_quoted_insert; map[Control ('t')].function = ea_transpose_chars; map[Control ('u')].function = info_universal_argument; map[Control ('y')].function = ea_yank; map[LFD].function = ea_newline; map[RET].function = ea_newline; map[SPC].function = ea_complete; map[TAB].function = ea_complete; map['?'].function = ea_possible_completions; map[DEL].function = ea_rubout; /* Bind the echo area ESC keymap. */ map = (Keymap)echo_area_keymap[ESC].function; map[Control ('g')].function = ea_abort; map[Control ('v')].function = ea_scroll_completions_window; map['b'].function = ea_backward_word; map['d'].function = ea_kill_word; map['f'].function = ea_forward_word; #if defined (NAMED_FUNCTIONS) /* map['x'].function = info_execute_command; */ #endif /* NAMED_FUNCTIONS */ map['y'].function = ea_yank_pop; map['?'].function = ea_possible_completions; map[TAB].function = ea_tab_insert; map[DEL].function = ea_backward_kill_word; /* Bind the echo area Control-x keymap. */ map = (Keymap)echo_area_keymap[Control ('x')].function; map['o'].function = info_next_window; map[DEL].function = ea_backward_kill_line; /* Arrow key bindings for echo area keymaps. It seems that some terminals do not match their termcap entries, so it's best to just define everything with both of the usual prefixes. */ map = echo_area_keymap; keymap_bind_keyseq (map, term_ku, &map[Control ('p')]); /* up */ keymap_bind_keyseq (map, "\033OA", &map[Control ('p')]); keymap_bind_keyseq (map, "\033[A", &map[Control ('p')]); keymap_bind_keyseq (map, term_kd, &map[Control ('n')]); /* down */ keymap_bind_keyseq (map, "\033OB", &map[Control ('n')]); keymap_bind_keyseq (map, "\033[B", &map[Control ('n')]); keymap_bind_keyseq (map, term_kr, &map[Control ('f')]); /* right */ keymap_bind_keyseq (map, "\033OC", &map[Control ('f')]); keymap_bind_keyseq (map, "\033[C", &map[Control ('f')]); keymap_bind_keyseq (map, term_kl, &map[Control ('b')]); /* left */ keymap_bind_keyseq (map, "\033OD", &map[Control ('b')]); keymap_bind_keyseq (map, "\033[D", &map[Control ('b')]); map = (Keymap)echo_area_keymap[ESC].function; keymap_bind_keyseq (map, term_kl, &map['b']); /* left */ keymap_bind_keyseq (map, "\033OA", &map['b']); keymap_bind_keyseq (map, "\033[A", &map['b']); keymap_bind_keyseq (map, term_kr, &map['f']); /* right */ keymap_bind_keyseq (map, "\033OB", &map['f']); keymap_bind_keyseq (map, "\033[B", &map['f']); /* Bind commands for Info window keymaps. */ map = info_keymap; map[TAB].function = info_move_to_next_xref; map[LFD].function = info_select_reference_this_line; map[RET].function = info_select_reference_this_line; map[SPC].function = info_scroll_forward; map[Control ('a')].function = info_beginning_of_line; map[Control ('b')].function = info_backward_char; map[Control ('e')].function = info_end_of_line; map[Control ('f')].function = info_forward_char; map[Control ('g')].function = info_abort_key; map[Control ('h')].function = info_get_help_window; map[Control ('l')].function = info_redraw_display; map[Control ('n')].function = info_next_line; map[Control ('p')].function = info_prev_line; map[Control ('r')].function = isearch_backward; map[Control ('s')].function = isearch_forward; map[Control ('u')].function = info_universal_argument; map[Control ('v')].function = info_scroll_forward; map[','].function = info_next_index_match; for (i = '1'; i < '9' + 1; i++) map[i].function = info_menu_digit; map['0'].function = info_last_menu_item; map['<'].function = info_first_node; map['>'].function = info_last_node; map['?'].function = info_get_help_window; map['['].function = info_global_prev_node; map[']'].function = info_global_next_node; map['b'].function = info_beginning_of_node; map['d'].function = info_dir_node; map['e'].function = info_end_of_node; map['f'].function = info_xref_item; map['g'].function = info_goto_node; map['h'].function = info_get_info_help_node; map['i'].function = info_index_search; map['l'].function = info_history_node; map['m'].function = info_menu_item; map['n'].function = info_next_node; map['p'].function = info_prev_node; map['q'].function = info_quit; map['r'].function = info_xref_item; map['s'].function = info_search; map['t'].function = info_top_node; map['u'].function = info_up_node; map[DEL].function = info_scroll_backward; /* Bind members in the ESC map for Info windows. */ map = (Keymap)info_keymap[ESC].function; map[Control ('f')].function = info_show_footnotes; map[Control ('g')].function = info_abort_key; map[TAB].function = info_move_to_prev_xref; map[Control ('v')].function = info_scroll_other_window; map['<'].function = info_beginning_of_node; map['>'].function = info_end_of_node; map['b'].function = info_backward_word; map['f'].function = info_forward_word; map['r'].function = info_move_to_window_line; map['v'].function = info_scroll_backward; #if defined (NAMED_FUNCTIONS) map['x'].function = info_execute_command; #endif /* NAMED_FUNCTIONS */ /* Bind members in the Control-X map for Info windows. */ map = (Keymap)info_keymap[Control ('x')].function; map[Control ('b')].function = list_visited_nodes; map[Control ('c')].function = info_quit; map[Control ('f')].function = info_view_file; map[Control ('g')].function = info_abort_key; map[Control ('v')].function = info_view_file; map['0'].function = info_delete_window; map['1'].function = info_keep_one_window; map['2'].function = info_split_window; map['^'].function = info_grow_window; map['b'].function = select_visited_node; map['k'].function = info_kill_node; map['o'].function = info_next_window; map['t'].function = info_tile_windows; map['w'].function = info_toggle_wrap; /* Arrow key bindings for Info windows keymap. */ map = info_keymap; keymap_bind_keyseq (map, term_kN, &map[Control ('v')]); /* pagedown */ keymap_bind_keyseq (map, term_ku, &map[Control ('p')]); /* up */ keymap_bind_keyseq (map, "\033OA", &map[Control ('p')]); keymap_bind_keyseq (map, "\033[A", &map[Control ('p')]); keymap_bind_keyseq (map, term_kd, &map[Control ('n')]); /* down */ keymap_bind_keyseq (map, "\033OB", &map[Control ('n')]); keymap_bind_keyseq (map, "\033[B", &map[Control ('n')]); keymap_bind_keyseq (map, term_kr, &map[Control ('f')]); /* right */ keymap_bind_keyseq (map, "\033OC", &map[Control ('f')]); keymap_bind_keyseq (map, "\033[C", &map[Control ('f')]); keymap_bind_keyseq (map, term_kl, &map[Control ('b')]); /* left */ keymap_bind_keyseq (map, "\033OD", &map[Control ('b')]); keymap_bind_keyseq (map, "\033[D", &map[Control ('b')]); map = (Keymap)info_keymap[ESC].function; keymap_bind_keyseq (map, term_kl, &map['b']); /* left */ keymap_bind_keyseq (map, "\033OA", &map['b']); keymap_bind_keyseq (map, "\033[A", &map['b']); keymap_bind_keyseq (map, term_kr, &map['f']); /* right */ keymap_bind_keyseq (map, "\033OB", &map['f']); keymap_bind_keyseq (map, "\033[B", &map['f']); keymap_bind_keyseq (map, term_kN, &map[Control ('v')]); /* pagedown */ /* The alternative to this definition of a `main map' key in the `ESC map' section, is something like: keymap_bind_keyseq (map, term_kP, &((KeyMap)map[ESC].function).map['v']); */ keymap_bind_keyseq (info_keymap/*sic*/, term_kP, &map['v']); /* pageup */ } texinfo-3.12/info/nodes.c0000444000175000017500000011440406365744666012610 0ustar gg/* nodes.c -- How to get an Info file and node. */ /* This file is part of GNU Info, a program for reading online documentation stored in Info format. Copyright (C) 1993 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ #include "info.h" #include "nodes.h" #include "search.h" #include "filesys.h" #include "info-utils.h" #if defined (HANDLE_MAN_PAGES) # include "man.h" #endif /* HANDLE_MAN_PAGES */ /* **************************************************************** */ /* */ /* Functions Static to this File */ /* */ /* **************************************************************** */ static void forget_info_file (), remember_info_file (); static void free_file_buffer_tags (), free_info_tag (); static void get_nodes_of_tags_table (), get_nodes_of_info_file (); static void get_tags_of_indirect_tags_table (); static void info_reload_file_buffer_contents (); static char *adjust_nodestart (); static FILE_BUFFER *info_load_file_internal (), *info_find_file_internal (); static NODE *info_node_of_file_buffer_tags (); static long get_node_length (); /* Magic number that RMS used to decide how much a tags table pointer could be off by. I feel that it should be much smaller, like on the order of 4. */ #define DEFAULT_INFO_FUDGE 1000 /* Passed to *_internal functions. INFO_GET_TAGS says to do what is neccessary to fill in the nodes or tags arrays in FILE_BUFFER. */ #define INFO_NO_TAGS 0 #define INFO_GET_TAGS 1 /* **************************************************************** */ /* */ /* Global Variables */ /* */ /* **************************************************************** */ /* When non-zero, this is a string describing the recent file error. */ char *info_recent_file_error = (char *)NULL; /* The list of already loaded nodes. */ FILE_BUFFER **info_loaded_files = (FILE_BUFFER **)NULL; /* The number of slots currently allocated to LOADED_FILES. */ int info_loaded_files_slots = 0; /* **************************************************************** */ /* */ /* Public Functions for Node Manipulation */ /* */ /* **************************************************************** */ /* Used to build "dir" menu from "localdir" files found in INFOPATH. */ extern void maybe_build_dir_node (); /* Return a pointer to a NODE structure for the Info node (FILENAME)NODENAME. FILENAME can be passed as NULL, in which case the filename of "dir" is used. NODENAME can be passed as NULL, in which case the nodename of "Top" is used. If the node cannot be found, return a NULL pointer. */ NODE * info_get_node (filename, nodename) char *filename, *nodename; { FILE_BUFFER *file_buffer; NODE *node; file_buffer = (FILE_BUFFER *)NULL; info_recent_file_error = (char *)NULL; info_parse_node (nodename, DONT_SKIP_NEWLINES); nodename = (char *)NULL; if (info_parsed_filename) filename = info_parsed_filename; if (info_parsed_nodename) nodename = info_parsed_nodename; /* If FILENAME is not specified, it defaults to "dir". */ if (!filename) filename = "dir"; /* If the file to be looked up is "dir", build the contents from all of the "dir"s and "localdir"s found in INFOPATH. */ if (strcasecmp (filename, "dir") == 0) maybe_build_dir_node (filename); /* Find the correct info file. */ file_buffer = info_find_file (filename); if (!file_buffer) { if (filesys_error_number) info_recent_file_error = filesys_error_string (filename, filesys_error_number); return ((NODE *)NULL); } node = info_get_node_of_file_buffer (nodename, file_buffer); /* If the node looked for was "Top", try again looking for the node under a slightly different name. */ if (!node && (nodename == NULL || strcasecmp (nodename, "Top") == 0)) { node = info_get_node_of_file_buffer ("Top", file_buffer); if (!node) node = info_get_node_of_file_buffer ("top", file_buffer); if (!node) node = info_get_node_of_file_buffer ("TOP", file_buffer); } return (node); } /* Return a pointer to a NODE structure for the Info node NODENAME in FILE_BUFFER. NODENAME can be passed as NULL, in which case the nodename of "Top" is used. If the node cannot be found, return a NULL pointer. */ NODE * info_get_node_of_file_buffer (nodename, file_buffer) char *nodename; FILE_BUFFER *file_buffer; { NODE *node = (NODE *)NULL; /* If we are unable to find the file, we have to give up. There isn't anything else we can do. */ if (!file_buffer) return ((NODE *)NULL); /* If the file buffer was gc'ed, reload the contents now. */ if (!file_buffer->contents) info_reload_file_buffer_contents (file_buffer); /* If NODENAME is not specified, it defaults to "Top". */ if (!nodename) nodename = "Top"; /* If the name of the node that we wish to find is exactly "*", then the node body is the contents of the entire file. Create and return such a node. */ if (strcmp (nodename, "*") == 0) { node = (NODE *)xmalloc (sizeof (NODE)); node->filename = file_buffer->fullpath; node->parent = (char *)NULL; node->nodename = xstrdup ("*"); node->contents = file_buffer->contents; node->nodelen = file_buffer->filesize; node->flags = 0; } #if defined (HANDLE_MAN_PAGES) /* If the file buffer is the magic one associated with manpages, call the manpage node finding function instead. */ else if (file_buffer->flags & N_IsManPage) { node = get_manpage_node (file_buffer, nodename); } #endif /* HANDLE_MAN_PAGES */ /* If this is the "main" info file, it might contain a tags table. Search the tags table for an entry which matches the node that we want. If there is a tags table, get the file which contains this node, but don't bother building a node list for it. */ else if (file_buffer->tags) { node = info_node_of_file_buffer_tags (file_buffer, nodename); } /* Return the results of our node search. */ return (node); } /* Locate the file named by FILENAME, and return the information structure describing this file. The file may appear in our list of loaded files already, or it may not. If it does not already appear, find the file, and add it to the list of loaded files. If the file cannot be found, return a NULL FILE_BUFFER *. */ FILE_BUFFER * info_find_file (filename) char *filename; { return (info_find_file_internal (filename, INFO_GET_TAGS)); } /* Load the info file FILENAME, remembering information about it in a file buffer. */ FILE_BUFFER * info_load_file (filename) char *filename; { return (info_load_file_internal (filename, INFO_GET_TAGS)); } /* **************************************************************** */ /* */ /* Private Functions Implementation */ /* */ /* **************************************************************** */ /* The workhorse for info_find_file (). Non-zero 2nd argument says to try to build a tags table (or otherwise glean the nodes) for this file once found. By default, we build the tags table, but when this function is called by info_get_node () when we already have a valid tags table describing the nodes, it is unnecessary. */ static FILE_BUFFER * info_find_file_internal (filename, get_tags) char *filename; int get_tags; { register int i; register FILE_BUFFER *file_buffer; /* First try to find the file in our list of already loaded files. */ if (info_loaded_files) { for (i = 0; (file_buffer = info_loaded_files[i]); i++) if ((strcmp (filename, file_buffer->filename) == 0) || (strcmp (filename, file_buffer->fullpath) == 0) || ((*filename != '/') && strcmp (filename, filename_non_directory (file_buffer->fullpath)) == 0)) { struct stat new_info, *old_info; /* This file is loaded. If the filename that we want is specifically "dir", then simply return the file buffer. */ if (strcasecmp (filename_non_directory (filename), "dir") == 0) return (file_buffer); #if defined (HANDLE_MAN_PAGES) /* Do the same for the magic MANPAGE file. */ if (file_buffer->flags & N_IsManPage) return (file_buffer); #endif /* HANDLE_MAN_PAGES */ /* The file appears to be already loaded, and it is not "dir". Check to see if it has changed since the last time it was loaded. */ if (stat (file_buffer->fullpath, &new_info) == -1) { filesys_error_number = errno; return ((FILE_BUFFER *)NULL); } old_info = &file_buffer->finfo; if ((new_info.st_size != old_info->st_size) || (new_info.st_mtime != old_info->st_mtime)) { /* The file has changed. Forget that we ever had loaded it in the first place. */ forget_info_file (filename); break; } else { /* The info file exists, and has not changed since the last time it was loaded. If the caller requested a nodes list for this file, and there isn't one here, build the nodes for this file_buffer. In any case, return the file_buffer object. */ if (get_tags && !file_buffer->tags) build_tags_and_nodes (file_buffer); return (file_buffer); } } } /* The file wasn't loaded. Try to load it now. */ #if defined (HANDLE_MAN_PAGES) /* If the name of the file that we want is our special file buffer for Unix manual pages, then create the file buffer, and return it now. */ if (strcasecmp (filename, MANPAGE_FILE_BUFFER_NAME) == 0) file_buffer = create_manpage_file_buffer (); else #endif /* HANDLE_MAN_PAGES */ file_buffer = info_load_file_internal (filename, get_tags); /* If the file was loaded, remember the name under which it was found. */ if (file_buffer) remember_info_file (file_buffer); return (file_buffer); } /* The workhorse function for info_load_file (). Non-zero second argument says to build a list of tags (or nodes) for this file. This is the default behaviour when info_load_file () is called, but it is not necessary when loading a subfile for which we already have tags. */ static FILE_BUFFER * info_load_file_internal (filename, get_tags) char *filename; int get_tags; { char *fullpath, *contents; long filesize; struct stat finfo; int retcode; FILE_BUFFER *file_buffer = (FILE_BUFFER *)NULL; /* Get the full pathname of this file, as known by the info system. That is to say, search along INFOPATH and expand tildes, etc. */ fullpath = info_find_fullpath (filename); /* Did we actually find the file? */ retcode = stat (fullpath, &finfo); /* If the file referenced by the name returned from info_find_fullpath () doesn't exist, then try again with the last part of the filename appearing in lowercase. */ if (retcode < 0) { char *lowered_name; char *basename; lowered_name = xstrdup (filename); basename = (char *) strrchr (lowered_name, '/'); if (basename) basename++; else basename = lowered_name; while (*basename) { if (isupper (*basename)) *basename = tolower (*basename); basename++; } fullpath = info_find_fullpath (lowered_name); free (lowered_name); retcode = stat (fullpath, &finfo); } /* If the file wasn't found, give up, returning a NULL pointer. */ if (retcode < 0) { filesys_error_number = errno; return ((FILE_BUFFER *)NULL); } /* Otherwise, try to load the file. */ contents = filesys_read_info_file (fullpath, &filesize, &finfo); if (!contents) return ((FILE_BUFFER *)NULL); /* The file was found, and can be read. Allocate FILE_BUFFER and fill in the various members. */ file_buffer = make_file_buffer (); file_buffer->filename = xstrdup (filename); file_buffer->fullpath = xstrdup (fullpath); file_buffer->finfo = finfo; file_buffer->filesize = filesize; file_buffer->contents = contents; if (file_buffer->filesize != file_buffer->finfo.st_size) file_buffer->flags |= N_IsCompressed; /* If requested, build the tags and nodes for this file buffer. */ if (get_tags) build_tags_and_nodes (file_buffer); return (file_buffer); } /* Grovel FILE_BUFFER->contents finding tags and nodes, and filling in the various slots. This can also be used to rebuild a tag or node table. */ void build_tags_and_nodes (file_buffer) FILE_BUFFER *file_buffer; { SEARCH_BINDING binding; long position; free_file_buffer_tags (file_buffer); file_buffer->flags &= ~N_HasTagsTable; /* See if there is a tags table in this info file. */ binding.buffer = file_buffer->contents; binding.start = file_buffer->filesize; binding.end = binding.start - 1000; if (binding.end < 0) binding.end = 0; binding.flags = S_FoldCase; position = search_backward (TAGS_TABLE_END_LABEL, &binding); /* If there is a tag table, find the start of it, and grovel over it extracting tag information. */ if (position != -1) while (1) { long tags_table_begin, tags_table_end; binding.end = position; binding.start = binding.end - 5 - strlen (TAGS_TABLE_END_LABEL); if (binding.start < 0) binding.start = 0; position = find_node_separator (&binding); /* For this test, (and all others here) failure indicates a bogus tags table. Grovel the file. */ if (position == -1) break; /* Remember the end of the tags table. */ binding.start = position; tags_table_end = binding.start; binding.end = 0; /* Locate the start of the tags table. */ position = search_backward (TAGS_TABLE_BEG_LABEL, &binding); if (position == -1) break; binding.end = position; binding.start = binding.end - 5 - strlen (TAGS_TABLE_BEG_LABEL); position = find_node_separator (&binding); if (position == -1) break; /* The file contains a valid tags table. Fill the FILE_BUFFER's tags member. */ file_buffer->flags |= N_HasTagsTable; tags_table_begin = position; /* If this isn't an indirect tags table, just remember the nodes described locally in this tags table. Note that binding.end is pointing to just after the beginning label. */ binding.start = binding.end; binding.end = file_buffer->filesize; if (!looking_at (TAGS_TABLE_IS_INDIRECT_LABEL, &binding)) { binding.start = tags_table_begin; binding.end = tags_table_end; get_nodes_of_tags_table (file_buffer, &binding); return; } else { /* This is an indirect tags table. Build TAGS member. */ SEARCH_BINDING indirect; indirect.start = tags_table_begin; indirect.end = 0; indirect.buffer = binding.buffer; indirect.flags = S_FoldCase; position = search_backward (INDIRECT_TAGS_TABLE_LABEL, &indirect); if (position == -1) { /* This file is malformed. Give up. */ return; } indirect.start = position; indirect.end = tags_table_begin; binding.start = tags_table_begin; binding.end = tags_table_end; get_tags_of_indirect_tags_table (file_buffer, &indirect, &binding); return; } } /* This file doesn't contain any kind of tags table. Grovel the file and build node entries for it. */ get_nodes_of_info_file (file_buffer); } /* Search through FILE_BUFFER->contents building an array of TAG *, one entry per each node present in the file. Store the tags in FILE_BUFFER->tags, and the number of allocated slots in FILE_BUFFER->tags_slots. */ static void get_nodes_of_info_file (file_buffer) FILE_BUFFER *file_buffer; { long nodestart; int tags_index = 0; SEARCH_BINDING binding; binding.buffer = file_buffer->contents; binding.start = 0; binding.end = file_buffer->filesize; binding.flags = S_FoldCase; while ((nodestart = find_node_separator (&binding)) != -1) { int start, end; char *nodeline; TAG *entry; /* Skip past the characters just found. */ binding.start = nodestart; binding.start += skip_node_separator (binding.buffer + binding.start); /* Move to the start of the line defining the node. */ nodeline = binding.buffer + binding.start; /* Find "Node:" */ start = string_in_line (INFO_NODE_LABEL, nodeline); /* If not there, this is not the start of a node. */ if (start == -1) continue; /* Find the start of the nodename. */ start += skip_whitespace (nodeline + start); /* Find the end of the nodename. */ end = start + skip_node_characters (nodeline + start, DONT_SKIP_NEWLINES); /* Okay, we have isolated the node name, and we know where the node starts. Remember this information in a NODE structure. */ entry = (TAG *)xmalloc (sizeof (TAG)); entry->nodename = (char *)xmalloc (1 + (end - start)); strncpy (entry->nodename, nodeline + start, end - start); entry->nodename[end - start] = '\0'; entry->nodestart = nodestart; { SEARCH_BINDING node_body; node_body.buffer = binding.buffer + binding.start; node_body.start = 0; node_body.end = binding.end - binding.start; node_body.flags = S_FoldCase; entry->nodelen = get_node_length (&node_body); } entry->filename = file_buffer->fullpath; /* Add this tag to the array of tag structures in this FILE_BUFFER. */ add_pointer_to_array (entry, tags_index, file_buffer->tags, file_buffer->tags_slots, 100, TAG *); } } /* Return the length of the node which starts at BINDING. */ static long get_node_length (binding) SEARCH_BINDING *binding; { register int i; char *body; /* From the Info-RFC file: [A node] ends with either a ^_, a ^L, or the end of file. */ for (i = binding->start, body = binding->buffer; i < binding->end; i++) { if (body[i] == INFO_FF || body[i] == INFO_COOKIE) break; } return ((long) i - binding->start); } /* Build and save the array of nodes in FILE_BUFFER by searching through the contents of BUFFER_BINDING for a tags table, and groveling the contents. */ static void get_nodes_of_tags_table (file_buffer, buffer_binding) FILE_BUFFER *file_buffer; SEARCH_BINDING *buffer_binding; { int offset, tags_index = 0; SEARCH_BINDING *search; long position; search = copy_binding (buffer_binding); /* Find the start of the tags table. */ position = find_tags_table (search); /* If none, we're all done. */ if (position == -1) return; /* Move to one character before the start of the actual table. */ search->start = position; search->start += skip_node_separator (search->buffer + search->start); search->start += strlen (TAGS_TABLE_BEG_LABEL); search->start--; /* The tag table consists of lines containing node names and positions. Do each line until we find one that doesn't contain a node name. */ while ((position = search_forward ("\n", search)) != -1) { TAG *entry; char *nodedef; /* Prepare to skip this line. */ search->start = position; search->start++; /* Skip past informative "(Indirect)" tags table line. */ if (!tags_index && looking_at (TAGS_TABLE_IS_INDIRECT_LABEL, search)) continue; /* Find the label preceding the node name. */ offset = string_in_line (INFO_NODE_LABEL, search->buffer + search->start); /* If not there, not a defining line, so we must be out of the tags table. */ if (offset == -1) break; /* Point to the beginning of the node definition. */ search->start += offset; nodedef = search->buffer + search->start; nodedef += skip_whitespace (nodedef); /* Move past the node's name. */ for (offset = 0; (nodedef[offset]) && (nodedef[offset] != INFO_TAGSEP); offset++); if (nodedef[offset] != INFO_TAGSEP) continue; entry = (TAG *)xmalloc (sizeof (TAG)); entry->nodename = (char *)xmalloc (1 + offset); strncpy (entry->nodename, nodedef, offset); entry->nodename[offset] = '\0'; offset++; entry->nodestart = (long) atol (nodedef + offset); /* We don't know the length of this node yet. */ entry->nodelen = -1; /* The filename of this node is currently known as the same as the name of this file. */ entry->filename = file_buffer->fullpath; /* Add this node structure to the array of node structures in this FILE_BUFFER. */ add_pointer_to_array (entry, tags_index, file_buffer->tags, file_buffer->tags_slots, 100, TAG *); } free (search); } /* A structure used only in get_tags_of_indirect_tags_table () to hold onto an intermediate value. */ typedef struct { char *filename; long first_byte; } SUBFILE; /* Remember in FILE_BUFFER the nodenames, subfilenames, and offsets within the subfiles of every node which appears in TAGS_BINDING. The 2nd argument is a binding surrounding the indirect files list. */ static void get_tags_of_indirect_tags_table (file_buffer, indirect_binding, tags_binding) FILE_BUFFER *file_buffer; SEARCH_BINDING *indirect_binding, *tags_binding; { register int i; SUBFILE **subfiles = (SUBFILE **)NULL; int subfiles_index = 0, subfiles_slots = 0; TAG *entry; /* First get the list of tags from the tags table. Then lookup the associated file in the indirect list for each tag, and update it. */ get_nodes_of_tags_table (file_buffer, tags_binding); /* We have the list of tags in file_buffer->tags. Get the list of subfiles from the indirect table. */ { char *start, *end, *line; SUBFILE *subfile; start = indirect_binding->buffer + indirect_binding->start; end = indirect_binding->buffer + indirect_binding->end; line = start; while (line < end) { int colon; colon = string_in_line (":", line); if (colon == -1) break; subfile = (SUBFILE *)xmalloc (sizeof (SUBFILE)); subfile->filename = (char *)xmalloc (colon); strncpy (subfile->filename, line, colon - 1); subfile->filename[colon - 1] = '\0'; subfile->first_byte = (long) atol (line + colon); add_pointer_to_array (subfile, subfiles_index, subfiles, subfiles_slots, 10, SUBFILE *); while (*line++ != '\n'); } } /* If we have successfully built the indirect files table, then merge the information in the two tables. */ if (!subfiles) { free_file_buffer_tags (file_buffer); return; } else { register int tags_index; long header_length; SEARCH_BINDING binding; /* Find the length of the header of the file containing the indirect tags table. This header appears at the start of every file. We want the absolute position of each node within each subfile, so we subtract the start of the containing subfile from the logical position of the node, and then add the length of the header in. */ binding.buffer = file_buffer->contents; binding.start = 0; binding.end = file_buffer->filesize; binding.flags = S_FoldCase; header_length = find_node_separator (&binding); if (header_length == -1) header_length = 0; /* Build the file buffer's list of subfiles. */ { char *containing_dir, *temp; int len_containing_dir; containing_dir = xstrdup (file_buffer->fullpath); temp = (char *) strrchr (containing_dir, '/'); if (temp) *temp = '\0'; len_containing_dir = strlen (containing_dir); for (i = 0; subfiles[i]; i++); file_buffer->subfiles = (char **) xmalloc ((1 + i) * sizeof (char *)); for (i = 0; subfiles[i]; i++) { char *fullpath; fullpath = (char *) xmalloc (2 + strlen (subfiles[i]->filename) + len_containing_dir); sprintf (fullpath, "%s/%s", containing_dir, subfiles[i]->filename); file_buffer->subfiles[i] = fullpath; } file_buffer->subfiles[i] = (char *)NULL; free (containing_dir); } /* For each node in the file's tags table, remember the starting position. */ for (tags_index = 0; (entry = file_buffer->tags[tags_index]); tags_index++) { for (i = 0; subfiles[i] && entry->nodestart >= subfiles[i]->first_byte; i++); /* If the Info file containing the indirect tags table is malformed, then give up. */ if (!i) { /* The Info file containing the indirect tags table is malformed. Give up. */ for (i = 0; subfiles[i]; i++) { free (subfiles[i]->filename); free (subfiles[i]); free (file_buffer->subfiles[i]); } file_buffer->subfiles = (char **)NULL; free_file_buffer_tags (file_buffer); return; } /* SUBFILES[i] is the index of the first subfile whose logical first byte is greater than the logical offset of this node's starting position. This means that the subfile directly preceding this one is the one containing the node. */ entry->filename = file_buffer->subfiles[i - 1]; entry->nodestart -= subfiles[i -1]->first_byte; entry->nodestart += header_length; entry->nodelen = -1; } /* We have successfully built the tags table. Remember that it was indirect. */ file_buffer->flags |= N_TagsIndirect; } /* Free the structures assigned to SUBFILES. Free the names as well as the structures themselves, then finally, the array. */ for (i = 0; subfiles[i]; i++) { free (subfiles[i]->filename); free (subfiles[i]); } free (subfiles); } /* Return the node from FILE_BUFFER which matches NODENAME by searching the tags table in FILE_BUFFER. If the node could not be found, return a NULL pointer. */ static NODE * info_node_of_file_buffer_tags (file_buffer, nodename) FILE_BUFFER *file_buffer; char *nodename; { register int i; TAG *tag; for (i = 0; (tag = file_buffer->tags[i]); i++) if (strcmp (nodename, tag->nodename) == 0) { FILE_BUFFER *subfile; subfile = info_find_file_internal (tag->filename, INFO_NO_TAGS); if (!subfile) return ((NODE *)NULL); if (!subfile->contents) { info_reload_file_buffer_contents (subfile); if (!subfile->contents) return ((NODE *)NULL); } /* If we were able to find this file and load it, then return the node within it. */ { NODE *node; node = (NODE *)xmalloc (sizeof (NODE)); node->filename = (subfile->fullpath); node->nodename = tag->nodename; node->contents = subfile->contents + tag->nodestart; node->flags = 0; node->parent = (char *)NULL; if (file_buffer->flags & N_HasTagsTable) { node->flags |= N_HasTagsTable; if (file_buffer->flags & N_TagsIndirect) { node->flags |= N_TagsIndirect; node->parent = file_buffer->fullpath; } } if (subfile->flags & N_IsCompressed) node->flags |= N_IsCompressed; /* If TAG->nodelen hasn't been calculated yet, then we aren't in a position to trust the entry pointer. Adjust things so that ENTRY->nodestart gets the exact address of the start of the node separator which starts this node, and NODE->contents gets the address of the line defining this node. If we cannot do that, the node isn't really here. */ if (tag->nodelen == -1) { int min, max; char *node_sep; SEARCH_BINDING node_body; char *buff_end; min = max = DEFAULT_INFO_FUDGE; if (tag->nodestart < DEFAULT_INFO_FUDGE) min = tag->nodestart; if (DEFAULT_INFO_FUDGE > (subfile->filesize - tag->nodestart)) max = subfile->filesize - tag->nodestart; /* NODE_SEP gets the address of the separator which defines this node, or (char *)NULL if the node wasn't found. NODE->contents is side-effected to point to right after the separator. */ node_sep = adjust_nodestart (node, min, max); if (node_sep == (char *)NULL) { free (node); return ((NODE *)NULL); } /* Readjust tag->nodestart. */ tag->nodestart = node_sep - subfile->contents; /* Calculate the length of the current node. */ buff_end = subfile->contents + subfile->filesize; node_body.buffer = node->contents; node_body.start = 0; node_body.end = buff_end - node_body.buffer; node_body.flags = 0; tag->nodelen = get_node_length (&node_body); } else { /* Since we know the length of this node, we have already adjusted tag->nodestart to point to the exact start of it. Simply skip the node separator. */ node->contents += skip_node_separator (node->contents); } node->nodelen = tag->nodelen; return (node); } } /* There was a tag table for this file, and the node wasn't found. Return NULL, since this file doesn't contain the desired node. */ return ((NODE *)NULL); } /* **************************************************************** */ /* */ /* Managing file_buffers, nodes, and tags. */ /* */ /* **************************************************************** */ /* Create a new, empty file buffer. */ FILE_BUFFER * make_file_buffer () { FILE_BUFFER *file_buffer; file_buffer = (FILE_BUFFER *)xmalloc (sizeof (FILE_BUFFER)); file_buffer->filename = file_buffer->fullpath = (char *)NULL; file_buffer->contents = (char *)NULL; file_buffer->tags = (TAG **)NULL; file_buffer->subfiles = (char **)NULL; file_buffer->tags_slots = 0; file_buffer->flags = 0; return (file_buffer); } /* Add FILE_BUFFER to our list of already loaded info files. */ static void remember_info_file (file_buffer) FILE_BUFFER *file_buffer; { int i; for (i = 0; info_loaded_files && info_loaded_files[i]; i++) ; add_pointer_to_array (file_buffer, i, info_loaded_files, info_loaded_files_slots, 10, FILE_BUFFER *); } /* Forget the contents, tags table, nodes list, and names of FILENAME. */ static void forget_info_file (filename) char *filename; { register int i; FILE_BUFFER *file_buffer; if (!info_loaded_files) return; for (i = 0; (file_buffer = info_loaded_files[i]); i++) if ((strcmp (filename, file_buffer->filename) == 0) || (strcmp (filename, file_buffer->fullpath) == 0)) { free (file_buffer->filename); free (file_buffer->fullpath); if (file_buffer->contents) free (file_buffer->contents); /* Note that free_file_buffer_tags () also kills the subfiles list, since the subfiles list is only of use in conjunction with tags. */ free_file_buffer_tags (file_buffer); while ((info_loaded_files[i] = info_loaded_files[++i])) ; break; } } /* Free the tags (if any) associated with FILE_BUFFER. */ static void free_file_buffer_tags (file_buffer) FILE_BUFFER *file_buffer; { register int i; if (file_buffer->tags) { register TAG *tag; for (i = 0; (tag = file_buffer->tags[i]); i++) free_info_tag (tag); free (file_buffer->tags); file_buffer->tags = (TAG **)NULL; file_buffer->tags_slots = 0; } if (file_buffer->subfiles) { for (i = 0; file_buffer->subfiles[i]; i++) free (file_buffer->subfiles[i]); free (file_buffer->subfiles); file_buffer->subfiles = (char **)NULL; } } /* Free the data associated with TAG, as well as TAG itself. */ static void free_info_tag (tag) TAG *tag; { free (tag->nodename); /* We don't free tag->filename, because that filename is part of the subfiles list for the containing FILE_BUFFER. free_info_tags () will free the subfiles when it is appropriate. */ free (tag); } /* Load the contents of FILE_BUFFER->contents. This function is called when a file buffer was loaded, and then in order to conserve memory, the file buffer's contents were freed and the pointer was zero'ed. Note that the file was already loaded at least once successfully, so the tags and/or nodes members are still correctly filled. */ static void info_reload_file_buffer_contents (fb) FILE_BUFFER *fb; { #if defined (HANDLE_MAN_PAGES) /* If this is the magic manpage node, don't try to reload, just give up. */ if (fb->flags & N_IsManPage) return; #endif fb->flags &= ~N_IsCompressed; /* Let the filesystem do all the work for us. */ fb->contents = filesys_read_info_file (fb->fullpath, &(fb->filesize), &(fb->finfo)); if (fb->filesize != (long) (fb->finfo.st_size)) fb->flags |= N_IsCompressed; } /* Return the actual starting memory location of NODE, side-effecting NODE->contents. MIN and MAX are bounds for a search if one is necessary. Because of the way that tags are implemented, the physical nodestart may not actually be where the tag says it is. If that is the case, but the node was found anyway, set N_UpdateTags in NODE->flags. If the node is found, return non-zero. NODE->contents is returned positioned right after the node separator that precedes this node, while the return value is position directly on the separator that precedes this node. If the node could not be found, return a NULL pointer. */ static char * adjust_nodestart (node, min, max) NODE *node; int min, max; { long position; SEARCH_BINDING node_body; /* Define the node body. */ node_body.buffer = node->contents; node_body.start = 0; node_body.end = max; node_body.flags = 0; /* Try the optimal case first. Who knows? This file may actually be formatted (mostly) correctly. */ if (node_body.buffer[0] != INFO_COOKIE && min > 2) node_body.buffer -= 3; position = find_node_separator (&node_body); /* If we found a node start, then check it out. */ if (position != -1) { int sep_len; sep_len = skip_node_separator (node->contents); /* If we managed to skip a node separator, then check for this node being the right one. */ if (sep_len != 0) { char *nodedef, *nodestart; int offset; nodestart = node_body.buffer + position + sep_len; nodedef = nodestart; offset = string_in_line (INFO_NODE_LABEL, nodedef); if (offset != -1) { nodedef += offset; nodedef += skip_whitespace (nodedef); offset = skip_node_characters (nodedef, DONT_SKIP_NEWLINES); if ((offset == strlen (node->nodename)) && (strncmp (node->nodename, nodedef, offset) == 0)) { node->contents = nodestart; return (node_body.buffer + position); } } } } /* Oh well, I guess we have to try to find it in a larger area. */ node_body.buffer = node->contents - min; node_body.start = 0; node_body.end = min + max; node_body.flags = 0; position = find_node_in_binding (node->nodename, &node_body); /* If the node couldn't be found, we lose big. */ if (position == -1) return ((char *)NULL); /* Otherwise, the node was found, but the tags table could need updating (if we used a tag to get here, that is). Set the flag in NODE->flags. */ node->contents = node_body.buffer + position; node->contents += skip_node_separator (node->contents); if (node->flags & N_HasTagsTable) node->flags |= N_UpdateTags; return (node_body.buffer + position); } texinfo-3.12/info/gc.h0000444000175000017500000000270606362742161012060 0ustar gg/* gc.h -- Functions for garbage collecting unused node contents. $Id: gc.h,v 1.2 1997/07/15 18:41:53 karl Exp $ This file is part of GNU Info, a program for reading online documentation stored in Info format. Copyright (C) 1993, 97 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, USA. Written by Brian Fox (bfox@ai.mit.edu). */ #ifndef INFO_GC_H #define INFO_GC_H /* Add POINTER to the list of garbage collectible pointers. A pointer is not actually garbage collected until no info window contains a node whose contents member is equal to the pointer. */ extern void add_gcable_pointer (); /* Grovel the list of info windows and gc-able pointers finding those node->contents which are collectible, and free them. */ extern void gc_pointers (); #endif /* not INFO_GC_H */ texinfo-3.12/missing0000775000175000017500000001160206475357522011771 0ustar gg#! /bin/sh # Common stub for a few missing GNU programs while installing. # Copyright (C) 1996, 1997 Free Software Foundation, Inc. # Franc,ois Pinard , 1996. # 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, USA. if test $# -eq 0; then echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi case "$1" in -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' automake touch all \`Makefile.in' files bison touch file \`y.tab.c' makeinfo touch the output file yacc touch file \`y.tab.c'" ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing - GNU libit 0.0" ;; -*) echo 1>&2 "$0: Unknown \`$1' option" echo 1>&2 "Try \`$0 --help' for more information" exit 1 ;; aclocal) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`acinclude.m4' or \`configure.in'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`configure.in'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." touch configure ;; autoheader) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`acconfig.h' or \`configure.in'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER([^):]*:\([^)]*\)).*/\1/p' configure.in` if test -z "$files"; then files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^):]*\)).*/\1/p' configure.in` test -z "$files" || files="$files.in" else files=`echo "$files" | sed -e 's/:/ /g'` fi test -z "$files" && files="config.h.in" touch $files ;; automake) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified \`Makefile.am', \`acinclude.m4' or \`configure.in'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." find . -type f -name Makefile.am -print \ | sed 's/^\(.*\).am$/touch \1.in/' \ | sh ;; bison|yacc) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.y' file. You may need the \`Bison' package in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." touch y.tab.c ;; makeinfo) echo 1>&2 "\ WARNING: \`$1' is missing on your system. You should only need it if you modified a \`.texi' or \`.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious call might also be the consequence of using a buggy \`make' (AIX, DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` fi touch $file ;; *) echo 1>&2 "\ WARNING: \`$1' is needed, and you do not seem to have it handy on your system. You might have modified some files without having the proper tools for further handling them. Check the \`README' file, it often tells you about the needed prerequirements for installing this package. You may also peek at any GNU archive site, in case some other package would contain this missing \`$1' program." exit 1 ;; esac exit 0 texinfo-3.12/config.h.in0000664000175000017500000001553706475360165012425 0ustar gg/* config.h.in. Generated automatically from configure.in by autoheader. */ /* acconfig.h This file is in the public domain. Descriptive text for the C preprocessor macros that the distributed Autoconf macros can define. No software package will use all of them; autoheader copies the ones your configure.in uses into your configuration header file templates. The entries are in sort -df order: alphabetical, case insensitive, ignoring punctuation (such as underscores). Although this order can split up related entries, it makes it easier to check whether a given entry is in the file. Leave the following blank line there!! Autoheader needs it. */ /* Define if using alloca.c. */ #undef C_ALLOCA /* Define to empty if the keyword does not work. */ #undef const /* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems. This function is required for alloca.c support on those systems. */ #undef CRAY_STACKSEG_END /* Define if you have alloca, as a function or macro. */ #undef HAVE_ALLOCA /* Define if you have and it should be used (not on Ultrix). */ #undef HAVE_ALLOCA_H /* Define if you don't have vprintf but do have _doprnt. */ #undef HAVE_DOPRNT /* Define if you have a working `mmap' system call. */ #undef HAVE_MMAP /* Define if you have the vprintf function. */ #undef HAVE_VPRINTF /* Define as __inline if that's what the C compiler calls it. */ #undef inline /* Define if on MINIX. */ #undef _MINIX /* Define to `long' if doesn't define. */ #undef off_t /* Define if the system does not provide POSIX.1 features except with this defined. */ #undef _POSIX_1_SOURCE /* Define if you need to in order for stat and other things to work. */ #undef _POSIX_SOURCE /* Define as the return type of signal handlers (int or void). */ #undef RETSIGTYPE /* Define if the setvbuf function takes the buffering type as its second argument and the buffer pointer as the third, as on System V before release 3. */ #undef SETVBUF_REVERSED /* Define to `unsigned' if doesn't define. */ #undef size_t /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be automatically deduced at run-time. STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ #undef STACK_DIRECTION /* Define if you have the ANSI C header files. */ #undef STDC_HEADERS /* Define if your declares struct tm. */ #undef TM_IN_SYS_TIME /* Define to 1 if NLS is requested. */ #undef ENABLE_NLS /* Define as 1 if you have catgets and don't want to use GNU gettext. */ #undef HAVE_CATGETS /* Define as 1 if you have gettext and don't want to use GNU gettext. */ #undef HAVE_GETTEXT /* Define if your locale.h file contains LC_MESSAGES. */ #undef HAVE_LC_MESSAGES /* Define as 1 if you have the stpcpy function. */ #undef HAVE_STPCPY /* Define to the name of the distribution. */ #undef PACKAGE /* Define to the version of the distribution. */ #undef VERSION /* Define if you have the __argz_count function. */ #undef HAVE___ARGZ_COUNT /* Define if you have the __argz_next function. */ #undef HAVE___ARGZ_NEXT /* Define if you have the __argz_stringify function. */ #undef HAVE___ARGZ_STRINGIFY /* Define if you have the bzero function. */ #undef HAVE_BZERO /* Define if you have the dcgettext function. */ #undef HAVE_DCGETTEXT /* Define if you have the getcwd function. */ #undef HAVE_GETCWD /* Define if you have the getpagesize function. */ #undef HAVE_GETPAGESIZE /* Define if you have the memcpy function. */ #undef HAVE_MEMCPY /* Define if you have the memmove function. */ #undef HAVE_MEMMOVE /* Define if you have the memset function. */ #undef HAVE_MEMSET /* Define if you have the munmap function. */ #undef HAVE_MUNMAP /* Define if you have the putenv function. */ #undef HAVE_PUTENV /* Define if you have the setenv function. */ #undef HAVE_SETENV /* Define if you have the setlocale function. */ #undef HAVE_SETLOCALE /* Define if you have the setvbuf function. */ #undef HAVE_SETVBUF /* Define if you have the sigprocmask function. */ #undef HAVE_SIGPROCMASK /* Define if you have the sigsetmask function. */ #undef HAVE_SIGSETMASK /* Define if you have the stpcpy function. */ #undef HAVE_STPCPY /* Define if you have the strcasecmp function. */ #undef HAVE_STRCASECMP /* Define if you have the strchr function. */ #undef HAVE_STRCHR /* Define if you have the strdup function. */ #undef HAVE_STRDUP /* Define if you have the strerror function. */ #undef HAVE_STRERROR /* Define if you have the header file. */ #undef HAVE_ARGZ_H /* Define if you have the header file. */ #undef HAVE_FCNTL_H /* Define if you have the header file. */ #undef HAVE_LIMITS_H /* Define if you have the header file. */ #undef HAVE_LOCALE_H /* Define if you have the header file. */ #undef HAVE_MALLOC_H /* Define if you have the header file. */ #undef HAVE_NCURSES_TERMCAP_H /* Define if you have the header file. */ #undef HAVE_NL_TYPES_H /* Define if you have the header file. */ #undef HAVE_PWD_H /* Define if you have the header file. */ #undef HAVE_STRING_H /* Define if you have the header file. */ #undef HAVE_STRINGS_H /* Define if you have the header file. */ #undef HAVE_SYS_FCNTL_H /* Define if you have the header file. */ #undef HAVE_SYS_FILE_H /* Define if you have the header file. */ #undef HAVE_SYS_PARAM_H /* Define if you have the header file. */ #undef HAVE_SYS_PTEM_H /* Define if you have the header file. */ #undef HAVE_SYS_TIME_H /* Define if you have the header file. */ #undef HAVE_SYS_TTOLD_H /* Define if you have the header file. */ #undef HAVE_SYS_WAIT_H /* Define if you have the header file. */ #undef HAVE_TERMCAP_H /* Define if you have the header file. */ #undef HAVE_TERMIO_H /* Define if you have the header file. */ #undef HAVE_TERMIOS_H /* Define if you have the header file. */ #undef HAVE_UNISTD_H /* Define if you have the header file. */ #undef HAVE_VALUES_H /* Define if you have the bsd library (-lbsd). */ #undef HAVE_LIBBSD /* Define if you have the i library (-li). */ #undef HAVE_LIBI /* Define if you have the z library (-lz). */ #undef HAVE_LIBZ /* For gettext (NLS) */ #include #define _(String) gettext (String) #define N_(String) (String) /* Leave that blank line there!! Autoheader needs it. If you're adding to this file, keep in mind: The entries are in sort -df order: alphabetical, case insensitive, ignoring punctuation (such as underscores). */ texinfo-3.12/acconfig.h0000664000175000017500000000273206350602142012277 0ustar gg/* acconfig.h This file is in the public domain. Descriptive text for the C preprocessor macros that the distributed Autoconf macros can define. No software package will use all of them; autoheader copies the ones your configure.in uses into your configuration header file templates. The entries are in sort -df order: alphabetical, case insensitive, ignoring punctuation (such as underscores). Although this order can split up related entries, it makes it easier to check whether a given entry is in the file. Leave the following blank line there!! Autoheader needs it. */ @TOP@ /* Define to 1 if NLS is requested. */ #undef ENABLE_NLS /* Define as 1 if you have catgets and don't want to use GNU gettext. */ #undef HAVE_CATGETS /* Define as 1 if you have gettext and don't want to use GNU gettext. */ #undef HAVE_GETTEXT /* Define if your locale.h file contains LC_MESSAGES. */ #undef HAVE_LC_MESSAGES /* Define as 1 if you have the stpcpy function. */ #undef HAVE_STPCPY /* Define to the name of the distribution. */ #undef PACKAGE /* Define to the version of the distribution. */ #undef VERSION @BOTTOM@ /* For gettext (NLS) */ #include #define _(String) gettext (String) #define N_(String) (String) /* Leave that blank line there!! Autoheader needs it. If you're adding to this file, keep in mind: The entries are in sort -df order: alphabetical, case insensitive, ignoring punctuation (such as underscores). */ texinfo-3.12/README0000664000175000017500000001324206474646020011245 0ustar ggThis is the README file for the GNU Texinfo distribution. The primary distribution point is ftp://ftp.gnu.org/pub/gnu. Please email bugs or suggestions to bug-texinfo@gnu.org. (If you wish, you can join this list by sending a subscribe message to bug-texinfo-request@gnu.org.) Patches are welcome; if possible, please make them with diff -c and include ChangeLog entries. Programs within this distribution have their own version numbers. When you refer to a file, please mention its own version, as well as the version number of the Texinfo distribution. For generic installation instructions on compiling and installing this Automake-based distribution, please read the file `INSTALL'. Installation notes specific to Texinfo: * The Info tree uses a file `dir' as its root node; the `dir-example' file in this distribution is included for informative purposes. Use it, modify it, or ignore it just as you like. * You can create a file texinfo.cnf to be read by TeX when processing Texinfo manuals. For example, it might contain the command @afourpaper. See the `Preparing for TeX' node in texinfo.texi for more details. * If your info files are not in $prefix/info, you may wish to add a line #define DEFAULT_INFOPATH "/mydir1:/mydir2:/etc" to config.h after running configure. This distribution includes (but is not limited to) the following files: README This file. INTRODUCTION Brief introduction to the system, and how to create readable files from the Texinfo source files in this distribution. Texinfo source files (in ./doc): texinfo.texi This manual describes the Texinfo language and many of the associated tools. It tells how to use Texinfo to write documentation, how to use Texinfo mode in GNU Emacs, TeX, makeinfo, and the Emacs Lisp Texinfo formatting commands. info.texi This manual tells you how to use Info. This document comes as part of GNU Emacs. If you do not have Emacs, you can format this Texinfo source file with makeinfo or TeX and then read the resulting Info file with the standalone Info reader that is part of this distribution. info-stnd.texi This manual tells you how to use the standalone GNU Info reader that is included in this distribution as C source (./info). Printing related files: doc/texinfo.tex This TeX definitions file tells the TeX program how to typeset a Texinfo file into a DVI file ready for printing. util/texindex.c This file contains the source for the `texindex' program that generates sorted indices used by TeX when typesetting a file for printing. util/texi2dvi This is a shell script for producing an indexed DVI file using TeX and texindex. Must be used if the source document uses Texinfo @macros. Source files for standalone C programs (./lib, ./makeinfo, ./info): makeinfo.c This file contains the source for the `makeinfo' program that you can use to create an Info file from a Texinfo file. info.c This file contains the source for the `info' program that you can use to view Info files on an ASCII terminal. getopt.c Various support files getopt1.c getopt.h Installation files: configure This file creates creates a Makefile which in turn creates an `info' or `makeinfo' executable, or a C sources distribution. configure.in This is a template for creating `configure' using Autoconf. Makefile.in This is a template for `configure' to use to make a Makefile. Created by Automake. Makefile.am This is a template for Automake to use to make a Makefile.in. Other files (util): NEWS This contains a summary of new features since the first edition of Texinfo. fixfonts This is a shell script to install the `lcircle10' TeX fonts as an alias for the `circle10' fonts. In some older TeX distributions the names are different. tex3patch This handles a bug for version 3.0 of TeX that does not occur in more recent versions. texinfo-3.12/ABOUT-NLS0000664000175000017500000002643506475640123011623 0ustar ggNotes on the Free Translation Project ************************************* Free software is going international! The Free Translation Project is a way to get maintainers of free software, translators, and users all together, so that will gradually become able to speak many languages. A few packages already provide translations for their messages. If you found this `ABOUT-NLS' file inside a distribution, you may assume that the distributed package does use GNU `gettext' internally, itself available at your nearest GNU archive site. But you do *not* need to install GNU `gettext' prior to configuring, installing or using this package with messages translated. Installers will find here some useful hints. These notes also explain how users should proceed for getting the programs to use the available translations. They tell how people wanting to contribute and work at translations should contact the appropriate team. When reporting bugs in the `intl/' directory or bugs which may be related to internationalization, you should tell about the version of `gettext' which is used. The information can be found in the `intl/VERSION' file, in internationalized packages. One advise in advance ===================== If you want to exploit the full power of internationalization, you should configure it using ./configure --with-included-gettext to force usage of internationalizing routines provided within this package, despite the existence of internationalizing capabilities in the operating system where this package is being installed. So far, only the `gettext' implementation in the GNU C library version 2 provides as many features (such as locale alias or message inheritance) as the implementation here. It is also not possible to offer this additional functionality on top of a `catgets' implementation. Future versions of GNU `gettext' will very likely convey even more functionality. So it might be a good idea to change to GNU `gettext' as soon as possible. So you need not provide this option if you are using GNU libc 2 or you have installed a recent copy of the GNU gettext package with the included `libintl'. INSTALL Matters =============== Some packages are "localizable" when properly installed; the programs they contain can be made to speak your own native language. Most such packages use GNU `gettext'. Other packages have their own ways to internationalization, predating GNU `gettext'. By default, this package will be installed to allow translation of messages. It will automatically detect whether the system provides usable `catgets' (if using this is selected by the installer) or `gettext' functions. If neither is available, the GNU `gettext' own library will be used. This library is wholly contained within this package, usually in the `intl/' subdirectory, so prior installation of the GNU `gettext' package is *not* required. Installers may use special options at configuration time for changing the default behaviour. The commands: ./configure --with-included-gettext ./configure --with-catgets ./configure --disable-nls will respectively bypass any pre-existing `catgets' or `gettext' to use the internationalizing routines provided within this package, enable the use of the `catgets' functions (if found on the locale system), or else, *totally* disable translation of messages. When you already have GNU `gettext' installed on your system and run configure without an option for your new package, `configure' will probably detect the previously built and installed `libintl.a' file and will decide to use this. This might be not what is desirable. You should use the more recent version of the GNU `gettext' library. I.e. if the file `intl/VERSION' shows that the library which comes with this package is more recent, you should use ./configure --with-included-gettext to prevent auto-detection. By default the configuration process will not test for the `catgets' function and therefore they will not be used. The reasons are already given above: the emulation on top of `catgets' cannot provide all the extensions provided by the GNU `gettext' library. If you nevertheless want to use the `catgets' functions use ./configure --with-catgets to enable the test for `catgets' (this causes no harm if `catgets' is not available on your system). If you really select this option we would like to hear about the reasons because we cannot think of any good one ourself. Internationalized packages have usually many `po/LL.po' files, where LL gives an ISO 639 two-letter code identifying the language. Unless translations have been forbidden at `configure' time by using the `--disable-nls' switch, all available translations are installed together with the package. However, the environment variable `LINGUAS' may be set, prior to configuration, to limit the installed set. `LINGUAS' should then contain a space separated list of two-letter codes, stating which languages are allowed. Using This Package ================== As a user, if your language has been installed for this package, you only have to set the `LANG' environment variable to the appropriate ISO 639 `LL' two-letter code prior to using the programs in the package. For example, let's suppose that you speak German. At the shell prompt, merely execute `setenv LANG de' (in `csh'), `export LANG; LANG=de' (in `sh') or `export LANG=de' (in `bash'). This can be done from your `.login' or `.profile' file, once and for all. An operating system might already offer message localization for many of its programs, while other programs have been installed locally with the full capabilities of GNU `gettext'. Just using `gettext' extended syntax for `LANG' would break proper localization of already available operating system programs. In this case, users should set both `LANGUAGE' and `LANG' variables in their environment, as programs using GNU `gettext' give preference to `LANGUAGE'. For example, some Swedish users would rather read translations in German than English for when Swedish is not available. This is easily accomplished by setting `LANGUAGE' to `sv:de' while leaving `LANG' to `sv'. Translating Teams ================= For the Free Translation Project to be a success, we need interested people who like their own language and write it well, and who are also able to synergize with other translators speaking the same language. Each translation team has its own mailing list, courtesy of Linux International. You may reach your translation team at the address `LL@li.org', replacing LL by the two-letter ISO 639 code for your language. Language codes are *not* the same as the country codes given in ISO 3166. The following translation teams exist, as of August 1997: Chinese `zh', Czech `cs', Danish `da', Dutch `nl', English `en', Esperanto `eo', Finnish `fi', French `fr', German `de', Hungarian `hu', Irish `ga', Italian `it', Indonesian `id', Japanese `ja', Korean `ko', Latin `la', Norwegian `no', Persian `fa', Polish `pl', Portuguese `pt', Russian `ru', Slovenian `sl', Spanish `es', Swedish `sv', and Turkish `tr'. For example, you may reach the Chinese translation team by writing to `zh@li.org'. If you'd like to volunteer to *work* at translating messages, you should become a member of the translating team for your own language. The subscribing address is *not* the same as the list itself, it has `-request' appended. For example, speakers of Swedish can send a message to `sv-request@li.org', having this message body: subscribe Keep in mind that team members are expected to participate *actively* in translations, or at solving translational difficulties, rather than merely lurking around. If your team does not exist yet and you want to start one, or if you are unsure about what to do or how to get started, please write to `translation@iro.umontreal.ca' to reach the coordinator for all translator teams. The English team is special. It works at improving and uniformizing the terminology in use. Proven linguistic skill are praised more than programming skill, here. Available Packages ================== Languages are not equally supported in all packages. The following matrix shows the current state of internationalization, as of August 1997. The matrix shows, in regard of each package, for which languages PO files have been submitted to translation coordination. Ready PO files cs da de en es fi fr it ja ko nl no pl pt sl sv .-------------------------------------------------. bash | [] [] [] | 3 bison | [] [] [] | 3 clisp | [] [] [] [] | 4 cpio | [] [] [] [] [] | 5 diffutils | [] [] [] [] [] | 5 enscript | [] [] [] [] [] [] | 6 fileutils | [] [] [] [] [] [] [] [] [] [] | 10 findutils | [] [] [] [] [] [] [] [] | 8 flex | [] [] [] [] | 4 gcal | [] [] [] [] [] | 5 gettext | [] [] [] [] [] [] [] [] [] [] | 11 grep | [] [] [] [] [] [] [] [] [] | 9 hello | [] [] [] [] [] [] [] [] [] [] | 10 id-utils | [] [] [] | 3 indent | [] [] [] [] | 4 libc | [] [] [] [] [] [] [] | 7 m4 | [] [] [] [] [] | 5 make | [] [] [] [] [] [] | 6 music | [] [] | 2 ptx | [] [] [] [] [] [] [] [] | 8 recode | [] [] [] [] [] [] [] [] [] | 9 sh-utils | [] [] [] [] [] [] [] | 7 sharutils | [] [] [] [] [] | 5 tar | [] [] [] [] [] [] [] [] [] [] | 10 texinfo | [] | 1 textutils | [] [] [] [] [] [] [] [] [] | 9 wdiff | [] [] [] [] [] [] [] [] | 8 `-------------------------------------------------' 16 languages cs da de en es fi fr it ja ko nl no pl pt sl sv 27 packages 3 2 24 1 17 1 26 2 1 11 20 9 19 7 7 17 167 Some counters in the preceding matrix are higher than the number of visible blocks let us expect. This is because a few extra PO files are used for implementing regional variants of languages, or language dialects. For a PO file in the matrix above to be effective, the package to which it applies should also have been internationalized and distributed as such by its maintainer. There might be an observable lag between the mere existence a PO file and its wide availability in a distribution. If August 1997 seems to be old, you may fetch a more recent copy of this `ABOUT-NLS' file on most GNU archive sites. texinfo-3.12/Makefile.in-ORIG0000664000175000017500000002432713751601653013175 0ustar gg# Makefile.in generated automatically by automake 1.2f from Makefile.am # Copyright (C) 1994, 1995, 1996, 1997, 1998 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. # Be sure we're using the right version of Automake. # 1.2f was the first version that supported .txi as a Texinfo suffix. SHELL = /bin/sh srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ bindir = @bindir@ sbindir = @sbindir@ libexecdir = @libexecdir@ datadir = @datadir@ sysconfdir = @sysconfdir@ sharedstatedir = @sharedstatedir@ localstatedir = @localstatedir@ libdir = @libdir@ infodir = @infodir@ mandir = @mandir@ includedir = @includedir@ oldincludedir = /usr/include pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ top_builddir = . ACLOCAL = @ACLOCAL@ AUTOCONF = @AUTOCONF@ AUTOMAKE = @AUTOMAKE@ AUTOHEADER = @AUTOHEADER@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ transform = @program_transform_name@ NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : CATALOGS = @CATALOGS@ CATOBJEXT = @CATOBJEXT@ CC = @CC@ DATADIRNAME = @DATADIRNAME@ GENCAT = @GENCAT@ GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ GT_NO = @GT_NO@ GT_YES = @GT_YES@ INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@ INSTOBJEXT = @INSTOBJEXT@ INTLDEPS = @INTLDEPS@ INTLLIBS = @INTLLIBS@ INTLOBJS = @INTLOBJS@ MAKEINFO = @MAKEINFO@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ PACKAGE = @PACKAGE@ POFILES = @POFILES@ POSUB = @POSUB@ RANLIB = @RANLIB@ TERMLIBS = @TERMLIBS@ TEXCONFIG = @TEXCONFIG@ TEXMF = @TEXMF@ USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ l = @l@ AUTOMAKE_OPTIONS = 1.2f # Additional files to distribute. EXTRA_DIST = INTRODUCTION dir-example # All subdirectories. # Do intl/ and lib/ first since the C programs depend on them. # Do doc/ last so makeinfo will be built when we get there. # Others are alphabetical. SUBDIRS = intl lib info makeinfo po util doc ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = DIST_COMMON = README ABOUT-NLS AUTHORS COPYING ChangeLog INSTALL \ Makefile.am Makefile.in NEWS TODO acconfig.h aclocal.m4 config.guess \ config.h.in config.sub configure configure.in install-sh missing \ mkinstalldirs stamp-h.in texinfo.tex DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) TAR = tar GZIP = --best default: all .SUFFIXES: $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) \ && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status $(ACLOCAL_M4): configure.in cd $(srcdir) && $(ACLOCAL) config.status: $(srcdir)/configure $(SHELL) ./config.status --recheck $(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) cd $(srcdir) && $(AUTOCONF) config.h: stamp-h @: stamp-h: $(srcdir)/config.h.in $(top_builddir)/config.status cd $(top_builddir) \ && CONFIG_FILES= CONFIG_HEADERS=config.h \ $(SHELL) ./config.status @echo timestamp > stamp-h $(srcdir)/config.h.in: $(srcdir)/stamp-h.in $(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) acconfig.h cd $(top_srcdir) && $(AUTOHEADER) @echo timestamp > $(srcdir)/stamp-h.in mostlyclean-hdr: clean-hdr: distclean-hdr: -rm -f config.h maintainer-clean-hdr: # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. @SET_MAKE@ all-recursive install-data-recursive install-exec-recursive \ installdirs-recursive install-recursive uninstall-recursive \ check-recursive installcheck-recursive info-recursive dvi-recursive: @set fnord $(MAKEFLAGS); amf=$$2; \ list='$(SUBDIRS)'; for subdir in $$list; do \ target=`echo $@ | sed s/-recursive//`; \ echo "Making $$target in $$subdir"; \ (cd $$subdir && $(MAKE) $$target) \ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ done && test -z "$$fail" mostlyclean-recursive clean-recursive distclean-recursive \ maintainer-clean-recursive: @set fnord $(MAKEFLAGS); amf=$$2; \ rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \ rev="$$subdir $$rev"; \ done; \ for subdir in $$rev; do \ target=`echo $@ | sed s/-recursive//`; \ echo "Making $$target in $$subdir"; \ (cd $$subdir && $(MAKE) $$target) \ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ (cd $$subdir && $(MAKE) tags); \ done tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) here=`pwd` && cd $(srcdir) \ && mkid -f$$here/ID $(SOURCES) $(HEADERS) $(LISP) TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) $(LISP) tags=; \ here=`pwd`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ done; \ list='$(SOURCES) $(HEADERS)'; \ unique=`for i in $$list; do echo $$i; done | \ awk ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ test -z "$(ETAGS_ARGS)config.h.in$$unique$(LISP)$$tags" \ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags config.h.in $$unique $(LISP) -o $$here/TAGS) mostlyclean-tags: clean-tags: distclean-tags: -rm -f TAGS ID maintainer-clean-tags: distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist -rm -rf $(distdir) GZIP=$(GZIP) $(TAR) zxf $(distdir).tar.gz mkdir $(distdir)/=build mkdir $(distdir)/=inst dc_install_base=`cd $(distdir)/=inst && pwd`; \ cd $(distdir)/=build \ && ../configure --with-included-gettext --srcdir=.. --prefix=$$dc_install_base \ && $(MAKE) \ && $(MAKE) dvi \ && $(MAKE) check \ && $(MAKE) install \ && $(MAKE) installcheck \ && $(MAKE) dist -rm -rf $(distdir) @echo "========================"; \ echo "$(distdir).tar.gz is ready for distribution"; \ echo "========================" dist: distdir -chmod -R a+r $(distdir) GZIP=$(GZIP) $(TAR) chozf $(distdir).tar.gz $(distdir) -rm -rf $(distdir) dist-all: distdir -chmod -R a+r $(distdir) GZIP=$(GZIP) $(TAR) chozf $(distdir).tar.gz $(distdir) -rm -rf $(distdir) distdir: $(DISTFILES) -rm -rf $(distdir) mkdir $(distdir) -chmod 777 $(distdir) @for file in $(DISTFILES); do \ d=$(srcdir); \ test -f $(distdir)/$$file \ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ || cp -p $$d/$$file $(distdir)/$$file; \ done for subdir in $(SUBDIRS); do \ test -d $(distdir)/$$subdir \ || mkdir $(distdir)/$$subdir \ || exit 1; \ chmod 777 $(distdir)/$$subdir; \ (cd $$subdir && $(MAKE) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \ || exit 1; \ done info: info-recursive dvi: dvi-recursive check: all-am $(MAKE) check-recursive installcheck: installcheck-recursive all-recursive-am: config.h $(MAKE) all-recursive all-am: Makefile config.h install-exec: install-exec-recursive @$(NORMAL_INSTALL) install-data: install-data-recursive @$(NORMAL_INSTALL) install: install-recursive @: uninstall: uninstall-recursive all: all-recursive-am all-am install-strip: $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install installdirs: installdirs-recursive mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -rm -f Makefile $(DISTCLEANFILES) -rm -f config.cache config.log stamp-h stamp-h[0-9]* -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) mostlyclean-am: mostlyclean-hdr mostlyclean-tags mostlyclean-generic clean-am: clean-hdr clean-tags clean-generic mostlyclean-am distclean-am: distclean-hdr distclean-tags distclean-generic clean-am maintainer-clean-am: maintainer-clean-hdr maintainer-clean-tags \ maintainer-clean-generic distclean-am mostlyclean: mostlyclean-recursive mostlyclean-am clean: clean-recursive clean-am distclean: distclean-recursive distclean-am -rm -f config.status maintainer-clean: maintainer-clean-recursive maintainer-clean-am @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." -rm -f config.status .PHONY: default mostlyclean-hdr distclean-hdr clean-hdr \ maintainer-clean-hdr install-data-recursive uninstall-data-recursive \ install-exec-recursive uninstall-exec-recursive installdirs-recursive \ uninstalldirs-recursive all-recursive check-recursive \ installcheck-recursive info-recursive dvi-recursive \ mostlyclean-recursive distclean-recursive clean-recursive \ maintainer-clean-recursive tags tags-recursive mostlyclean-tags \ distclean-tags clean-tags maintainer-clean-tags distdir info dvi \ installcheck all-recursive-am all-am install-exec install-data install \ uninstall all installdirs mostlyclean-generic distclean-generic \ clean-generic maintainer-clean-generic clean mostlyclean distclean \ maintainer-clean # 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: texinfo-3.12/NEWS0000664000175000017500000003202706477045734011076 0ustar ggThis file records noteworthy changes. 3.12 (3 March 1998) * Elisp files removed, since they are only usefully distributed with Emacs. * Restore inclusion of compile-time $(infodir) to INFOPATH. * install-info creates a proper dir file. * Various portability fixes. 3.11 (31 July 1997) * New commands: - @uref to make a reference to a url; @url now only indicates such. - @image to include graphics (epsf for TeX). - @deftypemethod and @deftypemethodx to document methods in strongly typed object-oriented languages, such as C++. - @html for raw HTML. - @ifnothtml @ifnotinfo @ifnottex for more precise conditionals. - @kbdinputstyle to control when @kbd uses the slanted typewriter font. - @email takes second optional argument. * texinfo.tex reads texinfo.cnf (if present) for site-wide TeX configuration; for example, A4 paper sizes. * info: - arrow keys supported. - trailing : in INFOPATH appends default path. - new option --index-search for online help support. * makeinfo: - output files removed if errors unless (new option) --force. - new option -P to prepend to search path. - macro expansion file can be standard output. * install-info creates a new dir file if necessary. * update-info script to create a dir file from all info files. * Elisp: texnfo-tex.el and detexinfo.el removed from the distribution; - texnfo-tex features are now part of standard TeX & Texinfo packages; - makeinfo --no-headers does a better job than detexinfo.el. * Documentation: - Updates, revisions, corrections in the manual. - makeinfo.texi removed, as it was a copy of what was in texinfo.texi. * gettext support in sources, French and German translations included. * info man page removed; use the Texinfo manual. * Automake used, other portability fixes. 3.10 (nonexistent) 3.9 (4 October 1996) * makeinfo: - Give a suppressible (with --no-validate) error for references outside of any node. - Keep track of multitable output correctly for split files; this caused nodes after the first multitable to be ``undefined''. * install-info: - Rename --infodir option to --info-dir. - More robust error checking to avoid various crashes. * configure: Include replacements for memcpy and memmove functions in the distribution, in case they are missing. 3.8 (30 September 1996) * Define and/or document new and/or previously existing commands: Accents: @" @' @, @" @= @^ @` @~ @H @d @dotaccent @dotless @ringaccent @tieaccent @u @ubaraccent @v Special characters: @AA @AE @L @O @OE @aa @ae @exclamdown @l @o @oe @pounds @questiondown @ss Special punctuation: @! @? @enddots dir file maintenance: @dircategory @direntry; also new program, install-info HTML support: @email @url @ifhtml...@end ifhtml Macros: @macro @unmacro Tables: @multitable @tab Hyphenation: @- @hyphenation Spacing: @ @ @ Sectioning: @headings singleafter/doubleafter (change heading style after current page) @centerchap @setchapterstyle Other: @shorttitlepage (simple title pages) @detailmenu...@end detailmenu (help makeinfo parse master menus) * Makeinfo prefers an input file named `foo.texinfo' or `foo.texi' or `foo.txinfo' to just `foo' (the latter most likely being an executable). * Makeinfo implements @. @! @? correctly, as end-of-sentence punctuation. * @key marks its argument with a lozenge in TeX and <...> in Info. * TeX output has substantially decreased interline spacing and other formatting changes. * Remove these obsolete and never-documented commands: @infotop @infoappendix @infoappendixsec @infoappendixsubsec @infoappendixsubsubsec @infochapter @infosection @infosubsection @infosubsubsection @infounnumbered @infounnumberedsec @infounnumberedsubsec @infounnumberedsubsubsec @input @smallbreak @medbreak @overfullrule @br * Deprecate these obsolete commands, to be removed in the next release: @ctrl @infoinclude @iappendix @iappendixsection @iappendixsec @iappendixsubsec @iappendixsubsubsec @ichapter @isection @isubsection @isubsubsection @iunnumbered @iunnumberedsec @iunnumberedsubsec @iunnumberedsubsubsec @setchapterstyle @titlespec 3.7 (24 December 1995) * Have --version print texinfo release number as well as the individual program version. * Better man page cleaning. * Update Elisp files from current Emacs release. 3.6 (21 June 1995) * Unmatched brace error reporting improved. * Missing comment terminator prevented compilation. 3.5 (20 June 1995) * Autoconf update. * Support for parallel makes. * make install does not install Elisp files. 3.4 (19 June 1995) * Handle @ifhtml in Elisp. * Update FSF address. 3.3 (15 June 1995) * Portability changes. * Compile Elisp files. * Don't distribute .info* files. 3.2 (9 June 1995) * Standalone Info can read Unix man pages. * New commands: @! @? @^ @" @enddots. * makeinfo -E does macro expansion (and nothing else). 3.1 (23 May 1993) Just bug fixes, see ChangeLog for full details. texinfo-3.0: first release of Texinfo version 2, with many new commands. Here is the separate NEWS for old releases of Info: Version 2.11, Sat Apr 1 09:15:21 1995 Changes since 2.7 beta: Although the basic code remains the same, there are numerous nits fixed, including some display bugs, and a memory leak. Some changes that have taken place with larger impact include the way in which the (dir) node is built; I have added in support for "localdir" directories among other things. Info files may be stored in compressed formats, and in their own subdirectories; menu items which do not explicitly name the node to which they are attached have the menu item name looked up as an Info file if it is not found within the current document. This means that the menu item: * Info:: The Info documentation reader. in (dir) refers to the info node "(info)Top". Please see the ChangeLog and documentation for details on other changes. Version 2.7 beta, Wed Dec 30 02:02:38 1992 Version 2.6 beta, Tue Dec 22 03:58:07 1992 Version 2.5 beta, Tue Dec 8 14:50:35 1992 Version 2.4 beta, Sat Nov 28 14:34:02 1992 Version 2.3 beta, Fri Nov 27 01:04:13 1992 Version 2.2 beta, Tue Nov 24 09:36:08 1992 Version 2.1 beta, Tue Nov 17 23:29:36 1992 Changes since 2.5 beta: Note that versions 2.6 and 2.7 Beta were only released to a select group. * "info-" removed from the front of M-x commands. * Automatic footnote display. When you enter a node which contains footnotes, and the variable "automatic-footnotes" is "On", Info pops up a window containing the footnotes. Likewise, when you leave that node, the window containing the footnotes goes away. * Cleaner built in documentation, and documentation functions. Use: o `M-x describe-variable' to read a variable's documenation o `M-x describe-key' to find out what a particular keystroke does. o `M-x describe-function' to read a function's documentation. o `M-x where-is' to find out what keys invoke a particular function. * Info can "tile" the displayed windows (via "M-x tile-windows"). If the variable "automatic-tiling" is "On", then splitting a window or deleting a window causes the remaining windows to be retiled. * You can save every keystroke you type in a "dribble file" by using the `--dribble FILENAME' option. You can initially read keystrokes from an alternate input stream with `--restore FILENAME', or by redirecting input on the command line `info < old-dribble'. * New behaviour of menu items. If the label is the same as the target node name, and the node couldn't be found in the current file, treat the label as a file name. For example, a menu entry in "DIR" might contain: * Emacs:: Cool text-editor. Info would not find the node "(dir)Emacs", so just plain "(emacs)" would be tried. * New variable "ISO-Latin" allows you to use European machines with 8-bit character sets. * Cleanups in echo area reading, and redisplay. Cleanups in handling the window which shows possible completions. * Info can now read files that have been compressed. An array in filesys.c maps extensions to programs that can decompress stdin, and write the results to stdout. Currently, ".Z"/uncompress, ".z"/gunzip, and ".Y"/unyabba are supported. The modeline for a compressed file shows "zz" in it. * There is a new variable "gc-compressed-files" which, if non-zero, says it is okay to reclaim the file buffer space allocated to a file which was compressed, if, and only if, that file's contents do not appear in any history node. * New file `nodemenu.c' implements a few functions for manipulating previously visited nodes. `C-x C-b' (list-visited-nodes) produces a menu of the nodes that could be reached by info-history-node in some window. `C-x b' (select-visited-node) is similar, but reads one of the node names with completion. * Keystroke `M-r' (move_to_screen_line) allows the user to place the cursor at the start of a specific screen line. Without a numeric argument, place the cursor on the center line; with an arg, place the cursor on that line. * Interruptible display implemented. Basic display speedups and hacks. * The message "*** Tags Out of Date ***" now means what it says. * Index searching with `,' (info-index-next) has been improved. * When scrolling with C-v, C-M-v, or M-v, only "Page Only" scrolling will happen. * Continous scrolling (along with `]' (info-global-next) and `[' (info-global-prev) works better. `]' and `[' accept numeric arguments, moving that many nodes in that case. * `C-x w' (info-toggle-wrap) controls how lines wider than the width of the screen are displayed. If a line is too long, a `$' is displayed in the rightmost column of the window. * There are some new variables for controlling the behaviour of Info interactively. The current list of variables is as follows: Variable Name Default Value Description ------------- ------------- ----------- `automatic-footnotes' On When "On", footnotes appear and disappear automatically. `automatic-tiling' Off When "On", creating of deleting a window resizes other windows. `visible-bell' Off If non-zero, try to use a visible bell. `errors-ring-bell' On If non-zero, errors cause a ring. `show-index-match' On If non-zero, the portion of the string matched is highlighted by changing its case. `scroll-behaviour' Continuous One of "Continuous", "Next Only", or "Page Only". "Page Only" prevents you from scrolling past the bottom or top of a node. "Next Only" causes the Next or Prev node to be selected when you scroll past the bottom or top of a node. "Continous" moves linearly through the files hierchichal structure. `scroll-step' 0 Controls how scrolling is done for you when the cursor moves out of the current window. Non-zero means it is the number of lines you would like the screen to shift. A value of 0 means to center the line containing the cursor in the window. `gc-compressed-files' Off If non-zero means it is okay to reclaim the file buffer space allocated to a file which was compressed, if, and only if, that file's contents do not appear in the node list of any window. `ISO-Latin' Off Non-zero means that you are using an ISO Latin character set. By default, standard ASCII characters are assumed. ________________________________________ This release of Info is version 2.5 beta. Changes since 2.4 beta: * Index (i) and (,) commands fully implemented. * "configure" script now shipped with Info. * New function "set-variable" allows users to set various variables. * User-settable behaviour on end or beginning of node scrolling. This supercedes the SPC and DEL changes in 2.3 beta. ________________________________________ This release of Info is version 2.4 beta. Changes since 2.3 beta: * info-last-node now means move to the last node of this info file. * info-history-node means move backwards through this window's node history. * info-first-node moves to the first node in the Info file. This node is not necessarily "Top"! * SPC and DEL can select the Next or Prev node after printing an informative message when pressed at the end/beg of a node. ---------------------------------------- This release of Info is version 2.3 beta. Changes since 2.2 beta: * M-x command lines if NAMED_COMMANDS is #defined. Variable in Makefile. * Screen height changes made quite robust. * Interactive function "set-screen-height" implements user height changes. * Scrolling on some terminals is faster now. * C-l with numeric arguement is fixed. ---------------------------------------- This release of Info is version 2.2 beta. Changes since 2.0: * C-g can now interrupt multi-file searches. * Incremental search is fully implemented. * Loading large tag tables is much faster now. * makedoc.c replaces shell script, speeding incremental builds. * Scrolling in redisplay is implemented. * Recursive uses of the echo area made more robust. * Garbage collection of unreferenced nodes.