This commit was generated by cvs2svn to compensate for changes in r42660,

which included commits to RCS files with non-trunk default branches.
This commit is contained in:
Mark Murray 1999-01-14 19:35:19 +00:00
commit e4c5982e1a
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=42661
132 changed files with 55751 additions and 4585 deletions

225
contrib/texinfo/ABOUT-NLS Normal file
View File

@ -0,0 +1,225 @@
Notes 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.

3
contrib/texinfo/AUTHORS Normal file
View File

@ -0,0 +1,3 @@
Richard Stallman, Brian Fox, Bob Chassell, Noah Friedman, Paul Rubin,
Karl Berry, and no doubt many others.

View File

@ -2,7 +2,7 @@
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
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.
@ -279,7 +279,7 @@ POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Programs
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
@ -305,7 +305,8 @@ the "copyright" line and a pointer to where the full notice is found.
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
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.

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +1,6 @@
Getting Started with Texinfo
============================
25 March 1993
Most of the installation instructions are described in the file `INSTALL'.
One additional note to make is that if your info files are in a nonstandard
place (i.e. not in the `info' directory immediately under $prefix) you may
wish to change the default info path as specified via DEFAULT_INFOPATH in
info/Makefile.in.
"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,
@ -16,23 +8,23 @@ 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.texi'.
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.texi' file. You do not need to
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, type
* If you want to use the `info' program, run
$ info -f info-stnd
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.
@ -40,7 +32,7 @@ GNU Emacs.
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
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
@ -114,6 +106,6 @@ 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@prep.ai.mit.edu.
Please report bugs to bug-texinfo@gnu.org.
Happy formatting.

View File

@ -0,0 +1,16 @@
## 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

View File

@ -1,211 +1,347 @@
# Makefile for Texinfo distribution.
# $Id: Makefile.in,v 1.11 1996/10/04 18:40:33 karl Exp $
#
# Copyright (C) 1993, 96 Free Software Foundation, Inc.
# Makefile.in generated automatically by automake 1.2f from Makefile.am
# 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.
# 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; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
# 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.
# Be sure we're using the right version of Automake.
# 1.2f was the first version that supported .txi as a Texinfo suffix.
#### Start of system configuration section. ####
SHELL = /bin/sh
srcdir = @srcdir@
VPATH = $(srcdir):$(common)
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
common = $(srcdir)/libtxi
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
CC = @CC@
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@
LN = ln
RM = rm -f
TAR = tar
MKDIR = mkdir
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@
DEFS = @DEFS@
LIBS = @LIBS@
LOADLIBES = $(LIBS)
AUTOMAKE_OPTIONS = 1.2f
ALLOCA = @ALLOCA@
# Additional files to distribute.
EXTRA_DIST = INTRODUCTION dir-example
SHELL = /bin/sh
# 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
CFLAGS = @CFLAGS@
LDFLAGS = @LDFLAGS@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = $(exec_prefix)/bin
# Prefix for each installed program, normally empty or `g'.
binprefix =
# Prefix for each installed man page, normally empty or `g'.
manprefix =
manext = 1
mandir = $(prefix)/man/man$(manext)
infodir = $(prefix)/info
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
# For info program.
DEFAULT_INFOPATH = $(infodir):.
TAR = tar
GZIP = --best
default: all
#### End of system configuration section. ####
.SUFFIXES:
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps Makefile
VERSION = 3.9
DISTNAME = texinfo-$(VERSION)
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
# Subdirectories that have makefiles
SUBDIRS = libtxi makeinfo info util emacs
$(ACLOCAL_M4): configure.in
cd $(srcdir) && $(ACLOCAL)
# All subdirectories that go into a distribution
ALL_SUBDIRS = $(SUBDIRS) makeinfo/macros
MDEFINES = bindir='$(bindir)' mandir='$(mandir)' manext='$(manext)' \
prefix='$(prefix)' binprefix='$(binprefix)' \
manprefix='$(manprefix)' infodir='$(infodir)' CFLAGS='$(CFLAGS)' \
CC='$(CC)' ALLOCA='$(ALLOCA)' LDFLAGS='$(LDFLAGS)' \
DEFAULT_INFOPATH='$(DEFAULT_INFOPATH)'
all: sub-all texinfo
install: all installdirs
test -f $(infodir)/dir || $(INSTALL_DATA) $(srcdir)/dir $(infodir)
for dir in $(SUBDIRS); do \
echo making $@ in $$dir; \
(cd $$dir && $(MAKE) $(MDEFINES) $@ || exit 1); \
done
d=$(srcdir); test -f ./texinfo && d=.; \
(cd $$d && for f in texinfo texinfo-* ; do \
$(INSTALL_DATA) $$f $(infodir)/$$f; done)
$(POST_INSTALL)
./util/install-info --info-dir=$(infodir) $(infodir)/texinfo
@echo Please install $(srcdir)/texinfo.tex manually.
installdirs:
-$(SHELL) $(srcdir)/util/mkinstalldirs $(bindir) $(datadir) $(infodir) $(mandir)
uninstall:
for dir in $(SUBDIRS); do \
echo making $@ in $$dir; \
(cd $$dir && $(MAKE) $(MDEFINES) $@ || exit 1); \
done
$(RM) $(infodir)/texinfo $(infodir)/texinfo-*
Makefile: Makefile.in config.status
$(SHELL) ./config.status
config.status: configure
config.status: $(srcdir)/configure
$(SHELL) ./config.status --recheck
$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
cd $(srcdir) && $(AUTOCONF)
configure: configure.in
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
sub-all TAGS:
for dir in $(SUBDIRS); do \
echo making $@ in $$dir; \
(cd $$dir && $(MAKE) $(MDEFINES) $@ || exit 1); \
done
.PHONY: sub-all
mostlyclean-hdr:
clean mostlyclean:
for dir in $(SUBDIRS); do \
echo making $@ in $$dir; \
(cd $$dir && $(MAKE) $(MDEFINES) $@ || exit 1); \
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
distclean: clean texclean
for dir in $(SUBDIRS); do \
echo making $@ in $$dir; \
(cd $$dir && $(MAKE) $(MDEFINES) $@ || exit 1); \
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
$(RM) Makefile *.status *.cache *.log texinfo texinfo-? texinfo-??
texclean:
$(RM) *.aux *.cp *.cps *.dvi *.fn *.fns *.ky *.kys *.pg *.pgs
$(RM) *.toc *.tp *.tps *.vr *.vrs
realclean: distclean
# Let's hope we weren't cross-compiling.
# If we depend on sub-all, this always gets remade. Annoying.
info texinfo: texinfo.texi
./makeinfo/makeinfo -I$(srcdir) texinfo.texi
.PHONY: info
dvi texinfo.dvi:
PATH="$(srcdir)/util:$${PATH}" TEXINPUTS="$(srcdir):$(common):$${TEXINPUTS}" texi2dvi $(srcdir)/texinfo.texi
.PHONY: dvi
dist: DISTFILES
$(RM) -r $(DISTNAME)
$(MKDIR) $(DISTNAME)
for d in `find . -type d ! -name RCS -print`; do \
d=`echo $$d | grep -v '[@=]'`; \
test -z "$$d" || test "$$d" = . || test "$$d" = "./$(DISTNAME)" \
|| mkdir $(DISTNAME)/$$d; done
for f in `cat DISTFILES`; do \
$(LN) $(srcdir)/$$f $(DISTNAME)/$$f || \
{ echo copying $$f; cp -p $(srcdir)/$$f $(DISTNAME)/$$f ; } \
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
(cd $(DISTNAME); $(MAKE) $(MFLAGS) distclean)
$(TAR) chvf - $(DISTNAME) | gzip >$(DISTNAME).tar.gz
$(RM) -r $(DISTNAME)
info: info-recursive
dvi: dvi-recursive
check: all-am
$(MAKE) check-recursive
installcheck: installcheck-recursive
all-recursive-am: config.h
$(MAKE) all-recursive
# Gets rid of most of the unwanted files. Verify manually (if necessary)
# that this produces a list of all the files desired in the distribution.
DISTFILES: force
(cd $(srcdir); find . ! -type d -print) \
| sed '/\/RCS\//d; \
/\/EMACS-BACKUPS\//d; \
/\.tar.*/d; \
/~$$/d; /\.o$$/d; \
/\.gdbinit$$/d; \
/\.orig$$/d; \
/\#$$/d; \
/\/info\/info$$/d; \
/\.info$$/d; \
/\.elc/d; \
/\/makeinfo\/makeinfo$$/d; \
/\/$(DISTNAME)\/.*$$/d; \
/\/util\/texindex$$/d; \
/texinfo$$/d; \
/texinfo-[0-9]+$$/d; \
/\/.*\.BAK$$/d; \
/\/.*\.a$$/d; \
/\/core$$/d; \
/\/*\.core$$/d; \
/\/core\..*$$/d; \
/\/a.out$$/d; \
/\/[=@]/d; \
/\/conftest\.c$$/d; \
/\/DISTFILES$$/d; \
/\/foo$$/d; \
/\/bar$$/d; \
/\.toc$$/d; \
/\.bak$$/d; \
/\.aux$$/d; /\.log$$/d; \
/\.cps$$/d; /\.cp$$/d; \
/\.fns$$/d; /\.fn$$/d; \
/\.tps$$/d; /\.tp$$/d; \
/\.vrs$$/d; /\.vr$$/d; \
/\.pgs$$/d; /\.pg$$/d; \
/\.kys$$/d; /\.ky$$/d; \
/\.ops$$/d; /\.op$$/d; \
s/^.\///; /^\.$$/d;' \
| sort | uniq > DISTFILES
all-am: Makefile config.h
force:
install-exec: install-exec-recursive
@$(NORMAL_INSTALL)
# Prevent GNU make v3 from overflowing arg limit on SysV.
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:

View File

@ -1,5 +1,45 @@
This 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
@ -91,3 +131,205 @@ This file records noteworthy changes.
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.

View File

@ -1,54 +1,48 @@
Texinfo, Version 3
==================
This is the README file for the GNU Texinfo distribution.
The primary distribution point is ftp://ftp.gnu.org/pub/gnu.
This is the README file for version 3 of the Texinfo distribution.
Files within this distribution have their own version and edition
numbers. When you refer to a file, please mention its own number, as
well as the version number of the Texinfo distribution.
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.
PLEASE REPORT BUGS TO: bug-texinfo@prep.ai.mit.edu
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.
Texinfo 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 "Info file", with an Info
documentation-reading program. By convention, Texinfo source file
names end with a `.texi' or `.texinfo' extension. Texinfo is
described in the Texinfo manual (the file ./texinfo.texi).
For generic installation instructions on compiling and installing this
Automake-based distribution, please read the file `INSTALL'.
Installation notes specific to Texinfo:
You can write and format Texinfo files into Info files within GNU Emacs,
and read them using the Emacs Info reader. If you do not have Emacs,
you can format Texinfo files into Info files using `makeinfo' and read
them using `info'. Use TeX, which is not included in this package (see
`How to Obtain TeX' in the Texinfo manual for information), to typeset
Texinfo files for printing.
* 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.
For instructions on compiling and installing info, makeinfo, texi2dvi,
and texindex, please read the file `INSTALL'. The Emacs Lisp files are
not installed by default; to install them, use `make install' in the
`emacs' subdirectory. The Info tree uses a file `dir' as its root node;
a sample `dir' file is included in the distribution, but not installed
anywhere. Use it or not as you like.
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.
INTRODUCTION This file tells you how to create
readable files from the Texinfo source
files in this distribution.
Texinfo source files (in ./doc):
Texinfo source files:
texinfo.texi This manual describes Texinfo. It
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, how to use TeX,
makeinfo, and the Emacs Lisp Texinfo
formatting commands.
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
@ -61,58 +55,28 @@ Texinfo source files:
info-stnd.texi This manual tells you how to use
the standalone GNU Info reader that is
included in this distribution as a C
source file, `info.c'.
makeinfo.texi This manual tells you how to use
makeinfo. The same information is
contained in a chapter of the Texinfo
manual; it has been extracted here for
your convenience.
included in this distribution as C
source (./info).
Printing related files:
texinfo.tex This TeX definitions file tells
doc/texinfo.tex This TeX definitions file tells
the TeX program how to typeset a
Texinfo file into a DVI file ready for
printing.
texindex.c This file contains the source for
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.
texi2dvi This is a shell script for
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.
GNU Emacs related files:
texinfmt.el This Emacs Lisp file provides the
functions that GNU Emacs uses to
format a Texinfo file into an Info
file.
texinfo.el This file provides Texinfo mode
for GNU Emacs.
texnfo-upd.el These files provides commands to
texnfo-tex.el help you write Texinfo files
makeinfo.el using GNU Emacs Texinfo mode.
detexinfo.el This extra utility file contains functions
to remove Texinfo commands from a
Texinfo source file.
info.el These are the standard GNU Emacs
informat.el Info reading and support files,
included here for your convenience.
Source files for standalone C programs:
Source files for standalone C programs (./lib, ./makeinfo, ./info):
makeinfo.c This file contains the source for
the `makeinfo' program that you can
@ -128,7 +92,7 @@ Source files for standalone C programs:
getopt.h
C Installation files:
Installation files:
configure This file creates creates a Makefile
which in turn creates an `info' or
@ -136,22 +100,22 @@ C Installation files:
distribution.
configure.in This is a template for creating
`configure' using m4 macros.
`configure' using Autoconf.
Makefile.in This is a template for `configure'
to use to make a Makefile.
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:
Other files (util):
NEWS This contains a summary of new
features since the first edition
of Texinfo.
info.1 This is a `man' page that briefly
describes the standalone `info'
program.
fixfonts This is a shell script to install the
`lcircle10' TeX fonts as an alias for
the `circle10' fonts. In some older

View File

@ -1,35 +1,79 @@
If you are interested in working on any of these,
email bug-texinfo@prep.ai.mit.edu.
If you are interested in working on any of these, email bug-texinfo@gnu.org.
* Use Automake.
* 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.
* Use a config header file instead of @DEFS@.
* 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.
* 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 come close.
* 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.
* Change bars. This is difficult or impossible in TeX,
unfortunately. To do it right requires device driver support.
* Language:
- @figure:
@figure [xref-label]
@figureinclude <filename>, [<height>], [<width>]
@figurehsize <dimen>
@figurevsize <dimen>
@caption ... @end caption
<arbitrary Texinfo commands>
@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.
* The dark corner symbol for the gawk manual.
* 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.
* Better i18n support, including support for 8-bit input
characters. Requires fonts, and the DC fonts are not (as of this
writing) free.
* 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)
* @exercise/@answer command for, e.g., gawk.
* @figure.
* HTML output in makeinfo.
* Include a complete functional summary, a la a reference card, in the manual.
* Use @ as the escape character, and Texinfo syntax generally, in the
table of contents, aux, and index files. Eliminate all the crazy
redefinitions of every Texinfo command (which lists always seem to be
incomplete).
* Improve the manuals for makeinfo, standalone info, etc.
* Install-info:
- be able to copy the info file to compile-time $(infodir), to
simplify by-hand installation.

View File

@ -0,0 +1,51 @@
/* 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 <libintl.h>
#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). */

513
contrib/texinfo/aclocal.m4 vendored Normal file
View File

@ -0,0 +1,513 @@
dnl 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>>, <<[^ ]>>, <<>>), <<>>,
<<test -z "<<$>>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>,
<<am_indx=1
for am_file in <<$1>>; 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 <drepper@cygnus.com>, 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 <libintl.h>], [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 <locale.h> in the installed <libintl.h> 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 <locale.h>"
else
INCLUDE_LOCALE_H="\
/* The system does not provide the header <locale.h>. 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 <drepper@cygnus.com>, 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 <locale.h>.
# Ulrich Drepper <drepper@cygnus.com>, 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 <locale.h>], [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])

890
contrib/texinfo/config.guess vendored Executable file
View File

@ -0,0 +1,890 @@
#! /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 <bothner@cygnus.com>.
# 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 <<EOF >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 <sys/systemcfg.h>
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 <unistd.h>
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/^ //' <<EOF >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 <<EOF
main(argc, argv)
int argc;
char *argv[];
{
#ifdef __MIPSEB__
printf ("%s-unknown-linux-gnu\n", argv[1]);
#endif
#ifdef __MIPSEL__
printf ("%sel-unknown-linux-gnu\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
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 <<EOF
#include <features.h>
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' </usr/options/cb.name`
echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
elif /bin/uname -X 2>/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 <Richard.M.Bartel@ccMail.Census.GOV>
echo i586-unisys-sysv4
exit 0 ;;
*:UNIX_System_V:4*:FTX*)
# From Gerald Hewes <hewes@openmarket.com>.
# 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 <<EOF
#ifdef _SEQUENT_
# include <sys/types.h>
# include <sys/utsname.h>
#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 <sys/param.h>
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

257
contrib/texinfo/config.h.in Normal file
View File

@ -0,0 +1,257 @@
/* 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 <alloca.h> 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 <sys/types.h> 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 <sys/types.h> 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 <sys/time.h> 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 <argz.h> header file. */
#undef HAVE_ARGZ_H
/* Define if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
/* Define if you have the <limits.h> header file. */
#undef HAVE_LIMITS_H
/* Define if you have the <locale.h> header file. */
#undef HAVE_LOCALE_H
/* Define if you have the <malloc.h> header file. */
#undef HAVE_MALLOC_H
/* Define if you have the <ncurses/termcap.h> header file. */
#undef HAVE_NCURSES_TERMCAP_H
/* Define if you have the <nl_types.h> header file. */
#undef HAVE_NL_TYPES_H
/* Define if you have the <pwd.h> header file. */
#undef HAVE_PWD_H
/* Define if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define if you have the <sys/fcntl.h> header file. */
#undef HAVE_SYS_FCNTL_H
/* Define if you have the <sys/file.h> header file. */
#undef HAVE_SYS_FILE_H
/* Define if you have the <sys/param.h> header file. */
#undef HAVE_SYS_PARAM_H
/* Define if you have the <sys/ptem.h> header file. */
#undef HAVE_SYS_PTEM_H
/* Define if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H
/* Define if you have the <sys/ttold.h> header file. */
#undef HAVE_SYS_TTOLD_H
/* Define if you have the <sys/wait.h> header file. */
#undef HAVE_SYS_WAIT_H
/* Define if you have the <termcap.h> header file. */
#undef HAVE_TERMCAP_H
/* Define if you have the <termio.h> header file. */
#undef HAVE_TERMIO_H
/* Define if you have the <termios.h> header file. */
#undef HAVE_TERMIOS_H
/* Define if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define if you have the <values.h> 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 <libintl.h>
#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). */

952
contrib/texinfo/config.sub vendored Executable file
View File

@ -0,0 +1,952 @@
#! /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

File diff suppressed because it is too large Load Diff

View File

@ -1,42 +1,80 @@
dnl Process this file with autoconf to produce a configure script.
dnl $Id: configure.in,v 1.3 1996/10/03 18:33:52 karl Exp $
AC_INIT(texinfo.texi)
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 </dev/null | grep '^TEXMF='`
AC_SUBST(TEXMF)
AC_ISC_POSIX
AC_MINIX
dnl Checks for libraries.
# Needed on sysV68 for sigblock, sigsetmask.
AC_CHECK_LIB(bsd, sigblock)
AC_CHECK_LIB(z, gzdopen)
# Needed on sysV68 for sigblock, sigsetmask. But check for it in libc first.
AC_CHECK_FUNC(sigblock, , AC_CHECK_LIB(bsd, sigblock))
# 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 curses termcap terminfo termlib ; do
for termlib in ncurses curses termcap terminfo termlib ; do
AC_CHECK_LIB(${termlib}, tputs,
[TERMLIBS="${TERMLIBS} -l${termlib}"; break])
done
AC_SUBST(TERMLIBS)
dnl Checks for header files.
dnl Do not use <ncurses/termcap.h> 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(unistd.h termios.h termio.h strings.h string.h varargs.h \
sys/time.h sys/fcntl.h sys/ttold.h sys/ptem.h sys/file.h)
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 \
vfprintf vsprintf strerror sigprocmask sigsetmask)
sigprocmask sigsetmask)
dnl strcasecmp, strerror, xmalloc, xrealloc, probably others should be added.
AC_REPLACE_FUNCS(memcpy memmove strdup)
AC_REPLACE_FUNCS(memcpy memmove strdup strerror)
AC_OUTPUT(Makefile libtxi/Makefile makeinfo/Makefile info/Makefile util/Makefile emacs/Makefile)
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])

View File

@ -1,309 +1,341 @@
This is the directory file `dir' a.k.a. `DIR', which contains the
topmost node of the Info hierarchy. This 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.
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.20 1996/10/04 18:39:29 karl Exp $
$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.
File: dir, Node: Top, This is the top of the INFO tree.
This node gives a menu of the major topics accessible through Info.
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). Cpio archiver.
* DC: (dc). Postfix arbitrary expression 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). A text processing and scanning language.
* 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). ``Tape'' archiver.
* Text utilities: (textutils). GNU text utilities.
* Time: (time). Measuring program resource usage.
* UUCP: (uucp). Copying between machines, offline.
* Wdiff: (wdiff). Word-by-word comparison.
* 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++.
* Gperf: (gperf). Perfect hash function generator.
* Gprof: (gprof). Profiler.
* Indent: (indent). Prettyprinter for programs.
* Ld: (ld). Linker.
* 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: (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.
* info program: (info-stnd). Standalone Info-reading program.
* makeinfo: (makeinfo). Convert Texinfo source to Info or plain ASCII.
* 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.
* Elisp: (elisp). GNU Emacs Lisp reference manual.
* Intro Elisp: (emacs-lisp-intro). Introduction to Elisp programming.
* Calc: (calc). Calculator and more.
* CC-mode: (ccmode). Editing C, C++, and Objective C.
* 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.
* 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 admin
* Autoconf: (autoconf). Automatic generation of package configuration.
* Automake: (automake). Making Makefile.in's.
* Configure: (configure). Cygnus configure.
* Gettext: (gettext). Internationalization.
* Gnats: (gnats). Cygnus bug tracking system.
* Maintaining: (maintain). Maintaining GNU software.
* Remsync: (remsync). Remote synchronization of directory trees.
* Send PR: (send-pr). Cygnus bug reporting for Gnats.
* Source config: (cfg-paper). Some theory on configuring source packages.
* Standards: (standards). GNU coding standards.
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.
* 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.
* Stabs: (stabs). Symbol table debugging information format.
* 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.
DOS
* Demacs: (demacs). GNU Emacs for DOS.
* GNUish: (gnuish). GNU utilities for DOS.
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.
* TeXDraw: (texdraw). Drawing PostScript diagrams within TeX.
* Web2c: (web2c). TeX, Metafont, and their companion programs.
* 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.
* HTML: (snafu). Hypertext Markup Language 2.0 specification.
* Jargon: (jargon). The jargon file.
* Perl: (perl). Practical extraction and report language.
* 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.
* Screen: (screen). Virtual screen manager.
* UMB C.S. Dept.: (csinfo). UMass/Boston Computer Science Dept. info.
Individual utilities
* aid: (id-utils)aid invocation. Matching strings.
* ar: (binutils)ar. Create/modify/extract archives.
* at-pr: (gnats)at-pr. Bug report timely reminders.
* 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 filesystems' disk usage.
* diff3: (diff)Invoking diff3. Three-way diff.
* dir: (fileutils)dir invocation. List directories briefly.
* 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.
* 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.
* 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.
* 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.
* 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.
* 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.
* 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.
* 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.
* 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.
* 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.
* 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.
* yes: (sh-utils)yes invocation. Print a string indefinitely.
* zcat: (gzip)Overview. Decompression to stdout.
* 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.

View File

@ -0,0 +1,57 @@
## 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*

View File

@ -0,0 +1,332 @@
# 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:

View File

@ -0,0 +1,27 @@
This 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
<texmf>/tex/texinfo/ for texinfo.tex and <texmf>/tex/plain/dvips/ for
epsf.tex. If you use the default installation paths, <texmf> will be
/usr/local/share/texmf. If you have teTeX, you can find <texmf> 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.

View File

@ -0,0 +1,546 @@
%%% ====================================================================
%%% 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=<dimen> \epsfbox{filename.ps}
%%% or
%%% \epsfysize=<dimen> \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
%%% <beebe@math.utah.edu>, 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
%%% <beebe@math.utah.edu>, 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
%%% <beebe@math.utah.edu>, 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
%%% <beebe@math.utah.edu>, 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
%%% <beebe@math.utah.edu>, 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
%%% <beebe@math.utah.edu>, 13 July 1993 [2.5].
%%% Add \epsfframethickness for control of
%%% \epsfframe frame lines.
%%%
%%% ---------------------------------------------
%%% Revised by Nelson H. F. Beebe
%%% <beebe@math.utah.edu>, 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
%%% <beebe@math.utah.edu>, 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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,911 @@
\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

View File

@ -0,0 +1,177 @@
@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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,45 @@
## 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)

View File

@ -1,227 +1,435 @@
# Makefile for texinfo/info. -*- Indented-Text -*-
# $Id: Makefile.in,v 1.9 1996/10/01 21:44:44 karl Exp $
#
# Copyright (C) 1993,96 Free Software Foundation, Inc.
# Makefile.in generated automatically by automake 1.2f from Makefile.am
# 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.
# 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; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
# 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.
#### Start of system configuration section. ####
SHELL = /bin/sh
srcdir = @srcdir@
VPATH = $(srcdir):$(common)
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
common = $(srcdir)/../libtxi
util = $(srcdir)/../util
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
CC = @CC@
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@
LN = ln
RM = rm -f
MKDIR = mkdir
MAKEINFO= ../makeinfo/makeinfo
DEFS = @DEFS@
LDEFS = -DHANDLE_MAN_PAGES -DNAMED_FUNCTIONS=1 -DDEFAULT_INFOPATH='"$(DEFAULT_INFOPATH)"'
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@
LIBS = $(TERMLIBS) -L../libtxi -ltxi @LIBS@
LOADLIBES = $(LIBS)
TEXCONFIG = @TEXCONFIG@
TEXMF = @TEXMF@
USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
USE_NLS = @USE_NLS@
VERSION = @VERSION@
l = @l@
SHELL = /bin/sh
noinst_PROGRAMS = makedoc
CFLAGS = @CFLAGS@
LDFLAGS = @LDFLAGS@
# 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@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = $(exec_prefix)/bin
# Prefix for each installed program, normally empty or `g'.
binprefix =
# Prefix for each installed man page, normally empty or `g'.
manprefix =
mandir = $(prefix)/man/man1
manext = 1
infodir = $(prefix)/info
DEFAULT_INFOPATH= $(infodir):.
localedir = $(datadir)/locale
#### End of system configuration section. ####
# -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@
SRCS = dir.c display.c echo_area.c filesys.c \
info-utils.c info.c infodoc.c infomap.c \
m-x.c nodes.c search.c session.c \
signals.c terminal.c tilde.c window.c \
xmalloc.c indices.c makedoc.c nodemenu.c \
footnotes.c dribble.c variables.c gc.c man.c \
clib.c
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
HDRS = display.h doc.h echo_area.h filesys.h \
general.h getopt.h info-utils.h info.h \
infomap.h nodes.h search.h session.h \
signals.h termdep.h terminal.h tilde.h \
indices.h window.h footnotes.h dribble.h \
variables.h gc.h clib.h
OBJS = dir.o display.o doc.o echo_area.o filesys.o info-utils.o info.o \
infodoc.o infomap.o m-x.o nodes.o search.o session.o signals.o \
terminal.o tilde.o window.o indices.o xmalloc.o nodemenu.o \
footnotes.o dribble.o variables.o gc.o man.o clib.o
# The names of files which declare info commands.
CMDFILES = $(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
# The name of the program which builds documentation structure from CMDFILES.
MAKEDOC_OBJECTS = makedoc.o clib.o xmalloc.o
MAKEDOC_SOURCE = makedoc.c clib.c xmalloc.c
infofiles = info.info info-stnd.info
.c.o:
$(CC) -c $(CPPFLAGS) $(LDEFS) $(DEFS) -I. -I$(srcdir) -I$(common) $(CFLAGS) $<
all: info $(infofiles)
sub-all: all
install: all
$(INSTALL_PROGRAM) info $(bindir)/$(binprefix)info
-d=$(srcdir); test -f ./info.info && d=.; $(INSTALL_DATA) $$d/info.info $(infodir)/info.info
-d=$(srcdir); test -f ./info-stnd.info && d=.; $(INSTALL_DATA) $$d/info-stnd.info $(infodir)/info-stnd.info
-$(INSTALL_DATA) $(srcdir)/info.1 $(mandir)/$(manprefix)info.$(manext)
$(POST_INSTALL)
../util/install-info --info-dir=$(infodir) $(infodir)/info.info
../util/install-info --info-dir=$(infodir) $(infodir)/info-stnd.info
uninstall:
$(RM) $(bindir)/info
$(RM) $(infodir)/info.info
$(RM) $(infodir)/info-stnd.info
$(RM) $(mandir)/$(manprefix)info.$(manext)
info: $(OBJS) ../libtxi/libtxi.a
$(CC) $(LDFLAGS) -o info $(OBJS) $(LOADLIBES)
all-info: info.info info-stnd.info
info.info: info.texi
$(MAKEINFO) --no-split -I$(srcdir) info.texi
info-stnd.info: info-stnd.texi
$(MAKEINFO) --no-split -I$(srcdir) info-stnd.texi
dvi all-dvi: info.dvi info-stnd.dvi
info.dvi: info.texi
PATH="$(util):$${PATH}" TEXINPUTS="$(srcdir):$(common):$${TEXINPUTS}" texi2dvi $(srcdir)/info.texi
info-stnd.dvi: info-stnd.texi
PATH="$(util):$${PATH}" TEXINPUTS="$(srcdir):$(common):$${TEXINPUTS}" texi2dvi $(srcdir)/info-stnd.texi
makedoc: $(MAKEDOC_OBJECTS) ../libtxi/libtxi.a
$(CC) $(LDFLAGS) -o makedoc $(MAKEDOC_OBJECTS) $(LOADLIBES)
Makefile: $(srcdir)/Makefile.in ../config.status
cd ..; sh config.status
clean:
$(RM) info funs.h doc.c makedoc $(OBJS) $(MAKEDOC_OBJECTS)
distclean: clean texclean
$(RM) Makefile config.status config.cache *~ core core.* *.core
$(RM) *.BAK makedoc-TAGS TAGS \#* *.info*
mostlyclean: clean
realclean: distclean
$(RM) info.info info-stnd.info
TAGS: $(SRCS) makedoc-TAGS
etags $(SRCS)
cat makedoc-TAGS >>TAGS && $(RM) makedoc-TAGS
makedoc-TAGS: $(CMDFILES)
./makedoc -tags $(CMDFILES) >makedoc-TAGS
texclean:
$(RM) *.toc *.aux *.log *.cp *.fn *.tp *.vr *.pg *.ky *.cps
$(RM) *.tps *.fns *.kys *.pgs *.vrs
check: info
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.
funs.h: makedoc $(CMDFILES)
-@if test -f funs.h; then mv -f funs.h old-funs.h; fi; :
-@if test -f doc.c; then mv -f doc.c old-doc.c; fi; :
./makedoc $(CMDFILES)
-@if cmp -s old-funs.h funs.h; then mv old-funs.h funs.h; \
else $(RM) old-funs.h; fi; :
-@if cmp -s old-doc.c doc.c; then mv old-doc.c doc.c; \
else $(RM) old-doc.c; fi; :
BUILT_SOURCES = doc.c funs.h
doc.c: funs.h
dribble.o: dribble.c dribble.h
display.o: display.c
echo_area.o: echo_area.c
filesys.o: filesys.c
info-utils.o: info-utils.c
info.o: info.c filesys.h
infodoc.o: infodoc.c
infomap.o: infomap.c
m-x.o: m-x.c
nodes.o: nodes.c
search.o: search.c
session.o: session.c
signals.o: signals.c
terminal.o: terminal.c
tilde.o: tilde.c
window.o: window.c
xmalloc.o: xmalloc.c
indices.o: indices.c
makedoc.o: makedoc.c
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)
dir.o: dir.c
display.o: nodes.h info-utils.h search.h
display.o: terminal.h window.h display.h
echo_area.o: info.h
filesys.o: general.h tilde.h filesys.h
footnotes.o: footnotes.h
info-utils.o: info-utils.h nodes.h search.h
info.o: info.h $(common)/getopt.h
infodoc.o: info.h doc.h
infomap.o: infomap.h funs.h
gc.o: info.h
m-x.o: info.h
nodes.o: search.h filesys.h
nodes.o: nodes.h info-utils.h
search.o: general.h search.h nodes.h
session.o: info.h
signals.o: info.h signals.h
terminal.o: terminal.h termdep.h
tilde.o: tilde.h
variables.c: variables.h
window.o: nodes.h window.h display.h
window.o: info-utils.h search.h infomap.h
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
# Prevent GNU make v3 from overflowing arg limit on SysV.
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:
# eof

View File

@ -1,9 +1,3 @@
The file NEWS contains information about what has changed since the last
release.
The file ../INSTALL contains instructions on how to install Info.
Info 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
@ -12,8 +6,7 @@ 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, and the only reason it is in Beta test is because of its
short life span.
original Info.
Info 2.0 is substantially different from its original standalone
predecessor. It appears almost identical to the GNU Emacs version, but has
@ -30,8 +23,4 @@ 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.
Please send your comments, bug reports, and suggestions to
bug-texinfo@prep.ai.mit.edu
--Brian Fox <bfox@ai.mit.edu>
--Brian Fox <bfox@gnu.org>

View File

@ -1,9 +1,7 @@
/* dir.c -- How to build a special "dir" node from "localdir" files. */
/* 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 $
/* This file is part of GNU Info, a program for reading online documentation
stored in Info format.
Copyright (C) 1993 Free Software Foundation, Inc.
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
@ -21,13 +19,7 @@
Written by Brian Fox (bfox@ai.mit.edu). */
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#if defined (HAVE_SYS_FILE_H)
#include <sys/file.h>
#endif /* HAVE_SYS_FILE_H */
#include <sys/errno.h>
#include "info.h"
#include "info-utils.h"
#include "filesys.h"
#include "tilde.h"
@ -37,23 +29,53 @@
dirs_to_add which are found in INFOPATH. */
static void add_menu_to_file_buffer (), insert_text_into_fb_at_binding ();
static void build_dir_node_internal ();
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;
{
FILE_BUFFER *dir_buffer;
int path_index, update_tags;
char *this_dir;
/* Check to see if the file has already been built. If so, then
do not build it again. */
dir_buffer = info_find_file (dirname);
FILE_BUFFER *dir_buffer = info_find_file (dirname);
/* If there is no "dir" in the current info path, we cannot build one
from nothing. */
@ -64,6 +86,10 @@ maybe_build_dir_node (dirname)
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
@ -71,62 +97,56 @@ maybe_build_dir_node (dirname)
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))
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;
{
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;
}
}
tilde_expanded_dirname = tilde_expand_word (this_dir);
if (tilde_expanded_dirname != this_dir)
{
free (this_dir);
this_dir = tilde_expanded_dirname;
}
}
/* For every file named in DIRS_TO_ADD found in the search path,
add the contents of that file's menu to our "dir" node. */
for (da_index = 0; from_file = dirs_to_add[da_index]; da_index++)
{
struct stat finfo;
char *fullpath;
int namelen, statable;
/* 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);
namelen = strlen (from_file);
statable = (stat (fullpath, &finfo) == 0);
fullpath = (char *)xmalloc (3 + strlen (this_dir) + namelen);
strcpy (fullpath, this_dir);
if (fullpath[strlen (fullpath) - 1] != '/')
strcat (fullpath, "/");
strcat (fullpath, from_file);
/* 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);
}
}
statable = (stat (fullpath, &finfo) == 0);
/* Only add the contents of this file if it is not identical to the
file of the DIR buffer. */
if ((statable && S_ISREG (finfo.st_mode)) &&
(strcmp (dir_buffer->fullpath, fullpath) != 0))
{
long filesize;
char *contents;
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 (fullpath);
}
free (this_dir);
}
@ -176,37 +196,37 @@ add_menu_to_file_buffer (contents, size, fb)
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. */
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;
return;
fb_binding.start = fb_offset;
fb_binding.start +=
skip_node_separator (fb_binding.buffer + 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). */
start of this menu is the end of the file buffer (i.e., fb->size). */
if (fb_offset != -1)
fb_binding.start = fb_offset;
fb_binding.start = fb_offset;
else
fb_binding.start = fb_binding.end;
fb_binding.start = fb_binding.end;
insert_text_into_fb_at_binding
(fb, &fb_binding, INFO_MENU_LABEL, strlen (INFO_MENU_LABEL));
(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 ();
abort ();
}
/* CONTENTS_OFFSET and FB_OFFSET point to the starts of the menus that
@ -224,23 +244,23 @@ add_menu_to_file_buffer (contents, size, fb)
int num_found = 0;
while ((fb_binding.start > 0) &&
(whitespace_or_newline (fb_binding.buffer[fb_binding.start - 1])))
(whitespace_or_newline (fb_binding.buffer[fb_binding.start - 1])))
{
num_found++;
fb_binding.start--;
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';
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;
/* Do it the hard way. */
insert_text_into_fb_at_binding (fb, &fb_binding, "\n\n", 2);
fb_binding.start += 2;
}
}

View File

@ -1,9 +1,7 @@
/* display.c -- How to display Info windows. */
/* display.c -- How to display Info windows.
$Id: display.c,v 1.6 1997/07/24 21:13:27 karl Exp $
/* This file is part of GNU Info, a program for reading online documentation
stored in Info format.
Copyright (C) 1993 Free Software Foundation, Inc.
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
@ -21,10 +19,7 @@
Written by Brian Fox (bfox@ai.mit.edu). */
#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "info.h"
#include "display.h"
extern int info_any_buffered_input_p (); /* Found in session.c. */
@ -57,7 +52,7 @@ display_clear_display (display)
register int i;
register DISPLAY_LINE *display_line;
for (i = 0; display_line = display[i]; i++)
for (i = 0; (display_line = display[i]); i++)
{
display[i]->text[0] = '\0';
display[i]->textlen = 0;
@ -83,13 +78,13 @@ display_update_display (window)
{
/* Only re-display visible windows which need updating. */
if (((win->flags & W_WindowVisible) == 0) ||
((win->flags & W_UpdateWindow) == 0) ||
(win->height == 0))
continue;
((win->flags & W_UpdateWindow) == 0) ||
(win->height == 0))
continue;
display_update_one_window (win);
if (display_was_interrupted_p)
break;
break;
}
/* Always update the echo area. */
@ -102,12 +97,12 @@ void
display_update_one_window (win)
WINDOW *win;
{
register char *nodetext; /* Current character to display. */
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. */
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. */
@ -142,165 +137,165 @@ display_update_one_window (win)
int replen;
if (isprint (*nodetext))
{
rep_temp[0] = *nodetext;
replen = 1;
rep_temp[1] = '\0';
rep = rep_temp;
}
{
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 (*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. */
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];
}
}
{
/* 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;
{
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 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';
}
/* 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];
/* 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;
}
/* 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;
/* 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 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 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 ();
/* 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);
fflush (stdout);
/* Update the display text buffer. */
strcpy (entry->text + i, printed_line + i);
entry->textlen = pl_index;
/* 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;
}
/* 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;
/* 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;
}
/* 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;
/* 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 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;
/* 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';
pl_index = 0;
printed_line[0] = '\0';
begin = nodetext;
while ((nodetext < last_node_char) && (*nodetext != '\n'))
nodetext++;
}
}
begin = nodetext;
while ((nodetext < last_node_char) && (*nodetext != '\n'))
nodetext++;
}
}
}
done_with_node_display:
@ -313,13 +308,13 @@ display_update_one_window (win)
/* If this line has text on it then make it go away. */
if (entry && entry->textlen)
{
entry->textlen = 0;
entry->text[0] = '\0';
{
entry->textlen = 0;
entry->text[0] = '\0';
terminal_goto_xy (0, line_index + win->first_row);
terminal_clear_to_eol ();
}
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.
@ -331,19 +326,19 @@ display_update_one_window (win)
line_index = win->first_row + win->height;
/* This display line must both be in inverse, and have the same
contents. */
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);
}
(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. */
@ -387,40 +382,40 @@ display_scroll_display (start, 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;
}
{
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. */
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;
}
{
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;
}
{
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. */
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;
}
{
the_display[i]->text[0] = '\0';
the_display[i]->textlen = 0;
the_display[i]->inverse = 0;
}
}
}
@ -434,9 +429,9 @@ display_scroll_line_starts (window, old_pagetop, old_starts, old_count)
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. */
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;
@ -466,39 +461,39 @@ display_scroll_line_starts (window, old_pagetop, old_starts, old_count)
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;
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;
/* 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;
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 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);
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;
}
}
}
/* Some lines have been scrolled. Simulate the scrolling
by offsetting the value of the old index. */
old += i;
already_scrolled += amount;
}
}
}
}
}
@ -512,12 +507,13 @@ display_cursor_at_point (window)
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 */
/* */
/* */
/* Functions Static to this File */
/* */
/* **************************************************************** */
/* Make a DISPLAY_LINE ** with width and height. */
@ -552,7 +548,7 @@ free_display (display)
if (!display)
return;
for (i = 0; display_line = display[i]; i++)
for (i = 0; (display_line = display[i]); i++)
{
free (display_line->text);
free (display_line);

View File

@ -1,9 +1,10 @@
/* display.h -- How the display in Info is done. */
/* 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
This file is part of GNU Info, a program for reading online documentation
stored in Info format.
Copyright (C) 1993 Free Software Foundation, Inc.
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
@ -21,8 +22,8 @@
Written by Brian Fox (bfox@ai.mit.edu). */
#if !defined (_DISPLAY_H_)
#define _DISPLAY_H_
#ifndef INFO_DISPLAY_H
#define INFO_DISPLAY_H
#include "info-utils.h"
#include "terminal.h"
@ -73,4 +74,4 @@ extern void display_scroll_display ();
that appear in the OLD_STARTS array. */
extern void display_scroll_line_starts ();
#endif /* !_DISPLAY_H_ */
#endif /* not INFO_DISPLAY_H */

View File

@ -21,18 +21,10 @@
Written by Brian Fox (bfox@ai.mit.edu). */
#if !defined (_DOC_H_)
#define _DOC_H_
#if !defined (DOC_H)
#define DOC_H
#if !defined (NULL)
# define NULL 0x0
#endif /* !NULL */
#if !defined (__FUNCTION_DEF)
# define __FUNCTION_DEF
typedef int Function ();
typedef void VFunction ();
#endif /* _FUNCTION_DEF */
#include "info.h" /* for NAMED_FUNCTIONS, VFunction, etc. */
typedef struct {
VFunction *func;
@ -55,4 +47,4 @@ extern void dump_map_to_message_buffer ();
extern char *function_name ();
extern VFunction *named_function ();
#endif /* NAMED_FUNCTIONS */
#endif /* !_DOC_H_ */
#endif /* !DOC_H */

View File

@ -21,7 +21,7 @@
Written by Brian Fox (bfox@ai.mit.edu). */
#include <stdio.h>
#include "info.h"
#include "dribble.h"
/* When non-zero, it is a stream to write all input characters to for the

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,64 @@
/* 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 */

View File

@ -1,9 +1,7 @@
/* filesys.c -- File system specific functions for hacking this system. */
/* filesys.c -- File system specific functions for hacking this system.
$Id: filesys.c,v 1.6 1998/02/21 22:52:46 karl Exp $
/* This file is part of GNU Info, a program for reading online documentation
stored in Info format.
Copyright (C) 1993 Free Software Foundation, Inc.
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
@ -21,49 +19,17 @@
Written by Brian Fox (bfox@ai.mit.edu). */
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#if defined (HAVE_SYS_FILE_H)
#include <sys/file.h>
#endif /* HAVE_SYS_FILE_H */
#include <sys/errno.h>
#include "general.h"
#include "info.h"
#include "tilde.h"
#include "filesys.h"
#if !defined (O_RDONLY)
#if defined (HAVE_SYS_FCNTL_H)
#include <sys/fcntl.h>
#else /* !HAVE_SYS_FCNTL_H */
#include <fcntl.h>
#endif /* !HAVE_SYS_FCNTL_H */
#endif /* !O_RDONLY */
#if !defined (errno)
extern int errno;
#endif /* !errno */
/* 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 */
/* Local to this file. */
static char *info_file_in_path (), *lookup_info_filename ();
static void remember_info_filename (), maybe_initialize_infopath ();
#if !defined (NULL)
# define NULL 0x0
#endif /* !NULL */
typedef struct {
typedef struct
{
char *suffix;
char *decompressor;
} COMPRESSION_ALIST;
@ -72,6 +38,7 @@ static char *info_suffixes[] = {
"",
".info",
"-info",
"/index",
(char *)NULL
};
@ -114,58 +81,58 @@ info_find_fullpath (partial)
expansion = lookup_info_filename (partial);
if (expansion)
return (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. */
various extensions to it. I guess we have to stat this file
after all. */
if (initial_character == '/')
temp = info_file_in_path (partial + 1, "/");
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;
}
{
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));
(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))
if (!getcwd (local_temp_filename, local_temp_filename_size))
#else /* !HAVE_GETCWD */
if (!getwd (local_temp_filename))
if (!getwd (local_temp_filename))
#endif /* !HAVE_GETCWD */
{
filesys_error_number = errno;
return (partial);
}
{
filesys_error_number = errno;
return (partial);
}
strcat (local_temp_filename, "/");
strcat (local_temp_filename, partial);
return (local_temp_filename);
}
strcat (local_temp_filename, "/");
strcat (local_temp_filename, partial);
return (local_temp_filename);
}
else
temp = info_file_in_path (partial, infopath);
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);
}
{
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);
}
@ -183,25 +150,25 @@ info_file_in_path (filename, path)
dirname_index = 0;
while (temp_dirname = extract_colon_unit (path, &dirname_index))
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;
{
char *expanded_dirname;
expanded_dirname = tilde_expand_word (temp_dirname);
free (temp_dirname);
temp_dirname = 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, "/");
strcat (temp, filename);
pre_suffix_length = strlen (temp);
@ -209,54 +176,54 @@ info_file_in_path (filename, path)
free (temp_dirname);
for (i = 0; info_suffixes[i]; i++)
{
strcpy (temp + pre_suffix_length, info_suffixes[i]);
{
strcpy (temp + pre_suffix_length, info_suffixes[i]);
statable = (stat (temp, &finfo) == 0);
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;
/* 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 = strdup (temp);
filename_only = filename_non_directory (filename);
newtemp = info_file_in_path (filename_only, newpath);
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;
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);
pre_compress_suffix_length = strlen (temp);
for (j = 0; compress_suffixes[j].suffix; j++)
{
strcpy (temp + pre_compress_suffix_length,
compress_suffixes[j].suffix);
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);
}
}
}
statable = (stat (temp, &finfo) == 0);
if (statable && (S_ISREG (finfo.st_mode)))
return (temp);
}
}
}
free (temp);
}
return ((char *)NULL);
@ -290,7 +257,7 @@ extract_colon_unit (string, idx)
strncpy (value, &string[start], (i - start));
value[i - start] = '\0';
if (string[i])
++i;
++i;
*idx = i;
return (value);
}
@ -317,10 +284,10 @@ lookup_info_filename (filename)
{
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);
}
{
if (strcmp (names_and_files[i]->filename, filename) == 0)
return (names_and_files[i]->expansion);
}
}
return (char *)NULL;;
}
@ -340,12 +307,12 @@ remember_info_filename (filename, expansion)
alloc_size = names_and_files_slots * sizeof (FILENAME_LIST *);
names_and_files =
(FILENAME_LIST **) xrealloc (names_and_files, alloc_size);
(FILENAME_LIST **) xrealloc (names_and_files, alloc_size);
}
new = (FILENAME_LIST *)xmalloc (sizeof (FILENAME_LIST));
new->filename = strdup (filename);
new->expansion = expansion ? strdup (expansion) : (char *)NULL;
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;
@ -357,7 +324,7 @@ maybe_initialize_infopath ()
if (!infopath_size)
{
infopath = (char *)
xmalloc (infopath_size = (1 + strlen (DEFAULT_INFOPATH)));
xmalloc (infopath_size = (1 + strlen (DEFAULT_INFOPATH)));
strcpy (infopath, DEFAULT_INFOPATH);
}
@ -392,7 +359,7 @@ info_add_path (path, where)
}
else if (where == INFOPATH_PREPEND)
{
char *temp = strdup (infopath);
char *temp = xstrdup (infopath);
strcpy (infopath, path);
strcat (infopath, ":");
strcat (infopath, temp);
@ -436,21 +403,21 @@ filesys_read_info_file (pathname, filesize, finfo)
/* If the file couldn't be opened, give up. */
if (descriptor < 0)
{
filesys_error_number = errno;
return ((char *)NULL);
}
{
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);
}
{
filesys_error_number = errno;
close (descriptor);
free (contents);
return ((char *)NULL);
}
close (descriptor);
@ -510,20 +477,20 @@ filesys_read_compressed (pathname, filesize, finfo)
chunk = (char *)xmalloc (FILESYS_PIPE_BUFFER_SIZE);
while (1)
{
int bytes_read;
{
int bytes_read;
bytes_read = fread (chunk, 1, FILESYS_PIPE_BUFFER_SIZE, stream);
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));
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;
}
memcpy (contents + offset, chunk, bytes_read);
offset += bytes_read;
if (bytes_read != FILESYS_PIPE_BUFFER_SIZE)
break;
}
free (chunk);
pclose (stream);
@ -572,8 +539,8 @@ filesys_decompressor_for_file (filename)
for (i = strlen (filename) - 1; i > 0; i--)
if (filename[i] == '.')
{
extension = filename + i;
break;
extension = filename + i;
break;
}
if (!extension)

View File

@ -1,9 +1,10 @@
/* filesys.h -- External declarations of functions and vars in filesys.c. */
/* 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
This file is part of GNU Info, a program for reading online documentation
stored in Info format.
Copyright (C) 1993 Free Software Foundation, Inc.
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
@ -21,8 +22,8 @@
Written by Brian Fox (bfox@ai.mit.edu). */
#if !defined (_FILESYS_H_)
#define _FILESYS_H_
#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
@ -70,7 +71,7 @@ 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:."
# 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)
@ -81,4 +82,4 @@ extern char *extract_colon_unit ();
# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#endif /* !S_ISDIR && S_IFDIR */
#endif /* !_FILESYS_H_ */
#endif /* not INFO_FILESYS_H */

View File

@ -1,9 +1,7 @@
/* footnotes.c -- Some functions for manipulating footnotes. */
/* footnotes.c -- Some functions for manipulating footnotes.
$Id: footnotes.c,v 1.4 1997/07/24 21:23:33 karl Exp $
/* This file is part of GNU Info, a program for reading online documentation
stored in Info format.
Copyright (C) 1993 Free Software Foundation, Inc.
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
@ -40,7 +38,7 @@ find_footnotes_window ()
/* 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))
(strcmp (win->node->nodename, footnote_nodename) == 0))
break;
return (win);
@ -72,37 +70,37 @@ make_footnotes_node (node)
refs = info_xrefs_of_node (node);
if (refs)
{
register int i;
char *refname;
{
register int i;
char *refname;
refname = (char *)xmalloc
(1 + strlen ("-Footnotes") + strlen (node->nodename));
refname = (char *)xmalloc
(1 + strlen ("-Footnotes") + strlen (node->nodename));
strcpy (refname, node->nodename);
strcat (refname, "-Footnotes");
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;
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;
filename = node->parent;
if (!filename)
filename = node->filename;
fn_node = info_get_node (filename, refname);
fn_node = info_get_node (filename, refname);
if (fn_node)
fn_start = 0;
if (fn_node)
fn_start = 0;
break;
}
break;
}
free (refname);
info_free_references (refs);
}
free (refname);
info_free_references (refs);
}
}
/* If we never found the start of a footnotes area, quit now. */
@ -126,7 +124,7 @@ make_footnotes_node (node)
This effectively skips either "---- footno...", or "File: foo...". */
while (text_start < fn_node->nodelen)
if (fn_node->contents[text_start++] == '\n')
break;
break;
result->nodelen = strlen (header) + fn_node->nodelen - text_start;
@ -134,7 +132,7 @@ make_footnotes_node (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);
fn_node->contents + text_start, fn_node->nodelen - text_start);
name_internal_node (result, footnote_nodename);
free (header);
@ -176,7 +174,7 @@ info_get_or_remove_footnotes (window)
if (fn_win && !new_footnotes)
{
if (windows->next)
info_delete_window_internal (fn_win);
info_delete_window_internal (fn_win);
}
/* If there are footnotes for this window's node, but no window around
@ -187,27 +185,27 @@ info_get_or_remove_footnotes (window)
WINDOW *last, *win;
/* Always make this window be the last one appearing in the list. Find
the last window in the chain. */
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. */
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);
{
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 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,
@ -217,7 +215,7 @@ info_get_or_remove_footnotes (window)
window_set_node_of_window (fn_win, new_footnotes);
window_change_window_height
(fn_win, fn_win->line_count - fn_win->height);
(fn_win, fn_win->line_count - fn_win->height);
remember_window_and_node (fn_win, new_footnotes);
add_gcable_pointer (new_footnotes->contents);
@ -231,19 +229,17 @@ info_get_or_remove_footnotes (window)
/* 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")
_("Show the footnotes associated with this node in another window"))
{
int result;
/* 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. */
on the screen, delete it. */
if (fn_win && windows->next)
info_delete_window_internal (fn_win);
info_delete_window_internal (fn_win);
}
else
{
@ -252,14 +248,14 @@ DECLARE_INFO_COMMAND (info_show_footnotes,
result = info_get_or_remove_footnotes (window);
switch (result)
{
case FN_UNFOUND:
info_error (NO_FOOT_NODE);
break;
{
case FN_UNFOUND:
info_error (NO_FOOT_NODE);
break;
case FN_UNABLE:
info_error (WIN_TOO_SMALL);
break;
}
case FN_UNABLE:
info_error (WIN_TOO_SMALL);
break;
}
}
}

View File

@ -1,9 +1,10 @@
/* footnotes.h -- Some functions for manipulating footnotes. */
/* 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
This file is part of GNU Info, a program for reading online documentation
stored in Info format.
Copyright (C) 1993 Free Software Foundation, Inc.
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
@ -21,11 +22,11 @@
Written by Brian Fox (bfox@ai.mit.edu). */
#if !defined (_FOOTNOTES_H_)
#define _FOOTNOTES_H_
#ifndef INFO_FOOTNOTES_H
#define INFO_FOOTNOTES_H
/* Magic string which indicates following text is footnotes. */
#define FOOTNOTE_LABEL "---------- Footnotes ----------"
#define FOOTNOTE_LABEL _("---------- Footnotes ----------")
#define FN_FOUND 0
#define FN_UNFOUND 1
@ -42,5 +43,4 @@ 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 /* !_FOOTNOTES_H_ */
#endif /* not INFO_FOOTNOTES_H */

View File

@ -56,7 +56,7 @@ gc_pointers ()
if (!info_windows || !gcable_pointers_index)
return;
for (i = 0; iw = info_windows[i]; i++)
for (i = 0; (iw = info_windows[i]); i++)
{
for (j = 0; j < iw->nodes_index; j++)
{

View File

@ -1,9 +1,10 @@
/* gc.h -- Functions for garbage collecting unused node contents. */
/* 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
This file is part of GNU Info, a program for reading online documentation
stored in Info format.
Copyright (C) 1993 Free Software Foundation, Inc.
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
@ -21,8 +22,8 @@
Written by Brian Fox (bfox@ai.mit.edu). */
#if !defined (_GC_H_)
#define _GC_H_
#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
@ -33,4 +34,4 @@ extern void add_gcable_pointer ();
node->contents which are collectible, and free them. */
extern void gc_pointers ();
#endif /* !_GC_H_ */
#endif /* not INFO_GC_H */

View File

@ -1,9 +1,7 @@
/* indices.c -- Commands for dealing with an Info file Index. */
/* indices.c -- Commands for dealing with an Info file Index.
$Id: indices.c,v 1.6 1997/07/24 21:25:53 karl Exp $
/* This file is part of GNU Info, a program for reading online documentation
stored in Info format.
Copyright (C) 1993 Free Software Foundation, Inc.
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
@ -43,9 +41,9 @@ 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. */
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. */
@ -65,7 +63,7 @@ add_index_to_index_nodenames (array, node)
for (last = 0; array[last]; last++);
assoc = (INDEX_NAME_ASSOC *)xmalloc (sizeof (INDEX_NAME_ASSOC));
assoc->name = strdup (node->nodename);
assoc->name = xstrdup (node->nodename);
if (!index_nodenames_index)
{
@ -119,10 +117,10 @@ info_indices_of_file_buffer (file_buffer)
if (index_nodenames)
{
for (i = 0; index_nodenames[i]; i++)
{
free (index_nodenames[i]->name);
free (index_nodenames[i]);
}
{
free (index_nodenames[i]->name);
free (index_nodenames[i]);
}
index_nodenames_index = 0;
index_nodenames[0] = (INDEX_NAME_ASSOC *)NULL;
@ -133,48 +131,59 @@ info_indices_of_file_buffer (file_buffer)
{
TAG *tag;
for (i = 0; tag = file_buffer->tags[i]; i++)
{
if (string_in_line ("Index", tag->nodename) != -1)
{
NODE *node;
REFERENCE **menu;
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;
/* 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 = strdup (file_buffer->filename);
initial_index_nodename = strdup (tag->nodename);
/* 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);
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);
/* 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);
}
}
/* 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 = strdup (file_buffer->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")
_("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;
@ -193,47 +202,52 @@ DECLARE_INFO_COMMAND (info_index_search,
(strcmp (initial_index_filename, fb->filename) != 0))
{
info_free_references (index_index);
window_message_in_echo_area ("Finding index entries...");
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.");
info_error (_("No indices found."));
return;
}
/* Okay, there is an index. Let the user select one of the members of it. */
line =
info_read_maybe_completing (window, "Index entry: ", index_index);
window = active_window;
/* User aborted? */
if (!line)
/* 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
{
info_abort_key (active_window, 1, 0);
return;
}
line = info_read_maybe_completing (window, _("Index entry: "),
index_index);
window = active_window;
/* Empty line means move to the Index node. */
if (!*line)
{
free (line);
/* User aborted? */
if (!line)
{
info_abort_key (active_window, 1, 0);
return;
}
if (initial_index_filename && initial_index_nodename)
{
NODE *node;
/* Empty line means move to the Index node. */
if (!*line)
{
free (line);
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;
}
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.
@ -246,9 +260,9 @@ DECLARE_INFO_COMMAND (info_index_search,
/* Start the search right after/before this index. */
if (count < 0)
{
register int i;
for (i = 0; index_index[i]; i++);
index_offset = i;
register int i;
for (i = 0; index_index[i]; i++);
index_offset = i;
}
else
index_offset = -1;
@ -267,8 +281,55 @@ DECLARE_INFO_COMMAND (info_index_search,
}
}
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")
_("Go to the next matching index item from the last `\\[index-search]' command"))
{
register int i;
int partial, dir;
@ -278,14 +339,14 @@ DECLARE_INFO_COMMAND (info_next_index_match,
yet. */
if (!index_search)
{
info_error ("No previous index search string.");
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.");
info_error (_("No index entries."));
return;
}
@ -308,18 +369,18 @@ DECLARE_INFO_COMMAND (info_next_index_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 (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);
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);
info_error (_("No %sindex entries containing \"%s\"."),
index_offset > 0 ? _("more ") : "", index_search);
return;
}
@ -329,43 +390,43 @@ DECLARE_INFO_COMMAND (info_next_index_match,
/* Report to the user on what we have found. */
{
register int j;
char *name = "CAN'T SEE THIS";
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 ((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 = strdup (index_index[i]->label);
match = xstrdup (index_index[i]->label);
if (partial && show_index_match)
{
int j, ls, start, upper;
int j, ls, start, upper;
ls = strlen (index_search);
start = partial - ls;
upper = isupper (match[start]) ? 1 : 0;
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]);
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.)");
(_("Found \"%s\" in %s. (`\\[next-index-match]' tries to find next.)"));
window_message_in_echo_area (format, match, name);
}
@ -379,7 +440,7 @@ DECLARE_INFO_COMMAND (info_next_index_match,
if (!node)
{
info_error (CANT_FILE_NODE,
index_index[i]->filename, index_index[i]->nodename);
index_index[i]->filename, index_index[i]->nodename);
return;
}
@ -397,16 +458,16 @@ DECLARE_INFO_COMMAND (info_next_index_match,
if (loc != -1)
{
window->point = loc;
window_adjust_pagetop (window);
window->point = loc;
window_adjust_pagetop (window);
}
}
}
/* **************************************************************** */
/* */
/* Info APROPOS: Search every known index. */
/* */
/* */
/* Info APROPOS: Search every known index. */
/* */
/* **************************************************************** */
/* For every menu item in DIR, search the indices of that file for
@ -420,14 +481,13 @@ apropos_in_all_indices (search_string, inform)
REFERENCE **all_indices = (REFERENCE **)NULL;
REFERENCE **dir_menu = (REFERENCE **)NULL;
NODE *dir_node;
int printed = 0;
dir_node = info_get_node ("dir", "Top");
if (dir_node)
dir_menu = info_menu_of_node (dir_node);
if (!dir_menu)
return;
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
@ -441,54 +501,54 @@ apropos_in_all_indices (search_string, inform)
this_item = dir_menu[dir_index];
if (!this_item->filename)
{
if (dir_node->parent)
this_item->filename = strdup (dir_node->parent);
else
this_item->filename = strdup (dir_node->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"). */
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");
(strcmp (this_item->label, this_item->nodename) == 0))
this_node = info_get_node (this_item->label, "Top");
if (!this_node)
continue;
continue;
/* Get the file buffer associated with this node. */
{
char *files_name;
char *files_name;
files_name = this_node->parent;
if (!files_name)
files_name = this_node->filename;
files_name = this_node->parent;
if (!files_name)
files_name = this_node->filename;
this_fb = info_find_file (files_name);
this_fb = info_find_file (files_name);
if (this_fb && inform)
message_in_echo_area ("Scanning indices of \"%s\"...", 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);
this_index = info_indices_of_file_buffer (this_fb);
free (this_node);
if (this_fb && inform)
unmessage_in_echo_area ();
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 = strdup (this_fb->filename);
{
/* 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);
}
/* Concatenate with the other indices. */
all_indices = info_concatenate_references (all_indices, this_index);
}
}
info_free_references (dir_menu);
@ -501,21 +561,21 @@ apropos_in_all_indices (search_string, inform)
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);
}
}
{
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;
@ -524,7 +584,7 @@ apropos_in_all_indices (search_string, inform)
}
#define APROPOS_NONE \
"No available info files reference \"%s\" in their indices."
_("No available info files reference \"%s\" in their indices.")
void
info_apropos (string)
@ -544,8 +604,8 @@ info_apropos (string)
REFERENCE *entry;
for (i = 0; (entry = apropos_list[i]); i++)
fprintf (stderr, "\"(%s)%s\" -- %s\n",
entry->filename, entry->nodename, entry->label);
fprintf (stderr, "\"(%s)%s\" -- %s\n",
entry->filename, entry->nodename, entry->label);
}
info_free_references (apropos_list);
}
@ -553,11 +613,11 @@ info_apropos (string)
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")
_("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: ");
line = info_read_in_echo_area (window, _("Index apropos: "));
window = active_window;
@ -577,85 +637,85 @@ DECLARE_INFO_COMMAND (info_index_apropos,
apropos_list = apropos_in_all_indices (line, 1);
if (!apropos_list)
{
info_error (APROPOS_NONE, line);
}
{
info_error (APROPOS_NONE, line);
}
else
{
register int i;
char *line_buffer;
{
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);
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);
}
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. */
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;
WINDOW *new;
NODE *node;
set_remembered_pagetop_and_point (window);
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 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 (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 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;
/* 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;
}
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;
/* 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;
/* 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;
window_set_node_of_window (new, apropos_node);
remember_window_and_node (new, apropos_node);
active_window = new;
}
info_free_references (apropos_list);
}

View File

@ -1,9 +1,10 @@
/* indices.h -- Functions defined in indices.c. */
/* 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
This file is part of GNU Info, a program for reading online documentation
stored in Info format.
Copyright (C) 1993 Free Software Foundation, Inc.
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
@ -21,8 +22,8 @@
Written by Brian Fox (bfox@ai.mit.edu). */
#if !defined (_INDICES_H_)
#define _INDICES_H_
#ifndef INFO_INDICES_H
#define INFO_INDICES_H
/* User-visible variable controls the output of info-index-next. */
extern int show_index_match;
@ -35,5 +36,7 @@ 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 /* !_INDICES_H_ */
#endif /* not INFO_INDICES_H */

View File

@ -21,15 +21,8 @@
Written by Brian Fox (bfox@ai.mit.edu). */
#include <stdio.h> /* For "NULL". Yechhh! */
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#if defined (HAVE_STRING_H)
# include <string.h>
#endif /* HAVE_STRING_H */
#include "info.h"
#include "info-utils.h"
#if defined (HANDLE_MAN_PAGES)
# include "man.h"
#endif /* HANDLE_MAN_PAGES */
@ -84,7 +77,7 @@ info_parse_node (string, newlines_okay)
/* Find the closing paren. */
while (string[i] && string[i] != ')')
i++;
i++;
/* Remember parsed filename. */
saven_filename (string, i);
@ -93,7 +86,7 @@ info_parse_node (string, newlines_okay)
string += i;
if (*string)
string++;
string++;
}
/* Parse out nodename. */
@ -136,9 +129,9 @@ info_parse_label (label, node)
}
/* **************************************************************** */
/* */
/* Finding and Building Menus */
/* */
/* */
/* Finding and Building Menus */
/* */
/* **************************************************************** */
/* Return a NULL terminated array of REFERENCE * which represents the menu
@ -246,23 +239,23 @@ info_references_internal (label, binding)
offset = string_in_line (":", refdef);
/* When searching for menu items, if no colon, there is no
menu item on this line. */
menu item on this line. */
if (offset == -1)
{
if (searching_for_menu_items)
continue;
else
{
int temp;
{
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;
}
}
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;
@ -277,32 +270,32 @@ info_references_internal (label, binding)
entry->end = refdef - binding->buffer;
/* If this reference entry continues with another ':' then the
nodename is the same as the label. */
nodename is the same as the label. */
if (*refdef == ':')
{
entry->nodename = strdup (entry->label);
}
{
entry->nodename = xstrdup (entry->label);
}
else
{
/* This entry continues with a specific nodename. Parse the
nodename from the specification. */
{
/* This entry continues with a specific nodename. Parse the
nodename from the specification. */
refdef += skip_whitespace_and_newlines (refdef);
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 (searching_for_menu_items)
info_parse_node (refdef, DONT_SKIP_NEWLINES);
else
info_parse_node (refdef, SKIP_NEWLINES);
if (info_parsed_filename)
entry->filename = strdup (info_parsed_filename);
if (info_parsed_filename)
entry->filename = xstrdup (info_parsed_filename);
if (info_parsed_nodename)
entry->nodename = strdup (info_parsed_nodename);
}
if (info_parsed_nodename)
entry->nodename = xstrdup (info_parsed_nodename);
}
add_pointer_to_array
(entry, refs_index, refs, refs_slots, 50, REFERENCE *);
(entry, refs_index, refs, refs_slots, 50, REFERENCE *);
}
return (refs);
}
@ -320,7 +313,7 @@ info_get_labeled_reference (label, references)
for (i = 0; references && (entry = references[i]); i++)
{
if (strcmp (label, entry->label) == 0)
return (entry);
return (entry);
}
return ((REFERENCE *)NULL);
}
@ -375,13 +368,13 @@ info_free_references (references)
if (references)
{
for (i = 0; references && (entry = references[i]); i++)
{
maybe_free (entry->label);
maybe_free (entry->filename);
maybe_free (entry->nodename);
{
maybe_free (entry->label);
maybe_free (entry->filename);
maybe_free (entry->nodename);
free (entry);
}
free (entry);
}
free (references);
}
@ -411,24 +404,24 @@ canonicalize_whitespace (string)
for (i = 0, j = 0; string[i]; i++)
{
if (whitespace_or_newline (string[i]))
{
whitespace_found++;
whitespace_loc = i;
continue;
}
{
whitespace_found++;
whitespace_loc = i;
continue;
}
else
{
if (whitespace_found && whitespace_loc)
{
whitespace_found = 0;
{
if (whitespace_found && whitespace_loc)
{
whitespace_found = 0;
/* Suppress whitespace at start of string. */
if (j)
temp[j++] = ' ';
}
/* Suppress whitespace at start of string. */
if (j)
temp[j++] = ' ';
}
temp[j++] = string[i];
}
temp[j++] = string[i];
}
}
/* Kill trailing whitespace. */
@ -466,26 +459,26 @@ printed_representation (character, hpos)
else if (iscntrl (character))
{
switch (character)
{
case '\r':
case '\n':
the_rep[i++] = character;
break;
{
case '\r':
case '\n':
the_rep[i++] = character;
break;
case '\t':
{
int tw;
case '\t':
{
int tw;
tw = ((hpos + 8) & 0xf8) - hpos;
while (i < tw)
the_rep[i++] = ' ';
}
break;
tw = ((hpos + 8) & 0xf8) - hpos;
while (i < tw)
the_rep[i++] = ' ';
}
break;
default:
the_rep[i++] = '^';
the_rep[i++] = (character | 0x40);
}
default:
the_rep[i++] = '^';
the_rep[i++] = (character | 0x40);
}
}
else if (character > printable_limit)
{
@ -502,9 +495,9 @@ printed_representation (character, hpos)
/* **************************************************************** */
/* */
/* Functions Static To This File */
/* */
/* */
/* Functions Static To This File */
/* */
/* **************************************************************** */
/* Amount of space allocated to INFO_PARSED_FILENAME via xmalloc (). */
@ -531,7 +524,7 @@ saven_filename (filename, len)
int len;
{
saven_string (filename, len,
&info_parsed_filename, &parsed_filename_size);
&info_parsed_filename, &parsed_filename_size);
}
/* Remember NODENAME in PARSED_NODENAME. An empty NODENAME is translated
@ -550,7 +543,7 @@ saven_nodename (nodename, len)
int len;
{
saven_string (nodename, len,
&info_parsed_nodename, &parsed_nodename_size);
&info_parsed_nodename, &parsed_nodename_size);
}
/* Remember STRING in STRING_P. STRING_P should currently have STRING_SIZE_P
@ -565,7 +558,7 @@ save_string (string, string_p, string_size_p)
if (!string || !*string)
{
if (*string_p)
free (*string_p);
free (*string_p);
*string_p = (char *)NULL;
*string_size_p = 0;
@ -573,8 +566,8 @@ save_string (string, string_p, string_size_p)
else
{
if (strlen (string) >= *string_size_p)
*string_p = (char *)xrealloc
(*string_p, (*string_size_p = 1 + strlen (string)));
*string_p = (char *)xrealloc
(*string_p, (*string_size_p = 1 + strlen (string)));
strcpy (*string_p, string);
}
@ -591,7 +584,7 @@ saven_string (string, len, string_p, string_size_p)
if (!string)
{
if (*string_p)
free (*string_p);
free (*string_p);
*string_p = (char *)NULL;
*string_size_p = 0;
@ -599,7 +592,7 @@ saven_string (string, len, string_p, string_size_p)
else
{
if (len >= *string_size_p)
*string_p = (char *)xrealloc (*string_p, (*string_size_p = 1 + len));
*string_p = (char *)xrealloc (*string_p, (*string_size_p = 1 + len));
strncpy (*string_p, string, len);
(*string_p)[len] = '\0';
@ -665,7 +658,7 @@ get_internal_info_window (name)
for (win = windows; win; win = win->next)
if (internal_info_node_p (win->node) &&
(strcmp (win->node->nodename, name) == 0))
(strcmp (win->node->nodename, name) == 0))
break;
return (win);

View File

@ -1,5 +1,5 @@
/* info-utils.h -- Exported functions and variables from info-util.c.
$Id: info-utils.h,v 1.2 1996/10/02 22:24:11 karl Exp $
$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.
@ -22,8 +22,8 @@
Written by Brian Fox (bfox@ai.mit.edu). */
#if !defined (_INFO_UTILS_H_)
#define _INFO_UTILS_H_
#ifndef INFO_UTILS_H
#define INFO_UTILS_H
#if !defined (HAVE_STRCHR)
# undef strchr
@ -40,10 +40,10 @@
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. */
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
@ -137,4 +137,4 @@ extern void info_parse_label (/* label, node */);
info_parse_label (INFO_ALTPREV_LABEL, n); \
} while (0)
#endif /* !_INFO_UTILS_H_ */
#endif /* not INFO_UTILS_H */

View File

@ -1,9 +1,7 @@
/* info.c -- Display nodes of Info files in multiple windows. */
/* info.c -- Display nodes of Info files in multiple windows.
$Id: info.c,v 1.18 1998/02/27 21:37:27 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.
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
@ -22,6 +20,7 @@
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)
@ -30,8 +29,10 @@
/* The version numbers of this version of Info. */
int info_major_version = 2;
int info_minor_version = 16;
int info_patch_level = 0;
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;
@ -39,6 +40,14 @@ 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;
@ -70,6 +79,7 @@ int dump_subnodes = 0;
#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' },
@ -81,6 +91,7 @@ static struct option long_options[] = {
{ "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}
};
@ -91,13 +102,13 @@ static char *short_options = "d:n:f:o:s";
int info_windows_initialized_p = 0;
/* Some "forward" declarations. */
static void usage (), info_short_help (), remember_info_program_name ();
static void info_short_help (), remember_info_program_name ();
/* **************************************************************** */
/* */
/* Main Entry Point to the Info Program */
/* */
/* */
/* Main Entry Point to the Info Program */
/* */
/* **************************************************************** */
int
@ -105,85 +116,102 @@ main (argc, argv)
int argc;
char **argv;
{
int getopt_long_index; /* Index returned by getopt_long (). */
NODE *initial_node; /* First node loaded by Info. */
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);
(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;
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;
option_character = long_options[getopt_long_index].val;
/* Case on the option that we have received. */
switch (option_character)
{
case 0:
break;
{
case 0:
break;
/* User wants to add a directory. */
case 'd':
info_add_path (optarg, INFOPATH_PREPEND);
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 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 is specifying a particular Info file. */
case 'f':
if (user_filename)
free (user_filename);
user_filename = strdup (optarg);
break;
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 = strdup (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 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 = strdup (optarg);
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 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 an alternate input stream. */
case RESTORE_OPTION:
info_set_input_from_file (optarg);
break;
default:
usage ();
}
/* 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
@ -191,18 +219,20 @@ main (argc, argv)
to stdout, and turn on the dumping of subnodes. */
if ((!isatty (fileno (stdout))) && (user_output_filename == (char *)NULL))
{
user_output_filename = strdup ("-");
user_output_filename = xstrdup ("-");
dump_subnodes = 1;
}
/* If the user specified --version, then show the version and exit. */
if (print_version_p)
{
printf ("GNU Info (Texinfo 3.9) %s\n", version_string ());
puts ("Copyright (C) 1996 Free Software Foundation, Inc.\n\
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.");
For more information about these matters, see the files named COPYING.\n"),
"1998");
exit (0);
}
@ -213,34 +243,49 @@ For more information about these matters, see the files named COPYING.");
exit (0);
}
/* If the user hasn't specified a path for Info files, default that path
now. */
/* 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 ();
path_from_env = getenv ("INFOPATH");
char *path_from_env = getenv ("INFOPATH");
if (path_from_env)
info_add_path (path_from_env, INFOPATH_PREPEND);
{
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);
{
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, *temp;
directory_name = strdup (user_filename);
temp = filename_non_directory (directory_name);
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);
}
{
*temp = 0;
info_add_path (directory_name, INFOPATH_PREPEND);
}
free (directory_name);
}
@ -255,39 +300,74 @@ For more information about these matters, see the files named COPYING.");
/* Get the initial Info node. It is either "(dir)Top", or what the user
specifed with values in user_filename and user_nodenames. */
if (user_nodenames)
initial_node = info_get_node (user_filename, user_nodenames[0]);
else
initial_node = info_get_node (user_filename, (char *)NULL);
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);
info_error (info_recent_file_error);
else
info_error
(CANT_FIND_NODE, user_nodenames ? user_nodenames[0] : "Top");
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. */
/* 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);
dump_nodes_to_file
(user_filename, user_nodenames, user_output_filename, dump_subnodes);
else
begin_multiple_window_info_session (user_filename, user_nodenames);
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
@ -303,134 +383,134 @@ For more information about these matters, see the files named COPYING.");
/* Remember the name of the menu entry we want. */
arg = argv[optind++];
if (first_arg == (char *)NULL)
first_arg = arg;
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. */
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;
}
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);
}
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". */
user typed "buffer" when they really meant "Buffers". */
if (!entry)
{
register int i;
int best_guess = -1;
{
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;
}
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 (!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. */
node anyway. It is probably a misspelling. */
if (!entry)
{
char *error_message = "There is no menu item \"%s\" in this node.";
{
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;
}
if (first_arg == arg)
{
node = make_manpage_node (first_arg);
if (node)
goto maybe_got_node;
}
#endif /* HANDLE_MAN_PAGES */
info_free_references (menu);
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);
/* 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);
}
exit (0);
}
/* We have found the reference that the user specified. Clean it
up a little bit. */
up a little bit. */
if (!entry->filename)
{
if (initial_node->parent)
entry->filename = strdup (initial_node->parent);
else
entry->filename = strdup (initial_node->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. */
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;
}
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");
(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);
}
{
free (initial_node);
initial_node = node;
info_free_references (menu);
}
else
{
char *temp = strdup (entry->label);
char *error_message;
{
char *temp = xstrdup (entry->label);
char *error_message;
error_message = "Unable to find the node referenced by \"%s\".";
error_message = _("Unable to find the node referenced by \"%s\".");
info_free_references (menu);
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);
/* 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);
}
exit (0);
}
}
/* If the user specified that this node should be output, then do that
@ -453,19 +533,12 @@ version_string ()
{
vstring = (char *)xmalloc (50);
sprintf (vstring, "%d.%d", info_major_version, info_minor_version);
if (info_patch_level)
sprintf (vstring + strlen (vstring), "-p%d", info_patch_level);
}
return (vstring);
}
/* **************************************************************** */
/* */
/* Error Handling for Info */
/* */
/* **************************************************************** */
static char *program_name = (char *)NULL;
/* Error handling. */
static void
remember_info_program_name (fullpath)
@ -474,7 +547,7 @@ remember_info_program_name (fullpath)
char *filename;
filename = filename_non_directory (fullpath);
program_name = strdup (filename);
program_name = xstrdup (filename);
}
/* Non-zero if an error has been signalled. */
@ -503,63 +576,52 @@ info_error (format, arg1, arg2)
else
{
if (!echo_area_is_active)
{
if (info_error_rings_bell_p)
terminal_ring_bell ();
window_message_in_echo_area (format, arg1, arg2);
}
{
if (info_error_rings_bell_p)
terminal_ring_bell ();
window_message_in_echo_area (format, arg1, arg2);
}
else
{
NODE *temp;
{
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);
}
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 very brief descripton of the available options and exit with
an error. */
static void
usage ()
{
fprintf (stderr,"%s\n%s\n%s\n%s\n%s\n",
"Usage: info [-d dir-path] [-f info-file] [-o output-file] [-n node-name]...",
" [--directory dir-path] [--file info-file] [--node node-name]...",
" [--help] [--output output-file] [--subnodes] [--version]",
" [--dribble dribble-file] [--restore from-file]",
" [menu-selection ...]");
exit (1);
}
/* Produce a scaled down description of the available options to Info. */
static void
info_short_help ()
{
puts ("\
Here is a quick description of Info's options. For a more complete\n\
description of how to use Info, type `info info options'.\n\
printf (_("\
Usage: %s [OPTION]... [INFO-FILE [MENU-ITEM...]]\n\
\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 Get this help message.\n\
--version Display Info's version information.\n\
Read documentation in Info format.\n\
For more complete documentation on how to use Info, run `info info options'.\n\
\n\
Remaining arguments to Info are treated as the names of menu\n\
items in the initial node visited. You can easily move to the\n\
node of your choice by specifying the menu names which describe\n\
the path to that node. For example, `info emacs buffers'.\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\
Email bug reports to bug-texinfo@prep.ai.mit.edu.");
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);
}

View File

@ -1,9 +1,10 @@
/* info.h -- Header file which includes all of the other headers. */
/* 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
This file is part of GNU Info, a program for reading online documentation
stored in Info format.
Copyright (C) 1993 Free Software Foundation, Inc.
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
@ -21,33 +22,86 @@
Written by Brian Fox (bfox@ai.mit.edu). */
#if !defined (_INFO_H_)
#define _INFO_H_
#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 <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#if defined (HAVE_STRING_H)
#include <string.h>
#endif /* HAVE_STRING_H */
#include "filesys.h"
#include "display.h"
#include "session.h"
#include "echo_area.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. */
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
@ -71,30 +125,41 @@ extern int info_error_rings_bell_p;
extern void info_error ();
/* The version numbers of Info. */
extern int info_major_version, info_minor_version, info_patch_level;
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."
#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.")
#endif /* !_INFO_H_ */
/* 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 */

View File

@ -1,9 +1,7 @@
/* infodoc.c -- Functions which build documentation nodes. */
/* infodoc.c -- Functions which build documentation nodes.
$Id: infodoc.c,v 1.4 1997/07/25 21:08:40 karl Exp $
/* This file is part of GNU Info, a program for reading online documentation
stored in Info format.
Copyright (C) 1993 Free Software Foundation, Inc.
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
@ -33,9 +31,9 @@
/* #define HELP_NODE_GETS_REGENERATED 1 */
/* **************************************************************** */
/* */
/* Info Help Windows */
/* */
/* */
/* Info Help Windows */
/* */
/* **************************************************************** */
/* The name of the node used in the help window. */
@ -49,10 +47,12 @@ 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[] = {
"Basic Commands in Info Windows",
N_ ("Basic Commands in Info Windows"),
"******************************",
"",
" h Invoke the Info tutorial.",
" h Invoke the Info tutorial.",
" CTRL-x 0 Quit this help.",
" q Quit Info altogether.",
"",
"Selecting other nodes:",
"----------------------",
@ -72,9 +72,8 @@ static char *info_internal_help_text[] = {
" b Go to the beginning of this node.",
" e Go to the end of this node.",
"",
"\"Advanced\" commands:",
"Other commands:",
"--------------------",
" q Quit Info.",
" 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.",
@ -82,7 +81,7 @@ static char *info_internal_help_text[] = {
" 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.",
(char *)NULL
NULL
};
static char *where_is (), *where_is_internal ();
@ -97,70 +96,70 @@ dump_map_to_message_buffer (prefix, map)
for (i = 0; i < 256; i++)
{
if (map[i].type == ISKMAP)
{
char *new_prefix, *keyname;
{
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);
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);
}
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;
{
register int last;
char *doc, *name;
doc = function_documentation (map[i].function);
name = function_name (map[i].function);
doc = function_documentation (map[i].function);
name = function_name (map[i].function);
if (!*doc)
continue;
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;
/* 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 (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. */
/* 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 ();
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);
}
}
}
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);
}
printf_to_message_buffer ("%s\n", doc);
}
}
}
@ -184,7 +183,7 @@ create_internal_info_help_node ()
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 ("%s\n", info_internal_help_text[i]);
printf_to_message_buffer ("---------------------\n\n");
printf_to_message_buffer ("The current search path is:\n");
@ -199,34 +198,34 @@ create_internal_info_help_node ()
#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;
{
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;
}
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));
}
}
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");
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"));
("%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;
}
@ -273,16 +272,16 @@ info_find_or_create_help_window ()
int max = 0;
for (window = windows; window; window = window->next)
{
if (window->height > max)
{
max = window->height;
eligible = window;
}
}
{
if (window->height > max)
{
max = window->height;
eligible = window;
}
}
if (!eligible)
return ((WINDOW *)NULL);
return ((WINDOW *)NULL);
}
#if !defined (HELP_NODE_GETS_REGENERATED)
else
@ -297,28 +296,28 @@ info_find_or_create_help_window ()
if (!help_window)
{
/* Split the largest window into 2 windows, and show the help text
in that window. */
in that window. */
if (eligible->height > 30)
{
active_window = eligible;
help_window = window_make_window (internal_info_help_node);
}
{
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;
}
{
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. */
existing window in which to place the node. */
if (active_window != help_window)
{
set_remembered_pagetop_and_point (active_window);
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);
@ -326,7 +325,7 @@ info_find_or_create_help_window ()
}
/* Create or move to the help window. */
DECLARE_INFO_COMMAND (info_get_help_window, "Display help message")
DECLARE_INFO_COMMAND (info_get_help_window, _("Display help message"))
{
WINDOW *help_window;
@ -344,7 +343,7 @@ DECLARE_INFO_COMMAND (info_get_help_window, "Display help message")
/* 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'")
DECLARE_INFO_COMMAND (info_get_info_help_node, _("Visit Info node `(info)Help'"))
{
NODE *node;
char *nodename;
@ -356,15 +355,15 @@ DECLARE_INFO_COMMAND (info_get_info_help_node, "Visit Info node `(info)Help'")
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 (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;
}
}
}
@ -380,32 +379,32 @@ DECLARE_INFO_COMMAND (info_get_info_help_node, "Visit Info node `(info)Help'")
if (!node)
{
if (info_recent_file_error)
info_error (info_recent_file_error);
info_error (info_recent_file_error);
else
info_error (CANT_FILE_NODE, "Info", nodename);
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. */
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);
active_window = window_make_window (node);
else
{
set_remembered_pagetop_and_point (active_window);
window_set_node_of_window (active_window, node);
}
{
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 */
/* */
/* */
/* Groveling Info Keymaps and Docs */
/* */
/* **************************************************************** */
/* Return the documentation associated with the Info command FUNCTION. */
@ -468,7 +467,7 @@ key_documentation (key, map)
return ((char *)NULL);
}
DECLARE_INFO_COMMAND (describe_key, "Print documentation for KEY")
DECLARE_INFO_COMMAND (describe_key, _("Print documentation for KEY"))
{
char keyname[50];
int keyname_index = 0;
@ -481,24 +480,24 @@ DECLARE_INFO_COMMAND (describe_key, "Print documentation for KEY")
while (1)
{
message_in_echo_area ("Describe key: %s", keyname);
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;
}
{
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;
}
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);
@ -506,40 +505,40 @@ DECLARE_INFO_COMMAND (describe_key, "Print documentation for KEY")
keyname_index = strlen (keyname);
if (map[keystroke].function == (VFunction *)NULL)
{
message_in_echo_area ("%s is undefined.", keyname);
return;
}
{
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;
}
{
map = (Keymap)map[keystroke].function;
strcat (keyname, " ");
keyname_index = strlen (keyname);
continue;
}
else
{
char *message, *fundoc, *funname = "";
{
char *message, *fundoc, *funname = "";
#if defined (NAMED_FUNCTIONS)
funname = function_name (map[keystroke].function);
funname = function_name (map[keystroke].function);
#endif /* NAMED_FUNCTIONS */
fundoc = function_documentation (map[keystroke].function);
fundoc = function_documentation (map[keystroke].function);
message = (char *)xmalloc
(10 + strlen (keyname) + strlen (fundoc) + strlen (funname));
message = (char *)xmalloc
(10 + strlen (keyname) + strlen (fundoc) + strlen (funname));
#if defined (NAMED_FUNCTIONS)
sprintf (message, "%s (%s): %s.", keyname, funname, fundoc);
sprintf (message, "%s (%s): %s.", keyname, funname, fundoc);
#else
sprintf (message, "%s is defined to %s.", keyname, fundoc);
sprintf (message, _("%s is defined to %s."), keyname, fundoc);
#endif /* !NAMED_FUNCTIONS */
window_message_in_echo_area ("%s", message);
free (message);
break;
}
window_message_in_echo_area ("%s", message);
free (message);
break;
}
}
}
@ -565,28 +564,28 @@ pretty_keyname (key)
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;
{
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;
}
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;
}
{
case ' ': rep = "SPC"; break;
case DEL: rep = "DEL"; break;
default:
rep_buffer[0] = key;
rep_buffer[1] = '\0';
rep = rep_buffer;
}
}
return (rep);
}
@ -609,39 +608,39 @@ replace_in_documentation (string)
{
/* Is this the start of a replaceable function name? */
if (string[i] == '\\' && string[i + 1] == '[')
{
char *fun_name, *rep;
VFunction *function;
{
char *fun_name, *rep;
VFunction *function;
/* Copy in the old text. */
strncpy (result + next, string + start, i - start);
next += (i - start);
start = i + 2;
/* 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++);
/* 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';
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);
/* 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 ();
/* 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);
rep = where_is (info_keymap, function);
strcpy (result + next, rep);
next = strlen (result);
start = i;
if (string[i])
start++;
}
start = i;
if (string[i])
start++;
}
}
strcpy (result + next, string + start);
return (result);
@ -674,7 +673,7 @@ where_is (map, function)
name = function_name (function);
if (name)
sprintf (where_is_rep, "M-x %s", name);
sprintf (where_is_rep, "M-x %s", name);
rep = where_is_rep;
}
@ -694,29 +693,29 @@ where_is_internal (map, function)
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);
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;
{
int saved_index = where_is_rep_index;
char *rep;
sprintf (where_is_rep + where_is_rep_index, "%s ",
pretty_keyname (i));
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);
where_is_rep_index = strlen (where_is_rep);
rep = where_is_internal ((Keymap)map[i].function, function);
if (rep)
return (where_is_rep);
if (rep)
return (where_is_rep);
where_is_rep_index = saved_index;
}
where_is_rep_index = saved_index;
}
}
return ((char *)NULL);
@ -729,7 +728,7 @@ DECLARE_INFO_COMMAND (info_where_is,
{
char *command_name;
command_name = read_function_name ("Where is command: ", window);
command_name = read_function_name (_("Where is command: "), window);
if (!command_name)
{
@ -744,27 +743,27 @@ DECLARE_INFO_COMMAND (info_where_is,
function = named_function (command_name);
if (function)
{
char *location;
{
char *location;
location = where_is (active_window->keymap, function);
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);
}
}
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);
info_error (_("There is no function named `%s'"), command_name);
}
free (command_name);

View File

@ -21,14 +21,14 @@
Written by Brian Fox (bfox@ai.mit.edu). */
#if !defined (_INFOMAP_H_)
#define _INFOMAP_H_
#ifndef INFOMAP_H
#define INFOMAP_H
#include "general.h"
#include "info.h"
#define ESC '\033'
#define DEL '\177'
#define TAB '\011'
#define TAB '\011'
#define RET '\r'
#define LFD '\n'
#define SPC ' '
@ -79,4 +79,4 @@ extern void keymap_discard_keymap ();
/* Initialize the info keymaps. */
extern void initialize_info_keymaps ();
#endif /* !_INFOMAP_H_ */
#endif /* not INFOMAP_H */

View File

@ -1,9 +1,7 @@
/* m-x.c -- Meta-X minibuffer reader. */
/* m-x.c -- Meta-X minibuffer reader.
$Id: m-x.c,v 1.5 1997/07/24 21:28:00 karl Exp $
/* This file is part of GNU Info, a program for reading online documentation
stored in Info format.
Copyright (C) 1993 Free Software Foundation, Inc.
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
@ -24,9 +22,9 @@
#include "info.h"
/* **************************************************************** */
/* */
/* Reading Named Commands */
/* */
/* */
/* Reading Named Commands */
/* */
/* **************************************************************** */
/* Read the name of an Info function in the echo area and return the
@ -49,12 +47,12 @@ read_function_name (prompt, window)
REFERENCE *entry;
entry = (REFERENCE *)xmalloc (sizeof (REFERENCE));
entry->label = strdup (function_doc_array[i].func_name);
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 *);
(entry, array_index, array, array_slots, 200, REFERENCE *);
}
line = info_read_completing_in_echo_area (window, prompt, array);
@ -68,11 +66,11 @@ read_function_name (prompt, window)
}
DECLARE_INFO_COMMAND (describe_command,
"Read the name of an Info command and describe it")
_("Read the name of an Info command and describe it"))
{
char *line;
line = read_function_name ("Describe command: ", window);
line = read_function_name (_("Describe command: "), window);
if (!line)
{
@ -83,22 +81,19 @@ DECLARE_INFO_COMMAND (describe_command,
/* Describe the function named in "LINE". */
if (*line)
{
char *fundoc;
VFunction *fun;
fun = named_function (line);
VFunction *fun = named_function (line);
if (!fun)
return;
return;
window_message_in_echo_area ("%s: %s.",
line, function_documentation (fun));
line, function_documentation (fun));
}
free (line);
}
DECLARE_INFO_COMMAND (info_execute_command,
"Read a command name in the echo area and execute it")
_("Read a command name in the echo area and execute it"))
{
char *line;
@ -133,11 +128,11 @@ DECLARE_INFO_COMMAND (info_execute_command,
VFunction *function;
if ((active_window != the_echo_area) &&
(strncmp (line, "echo-area-", 10) == 0))
(strncmp (line, "echo-area-", 10) == 0))
{
free (line);
info_error ("Cannot execute an `echo-area' command here.");
return;
free (line);
info_error (_("Cannot execute an `echo-area' command here."));
return;
}
function = named_function (line);
@ -152,7 +147,7 @@ DECLARE_INFO_COMMAND (info_execute_command,
/* 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")
_("Set the height of the displayed window"))
{
int new_height;
@ -165,24 +160,24 @@ DECLARE_INFO_COMMAND (set_screen_height,
new_height = screenheight;
sprintf (prompt, "Set screen height to (%d): ", new_height);
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;
}
{
info_abort_key (active_window, count, 0);
return;
}
/* Find out what the new height is supposed to be. */
if (*line)
new_height = atoi (line);
new_height = atoi (line);
/* Clear the echo area if it isn't active. */
if (!echo_area_is_active)
window_clear_echo_area ();
window_clear_echo_area ();
free (line);
}

View File

@ -1,9 +1,10 @@
/* makedoc.c -- Make DOC.C and FUNS.H from input files. */
/* 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
This file is part of GNU Info, a program for reading online documentation
stored in Info format.
Copyright (C) 1993 Free Software Foundation, Inc.
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
@ -26,24 +27,8 @@
a header file which describes the contents. This only does the functions
declared with DECLARE_INFO_COMMAND. */
#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#if defined (HAVE_SYS_FILE_H)
#include <sys/file.h>
#endif /* HAVE_SYS_FILE_H */
#include <sys/stat.h>
#include "general.h"
#include "info.h"
#if !defined (O_RDONLY)
#if defined (HAVE_SYS_FCNTL_H)
#include <sys/fcntl.h>
#else /* !HAVE_SYS_FCNTL_H */
#include <fcntl.h>
#endif /* !HAVE_SYS_FCNTL_H */
#endif /* !O_RDONLY */
extern void *xmalloc (), *xrealloc ();
static void fatal_file_error ();
/* Name of the header file which receives the declarations of functions. */
@ -79,15 +64,15 @@ static char *doc_header_1[] = {
/* 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. */
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. */
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;
@ -114,8 +99,8 @@ main (argc, argv)
for (i = 1; i < argc; i++)
if (strcmp (argv[i], "-tags") == 0)
{
tags_only++;
break;
tags_only++;
break;
}
if (tags_only)
@ -128,8 +113,8 @@ main (argc, argv)
doc_stream = must_fopen (doc_filename, "w");
fprintf (funs_stream,
"/* %s -- Generated declarations for Info commands. */\n",
funs_filename);
"/* %s -- Generated declarations for Info commands. */\n",
funs_filename);
for (i = 0; doc_header[i]; i++)
{
@ -138,7 +123,7 @@ main (argc, argv)
}
fprintf (doc_stream,
" Source files groveled to make this file include:\n\n");
_(" Source files groveled to make this file include:\n\n"));
for (i = 1; i < argc; i++)
fprintf (doc_stream, "\t%s\n", argv[i]);
@ -155,17 +140,17 @@ main (argc, argv)
curfile = argv[i];
if (*curfile == '-')
continue;
continue;
fprintf (doc_stream, "/* Commands found in \"%s\". */\n", curfile);
fprintf (funs_stream, "\n/* Functions declared in \"%s\". */\n",
curfile);
curfile);
process_one_file (curfile, doc_stream, funs_stream);
}
fprintf (doc_stream,
" { (VFunction *)NULL, (char *)NULL, (char *)NULL }\n};\n");
" { (VFunction *)NULL, (char *)NULL, (char *)NULL }\n};\n");
fclose (funs_stream);
fclose (doc_stream);
@ -195,25 +180,25 @@ maybe_dump_tags (stream)
/* 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,%d", etag->line, etag->char_offset);
block_len += strlen (digits);
}
{
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,%d\n", block->filename, block_len);
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];
{
etag = block->entries[j];
fprintf (stream, "%s,\177%d,%d\n",
etag->name, etag->line, etag->char_offset);
}
fprintf (stream, "%s,\177%d,%ld\n",
etag->name, etag->line, etag->char_offset);
}
}
}
@ -226,7 +211,7 @@ make_emacs_tag_block (filename)
EMACS_TAG_BLOCK *block;
block = (EMACS_TAG_BLOCK *)xmalloc (sizeof (EMACS_TAG_BLOCK));
block->filename = strdup (filename);
block->filename = xstrdup (filename);
block->entrylen = 0;
block->entries = (EMACS_TAG **)NULL;
block->entries_index = 0;
@ -248,7 +233,7 @@ add_tag_to_block (block, name, line, char_offset)
tag->line = line;
tag->char_offset = char_offset;
add_pointer_to_array (tag, block->entries_index, block->entries,
block->entries_slots, 50, EMACS_TAG *);
block->entries_slots, 50, EMACS_TAG *);
}
/* Read the file represented by FILENAME into core, and search it for Info
@ -297,51 +282,51 @@ process_one_file (filename, doc_stream, funs_stream)
#endif /* NAMED_FUNCTIONS */
for (; offset < (file_size - decl_len); offset++)
{
if (buffer[offset] == '\n')
{
line_number++;
line_start = offset + 1;
}
{
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 (strncmp (buffer + offset, decl_str, decl_len) == 0)
{
offset += decl_len;
point = offset;
break;
}
}
if (!point)
break;
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;
{
if (buffer[point] == '\n')
{
line_number++;
line_start = point + 1;
}
else if (buffer[point] == '(')
break;
point++;
}
point++;
}
while (point++ < file_size)
{
if (!whitespace_or_newline (buffer[point]))
break;
else if (buffer[point] == '\n')
{
line_number++;
line_start = point + 1;
}
}
{
if (!whitespace_or_newline (buffer[point]))
break;
else if (buffer[point] == '\n')
{
line_number++;
line_start = point + 1;
}
}
if (point >= file_size)
break;
break;
/* Now looking at name of function. Get it. */
for (offset = point; buffer[offset] != ','; offset++);
@ -351,42 +336,42 @@ process_one_file (filename, doc_stream, funs_stream)
/* Remember this tag in the current block. */
{
char *tag_name;
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);
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;
register int i;
char *name_start;
name_start = func;
name_start = func;
if (strncmp (name_start, "info_", 5) == 0)
name_start += 5;
if (strncmp (name_start, "info_", 5) == 0)
name_start += 5;
func_name = strdup (name_start);
func_name = xstrdup (name_start);
/* Fix up "ea" commands. */
if (strncmp (func_name, "ea_", 3) == 0)
{
char *temp_func_name;
/* 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;
}
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] = '-';
for (i = 0; func_name[i]; i++)
if (func_name[i] == '_')
func_name[i] = '-';
}
#endif /* NAMED_FUNCTIONS */
@ -394,40 +379,40 @@ process_one_file (filename, doc_stream, funs_stream)
point = offset + 1;
while (point < file_size)
{
if (buffer[point] == '\n')
{
line_number++;
line_start = point + 1;
}
{
if (buffer[point] == '\n')
{
line_number++;
line_start = point + 1;
}
if (buffer[point] == '"')
break;
else
point++;
}
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] == '\n')
{
line_number++;
line_start = offset + 1;
}
if (buffer[offset] == '\\')
offset += 2;
else if (buffer[offset] == '"')
break;
else
offset++;
}
if (buffer[offset] == '\\')
offset += 2;
else if (buffer[offset] == '"')
break;
else
offset++;
}
offset++;
if (offset >= file_size)
break;
break;
doc = (char *)xmalloc (1 + (offset - point));
strncpy (doc, buffer + point, offset - point);
@ -450,7 +435,7 @@ process_one_file (filename, doc_stream, funs_stream)
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 *);
emacs_tags_slots, 10, EMACS_TAG_BLOCK *);
else
{
free (block->filename);
@ -462,7 +447,7 @@ static void
fatal_file_error (filename)
char *filename;
{
fprintf (stderr, "Couldn't manipulate the file %s.\n", filename);
fprintf (stderr, _("Couldn't manipulate the file %s.\n"), filename);
exit (2);
}

View File

@ -1,9 +1,7 @@
/* man.c: How to read and format man files. */
/* man.c: How to read and format man files.
$Id: man.c,v 1.6 1997/07/31 23:49:59 karl Exp $
/* This file is part of GNU Info, a program for reading online documentation
stored in Info format.
Copyright (C) 1995 Free Software Foundation, Inc.
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
@ -23,7 +21,6 @@
#include "info.h"
#include <sys/ioctl.h>
#include <sys/file.h>
#include "signals.h"
#if defined (HAVE_SYS_TIME_H)
#include <sys/time.h>
@ -31,8 +28,8 @@
#if defined (HAVE_SYS_WAIT_H)
#include <sys/wait.h>
#endif
#include "tilde.h"
#include "tilde.h"
#include "man.h"
#if !defined (_POSIX_VERSION)
@ -75,31 +72,31 @@ get_manpage_node (file_buffer, pagename)
page = get_manpage_contents (pagename);
if (page)
{
char header[1024];
long oldsize, newsize;
int hlen, plen;
{
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);
}
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);
}
@ -110,12 +107,9 @@ get_manpage_node (file_buffer, pagename)
FILE_BUFFER *
create_manpage_file_buffer ()
{
FILE_BUFFER *file_buffer;
struct stat *finfo;
file_buffer = make_file_buffer ();
file_buffer->filename = strdup (MANPAGE_FILE_BUFFER_NAME);
file_buffer->fullpath = strdup (MANPAGE_FILE_BUFFER_NAME);
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;
@ -137,25 +131,24 @@ executable_file_in_path (filename, path)
dirname_index = 0;
while (temp_dirname = extract_colon_unit (path, &dirname_index))
while ((temp_dirname = extract_colon_unit (path, &dirname_index)))
{
register int i;
char *temp;
/* Expand a leading tilde if one is present. */
if (*temp_dirname == '~')
{
char *expanded_dirname;
{
char *expanded_dirname;
expanded_dirname = tilde_expand_word (temp_dirname);
free (temp_dirname);
temp_dirname = 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, "/");
strcat (temp, filename);
free (temp_dirname);
@ -164,10 +157,10 @@ executable_file_in_path (filename, path)
/* 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);
(access (temp, X_OK) == 0))
return (temp);
else
free (temp);
free (temp);
}
return ((char *)NULL);
}
@ -221,7 +214,7 @@ static void
reap_children (sig)
int sig;
{
unsigned int status;
int status;
wait (&status);
}
@ -233,7 +226,6 @@ get_manpage_contents (pagename)
int pipes[2];
pid_t child;
char *formatted_page = (char *)NULL;
char *section = (char *)NULL;
int arg_index = 1;
if (formatter_args[0] == (char *)NULL)
@ -265,7 +257,7 @@ get_manpage_contents (pagename)
if (child != 0)
{
/* In the parent, close the writing end of the pipe, and read from
the exec'd child. */
the exec'd child. */
close (pipes[1]);
formatted_page = read_from_fd (pipes[0]);
close (pipes[0]);
@ -273,16 +265,16 @@ get_manpage_contents (pagename)
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. */
of the pipe be stdout, and execute the man page formatter. */
close (pipes[0]);
close (fileno (stderr));
close (fileno (stdin)); /* Don't print errors. */
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. */
exit. */
close (pipes[1]);
exit (0);
}
@ -304,21 +296,21 @@ clean_manpage (manpage)
newpage = (char *)xmalloc (1 + strlen (manpage));
for (i = 0, j = 0; newpage[j] = manpage[i]; i++, j++)
for (i = 0, j = 0; (newpage[j] = manpage[i]); i++, j++)
{
if (manpage[i] == '\n')
newline_count++;
newline_count++;
else
newline_count = 0;
newline_count = 0;
if (newline_count == 3)
{
j--;
newline_count--;
}
{
j--;
newline_count--;
}
if (manpage[i] == '\b' || manpage[i] == '\f')
j -= 2;
j -= 2;
}
newpage[j++] = '\0';
@ -339,11 +331,11 @@ manpage_node_of_file_buffer (file_buffer, pagename)
{
register int i;
for (i = 0; tag = file_buffer->tags[i]; i++)
{
if (strcasecmp (pagename, tag->nodename) == 0)
break;
}
for (i = 0; (tag = file_buffer->tags[i]); i++)
{
if (strcasecmp (pagename, tag->nodename) == 0)
break;
}
}
if (tag)
@ -459,7 +451,7 @@ find_reference_section (node)
{
position = search_forward (reference_section_starters[i], &frs_binding);
if (position != -1)
break;
break;
}
if (position == -1)
@ -473,11 +465,11 @@ find_reference_section (node)
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;
}
(!whitespace (frs_binding.buffer[i + 1])))
{
frs_binding.end = i;
break;
}
}
return (&frs_binding);
@ -508,43 +500,43 @@ xrefs_of_manpage (node)
register int start, end;
for (start = position; start > reference_section->start; start--)
if (whitespace (reference_section->buffer[start]))
break;
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 (whitespace (reference_section->buffer[end]))
{
end = start;
break;
}
if (reference_section->buffer[end] == ')')
{
end++;
break;
}
}
if (reference_section->buffer[end] == ')')
{
end++;
break;
}
}
if (end != start)
{
REFERENCE *entry;
int len = 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 = strdup (node->filename);
entry->nodename = strdup (entry->label);
entry->start = start;
entry->end = end;
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 *);
}
add_pointer_to_array
(entry, refs_index, refs, refs_slots, 10, REFERENCE *);
}
reference_section->start = position + 1;
}
@ -558,7 +550,6 @@ locate_manpage_xref (node, start, dir)
long start;
int dir;
{
register int i, count;
REFERENCE **refs;
long position = -1;
@ -573,27 +564,27 @@ locate_manpage_xref (node, start, dir)
count = i;
if (dir > 0)
{
for (i = 0; entry = refs[i]; i++)
if (entry->start > start)
{
position = entry->start;
break;
}
}
{
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];
{
for (i = count - 1; i > -1; i--)
{
entry = refs[i];
if (entry->start < start)
{
position = entry->start;
break;
}
}
}
if (entry->start < start)
{
position = entry->start;
break;
}
}
}
info_free_references (refs);
}
@ -622,20 +613,20 @@ manpage_xrefs_in_binding (node, binding)
start = binding->start + (binding->buffer - node->contents);
end = binding->end + (binding->buffer - node->contents);
for (i = 0; entry = all_refs[i]; i++)
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 *);
}
{
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);
}
{
maybe_free (entry->label);
maybe_free (entry->filename);
maybe_free (entry->nodename);
free (entry);
}
}
free (all_refs);

View File

@ -1,9 +1,10 @@
/* man.h: Defines and external function declarations for man.c */
/* 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
This file is part of GNU Info, a program for reading online documentation
stored in Info format.
Copyright (C) 1993 Free Software Foundation, Inc.
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
@ -21,8 +22,8 @@
Author: Brian J. Fox (bfox@ai.mit.edu) Sat May 6 16:19:13 1995. */
#if !defined (_MAN_H_)
#define _MAN_H_
#ifndef INFO_MAN_H
#define INFO_MAN_H
#define MANPAGE_FILE_BUFFER_NAME "*manpages*"
@ -33,4 +34,4 @@ 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 /* !_MAN_H_ */
#endif /* INFO_MAN_H */

View File

@ -21,17 +21,8 @@
Written by Brian Fox (bfox@ai.mit.edu). */
#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#if defined (HAVE_SYS_FILE_H)
#include <sys/file.h>
#endif /* HAVE_SYS_FILE_H */
#include <sys/errno.h>
#include <sys/stat.h>
#if defined (HAVE_STRING_H)
#include <string.h>
#endif /* HAVE_STRING_H */
#include "info.h"
#include "nodes.h"
#include "search.h"
#include "filesys.h"
@ -41,22 +32,10 @@
# include "man.h"
#endif /* HANDLE_MAN_PAGES */
#if !defined (O_RDONLY)
#if defined (HAVE_SYS_FCNTL_H)
#include <sys/fcntl.h>
#else /* !HAVE_SYS_FCNTL_H */
#include <fcntl.h>
#endif /* !HAVE_SYS_FCNTL_H */
#endif /* !O_RDONLY */
#if !defined (errno)
extern int errno;
#endif /* !errno */
/* **************************************************************** */
/* */
/* Functions Static to this File */
/* */
/* */
/* Functions Static to this File */
/* */
/* **************************************************************** */
static void forget_info_file (), remember_info_file ();
@ -81,9 +60,9 @@ static long get_node_length ();
#define INFO_GET_TAGS 1
/* **************************************************************** */
/* */
/* Global Variables */
/* */
/* */
/* Global Variables */
/* */
/* **************************************************************** */
/* When non-zero, this is a string describing the recent file error. */
@ -96,9 +75,9 @@ FILE_BUFFER **info_loaded_files = (FILE_BUFFER **)NULL;
int info_loaded_files_slots = 0;
/* **************************************************************** */
/* */
/* Public Functions for Node Manipulation */
/* */
/* */
/* Public Functions for Node Manipulation */
/* */
/* **************************************************************** */
/* Used to build "dir" menu from "localdir" files found in INFOPATH. */
@ -142,8 +121,8 @@ info_get_node (filename, nodename)
if (!file_buffer)
{
if (filesys_error_number)
info_recent_file_error =
filesys_error_string (filename, filesys_error_number);
info_recent_file_error =
filesys_error_string (filename, filesys_error_number);
return ((NODE *)NULL);
}
@ -154,9 +133,9 @@ info_get_node (filename, nodename)
{
node = info_get_node_of_file_buffer ("Top", file_buffer);
if (!node)
node = info_get_node_of_file_buffer ("top", file_buffer);
node = info_get_node_of_file_buffer ("top", file_buffer);
if (!node)
node = info_get_node_of_file_buffer ("TOP", file_buffer);
node = info_get_node_of_file_buffer ("TOP", file_buffer);
}
return (node);
}
@ -193,7 +172,7 @@ info_get_node_of_file_buffer (nodename, file_buffer)
node = (NODE *)xmalloc (sizeof (NODE));
node->filename = file_buffer->fullpath;
node->parent = (char *)NULL;
node->nodename = strdup ("*");
node->nodename = xstrdup ("*");
node->contents = file_buffer->contents;
node->nodelen = file_buffer->filesize;
node->flags = 0;
@ -203,7 +182,7 @@ info_get_node_of_file_buffer (nodename, file_buffer)
the manpage node finding function instead. */
else if (file_buffer->flags & N_IsManPage)
{
node = get_manpage_node (file_buffer, nodename);
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
@ -242,9 +221,9 @@ info_load_file (filename)
/* **************************************************************** */
/* */
/* Private Functions Implementation */
/* */
/* */
/* Private Functions Implementation */
/* */
/* **************************************************************** */
/* The workhorse for info_find_file (). Non-zero 2nd argument says to
@ -263,58 +242,58 @@ info_find_file_internal (filename, get_tags)
/* 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;
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);
/* 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);
/* 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);
}
/* 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;
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);
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);
}
}
return (file_buffer);
}
}
}
/* The file wasn't loaded. Try to load it now. */
@ -364,21 +343,21 @@ info_load_file_internal (filename, get_tags)
char *lowered_name;
char *basename;
lowered_name = strdup (filename);
lowered_name = xstrdup (filename);
basename = (char *) strrchr (lowered_name, '/');
if (basename)
basename++;
basename++;
else
basename = lowered_name;
basename = lowered_name;
while (*basename)
{
if (isupper (*basename))
*basename = tolower (*basename);
{
if (isupper (*basename))
*basename = tolower (*basename);
basename++;
}
basename++;
}
fullpath = info_find_fullpath (lowered_name);
free (lowered_name);
@ -402,8 +381,8 @@ info_load_file_internal (filename, get_tags)
/* 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 = strdup (filename);
file_buffer->fullpath = strdup (fullpath);
file_buffer->filename = xstrdup (filename);
file_buffer->fullpath = xstrdup (fullpath);
file_buffer->finfo = finfo;
file_buffer->filesize = filesize;
file_buffer->contents = contents;
@ -444,81 +423,81 @@ build_tags_and_nodes (file_buffer)
if (position != -1)
while (1)
{
long tags_table_begin, tags_table_end;
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;
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);
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;
/* 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;
/* 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);
/* Locate the start of the tags table. */
position = search_backward (TAGS_TABLE_BEG_LABEL, &binding);
if (position == -1)
break;
if (position == -1)
break;
binding.end = position;
binding.start = binding.end - 5 - strlen (TAGS_TABLE_BEG_LABEL);
position = find_node_separator (&binding);
binding.end = position;
binding.start = binding.end - 5 - strlen (TAGS_TABLE_BEG_LABEL);
position = find_node_separator (&binding);
if (position == -1)
break;
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;
/* 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 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;
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;
indirect.start = tags_table_begin;
indirect.end = 0;
indirect.buffer = binding.buffer;
indirect.flags = S_FoldCase;
position = search_backward (INDIRECT_TAGS_TABLE_LABEL, &indirect);
position = search_backward (INDIRECT_TAGS_TABLE_LABEL, &indirect);
if (position == -1)
{
/* This file is malformed. Give up. */
return;
}
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;
}
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
@ -561,37 +540,37 @@ get_nodes_of_info_file (file_buffer)
/* If not there, this is not the start of a node. */
if (start == -1)
continue;
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);
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. */
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;
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);
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 *);
file_buffer->tags_slots, 100, TAG *);
}
}
@ -608,7 +587,7 @@ get_node_length (binding)
for (i = binding->start, body = binding->buffer; i < binding->end; i++)
{
if (body[i] == INFO_FF || body[i] == INFO_COOKIE)
break;
break;
}
return ((long) i - binding->start);
}
@ -652,16 +631,16 @@ get_nodes_of_tags_table (file_buffer, buffer_binding)
/* Skip past informative "(Indirect)" tags table line. */
if (!tags_index && looking_at (TAGS_TABLE_IS_INDIRECT_LABEL, search))
continue;
continue;
/* Find the label preceding the node name. */
offset =
string_in_line (INFO_NODE_LABEL, search->buffer + search->start);
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. */
tags table. */
if (offset == -1)
break;
break;
/* Point to the beginning of the node definition. */
search->start += offset;
@ -670,11 +649,11 @@ get_nodes_of_tags_table (file_buffer, buffer_binding)
/* Move past the node's name. */
for (offset = 0;
(nodedef[offset]) && (nodedef[offset] != INFO_TAGSEP);
offset++);
(nodedef[offset]) && (nodedef[offset] != INFO_TAGSEP);
offset++);
if (nodedef[offset] != INFO_TAGSEP)
continue;
continue;
entry = (TAG *)xmalloc (sizeof (TAG));
entry->nodename = (char *)xmalloc (1 + offset);
@ -687,13 +666,13 @@ get_nodes_of_tags_table (file_buffer, buffer_binding)
entry->nodelen = -1;
/* The filename of this node is currently known as the same as the
name of this file. */
name of this file. */
entry->filename = file_buffer->fullpath;
/* Add this node structure to the array of node structures in this
FILE_BUFFER. */
FILE_BUFFER. */
add_pointer_to_array (entry, tags_index, file_buffer->tags,
file_buffer->tags_slots, 100, TAG *);
file_buffer->tags_slots, 100, TAG *);
}
free (search);
}
@ -734,23 +713,23 @@ get_tags_of_indirect_tags_table (file_buffer, indirect_binding, tags_binding)
while (line < end)
{
int colon;
int colon;
colon = string_in_line (":", line);
colon = string_in_line (":", line);
if (colon == -1)
break;
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);
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 *);
add_pointer_to_array
(subfile, subfiles_index, subfiles, subfiles_slots, 10, SUBFILE *);
while (*line++ != '\n');
while (*line++ != '\n');
}
}
@ -768,10 +747,10 @@ get_tags_of_indirect_tags_table (file_buffer, indirect_binding, tags_binding)
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. */
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;
@ -779,81 +758,80 @@ get_tags_of_indirect_tags_table (file_buffer, indirect_binding, tags_binding)
header_length = find_node_separator (&binding);
if (header_length == -1)
header_length = 0;
header_length = 0;
/* Build the file buffer's list of subfiles. */
{
char *containing_dir, *temp;
int len_containing_dir;
char *containing_dir, *temp;
int len_containing_dir;
containing_dir = strdup (file_buffer->fullpath);
temp = (char *) strrchr (containing_dir, '/');
containing_dir = xstrdup (file_buffer->fullpath);
temp = (char *) strrchr (containing_dir, '/');
if (temp)
*temp = '\0';
if (temp)
*temp = '\0';
len_containing_dir = strlen (containing_dir);
len_containing_dir = strlen (containing_dir);
for (i = 0; subfiles[i]; i++);
for (i = 0; subfiles[i]; i++);
file_buffer->subfiles = (char **) xmalloc ((1 + i) * sizeof (char *));
file_buffer->subfiles = (char **) xmalloc ((1 + i) * sizeof (char *));
for (i = 0; subfiles[i]; i++)
{
char *fullpath;
for (i = 0; subfiles[i]; i++)
{
char *fullpath;
fullpath = (char *) xmalloc
(2 + strlen (subfiles[i]->filename) + len_containing_dir);
fullpath = (char *) xmalloc
(2 + strlen (subfiles[i]->filename) + len_containing_dir);
sprintf (fullpath, "%s/%s",
containing_dir, subfiles[i]->filename);
sprintf (fullpath, "%s/%s",
containing_dir, subfiles[i]->filename);
file_buffer->subfiles[i] = fullpath;
}
file_buffer->subfiles[i] = (char *)NULL;
free (containing_dir);
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++);
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;
}
/* 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. */
/* 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;
}
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. */
was indirect. */
file_buffer->flags |= N_TagsIndirect;
}
@ -878,105 +856,105 @@ info_node_of_file_buffer_tags (file_buffer, nodename)
register int i;
TAG *tag;
for (i = 0; tag = file_buffer->tags[i]; i++)
for (i = 0; (tag = file_buffer->tags[i]); i++)
if (strcmp (nodename, tag->nodename) == 0)
{
FILE_BUFFER *subfile;
FILE_BUFFER *subfile;
subfile = info_find_file_internal (tag->filename, INFO_NO_TAGS);
subfile = info_find_file_internal (tag->filename, INFO_NO_TAGS);
if (!subfile)
return ((NODE *)NULL);
if (!subfile)
return ((NODE *)NULL);
if (!subfile->contents)
{
info_reload_file_buffer_contents (subfile);
if (!subfile->contents)
{
info_reload_file_buffer_contents (subfile);
if (!subfile->contents)
return ((NODE *)NULL);
}
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;
/* 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;
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_HasTagsTable)
{
node->flags |= N_HasTagsTable;
if (file_buffer->flags & N_TagsIndirect)
{
node->flags |= N_TagsIndirect;
node->parent = file_buffer->fullpath;
}
}
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 (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;
/* 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;
min = max = DEFAULT_INFO_FUDGE;
if (tag->nodestart < DEFAULT_INFO_FUDGE)
min = tag->nodestart;
if (tag->nodestart < DEFAULT_INFO_FUDGE)
min = tag->nodestart;
if (DEFAULT_INFO_FUDGE >
(subfile->filesize - tag->nodestart))
max = subfile->filesize - 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;
/* 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;
/* 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_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);
}
node->nodelen = tag->nodelen;
return (node);
}
}
/* There was a tag table for this file, and the node wasn't found.
@ -985,9 +963,9 @@ info_node_of_file_buffer_tags (file_buffer, nodename)
}
/* **************************************************************** */
/* */
/* Managing file_buffers, nodes, and tags. */
/* */
/* */
/* Managing file_buffers, nodes, and tags. */
/* */
/* **************************************************************** */
/* Create a new, empty file buffer. */
@ -1018,7 +996,7 @@ remember_info_file (file_buffer)
;
add_pointer_to_array (file_buffer, i, info_loaded_files,
info_loaded_files_slots, 10, FILE_BUFFER *);
info_loaded_files_slots, 10, FILE_BUFFER *);
}
/* Forget the contents, tags table, nodes list, and names of FILENAME. */
@ -1032,25 +1010,25 @@ forget_info_file (filename)
if (!info_loaded_files)
return;
for (i = 0; file_buffer = info_loaded_files[i]; i++)
for (i = 0; (file_buffer = info_loaded_files[i]); i++)
if ((strcmp (filename, file_buffer->filename) == 0) ||
(strcmp (filename, file_buffer->fullpath) == 0))
(strcmp (filename, file_buffer->fullpath) == 0))
{
free (file_buffer->filename);
free (file_buffer->fullpath);
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);
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])
;
while ((info_loaded_files[i] = info_loaded_files[++i]))
;
break;
break;
}
}
@ -1065,8 +1043,8 @@ free_file_buffer_tags (file_buffer)
{
register TAG *tag;
for (i = 0; tag = file_buffer->tags[i]; i++)
free_info_tag (tag);
for (i = 0; (tag = file_buffer->tags[i]); i++)
free_info_tag (tag);
free (file_buffer->tags);
file_buffer->tags = (TAG **)NULL;
@ -1076,7 +1054,7 @@ free_file_buffer_tags (file_buffer)
if (file_buffer->subfiles)
{
for (i = 0; file_buffer->subfiles[i]; i++)
free (file_buffer->subfiles[i]);
free (file_buffer->subfiles[i]);
free (file_buffer->subfiles);
file_buffer->subfiles = (char **)NULL;
@ -1160,29 +1138,29 @@ adjust_nodestart (node, min, max)
sep_len = skip_node_separator (node->contents);
/* If we managed to skip a node separator, then check for this node
being the right one. */
being the right one. */
if (sep_len != 0)
{
char *nodedef, *nodestart;
int offset;
{
char *nodedef, *nodestart;
int offset;
nodestart = node_body.buffer + position + sep_len;
nodedef = nodestart;
offset = string_in_line (INFO_NODE_LABEL, nodedef);
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);
}
}
}
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. */

View File

@ -1,9 +1,10 @@
/* nodes.h -- How we represent nodes internally. */
/* 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
This file is part of GNU Info, a program for reading online documentation
stored in Info format.
Copyright (C) 1993 Free Software Foundation, Inc.
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
@ -21,15 +22,15 @@
Written by Brian Fox (bfox@ai.mit.edu). */
#if !defined (_NODES_H_)
#define _NODES_H_
#if !defined (NODES_H)
#define NODES_H
#include "general.h"
#include "info.h"
/* **************************************************************** */
/* */
/* User Code Interface */
/* */
/* */
/* User Code Interface */
/* */
/* **************************************************************** */
/* Callers generally only want the node itself. This structure is used
@ -41,45 +42,45 @@
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. */
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. */
#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 */
/* */
/* */
/* 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)"
#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'
@ -94,10 +95,10 @@ typedef struct {
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. */
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
@ -108,21 +109,21 @@ typedef struct {
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. */
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 */
/* */
/* */
/* Externally Visible Functions */
/* */
/* **************************************************************** */
/* Array of FILE_BUFFER * which represents the currently loaded info files. */
@ -165,4 +166,4 @@ extern char *info_recent_file_error;
/* Create a new, empty file buffer. */
extern FILE_BUFFER *make_file_buffer ();
#endif /* !_NODES_H_ */
#endif /* !NODES_H */

View File

@ -3,7 +3,7 @@
/* This file is part of GNU Info, a program for reading online documentation
stored in Info format.
Copyright (C) 1993 Free Software Foundation, Inc.
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
@ -21,17 +21,11 @@
Written by Brian Fox (bfox@ai.mit.edu). */
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "general.h"
#include "info.h"
#include "search.h"
#include "nodes.h"
#if !defined (NULL)
# define NULL 0x0
#endif /* !NULL */
/* The search functions take two arguments:
1) a string to search for, and
@ -73,9 +67,9 @@ copy_binding (binding)
/* **************************************************************** */
/* */
/* The Actual Searching Functions */
/* */
/* */
/* The Actual Searching Functions */
/* */
/* **************************************************************** */
/* Search forwards or backwards for the text delimited by BINDING.
@ -115,15 +109,15 @@ search_forward (string, binding)
if (binding->flags & S_FoldCase)
{
alternate = strdup (string);
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]);
}
{
if (islower (alternate[i]))
alternate[i] = toupper (alternate[i]);
else if (isupper (alternate[i]))
alternate[i] = tolower (alternate[i]);
}
}
buff = binding->buffer + binding->start;
@ -132,21 +126,21 @@ search_forward (string, binding)
while (buff < (end - len))
{
for (i = 0; i < len; i++)
{
c = buff[i];
{
c = buff[i];
if ((c != string[i]) && (!alternate || c != alternate[i]))
break;
}
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));
}
{
if (alternate)
free (alternate);
if (binding->flags & S_SkipDest)
buff += len;
return ((long) (buff - binding->buffer));
}
buff++;
}
@ -184,15 +178,15 @@ search_backward (input_string, binding)
if (binding->flags & S_FoldCase)
{
alternate = strdup (string);
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]);
}
{
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;
@ -201,23 +195,23 @@ search_backward (input_string, binding)
while (buff > (end + len))
{
for (i = 0; i < len; i++)
{
c = *(buff - i);
{
c = *(buff - i);
if (c != string[i] && (alternate && c != alternate[i]))
break;
}
if (c != string[i] && (alternate && c != alternate[i]))
break;
}
if (!string[i])
{
free (string);
if (alternate)
free (alternate);
{
free (string);
if (alternate)
free (alternate);
if (binding->flags & S_SkipDest)
buff -= len;
return ((long) (1 + (buff - binding->buffer)));
}
if (binding->flags & S_SkipDest)
buff -= len;
return ((long) (1 + (buff - binding->buffer)));
}
buff--;
}
@ -268,9 +262,9 @@ looking_at (string, binding)
}
/* **************************************************************** */
/* */
/* Small String Searches */
/* */
/* */
/* Small String Searches */
/* */
/* **************************************************************** */
/* Function names that start with "skip" are passed a string, and return
@ -346,37 +340,43 @@ skip_node_characters (string, newlines_okay)
for (; string && (c = string[i]); i++)
{
if (paren)
{
if (c == '(')
paren++;
else if (c == ')')
paren--;
{
if (c == '(')
paren++;
else if (c == ')')
paren--;
continue;
}
continue;
}
/* If the character following the close paren is a space or period,
then this node name has no more characters associated with it. */
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 == '.' &&
((!string[i + 1]) ||
(whitespace_or_newline (string[i + 1])) ||
(string[i + 1] == ')'))))
break;
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 */
/* */
/* */
/* Searching FILE_BUFFER's */
/* */
/* **************************************************************** */
/* Return the absolute position of the first occurence of a node separator in
@ -397,11 +397,11 @@ find_node_separator (binding)
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'))))
(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);
}
@ -467,7 +467,7 @@ find_tags_table (binding)
search.start += skip_node_separator (search.buffer + search.start);
if (looking_at (TAGS_TABLE_BEG_LABEL, &search))
return (position);
return (position);
}
return (-1);
}
@ -482,8 +482,8 @@ find_node_in_binding (nodename, binding)
char *nodename;
SEARCH_BINDING *binding;
{
register long position;
register int offset, namelen;
long position;
int offset, namelen;
SEARCH_BINDING search;
namelen = strlen (nodename);
@ -501,19 +501,19 @@ find_node_in_binding (nodename, binding)
offset = string_in_line (INFO_NODE_LABEL, search.buffer + search.start);
if (offset == -1)
continue;
continue;
search.start += offset;
search.start += skip_whitespace (search.buffer + search.start);
offset = skip_node_characters
(search.buffer + search.start, DONT_SKIP_NEWLINES);
(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. */
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);
(search.buffer[search.start] == nodename[0]) &&
(strncmp (search.buffer + search.start, nodename, offset) == 0))
return (position);
}
return (-1);
}

View File

@ -1,9 +1,10 @@
/* search.h -- Structure used to search large bodies of text, with bounds. */
/* 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
This file is part of GNU Info, a program for reading online documentation
stored in Info format.
Copyright (C) 1993 Free Software Foundation, Inc.
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
@ -31,18 +32,18 @@
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. */
#if !defined (_SEARCH_H_)
#define _SEARCH_H_
#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. */
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. */
#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 ();
@ -71,5 +72,4 @@ extern int skip_node_characters (), skip_node_separator ();
extern long find_node_separator (), find_tags_table ();
extern long find_node_in_binding ();
#endif /* !_SEARCH_H_ */
#endif /* not INFO_SEARCH_H */

View File

@ -21,10 +21,10 @@
Written by Brian Fox (bfox@ai.mit.edu). */
#if !defined (_SESSION_H_)
#define _SESSION_H_
#if !defined (SESSION_H)
#define SESSION_H
#include "general.h"
#include "info.h"
#include "dribble.h"
/* All commands that can be invoked from within info_session () receive
@ -55,11 +55,11 @@ 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_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. */
#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 ();
@ -143,4 +143,4 @@ extern void info_print_node ();
/* Miscellaneous commands. */
extern void info_abort_key (), info_quit (), info_do_lowercase_version ();
#endif /* _SESSION_H_ */
#endif /* SESSION_H */

View File

@ -1,9 +1,10 @@
/* signals.h -- Header to include system dependent signal definitions. */
/* 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
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.
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
@ -21,11 +22,17 @@
Written by Brian Fox (bfox@ai.mit.edu). */
#if !defined (_SIGNALS_H_)
#define _SIGNALS_H_
#ifndef INFO_SIGNALS_H
#define INFO_SIGNALS_H
#include <sys/types.h>
#include <signal.h>
/* 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 */
@ -86,4 +93,4 @@
# define UNBLOCK_SIGNAL(sig)
#endif /* !HAVE_SIGPROCMASK && !HAVE_SIGSETMASK */
#endif /* !_SIGNALS_H_ */
#endif /* not INFO_SIGNALS_H */

View File

@ -1,10 +1,10 @@
/* termdep.h -- System things that terminal.c depends on.
$Id: termdep.h,v 1.3 1996/10/02 22:23:52 karl Exp $
$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 Free Software Foundation, Inc.
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
@ -22,28 +22,16 @@
Written by Brian Fox (bfox@ai.mit.edu). */
#if !defined (_TERMDEP_H_)
# define _TERMDEP_H_
#ifndef INFO_TERMDEP_H
#define INFO_TERMDEP_H
#if defined (HAVE_SYS_FCNTL_H)
# include <sys/fcntl.h>
#else
# include <fcntl.h>
#endif /* !HAVE_SYS_FCNTL_H */
#if defined (HAVE_SYS_FILE_H)
# include <sys/file.h>
#endif /* HAVE_SYS_FILE_H */
#if defined (HAVE_STRINGS_H)
# include <strings.h>
#else
# if defined (HAVE_STRING_H)
# include <string.h>
# endif
/* NeXT supplies <termios.h> but it is broken. Probably Autoconf should
have a separate test, but anyway ... */
#ifdef NeXT
#undef HAVE_TERMIOS_H
#endif
#if defined (HAVE_TERMIOS_H)
#ifdef HAVE_TERMIOS_H
# include <termios.h>
#else
# if defined (HAVE_TERMIO_H)
@ -62,15 +50,8 @@
# endif /* !HAVE_TERMIO_H */
#endif /* !HAVE_TERMIOS_H */
#if defined (HAVE_SYS_TTOLD_H)
#ifdef HAVE_SYS_TTOLD_H
# include <sys/ttold.h>
#endif /* HAVE_SYS_TTOLD_H */
#if !defined (HAVE_STRCHR)
# undef strchr
# undef strrchr
# define strchr index
# define strrchr rindex
#endif /* !HAVE_STRCHR */
#endif /* _TERMDEP_H_ */
#endif /* not INFO_TERMDEP_H */

View File

@ -3,7 +3,7 @@
/* 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.
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
@ -21,15 +21,10 @@
Written by Brian Fox (bfox@ai.mit.edu). */
#if !defined (_TERMINAL_H_)
#define _TERMINAL_H_
#if !defined (TERMINAL_H)
#define TERMINAL_H
/* We use the following data type to talk about pointers to functions. */
#if !defined (__FUNCTION_DEF)
# define __FUNCTION_DEF
typedef int Function ();
typedef void VFunction ();
#endif /* _FUNCTION_DEF */
#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
@ -125,5 +120,6 @@ 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_ */
#endif /* !TERMINAL_H */

View File

@ -1,10 +1,11 @@
/* tilde.c -- Tilde expansion code (~/foo := $HOME/foo).
$Id: tilde.c,v 1.3 1996/09/29 23:12:30 karl Exp $
$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 Free Software Foundation, Inc.
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
@ -22,39 +23,29 @@
Written by Brian Fox (bfox@ai.mit.edu). */
#if defined (__GNUC__)
# define alloca __builtin_alloca
#else /* !__GNUC__ */
# if defined (_AIX)
/* Indent #pragma so that older Cpp's don't try to parse it. */
#ifdef _AIX
#pragma alloca
# else /* !_AIX */
# if defined (HAVE_ALLOCA_H)
# include <alloca.h>
# endif /* HAVE_ALLOCA_H */
# endif /* !AIX */
#endif /* !__GNUC__ */
#endif /* _AIX */
#if defined (HAVE_STDLIB_H)
#include <stdlib.h>
#endif
/* Include config.h before doing alloca. */
#include "info.h"
#include "tilde.h"
#include <pwd.h>
#if defined (HAVE_STRING_H)
#include <string.h>
#endif
#include "clib.h"
#if !defined (NULL)
# define NULL 0x0
#ifdef __GNUC__
# undef alloca
# define alloca __builtin_alloca
#else
# ifdef HAVE_ALLOCA_H
# include <alloca.h>
# else
# ifndef _AIX
char *alloca ();
# endif
# endif
#endif
#if defined (TEST) || defined (STATIC_MALLOC)
static void *xmalloc (), *xrealloc ();
#else
extern void *xmalloc (), *xrealloc ();
#endif /* TEST || STATIC_MALLOC */
/* The default value of tilde_additional_prefixes. This is set to
@ -105,16 +96,16 @@ tilde_find_prefix (string, len)
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);
}
}
}
{
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);
}
@ -133,13 +124,13 @@ tilde_find_suffix (string)
for (i = 0; i < string_len; i++)
{
if (string[i] == '/' || !string[i])
break;
break;
for (j = 0; suffixes && suffixes[j]; j++)
{
if (strncmp (string + i, suffixes[j], strlen (suffixes[j])) == 0)
return (i);
}
{
if (strncmp (string + i, suffixes[j], strlen (suffixes[j])) == 0)
return (i);
}
}
return (i);
}
@ -167,7 +158,7 @@ tilde_expand (string)
/* Copy the skipped text into the result. */
if ((result_index + start + 1) > result_size)
result = (char *)xrealloc (result, 1 + (result_size += (start + 20)));
result = (char *)xrealloc (result, 1 + (result_size += (start + 20)));
strncpy (result + result_index, string, start);
result_index += start;
@ -176,12 +167,12 @@ tilde_expand (string)
string += start;
/* Make END be the index of one after the last character of the
username. */
username. */
end = tilde_find_suffix (string);
/* If both START and END are zero, we are all done. */
if (!start && !end)
break;
break;
/* Expand the entire tilde word, and copy it into RESULT. */
tilde_word = (char *)xmalloc (1 + end);
@ -194,7 +185,7 @@ tilde_expand (string)
len = strlen (expansion);
if ((result_index + len + 1) > result_size)
result = (char *)xrealloc (result, 1 + (result_size += (len + 20)));
result = (char *)xrealloc (result, 1 + (result_size += (len + 20)));
strcpy (result + result_index, expansion);
result_index += len;
@ -214,88 +205,87 @@ tilde_expand_word (filename)
{
char *dirname;
dirname = filename ? strdup (filename) : (char *)NULL;
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. */
extern char *getenv ();
char *temp_home = getenv ("HOME");
{
/* 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;
/* 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;
}
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 = strdup (temp_name);
}
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;
{
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';
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;
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);
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 = strdup (temp_name);
}
endpwent ();
}
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);
}
@ -318,15 +308,15 @@ main (argc, argv)
fflush (stdout);
if (!gets (line))
strcpy (line, "done");
strcpy (line, "done");
if ((strcmp (line, "done") == 0) ||
(strcmp (line, "quit") == 0) ||
(strcmp (line, "exit") == 0))
{
done = 1;
break;
}
(strcmp (line, "quit") == 0) ||
(strcmp (line, "exit") == 0))
{
done = 1;
break;
}
result = tilde_expand (line);
printf (" --> %s\n", result);
@ -369,7 +359,7 @@ xrealloc (pointer, bytes)
static void
memory_error_and_abort ()
{
fprintf (stderr, "readline: Out of virtual memory!\n");
fprintf (stderr, _("readline: Out of virtual memory!\n"));
abort ();
}
#endif /* TEST */

View File

@ -25,13 +25,10 @@
Written by Brian Fox (bfox@ai.mit.edu). */
/* Function pointers can be declared as (Function *)foo. */
#if !defined (__FUNCTION_DEF)
# define __FUNCTION_DEF
typedef int Function ();
typedef void VFunction ();
typedef char *CFunction ();
#endif /* _FUNCTION_DEF */
#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
@ -56,3 +53,4 @@ extern char *tilde_expand ();
tilde. If there is no expansion, call tilde_expansion_failure_hook. */
extern char *tilde_expand_word ();
#endif /* not TILDE_H */

View File

@ -1,9 +1,10 @@
/* variables.c -- How to manipulate user visible variables in Info. */
/* 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
This file is part of GNU Info, a program for reading online documentation
stored in Info format.
Copyright (C) 1993 Free Software Foundation, Inc.
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
@ -25,9 +26,9 @@
#include "variables.h"
/* **************************************************************** */
/* */
/* User Visible Variables in Info */
/* */
/* */
/* User Visible Variables in Info */
/* */
/* **************************************************************** */
/* Choices used by the completer when reading a zero/non-zero value for
@ -36,73 +37,75 @@ static char *on_off_choices[] = { "Off", "On", (char *)NULL };
VARIABLE_ALIST info_variables[] = {
{ "automatic-footnotes",
"When \"On\", footnotes appear and disappear automatically",
N_("When \"On\", footnotes appear and disappear automatically"),
&auto_footnotes_p, (char **)on_off_choices },
{ "automatic-tiling",
"When \"On\", creating or deleting a window resizes other windows",
N_("When \"On\", creating or deleting a window resizes other windows"),
&auto_tiling_p, (char **)on_off_choices },
{ "visible-bell",
"When \"On\", flash the screen instead of ringing the bell",
N_("When \"On\", flash the screen instead of ringing the bell"),
&terminal_use_visible_bell_p, (char **)on_off_choices },
{ "errors-ring-bell",
"When \"On\", errors cause the bell to ring",
N_("When \"On\", errors cause the bell to ring"),
&info_error_rings_bell_p, (char **)on_off_choices },
{ "gc-compressed-files",
"When \"On\", Info garbage collects files which had to be uncompressed",
N_("When \"On\", Info garbage collects files which had to be uncompressed"),
&gc_compressed_files, (char **)on_off_choices },
{ "show-index-match",
"When \"On\", the portion of the matched search string is highlighted",
N_("When \"On\", the portion of the matched search string is highlighted"),
&show_index_match, (char **)on_off_choices },
{ "scroll-behaviour",
"Controls what happens when scrolling is requested at the end of a node",
N_("Controls what happens when scrolling is requested at the end of a node"),
&info_scroll_behaviour, (char **)info_scroll_choices },
{ "scroll-step",
"The number lines to scroll when the cursor moves out of the window",
N_("The number lines to scroll when the cursor moves out of the window"),
&window_scroll_step, (char **)NULL },
{ "ISO-Latin",
"When \"On\", Info accepts and displays ISO Latin characters",
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")
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);
var = read_variable_name (_("Describe variable: "), window);
if (!var)
return;
description = (char *)xmalloc (20 + strlen (var->name) + strlen (var->doc));
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);
var->name, var->choices[*(var->value)], _(var->doc));
else
sprintf (description, "%s (%d): %s.", var->name, *(var->value), var->doc);
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")
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);
var = read_variable_name (_("Set variable: "), window);
if (!var)
return;
@ -113,86 +116,86 @@ DECLARE_INFO_COMMAND (set_variable, "Set the value of an Info variable")
if (!var->choices)
{
int potential_value;
int potential_value;
if (info_explicit_arg || count != 1)
potential_value = count;
else
potential_value = *(var->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);
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 ();
/* If no error was printed, clear the echo area. */
if (!info_error_was_printed)
window_clear_echo_area ();
/* User aborted? */
if (!line)
return;
/* 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;
/* 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);
free (line);
}
else
{
register int i;
REFERENCE **array = (REFERENCE **)NULL;
int array_index = 0;
int array_slots = 0;
register int i;
REFERENCE **array = (REFERENCE **)NULL;
int array_index = 0;
int array_slots = 0;
for (i = 0; var->choices[i]; i++)
{
REFERENCE *entry;
for (i = 0; var->choices[i]; i++)
{
REFERENCE *entry;
entry = (REFERENCE *)xmalloc (sizeof (REFERENCE));
entry->label = strdup (var->choices[i]);
entry->nodename = (char *)NULL;
entry->filename = (char *)NULL;
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 *);
}
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)]);
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);
/* Ask the completer to read a variable value for us. */
line = info_read_completing_in_echo_area (window, prompt, array);
info_free_references (array);
info_free_references (array);
if (!echo_area_is_active)
window_clear_echo_area ();
if (!echo_area_is_active)
window_clear_echo_area ();
/* User aborted? */
if (!line)
{
info_abort_key (active_window, 0, 0);
return;
}
/* 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;
}
/* 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;
/* 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;
if (var->choices[i])
*(var->value) = i;
}
}
}
@ -259,13 +262,13 @@ make_variable_completions_array ()
{
REFERENCE *entry;
entry = (REFERENCE *)xmalloc (sizeof (REFERENCE));
entry->label = strdup (info_variables[i].name);
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 *);
(entry, array_index, array, array_slots, 200, REFERENCE *);
}
return (array);

View File

@ -1,9 +1,10 @@
/* variables.h -- Description of user visible variables in Info. */
/* 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
This file is part of GNU Info, a program for reading online documentation
stored in Info format.
Copyright (C) 1993 Free Software Foundation, Inc.
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
@ -21,8 +22,8 @@
Written by Brian Fox (bfox@ai.mit.edu). */
#if !defined (_VARIABLES_H_)
#define _VARIABLES_H_
#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
@ -32,10 +33,10 @@
/* 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. */
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
@ -61,4 +62,4 @@ extern int info_scroll_behaviour;
extern int window_scroll_step;
extern int ISO_Latin_p;
#endif /* _VARIABLES_H_ */
#endif /* not INFO_VARIABLES_H */

View File

@ -1,9 +1,10 @@
/* window.c -- Windows in Info. */
/* 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
This file is part of GNU Info, a program for reading online documentation
stored in Info format.
Copyright (C) 1993 Free Software Foundation, Inc.
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
@ -21,10 +22,7 @@
Written by Brian Fox (bfox@ai.mit.edu). */
#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "info.h"
#include "nodes.h"
#include "window.h"
#include "display.h"
@ -136,36 +134,36 @@ window_new_screen_size (width, height)
while ((height - echo_area_required) / numwins <= WINDOW_MIN_SIZE)
{
/* If only one window, make the size of it be zero, and return
immediately. */
immediately. */
if (!windows->next)
{
windows->height = 0;
maybe_free (windows->line_starts);
windows->line_starts = (char **)NULL;
windows->line_count = 0;
break;
}
{
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;
if (win->flags & W_TempWindow)
break;
/* Otherwise, delete the first window, and try again. */
if (!win)
win = windows;
win = windows;
if (window_deletion_notifier)
(*window_deletion_notifier) (win);
(*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. */
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;
@ -186,34 +184,34 @@ window_new_screen_size (width, height)
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->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. */
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);
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. */
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;
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;
win->height += delta_leftover;
if (win->node)
recalculate_line_starts (win);
recalculate_line_starts (win);
win->flags |= W_UpdateWindow;
}
@ -232,32 +230,32 @@ window_new_screen_size (width, height)
win = windows;
while (win)
{
if ((win->height < WINDOW_MIN_HEIGHT) ||
(win->height > avail))
{
WINDOW *lastwin;
{
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);
/* 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;
}
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;
}
/* Give the leftover space (if any) to the last window. */
lastwin->height += delta_leftover;
break;
}
else
win= win->next;
}
}
}
@ -412,25 +410,25 @@ window_change_window_height (window, amount)
/* WINDOW decreasing in size? */
if (amount < 0)
{
int abs_amount = -amount; /* It is easier to deal with this way. */
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;
return;
/* If we have two neighboring windows, choose the smaller one to get
larger. */
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);
}
{
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);
shrink_me_growing_next (window, next, abs_amount);
else
shrink_me_growing_prev (window, prev, abs_amount);
shrink_me_growing_prev (window, prev, abs_amount);
}
/* WINDOW increasing in size? */
@ -439,65 +437,65 @@ window_change_window_height (window, amount)
int total_avail, next_avail = 0, prev_avail = 0;
if (next)
next_avail = next->height - WINDOW_MIN_SIZE;
next_avail = next->height - WINDOW_MIN_SIZE;
if (prev)
prev_avail = prev->height - WINDOW_MIN_SIZE;
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;
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. */
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);
grow_me_shrinking_next (window, next, amount);
else if ((prev && !next) || ((prev_avail - amount) >= next_avail))
grow_me_shrinking_prev (window, prev, amount);
grow_me_shrinking_prev (window, prev, amount);
else
{
int change;
{
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;
}
/* 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--;
/* 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);
}
/* 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;
@ -526,10 +524,10 @@ window_tile_windows (style)
for (win = windows; win; win = win->next)
if (do_internals || !win->node ||
(win->node->flags & N_IsInternal) == 0)
(win->node->flags & N_IsInternal) == 0)
{
avail += win->height;
numwins++;
avail += win->height;
numwins++;
}
if (numwins <= 1 || !the_screen->height)
@ -544,11 +542,11 @@ window_tile_windows (style)
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;
}
(win->node->flags & N_IsInternal) == 0)
{
last_adjusted = win;
win->height = per_win_height;
}
}
if (last_adjusted)
@ -558,7 +556,7 @@ window_tile_windows (style)
for (win = windows; win; win = win->next)
{
if (win->prev)
win->first_row = win->prev->first_row + win->prev->height + 1;
win->first_row = win->prev->first_row + win->prev->height + 1;
window_adjust_pagetop (win);
win->flags |= W_UpdateWindow;
@ -591,11 +589,11 @@ window_toggle_wrap (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.*/
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);
display_scroll_line_starts
(window, old_pagetop, old_starts, old_lines);
maybe_free (old_starts);
}
window->flags |= W_UpdateWindow;
@ -650,12 +648,12 @@ window_delete_window (window)
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. */
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;
active_window = next;
else
active_window = prev;
active_window = prev;
}
if (next && active_window == next)
@ -674,13 +672,13 @@ window_delete_window (window)
int diff;
/* Try to adjust the visible part of the node so that as little
text as possible has to move. */
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;
window_to_fix->pagetop = 0;
}
/* The `+ 1' is to offset the difference between the first_row locations.
@ -725,24 +723,24 @@ character_width (character, hpos)
int width = 1;
if (ISO_Latin_p)
printable_limit = 160;
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;
}
{
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;
@ -820,61 +818,61 @@ calculate_line_starts (window)
unsigned int cwidth, c;
add_pointer_to_array (line, line_starts_index, line_starts,
line_starts_slots, 100, char *);
line_starts_slots, 100, char *);
if (bump_index)
{
i++;
bump_index = 0;
}
{
i++;
bump_index = 0;
}
while (1)
{
c = node->contents[i];
cwidth = character_width (c, hpos);
{
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 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 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;
}
}
}
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;
@ -916,7 +914,7 @@ window_adjust_pagetop (window)
line_start = window->line_starts[line];
if ((line_start - contents) > window->point)
break;
break;
}
/* The line index preceding the line start which is past point is the
@ -929,26 +927,26 @@ window_adjust_pagetop (window)
(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. */
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);
}
{
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);
window->pagetop = line - ((window->height - 1) / 2);
if (window->pagetop < 0)
window->pagetop = 0;
window->pagetop = 0;
window->flags |= W_UpdateWindow;
}
}
@ -970,7 +968,7 @@ window_line_of_point (window)
for (i = start; i < window->line_count; i++)
{
if ((window->line_starts[i] - window->node->contents) > window->point)
break;
break;
}
return (i - 1);
@ -1029,7 +1027,7 @@ window_chars_to_goal (line, goal)
check = hpos + character_width (line[i], hpos);
if (check > goal)
break;
break;
hpos = check;
}
@ -1056,26 +1054,26 @@ window_make_modeline (window)
if (window->pagetop == 0)
{
if (lines_remaining <= window->height)
strcpy (location_indicator, "All");
strcpy (location_indicator, "All");
else
strcpy (location_indicator, "Top");
strcpy (location_indicator, "Top");
}
else
{
if (lines_remaining <= window->height)
strcpy (location_indicator, "Bot");
strcpy (location_indicator, "Bot");
else
{
float pt, lc;
int percentage;
{
float pt, lc;
int percentage;
pt = (float)window->pagetop;
lc = (float)window->line_count;
pt = (float)window->pagetop;
lc = (float)window->line_count;
percentage = 100 * (pt / lc);
percentage = 100 * (pt / lc);
sprintf (location_indicator, "%2d%%", percentage);
}
sprintf (location_indicator, "%2d%%", percentage);
}
}
/* Calculate the maximum size of the information to stick in MODELINE. */
@ -1088,49 +1086,49 @@ window_make_modeline (window)
if (node)
{
if (node->nodename)
nodename = node->nodename;
if (node->nodename)
nodename = node->nodename;
if (node->parent)
{
parent = filename_non_directory (node->parent);
modeline_len += strlen ("Subfile: ") + strlen (node->filename);
}
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->filename)
filename = filename_non_directory (node->filename);
if (node->flags & N_UpdateTags)
update_message = "--*** Tags out of Date ***";
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). */
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 += 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);
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);
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);
sprintf (modeline + strlen (modeline), _(" Subfile: %s"), filename);
if (update_message)
sprintf (modeline + strlen (modeline), "%s", update_message);
@ -1141,9 +1139,9 @@ window_make_modeline (window)
modeline[window->width] = '\0';
else
{
while (i < window->width)
modeline[i++] = '-';
modeline[i] = '\0';
while (i < window->width)
modeline[i++] = '-';
modeline[i] = '\0';
}
strcpy (window->modeline, modeline);
@ -1197,9 +1195,9 @@ window_set_state (window, state)
/* **************************************************************** */
/* */
/* Manipulating Home-Made Nodes */
/* */
/* */
/* Manipulating Home-Made Nodes */
/* */
/* **************************************************************** */
/* A place to buffer echo area messages. */
@ -1259,8 +1257,8 @@ message_in_echo_area (format, 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 *);
old_echo_area_nodes, old_echo_area_nodes_slots,
4, NODE *);
}
echo_area_node = (NODE *)NULL;
window_message_in_echo_area (format, arg1, arg2);
@ -1299,7 +1297,7 @@ message_buffer_resize (length)
while (message_buffer_size <= message_buffer_index + length)
message_buffer = (char *)
xrealloc (message_buffer,
message_buffer_size += 100 + (2 * length));
message_buffer_size += 100 + (2 * length));
}
/* Format MESSAGE_BUFFER with the results of printing FORMAT with ARG1 and
@ -1323,70 +1321,70 @@ build_message_buffer (format, arg1, arg2)
for (i = 0; format[i]; i++)
{
if (format[i] != '%')
{
message_buffer[message_buffer_index++] = format[i];
len--;
}
{
message_buffer[message_buffer_index++] = format[i];
len--;
}
else
{
char c;
{
char c;
c = format[++i];
c = format[++i];
switch (c)
{
case '%': /* Insert a percent sign. */
message_buffer_resize (len + 1);
message_buffer[message_buffer_index++] = '%';
break;
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;
case 's': /* Insert the current arg as a string. */
{
char *string;
int string_len;
string = (char *)args[arg_index++];
string_len = strlen (string);
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;
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;
case 'd': /* Insert the current arg as an integer. */
{
long long_val;
int integer;
long_val = (long)args[arg_index++];
integer = (int)long_val;
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;
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;
case 'c': /* Insert the current arg as a character. */
{
long long_val;
int character;
long_val = (long)args[arg_index++];
character = (int)long_val;
long_val = (long)args[arg_index++];
character = (int)long_val;
message_buffer_resize (len + 1);
message_buffer[message_buffer_index++] = character;
}
break;
message_buffer_resize (len + 1);
message_buffer[message_buffer_index++] = character;
}
break;
default:
abort ();
}
}
default:
abort ();
}
}
}
message_buffer[message_buffer_index] = '\0';
}
@ -1474,7 +1472,7 @@ pad_to (count, string)
else
{
while (i < count)
string[i++] = ' ';
string[i++] = ' ';
}
string[i] = '\0';

View File

@ -1,9 +1,10 @@
/* window.h -- Structure and flags used in manipulating Info windows. */
/* 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
This file is part of GNU Info, a program for reading online documentation
stored in Info format.
Copyright (C) 1993 Free Software Foundation, Inc.
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
@ -21,8 +22,8 @@
Written by Brian Fox (bfox@ai.mit.edu). */
#if !defined (_WINDOW_H_)
#define _WINDOW_H_
#ifndef INFO_WINDOW_H
#define INFO_WINDOW_H
#include "nodes.h"
#include "infomap.h"
@ -44,9 +45,9 @@
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. */
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
@ -54,37 +55,38 @@
(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 __window__ *next; /* Next window in this chain. */
struct __window__ *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. */
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_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. */
#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. */
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
@ -226,4 +228,4 @@ extern void window_get_state (), window_set_state ();
offset of GOAL. */
extern int window_chars_to_goal ();
#endif /* !_WINDOW_H_ */
#endif /* not INFO_WINDOW_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,214 @@
# 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:

View File

@ -0,0 +1 @@
GNU gettext library from gettext-0.10.32

View File

@ -0,0 +1,199 @@
/* 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 <config.h>
#endif
#if defined STDC_HEADERS || defined _LIBC
# include <stdlib.h>
#else
# ifdef HAVE_MALLOC_H
# include <malloc.h>
# else
void free ();
# endif
#endif
#if defined HAVE_STRING_H || defined _LIBC
# include <string.h>
#else
# include <strings.h>
# ifndef memcpy
# define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num)
# endif
#endif
#ifdef _LIBC
# include <libintl.h>
#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

View File

@ -0,0 +1,262 @@
/* 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 <config.h>
#endif
#include <stdio.h>
#ifdef STDC_HEADERS
# include <stdlib.h>
# include <string.h>
#else
char *getenv ();
# ifdef HAVE_MALLOC_H
# include <malloc.h>
# endif
#endif
#ifdef HAVE_NL_TYPES_H
# include <nl_types.h>
#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

View File

@ -0,0 +1,593 @@
/* 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 <config.h>
#endif
#include <sys/types.h>
#ifdef __GNUC__
# define alloca __builtin_alloca
# define HAVE_ALLOCA 1
#else
# if defined HAVE_ALLOCA_H || defined _LIBC
# include <alloca.h>
# else
# ifdef _AIX
#pragma alloca
# else
# ifndef alloca
char *alloca ();
# endif
# endif
# endif
#endif
#include <errno.h>
#ifndef errno
extern int errno;
#endif
#ifndef __set_errno
# define __set_errno(val) errno = (val)
#endif
#if defined STDC_HEADERS || defined _LIBC
# include <stdlib.h>
#else
char *getenv ();
# ifdef HAVE_MALLOC_H
# include <malloc.h>
# else
void free ();
# endif
#endif
#if defined HAVE_STRING_H || defined _LIBC
# ifndef _GNU_SOURCE
# define _GNU_SOURCE 1
# endif
# include <string.h>
#else
# include <strings.h>
#endif
#if !HAVE_STRCHR && !defined _LIBC
# ifndef strchr
# define strchr index
# endif
#endif
#if defined HAVE_UNISTD_H || defined _LIBC
# include <unistd.h>
#endif
#include "gettext.h"
#include "gettextP.h"
#ifdef _LIBC
# include <libintl.h>
#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 <limits.h>
#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 <sys/param.h>
#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

View File

@ -0,0 +1,59 @@
/* 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 <config.h>
#endif
#if defined HAVE_LOCALE_H || defined _LIBC
# include <locale.h>
#endif
#ifdef _LIBC
# include <libintl.h>
#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

View File

@ -0,0 +1,181 @@
/* Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 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 <config.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#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;
}

View File

@ -0,0 +1,189 @@
/* Handle list of needed message catalogs
Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 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 <config.h>
#endif
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <sys/types.h>
#if defined STDC_HEADERS || defined _LIBC
# include <stdlib.h>
#else
# ifdef HAVE_MALLOC_H
# include <malloc.h>
# else
void free ();
# endif
#endif
#if defined HAVE_STRING_H || defined _LIBC
# include <string.h>
#else
# include <strings.h>
# 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 <unistd.h>
#endif
#include "gettext.h"
#include "gettextP.h"
#ifdef _LIBC
# include <libintl.h>
#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;
}

View File

@ -0,0 +1,70 @@
/* 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 <config.h>
#endif
#ifdef _LIBC
# define __need_NULL
# include <stddef.h>
#else
# ifdef STDC_HEADERS
# include <stdlib.h> /* Just for NULL. */
# else
# ifdef HAVE_STRING_H
# include <string.h>
# else
# define NULL ((void *) 0)
# endif
# endif
#endif
#ifdef _LIBC
# include <libintl.h>
#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

View File

@ -0,0 +1,105 @@
/* 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 <stdio.h>
#if HAVE_LIMITS_H || _LIBC
# include <limits.h>
#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 <limits.h>) 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 */

View File

@ -0,0 +1,73 @@
/* 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 */

View File

@ -0,0 +1,63 @@
/* 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 <values.h>
#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;
}

View File

@ -0,0 +1,76 @@
/* 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 <config.h>
#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);
}

View File

@ -0,0 +1,409 @@
/* Handle list of needed message catalogs
Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 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 <config.h>
#endif
#if defined HAVE_STRING_H || defined _LIBC
# ifndef _GNU_SOURCE
# define _GNU_SOURCE 1
# endif
# include <string.h>
#else
# include <strings.h>
# 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 <argz.h>
#endif
#include <ctype.h>
#include <sys/types.h>
#if defined STDC_HEADERS || defined _LIBC
# include <stdlib.h>
#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

View File

@ -0,0 +1,182 @@
/* 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 <sys/types.h>
#if HAVE_LOCALE_H
# include <locale.h>
#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

View File

@ -0,0 +1,100 @@
# po2msg.sed - Convert Uniforum style .po file to Linux style .msg file
# Copyright (C) 1995 Free Software Foundation, Inc.
# Ulrich Drepper <drepper@gnu.ai.mit.edu>, 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 <Haible@ma2s2.mathematik.uni-karlsruhe.de>
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

View File

@ -0,0 +1,58 @@
#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));

View File

@ -0,0 +1,199 @@
/* 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 <config.h>
#endif
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#if defined STDC_HEADERS || defined _LIBC
# include <stdlib.h>
#endif
#if defined HAVE_UNISTD_H || defined _LIBC
# include <unistd.h>
#endif
#if (defined HAVE_MMAP && defined HAVE_MUNMAP) || defined _LIBC
# include <sys/mman.h>
#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;
}

View File

@ -0,0 +1,378 @@
/* Handle aliases for locale names
Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 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 <config.h>
#endif
#include <ctype.h>
#include <stdio.h>
#include <sys/types.h>
#ifdef __GNUC__
# define alloca __builtin_alloca
# define HAVE_ALLOCA 1
#else
# if defined HAVE_ALLOCA_H || defined _LIBC
# include <alloca.h>
# else
# ifdef _AIX
#pragma alloca
# else
# ifndef alloca
char *alloca ();
# endif
# endif
# endif
#endif
#if defined STDC_HEADERS || defined _LIBC
# include <stdlib.h>
#else
char *getenv ();
# ifdef HAVE_MALLOC_H
# include <malloc.h>
# else
void free ();
# endif
#endif
#if defined HAVE_STRING_H || defined _LIBC
# ifndef _GNU_SOURCE
# define _GNU_SOURCE 1
# endif
# include <string.h>
#else
# include <strings.h>
# 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
}

View File

@ -0,0 +1,102 @@
# po2tbl.sed - Convert Uniforum style .po file to lookup table for catgets
# Copyright (C) 1995 Free Software Foundation, Inc.
# Ulrich Drepper <drepper@gnu.ai.mit.edu>, 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 <config.h>\
#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 <Haible@ma2s2.mathematik.uni-karlsruhe.de>
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

View File

@ -0,0 +1,106 @@
/* Implementation of the textdomain(3) function
Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 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 <config.h>
#endif
#if defined STDC_HEADERS || defined _LIBC
# include <stdlib.h>
#endif
#if defined STDC_HEADERS || defined HAVE_STRING_H || defined _LIBC
# include <string.h>
#else
# include <strings.h>
# ifndef memcpy
# define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num)
# endif
#endif
#ifdef _LIBC
# include <libintl.h>
#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

View File

@ -0,0 +1,104 @@
# po2msg.sed - Convert Uniforum style .po file to X/Open style .msg file
# Copyright (C) 1995 Free Software Foundation, Inc.
# Ulrich Drepper <drepper@gnu.ai.mit.edu>, 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 <Haible@ma2s2.mathematik.uni-karlsruhe.de>
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 `<number> <message>'
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

View File

@ -0,0 +1,15 @@
## 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

View File

@ -0,0 +1,273 @@
# 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:

View File

@ -0,0 +1,4 @@
Common 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.)

View File

@ -0,0 +1,504 @@
/* 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 <jot@cray.com> 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 <config.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#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 <stdio.h>
#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 */

1044
contrib/texinfo/lib/getopt.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,133 @@
/* 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 */

View File

@ -0,0 +1,189 @@
/* 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 <config.h>
#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 <stdio.h>
/* 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 <gnu-versions.h>
#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 <stdlib.h>
#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 <stdio.h>
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 */

Some files were not shown because too many files have changed in this diff Show More