Virgin import of GNU texinfo 4.0
This commit is contained in:
parent
d8b5c7ed06
commit
cab79d6646
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/vendor/texinfo/dist/; revision=56160
@ -1,3 +1,3 @@
|
||||
Richard Stallman, Brian Fox, Bob Chassell, Noah Friedman, Paul Rubin,
|
||||
Karl Berry, and no doubt many others.
|
||||
Karl Berry, Eli Zaretskii, and many others.
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -48,18 +48,6 @@ read this file, type
|
||||
|
||||
$ info -f info-stnd
|
||||
|
||||
If you are using GNU Emacs, you may want to install the Emacs Lisp files
|
||||
permanently. Move them them to a directory in the load-path for Emacs;
|
||||
otherwise Emacs will not be able to load the autoloaded support files, such
|
||||
as `texinfmt.el'.
|
||||
|
||||
The `texinfo.el' file contains the autoload commands; it is the only
|
||||
file that needs to be loaded initially. If your Emacs does not
|
||||
automatically load `texinfo.el', you can tell it to do so by placing
|
||||
the following in `default.el' or in your `.emacs' file:
|
||||
|
||||
(load "texinfo")
|
||||
|
||||
|
||||
To create a printed manual
|
||||
==========================
|
||||
@ -90,13 +78,10 @@ program is not part of this distribution, but is available separately.
|
||||
After following those instructions, type the following to make the .dvi
|
||||
files:
|
||||
|
||||
$ make texinfo.dvi
|
||||
$ (cd info; make info.dvi info-stnd.dvi)
|
||||
$ (cd makeinfo; make makeinfo.dvi)
|
||||
$ (cd doc; make dvi)
|
||||
|
||||
You can then print the resulting .dvi files with the `lpr' command (on BSD
|
||||
systems. On SysV systems the command is `lp'. Consult your man pages for
|
||||
more information).
|
||||
You can then print the resulting .dvi files with the `lpr' or `lp'
|
||||
commands, or maybe `dvips'.
|
||||
|
||||
For example, the command to print the texinfo.dvi file might be:
|
||||
|
||||
|
@ -1,11 +1,113 @@
|
||||
This file records noteworthy changes.
|
||||
|
||||
4.0 (28 September 1999)
|
||||
* Language:
|
||||
. New command @anchor for cross references to arbitrary points.
|
||||
. New commands @documentlanguage sets the main document language,
|
||||
and @documentencoding sets the document input encoding (although not
|
||||
much is done yet with either).
|
||||
. New command @pagesizes allows limited control of text area for typesetting.
|
||||
. New command @acronym for abbreviations in all caps, such as `NASA'.
|
||||
. New command @alias for simple command aliases.
|
||||
. New command @definfoenclose for better control of info output.
|
||||
. New commands @deftypeivar for typed instance variables of a class
|
||||
and @deftypeop for typed operations of a class.
|
||||
. New command @novalidate suppresses cross-reference checking and (in
|
||||
TeX) auxiliary file creation.
|
||||
. New commands @setcontentsaftertitlepage and
|
||||
@setshortcontentsaftertitlepage to force printing the table of
|
||||
contents after @end titlepage. Also, @contents and @shortcontents
|
||||
themselves can now appear at the beginning of the document as
|
||||
well as the end.
|
||||
. New markup commands: @env (for environment variables), @command (for
|
||||
command names), @option (for command-line options).
|
||||
. New commands @smallformat and @smalldisplay, a la @smallexample.
|
||||
. New command @exampleindent to set indentation of example-like
|
||||
environments a la @paragraphindent.
|
||||
. @uref takes an optional third argument of text to show instead of
|
||||
(rather than in addition to) the url for info and dvi output.
|
||||
. @footnote works in an @item for a @table.
|
||||
* texinfo.tex:
|
||||
. latest version always at ftp://ftp.gnu.org/gnu/texinfo.tex (and mirrors).
|
||||
. implements @macro.
|
||||
. implements @paragraphindent (except asis).
|
||||
. @emph and @i use true italic type (cmti) instead of slanted (cmsl).
|
||||
. implements pdf output when run with pdftex.
|
||||
. better support for internationalization via txi-??.tex files.
|
||||
* makeinfo:
|
||||
. supports HTML output with the --html option.
|
||||
. implication of --html: @top nodes should be wrapped in @ifnottex
|
||||
rather than @ifinfo. @ifinfo conditionals are not expanded with --html.
|
||||
. new option --number-sections to output chapter/section numbers.
|
||||
. dashes and quotes are not treated specially in node names.
|
||||
. new option --commands-in-node-names to allow @-commands in node names.
|
||||
(Not implemented in TeX, and most likely never will be.)
|
||||
. @emph output uses _underscores_.
|
||||
. @image looks for .png files before .jpg.
|
||||
. only output `Making ... file' line when verbose.
|
||||
. allow -v as synonym for --verbose.
|
||||
. new command line options to specify which conditionals to process
|
||||
(but --iftex is not fully implemented).
|
||||
. warns if @var contains any of ,[]().
|
||||
. @quote-arg implicitly done for all one-argument macros, so commas in
|
||||
the argument text are allowed.
|
||||
. \\ required in macro body to get single \, no other `escapes' defined.
|
||||
* info:
|
||||
. ISO Latin 1 characters are displayed and input as-is by default.
|
||||
. new option --vi-keys to enable vi-like and less-like key bindings.
|
||||
. new command S does case-sensitive searching.
|
||||
. new commands C-x n and C-x N repeat last search, respectively, in the
|
||||
same and in reverse direction, without prompting for the string. These
|
||||
commands are bound to n and N under --vi-keys, like in Less.
|
||||
. new command G menu1 menu2 ... searches for menu items from (dir),
|
||||
as allowed on the command line.
|
||||
. new command O (capital o, not zero) goes directly to the node that
|
||||
describes command-line options.
|
||||
. new command-line option --show-options causes the node which
|
||||
describes command-line options to be the first node displayed.
|
||||
. M-prior and M-DEL do new command info-scroll-other-window-backward.
|
||||
. / searches like s does.
|
||||
. If the search string includes upper-case letters, in both incremental
|
||||
and non-incremental search, the search is case-sensitive.
|
||||
. S searches case-sensitively even if the search string is all
|
||||
lower-case.
|
||||
. - makes the argument negative (so e.g. `- /' searches backward).
|
||||
. l restores point in the window returned to.
|
||||
. SPC/DEL do not move outside the current document.
|
||||
. foo.info is found before foo.
|
||||
. `info foo --index-search=bar' now searches for bar in foo's index.
|
||||
. support for files compressed with bzip2.
|
||||
* install-info:
|
||||
. handles gzipped dir files.
|
||||
. sort entries into alphabetical order.
|
||||
. install direntries only in preceding dircategory, not in all.
|
||||
. --delete does not require the info file to exist.
|
||||
. --delete can handle XEmacs-style dir entries.
|
||||
* texi2dvi:
|
||||
. bug fixed: now uses only the @iftex and @tex parts of the source.
|
||||
. process LaTeX source as well as Texinfo source.
|
||||
. output PDF (using pdftex) with new option --pdf.
|
||||
. handles --OPTION=ARG style of command line arguments.
|
||||
. new option --batch for progress reports but no interaction.
|
||||
. new option --clean to remove all auxiliary files.
|
||||
. new option --quiet for silence (unless there are errors).
|
||||
. new option -I for specifying directories for @include to search.
|
||||
. handles LaTeX files (running BibTeX etc.).
|
||||
* Fixes to util/gen-dir-node and util/fix-info-dir (formerly util/update-info).
|
||||
* Distribution:
|
||||
. Man pages included.
|
||||
. Czech and Norwegian message translations.
|
||||
. Various translations for texinfo.tex fixed words included.
|
||||
. DJGPP support.
|
||||
|
||||
|
||||
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.
|
||||
@ -40,6 +142,7 @@ This file records noteworthy changes.
|
||||
|
||||
3.10 (nonexistent)
|
||||
|
||||
|
||||
3.9 (4 October 1996)
|
||||
* makeinfo:
|
||||
- Give a suppressible (with --no-validate) error for references
|
||||
@ -52,6 +155,7 @@ This file records noteworthy changes.
|
||||
* configure: Include replacements for memcpy and memmove functions in
|
||||
the distribution, in case they are missing.
|
||||
|
||||
|
||||
3.8 (30 September 1996)
|
||||
* Define and/or document new and/or previously existing commands:
|
||||
Accents: @" @' @, @" @= @^ @` @~ @H @d @dotaccent @dotless @ringaccent
|
||||
@ -93,46 +197,55 @@ This file records noteworthy changes.
|
||||
@infoinclude
|
||||
@iappendix @iappendixsection @iappendixsec @iappendixsubsec
|
||||
@iappendixsubsubsec
|
||||
@ichapter @isection @isubsection @isubsubsection
|
||||
@ichapter @isection @isubsection @isubsubsection
|
||||
@iunnumbered @iunnumberedsec @iunnumberedsubsec @iunnumberedsubsubsec
|
||||
@setchapterstyle
|
||||
@titlespec
|
||||
|
||||
|
||||
3.7 (24 December 1995)
|
||||
* Have --version print texinfo release number as well as the individual
|
||||
program version.
|
||||
* Better man page cleaning.
|
||||
* Update Elisp files from current Emacs release.
|
||||
|
||||
|
||||
3.6 (21 June 1995)
|
||||
* Unmatched brace error reporting improved.
|
||||
* Missing comment terminator prevented compilation.
|
||||
|
||||
|
||||
3.5 (20 June 1995)
|
||||
* Autoconf update.
|
||||
* Support for parallel makes.
|
||||
* make install does not install Elisp files.
|
||||
|
||||
|
||||
3.4 (19 June 1995)
|
||||
* Handle @ifhtml in Elisp.
|
||||
* Update FSF address.
|
||||
|
||||
|
||||
3.3 (15 June 1995)
|
||||
* Portability changes.
|
||||
* Compile Elisp files.
|
||||
* Don't distribute .info* files.
|
||||
|
||||
|
||||
3.2 (9 June 1995)
|
||||
* Standalone Info can read Unix man pages.
|
||||
* New commands: @! @? @^ @" @enddots.
|
||||
* makeinfo -E does macro expansion (and nothing else).
|
||||
|
||||
|
||||
3.1 (23 May 1993)
|
||||
Just bug fixes, see ChangeLog for full details.
|
||||
Just bug fixes, see ChangeLog for full details.
|
||||
|
||||
texinfo-3.0: first release of Texinfo version 2, with many new commands.
|
||||
|
||||
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
|
||||
@ -332,4 +445,3 @@ Changes since 2.0:
|
||||
* Scrolling in redisplay is implemented.
|
||||
* Recursive uses of the echo area made more robust.
|
||||
* Garbage collection of unreferenced nodes.
|
||||
|
||||
|
@ -1,48 +1,82 @@
|
||||
This is the README file for the GNU Texinfo distribution.
|
||||
The primary distribution point is ftp://ftp.gnu.org/pub/gnu.
|
||||
The primary distribution point is ftp://ftp.gnu.org/gnu/texinfo/.
|
||||
|
||||
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.
|
||||
Mailing lists:
|
||||
- bug-texinfo@gnu.org for bug reports or enhancement suggestions,
|
||||
archived at ftp://ftp-mailing-list-archives.gnu.org/.
|
||||
- help-texinfo@gnu.org for authoring questions and general discussion.
|
||||
archived at the same place.
|
||||
- texinfo-pretest@tug.org for pretests of new releases,
|
||||
archived at http://tug.org/archives/texinfo-pretest/.
|
||||
There are as yet no corresponding newsgroups.
|
||||
|
||||
For bug reports, please include enough information for the maintainers
|
||||
to reproduce the problem. Generally speaking, that means:
|
||||
- the version number of Texinfo and the program(s) involved (use --version).
|
||||
- hardware, operating system, and compiler versions (uname -a).
|
||||
- any unusual options you gave to configure (see config.status).
|
||||
- the contents of any input files necessary to reproduce the bug (crucial!).
|
||||
- a description of the problem and any samples of the erroneous output.
|
||||
- anything else that you think would be helpful.
|
||||
|
||||
Patches are most welcome; if possible, please make them with diff -c and
|
||||
include ChangeLog entries.
|
||||
|
||||
When sending email, please do not encode or split the messages in any
|
||||
way if at all possible; it's much easier to deal with one large message
|
||||
than many small ones. GNU shar is a convenient way of packaging
|
||||
multiple and/or binary files for email.
|
||||
|
||||
Programs within this distribution have their own version numbers. When
|
||||
you refer to a file, please mention its own version, as well as the
|
||||
version number of the Texinfo distribution.
|
||||
|
||||
For generic installation instructions on compiling and installing this
|
||||
Automake-based distribution, please read the file `INSTALL'.
|
||||
Installation notes specific to Texinfo:
|
||||
|
||||
* The Info tree uses a file `dir' as its root node; the `dir-example'
|
||||
file in this distribution is included for informative purposes.
|
||||
Use it, modify it, or ignore it just as you like.
|
||||
* The Info tree uses a file `dir' as its root node; the `dir-example'
|
||||
file in this distribution is included as a possible starting point.
|
||||
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.
|
||||
* You can create a file texinfo.cnf to be read by TeX when
|
||||
processing Texinfo manuals. For example, you might like to use
|
||||
@afourpaper by default. See the `Preparing for TeX' node in
|
||||
texinfo.txi for more details. You don't have to create the file if
|
||||
you have nothing to put in it.
|
||||
|
||||
* 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.
|
||||
* If your info files are not in $prefix/info, you may wish to add a line
|
||||
#define DEFAULT_INFOPATH "/mydir1:/mydir2:..."
|
||||
to config.h after running configure.
|
||||
|
||||
* For instructions on compiling this distribution with DJGPP tools
|
||||
for MS-DOS and MS-Windows, please see the file djgpp/README.
|
||||
|
||||
|
||||
This distribution includes (but is not limited to) the following files:
|
||||
If you would like to contribute to the GNU project by implementing
|
||||
additional documentation output formats for Texinfo, that would be
|
||||
great. But please do not write a separate translator texi2foo for your
|
||||
favorite format foo! That is the hard way to do the job, and makes
|
||||
extra work in subsequent maintenance, since the Texinfo language is
|
||||
continually being enhanced and updated. Instead, the best approach is
|
||||
modify Makeinfo to generate the new format, as it does now for Info and HTML.
|
||||
|
||||
|
||||
This distribution includes the following files, among others:
|
||||
|
||||
README This file.
|
||||
|
||||
NEWS Summary of new features by release.
|
||||
|
||||
INTRODUCTION Brief introduction to the system, and
|
||||
how to create readable files from the
|
||||
Texinfo source files in this distribution.
|
||||
|
||||
Texinfo source files (in ./doc):
|
||||
|
||||
texinfo.texi This manual describes the Texinfo language
|
||||
and many of the associated tools. It
|
||||
tells how to use Texinfo to write
|
||||
documentation, how to use Texinfo mode
|
||||
in GNU Emacs, TeX, makeinfo, and the
|
||||
Emacs Lisp Texinfo formatting commands.
|
||||
texinfo.txi Describes the Texinfo language and many
|
||||
of the associated tools. It tells how
|
||||
to use Texinfo to write documentation,
|
||||
how to use Texinfo mode in GNU Emacs,
|
||||
TeX, makeinfo, and the Emacs Lisp
|
||||
Texinfo formatting commands.
|
||||
|
||||
info.texi This manual tells you how to use
|
||||
Info. This document comes as part of
|
||||
@ -72,26 +106,20 @@ Printing related files:
|
||||
|
||||
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.
|
||||
TeX and texindex.
|
||||
|
||||
|
||||
Source files for standalone C programs (./lib, ./makeinfo, ./info):
|
||||
|
||||
makeinfo.c This file contains the source for
|
||||
makeinfo/makeinfo.c This file contains the source for
|
||||
the `makeinfo' program that you can
|
||||
use to create an Info file from a
|
||||
Texinfo file.
|
||||
|
||||
info.c This file contains the source for
|
||||
info/info.c This file contains the source for
|
||||
the `info' program that you can use to
|
||||
view Info files on an ASCII terminal.
|
||||
|
||||
getopt.c Various support files
|
||||
getopt1.c
|
||||
getopt.h
|
||||
|
||||
|
||||
Installation files:
|
||||
|
||||
configure This file creates creates a Makefile
|
||||
@ -110,11 +138,7 @@ Installation files:
|
||||
to use to make a Makefile.in.
|
||||
|
||||
|
||||
Other files (util):
|
||||
|
||||
NEWS This contains a summary of new
|
||||
features since the first edition
|
||||
of Texinfo.
|
||||
Other files:
|
||||
|
||||
fixfonts This is a shell script to install the
|
||||
`lcircle10' TeX fonts as an alias for
|
||||
|
@ -1,8 +1,8 @@
|
||||
If you are interested in working on any of these, email bug-texinfo@gnu.org.
|
||||
|
||||
* Makeinfo:
|
||||
- HTML output is being actively worked on, and with luck will be in
|
||||
the next release.
|
||||
- Support output of Docbook format and SGML-Tools format.
|
||||
- Support output of true 8-bit characters from accent commands, etc.
|
||||
- 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.
|
||||
@ -13,23 +13,27 @@ If you are interested in working on any of these, email bug-texinfo@gnu.org.
|
||||
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.
|
||||
- Better HTML output: allow settable background color, table colors
|
||||
and spacing, <head> meta tags, back link from footnote marker, etc.
|
||||
- Could warn if @sc{TEXT} for all-caps TEXT, since it's a no-op.
|
||||
|
||||
* 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.
|
||||
- Introduce new command to change \bindingoffset.
|
||||
- How about using latex2html to produce HTML?
|
||||
|
||||
* 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'.
|
||||
- Allow @end (and other?) commands to be indented in the source.
|
||||
- Get Info declared as a MIME Content-Type.
|
||||
|
||||
* Language:
|
||||
@ -41,15 +45,18 @@ If you are interested in working on any of these, email bug-texinfo@gnu.org.
|
||||
@caption ... @end caption
|
||||
<arbitrary Texinfo commands>
|
||||
@end figure
|
||||
- support bibliographies with BibTeX (see web2c/doc for kludge prototype).
|
||||
- @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.
|
||||
- @verbatim ... @end verbatim.
|
||||
- @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.
|
||||
- Support automatic line numbering of examples.
|
||||
- Change bars. This is difficult or impossible in TeX,
|
||||
unfortunately. To do it right requires device driver support.
|
||||
wdiff or ediff may be better in some cases, anyway.
|
||||
|
||||
* Doc:
|
||||
- Include a complete functional summary, as in a reference card, in
|
||||
@ -59,20 +66,29 @@ If you are interested in working on any of these, email bug-texinfo@gnu.org.
|
||||
for an example of doing it in both the tex and info versions.
|
||||
|
||||
* Info:
|
||||
- Regular expression search.
|
||||
- Allow key rebinding, perhaps through the readline library.
|
||||
- Full-text search across all info files installed on the system.
|
||||
- Support character sets other than ISO Latin 1.
|
||||
- Perhaps comply with LANGUAGE setting on a per-node basis, to allow
|
||||
incremental translation of Texinfo files.
|
||||
- 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.
|
||||
within a page, number links, use color, etc. Perhaps code from the pinfo
|
||||
viewer can be reused: http://zeus.polsl.gliwice.pl/~pborys/.
|
||||
- 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/.
|
||||
- Incorporate an X-based viewer, perhaps tkinfo
|
||||
http://www.math.ucsb.edu/~boldt/tkinfo/
|
||||
or saxinfo.
|
||||
- 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)
|
||||
(But this has the disadvantage of needing to be updated when the
|
||||
Texinfo language changes, so don't.)
|
||||
|
||||
* Install-info:
|
||||
- be able to copy the info file to compile-time $(infodir), to
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* config.h.in. Generated automatically from configure.in by autoheader. */
|
||||
/* config.in. Generated automatically from configure.in by autoheader. */
|
||||
/* acconfig.h
|
||||
This file is in the public domain.
|
||||
$Id: acconfig.h,v 1.3 1998/12/06 22:04:03 karl Exp $
|
||||
|
||||
Descriptive text for the C preprocessor macros that
|
||||
the distributed Autoconf macros can define.
|
||||
@ -38,6 +39,9 @@
|
||||
/* Define if you have a working `mmap' system call. */
|
||||
#undef HAVE_MMAP
|
||||
|
||||
/* Define if you have the strcoll function and it is properly defined. */
|
||||
#undef HAVE_STRCOLL
|
||||
|
||||
/* Define if you have the vprintf function. */
|
||||
#undef HAVE_VPRINTF
|
||||
|
||||
@ -77,6 +81,9 @@
|
||||
*/
|
||||
#undef STACK_DIRECTION
|
||||
|
||||
/* Define if the `S_IS*' macros in <sys/stat.h> do not work properly. */
|
||||
#undef STAT_MACROS_BROKEN
|
||||
|
||||
/* Define if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
@ -98,12 +105,6 @@
|
||||
/* 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
|
||||
|
||||
@ -170,6 +171,9 @@
|
||||
/* Define if you have the strerror function. */
|
||||
#undef HAVE_STRERROR
|
||||
|
||||
/* Define if you have the strncasecmp function. */
|
||||
#undef HAVE_STRNCASECMP
|
||||
|
||||
/* Define if you have the <argz.h> header file. */
|
||||
#undef HAVE_ARGZ_H
|
||||
|
||||
@ -185,6 +189,9 @@
|
||||
/* Define if you have the <malloc.h> header file. */
|
||||
#undef HAVE_MALLOC_H
|
||||
|
||||
/* Define if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define if you have the <ncurses/termcap.h> header file. */
|
||||
#undef HAVE_NCURSES_TERMCAP_H
|
||||
|
||||
@ -194,6 +201,9 @@
|
||||
/* Define if you have the <pwd.h> header file. */
|
||||
#undef HAVE_PWD_H
|
||||
|
||||
/* Define if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
@ -233,22 +243,33 @@
|
||||
/* 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
|
||||
/* Name of package */
|
||||
#undef PACKAGE
|
||||
|
||||
/* Version number of package */
|
||||
#undef VERSION
|
||||
|
||||
/* Define if TIOCGWINSZ requires sys/ioctl.h */
|
||||
#undef GWINSZ_IN_SYS_IOCTL
|
||||
|
||||
/* Define if this function is declared. */
|
||||
#undef HAVE_DECL_STRERROR
|
||||
|
||||
/* Define if this function is declared. */
|
||||
#undef HAVE_DECL_STRCASECMP
|
||||
|
||||
/* Define if this function is declared. */
|
||||
#undef HAVE_DECL_STRNCASECMP
|
||||
|
||||
/* Define if this function is declared. */
|
||||
#undef HAVE_DECL_STRCOLL
|
||||
|
||||
/* For gettext (NLS) */
|
||||
#include <libintl.h>
|
||||
#define _(String) gettext (String)
|
||||
#define N_(String) (String)
|
||||
|
||||
|
||||
/* Leave that blank line there!! Autoheader needs it.
|
||||
|
@ -1,22 +1,30 @@
|
||||
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.)
|
||||
sources needed to process Texinfo sources. We recommend using the
|
||||
texi2dvi included in the distribution 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
|
||||
standard (http://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.)
|
||||
/usr/local/share/texmf. On systems with TeX preinstalled, as most
|
||||
GNU/Linux distributions offer, <texmf> will often be something like
|
||||
/usr/share/texmf.
|
||||
|
||||
It is also possible to put these .tex files in a `local' place instead
|
||||
of overwriting existing ones, but it is more complicated. See your TeX
|
||||
documentation in general and the texmf.cnf file in particular for information.
|
||||
|
||||
If you add files to your TeX installations, not just replace existing
|
||||
ones, you very likely have to update your ls-R file; do this with the
|
||||
mktexlsr command. In older versions, this was named MakeTeXls-R.
|
||||
|
||||
You can get the latest texinfo.tex from
|
||||
ftp://ftp.tug.org/tex/texinfo.tex
|
||||
ftp://ftp.cs.umb.edu/pub/tex/texinfo.tex
|
||||
ftp://ftp.gnu.org/gnu/texinfo.tex (and all GNU mirrors)
|
||||
ftp://tug.org/tex/texinfo.tex (and all CTAN mirrors)
|
||||
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.
|
||||
|
401
contrib/texinfo/doc/help2man
Executable file
401
contrib/texinfo/doc/help2man
Executable file
@ -0,0 +1,401 @@
|
||||
#!/usr/local/bin/perl -w
|
||||
|
||||
# Generate a short man page from --help and --version output.
|
||||
# Copyright © 1997, 98, 99 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 Brendan O'Dea <bod@compusol.com.au>
|
||||
|
||||
use 5.004;
|
||||
use strict;
|
||||
use Getopt::Long;
|
||||
use Text::Tabs qw(expand);
|
||||
use POSIX qw(strftime setlocale LC_TIME);
|
||||
|
||||
my $this_program = 'help2man';
|
||||
my $this_version = '1.013';
|
||||
my $version_info = <<EOT;
|
||||
$this_program $this_version
|
||||
|
||||
Copyright (C) 1997, 98, 99 Free Software Foundation, Inc.
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
Written by Brendan O'Dea <bod\@compusol.com.au>
|
||||
EOT
|
||||
|
||||
my $help_info = <<EOT;
|
||||
`$this_program' generates a man page out of `--help' and `--version' output.
|
||||
|
||||
Usage: $this_program [OPTION]... EXECUTABLE
|
||||
|
||||
-n, --name=STRING use `STRING' as the description for the NAME paragraph
|
||||
-s, --section=SECTION use `SECTION' as the section for the man page
|
||||
-i, --include=FILE include material from `FILE'
|
||||
-I, --opt-include=FILE include material from `FILE' if it exists
|
||||
-o, --output=FILE send output to `FILE'
|
||||
-N, --no-info suppress pointer to Texinfo manual
|
||||
--help print this help, then exit
|
||||
--version print $this_program program version number, then exit
|
||||
|
||||
EXECUTABLE should accept `--help' and `--version' options.
|
||||
EOT
|
||||
|
||||
my $section = 1;
|
||||
my ($include, $opt_name, $opt_include, $opt_output, $opt_no_info);
|
||||
|
||||
# Parse options.
|
||||
Getopt::Long::config('bundling');
|
||||
GetOptions (
|
||||
'n|name=s' => \$opt_name,
|
||||
's|section=s' => \$section,
|
||||
'i|include=s' => \$include,
|
||||
'I|opt-include=s' => \$opt_include,
|
||||
'o|output=s' => \$opt_output,
|
||||
'N|no-info' => \$opt_no_info,
|
||||
help => sub { print $help_info; exit },
|
||||
version => sub { print $version_info; exit },
|
||||
) or die $help_info;
|
||||
|
||||
die $help_info unless @ARGV == 1;
|
||||
|
||||
my %include = ();
|
||||
my @include = (); # to retain order
|
||||
|
||||
# Process include file (if given). Format is:
|
||||
#
|
||||
# [section name]
|
||||
# verbatim text
|
||||
|
||||
if ($include or $opt_include)
|
||||
{
|
||||
if (open INC, $include || $opt_include)
|
||||
{
|
||||
my $sect;
|
||||
|
||||
while (<INC>)
|
||||
{
|
||||
if (/^\[([^]]+)\]/)
|
||||
{
|
||||
$sect = uc $1;
|
||||
$sect =~ s/^\s+//;
|
||||
$sect =~ s/\s+$//;
|
||||
next;
|
||||
}
|
||||
|
||||
# Silently ignore anything before the first
|
||||
# section--allows for comments and revision info.
|
||||
next unless $sect;
|
||||
|
||||
push @include, $sect unless $include{$sect};
|
||||
$include{$sect} ||= '';
|
||||
$include{$sect} .= $_;
|
||||
}
|
||||
|
||||
close INC;
|
||||
|
||||
die "$this_program: no valid information found in `$include'\n"
|
||||
unless %include;
|
||||
|
||||
# Compress trailing blank lines.
|
||||
for (keys %include)
|
||||
{
|
||||
$include{$_} =~ s/\n+$//;
|
||||
$include{$_} .= "\n" unless /^NAME$/;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
die "$this_program: can't open `$include' ($!)\n" if $include;
|
||||
}
|
||||
}
|
||||
|
||||
# Turn off localisation of executable's ouput.
|
||||
@ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3;
|
||||
|
||||
# Turn off localisation of date (for strftime)
|
||||
setlocale LC_TIME, 'C';
|
||||
|
||||
# Expand tabs, strip trailing spaces and break into paragraphs
|
||||
sub paragraphs { split /\n\n+/, join '', expand @_ }
|
||||
|
||||
# Grab help and version paragraphs from executable
|
||||
my @help = paragraphs `$ARGV[0] --help 2>/dev/null`
|
||||
or die "$this_program: can't get `--help' info from $ARGV[0]\n";
|
||||
|
||||
my @version = paragraphs `$ARGV[0] --version 2>/dev/null`
|
||||
or die "$this_program: can't get `--version' info from $ARGV[0]\n";
|
||||
|
||||
my $date = strftime "%B %Y", localtime;
|
||||
(my $program = $ARGV[0]) =~ s!.*/!!;
|
||||
my $package = $program;
|
||||
my $version;
|
||||
|
||||
if ($opt_output)
|
||||
{
|
||||
unlink $opt_output
|
||||
or die "$this_program: can't unlink $opt_output ($!)\n"
|
||||
if -e $opt_output;
|
||||
|
||||
open STDOUT, ">$opt_output"
|
||||
or die "$this_program: can't create $opt_output ($!)\n";
|
||||
}
|
||||
|
||||
# The first line of the --version information is assumed to be in one
|
||||
# of the following formats:
|
||||
#
|
||||
# <version>
|
||||
# <program> <version>
|
||||
# {GNU,Free} <program> <version>
|
||||
# <program> ({GNU,Free} <package>) <version>
|
||||
# <program> - {GNU,Free} <package> <version>
|
||||
#
|
||||
# and seperated from any copyright/author details by a blank line.
|
||||
|
||||
$_ = shift @version;
|
||||
|
||||
if (/^(\S+) +\(((?:GNU|Free) +[^)]+)\) +(.*)/ or
|
||||
/^(\S+) +- *((?:GNU|Free) +\S+) +(.*)/)
|
||||
{
|
||||
$program = $1;
|
||||
$package = $2;
|
||||
$version = $3;
|
||||
}
|
||||
elsif (/^((?:GNU|Free) +)?(\S+) +(.*)/)
|
||||
{
|
||||
$program = $2;
|
||||
$package = $1 ? "$1$2" : $2;
|
||||
$version = $3;
|
||||
}
|
||||
else
|
||||
{
|
||||
$version = $_;
|
||||
}
|
||||
|
||||
$program =~ s!.*/!!;
|
||||
|
||||
# no info for `info' itself
|
||||
$opt_no_info = 1 if $program eq 'info';
|
||||
|
||||
# --name overrides --include contents
|
||||
$include{NAME} = "$program \\- $opt_name" if $opt_name;
|
||||
|
||||
# Default (useless) NAME paragraph
|
||||
$include{NAME} ||= "$program \\- manual page for $program $version";
|
||||
|
||||
# Man pages traditionally have the page title in caps.
|
||||
my $PROGRAM = uc $program;
|
||||
|
||||
# Header.
|
||||
print <<EOT;
|
||||
.\\" DO NOT MODIFY THIS FILE! It was generated by $this_program $this_version.
|
||||
.TH $PROGRAM "$section" "$date" "$package $version" FSF
|
||||
.SH NAME
|
||||
$include{NAME}
|
||||
EOT
|
||||
|
||||
my $break;
|
||||
my $accumulate = 1;
|
||||
my @description = ();
|
||||
|
||||
sub convert_option;
|
||||
|
||||
# Output converted --help information.
|
||||
for (@help)
|
||||
{
|
||||
chomp;
|
||||
|
||||
if (s/^Usage: +\S+ +(.*)\n?//)
|
||||
{
|
||||
# Turn the usage clause into a synopsis.
|
||||
my $synopsis = '';
|
||||
|
||||
do {
|
||||
my $syn = $1;
|
||||
$syn =~ s/(([][]|\.\.+)+)/\\fR$1\\fI/g;
|
||||
$syn =~ s/^/\\fI/ unless $syn =~ s/^\\fR//;
|
||||
$syn .= '\fR';
|
||||
$syn =~ s/\\fI( *)\\fR/$1/g;
|
||||
|
||||
$synopsis .= ".br\n" unless $accumulate;
|
||||
$synopsis .= ".B $program\n";
|
||||
$synopsis .= "$syn\n";
|
||||
$accumulate = 0;
|
||||
} while s/^(?:Usage| *or): +\S+ +(.*)\n?//;
|
||||
|
||||
# Include file overrides SYNOPSIS.
|
||||
print ".SH SYNOPSIS\n", $include{SYNOPSIS} || $synopsis;
|
||||
|
||||
# Dump any accumulated description text.
|
||||
print ".SH DESCRIPTION\n";
|
||||
print @description;
|
||||
|
||||
# Add additional description text from include file.
|
||||
if ($include{DESCRIPTION})
|
||||
{
|
||||
print ".PP\n" unless $include{DESCRIPTION} =~ /^\..P/;
|
||||
print $include{DESCRIPTION};
|
||||
}
|
||||
|
||||
$break = 1;
|
||||
next unless $_;
|
||||
}
|
||||
|
||||
# Accumulate text if the synopsis has not been produced yet.
|
||||
if ($accumulate)
|
||||
{
|
||||
push @description, ".PP\n" if @description;
|
||||
push @description, "$_\n";
|
||||
next;
|
||||
}
|
||||
|
||||
# Convert some standard paragraph names
|
||||
if (s/^(Options|Examples): *\n//)
|
||||
{
|
||||
print qq(.SH \U$1\n);
|
||||
$break = '';
|
||||
next unless length;
|
||||
}
|
||||
|
||||
# Catch bug report text.
|
||||
if (/^Report bugs |^Email bug reports to /)
|
||||
{
|
||||
print qq(.SH "REPORTING BUGS"\n$_\n);
|
||||
$break = '';
|
||||
next;
|
||||
}
|
||||
|
||||
# Option subsections have second line indented.
|
||||
if (s/^(\S.*)\n / /)
|
||||
{
|
||||
print qq(.SS "$1"\n);
|
||||
$break = '';
|
||||
}
|
||||
|
||||
my $output = '';
|
||||
while (length)
|
||||
{
|
||||
my $indent = 0;
|
||||
|
||||
# Tagged paragraph
|
||||
if (s/^( +(\S.*?) +)(\S.*)\n?//)
|
||||
{
|
||||
$indent = length $1;
|
||||
$output .= ".TP\n$2\n$3\n";
|
||||
$break = 1;
|
||||
}
|
||||
|
||||
# Indented paragraph
|
||||
elsif (s/^( +)(\S.*)\n?//)
|
||||
{
|
||||
$indent = length $1;
|
||||
$output .= ".IP\n$2\n";
|
||||
$break = 1;
|
||||
}
|
||||
|
||||
# Left justified paragraph
|
||||
else
|
||||
{
|
||||
s/(.*)\n?//;
|
||||
$output .= ".PP\n" if $break;
|
||||
$output .= "$1\n";
|
||||
$break = 1;
|
||||
}
|
||||
|
||||
# Continuations
|
||||
$output .= "$1\n" while s/^ {$indent}(\S.*)\n?//;
|
||||
}
|
||||
|
||||
$_ = $output;
|
||||
|
||||
# Escape backslashes.
|
||||
s/\\/\\e/g;
|
||||
|
||||
# Convert options.
|
||||
s/(^| )(-[][\w=-]+)/$1 . convert_option $2/mge;
|
||||
print;
|
||||
}
|
||||
|
||||
# Print any include items other than the ones we have already dealt
|
||||
# with.
|
||||
for (@include)
|
||||
{
|
||||
print qq(.SH "$_"\n$include{$_})
|
||||
unless /^(NAME|SYNOPSIS|DESCRIPTION|SEE ALSO)$/;
|
||||
}
|
||||
|
||||
# Refer to the real documentation.
|
||||
if ($include{'SEE ALSO'} or !$opt_no_info)
|
||||
{
|
||||
print qq(.SH "SEE ALSO"\n);
|
||||
print $include{'SEE ALSO'}, ".PP\n" if $include{'SEE ALSO'};
|
||||
|
||||
print <<EOT unless $opt_no_info;
|
||||
The full documentation for
|
||||
.B $program
|
||||
is maintained as a Texinfo manual. If the
|
||||
.B info
|
||||
and
|
||||
.B $program
|
||||
programs are properly installed at your site, the command
|
||||
.IP
|
||||
.B info $program
|
||||
.PP
|
||||
should give you access to the complete manual.
|
||||
EOT
|
||||
}
|
||||
|
||||
# Output converted --version information.
|
||||
for (@version)
|
||||
{
|
||||
chomp;
|
||||
|
||||
# Join hyphenated lines.
|
||||
s/([A-Za-z])-\n */$1/g;
|
||||
|
||||
# Convert copyright symbol or (c) to nroff character.
|
||||
s/Copyright +(?:\xa9|\([Cc]\))/Copyright \\(co/g;
|
||||
|
||||
# Insert appropriate headings for copyright and author.
|
||||
if (/^Copyright \\/) { print ".SH COPYRIGHT\n" }
|
||||
elsif (/^Written +by/) { print ".SH AUTHOR\n" }
|
||||
else { print ".PP\n"; }
|
||||
|
||||
# Insert line breaks before additional copyright messages and the
|
||||
# disclaimer.
|
||||
s/(.)\n(Copyright |This is free software)/$1\n.br\n$2/g;
|
||||
|
||||
print "$_\n";
|
||||
}
|
||||
|
||||
exit;
|
||||
|
||||
# Convert option dashes to \- to stop nroff from hyphenating 'em, and
|
||||
# embolden. Option arguments get italicised.
|
||||
sub convert_option
|
||||
{
|
||||
my $option = '\fB' . shift;
|
||||
|
||||
$option =~ s/-/\\-/g;
|
||||
unless ($option =~ s/\[=(.*)\]$/\\fR[=\\fI$1\\fR]/)
|
||||
{
|
||||
$option =~ s/=(.)/\\fR=\\fI$1/;
|
||||
$option =~ s/ (.)/ \\fI$1/;
|
||||
$option .= '\fR';
|
||||
}
|
||||
|
||||
$option;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
80
contrib/texinfo/doc/info.1
Normal file
80
contrib/texinfo/doc/info.1
Normal file
@ -0,0 +1,80 @@
|
||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.013.
|
||||
.TH INFO "1" "September 1999" "GNU texinfo 4.0" FSF
|
||||
.SH NAME
|
||||
info \- read Info documents
|
||||
.SH SYNOPSIS
|
||||
.B info
|
||||
[\fIOPTION\fR]... [\fIMENU-ITEM\fR...]
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
Read documentation in Info format.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\fB\-\-apropos\fR=\fISUBJECT\fR
|
||||
look up SUBJECT in all indices of all manuals.
|
||||
.TP
|
||||
\fB\-\-directory\fR=\fIDIR\fR
|
||||
add DIR to INFOPATH.
|
||||
.TP
|
||||
\fB\-\-dribble\fR=\fIFILENAME\fR
|
||||
remember user keystrokes in FILENAME.
|
||||
.TP
|
||||
\fB\-\-file\fR=\fIFILENAME\fR
|
||||
specify Info file to visit.
|
||||
.TP
|
||||
\fB\-\-help\fR
|
||||
display this help and exit.
|
||||
.TP
|
||||
\fB\-\-index\-search\fR=\fISTRING\fR
|
||||
go to node pointed by index entry STRING.
|
||||
.TP
|
||||
\fB\-\-node\fR=\fINODENAME\fR
|
||||
specify nodes in first visited Info file.
|
||||
.TP
|
||||
\fB\-\-output\fR=\fIFILENAME\fR
|
||||
output selected nodes to FILENAME.
|
||||
.TP
|
||||
\fB\-\-restore\fR=\fIFILENAME\fR
|
||||
read initial keystrokes from FILENAME.
|
||||
.TP
|
||||
\fB\-\-show\-options\fR, \fB\-\-usage\fR
|
||||
go to command-line options node.
|
||||
.TP
|
||||
\fB\-\-subnodes\fR
|
||||
recursively output menu items.
|
||||
.TP
|
||||
\fB\-\-vi\-keys\fR
|
||||
use vi-like and less-like key bindings.
|
||||
.TP
|
||||
\fB\-\-version\fR
|
||||
display version information and exit.
|
||||
.PP
|
||||
The first non-option argument, if present, is the menu entry to start from;
|
||||
it is searched for in all `dir' files along INFOPATH.
|
||||
If it is not present, info merges all `dir' files and shows the result.
|
||||
Any remaining arguments are treated as the names of menu
|
||||
items relative to the initial node visited.
|
||||
.SH EXAMPLES
|
||||
.TP
|
||||
info
|
||||
show top-level dir menu
|
||||
.TP
|
||||
info emacs
|
||||
start at emacs node from top-level dir
|
||||
.TP
|
||||
info emacs buffers
|
||||
start at buffers node within emacs manual
|
||||
.TP
|
||||
info \fB\-\-show\-options\fR emacs
|
||||
start at node with emacs' command line options
|
||||
.TP
|
||||
info \fB\-f\fR ./foo.info
|
||||
show file ./foo.info, not searching dir
|
||||
.SH "REPORTING BUGS"
|
||||
Email bug reports to bug-texinfo@gnu.org,
|
||||
general questions and discussion to help-texinfo@gnu.org.
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 1999 Free Software Foundation, Inc.
|
||||
There is NO warranty. You may redistribute this software
|
||||
under the terms of the GNU General Public License.
|
||||
For more information about these matters, see the files named COPYING.
|
62
contrib/texinfo/doc/info.5
Normal file
62
contrib/texinfo/doc/info.5
Normal file
@ -0,0 +1,62 @@
|
||||
.\" info(5)
|
||||
.\" $Id: info.5,v 1.2 1998/07/31 17:39:31 karl Exp $
|
||||
.\"
|
||||
.\" Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
.\"
|
||||
.\" Permission is granted to make and distribute verbatim copies of this
|
||||
.\" manual provided the copyright notice and this permission notice are
|
||||
.\" preserved on all copies.
|
||||
.\"
|
||||
.\" 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 Foundation.
|
||||
.\"
|
||||
.TH INFO 5 "GNU Info" "FSF"
|
||||
.SH NAME
|
||||
info \- readable online documentation
|
||||
.SH DESCRIPTION
|
||||
The Info file format is an easily-parsable representation for online
|
||||
documents. It can be read by
|
||||
.I emacs(1)
|
||||
and
|
||||
.I info(1)
|
||||
among other programs.
|
||||
.PP
|
||||
Info files are usually created from
|
||||
.I texinfo(5)
|
||||
sources by
|
||||
.IR makeinfo(1) ,
|
||||
but can be created from scratch if so desired.
|
||||
.PP
|
||||
For a full description of the Texinfo language and associated tools,
|
||||
please see the Texinfo manual (written in Texinfo itself). Most likely,
|
||||
running this command from your shell:
|
||||
.RS
|
||||
.I info texinfo
|
||||
.RE
|
||||
or this key sequence from inside Emacs:
|
||||
.RS
|
||||
.I M-x info RET m texinfo RET
|
||||
.RE
|
||||
will get you there.
|
||||
.SH AVAILABILITY
|
||||
ftp://ftp.gnu.org/pub/gnu/texinfo-<version>.tar.gz
|
||||
.br
|
||||
or any GNU mirror site.
|
||||
.SH "REPORTING BUGS"
|
||||
Please send bug reports to bug-texinfo@gnu.org,
|
||||
general questions and discussion to help-texinfo@gnu.org.
|
||||
.SH "SEE ALSO"
|
||||
info(1), install-info(1), makeinfo(1), texi2dvi(1),
|
||||
.br
|
||||
texindex(1).
|
||||
.br
|
||||
emacs(1), tex(1).
|
||||
.br
|
||||
texinfo(5).
|
@ -1,9 +1,9 @@
|
||||
\input texinfo @c -*-texinfo-*-
|
||||
@comment %**start of header
|
||||
@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 $
|
||||
@settitle Info
|
||||
@comment %**end of header
|
||||
@comment $Id: info.texi,v 1.11 1999/04/19 21:37:23 karl Exp $
|
||||
|
||||
@dircategory Texinfo documentation system
|
||||
@direntry
|
||||
@ -11,10 +11,10 @@
|
||||
@end direntry
|
||||
|
||||
@ifinfo
|
||||
This file describes how to use Info,
|
||||
the on-line, menu-driven GNU documentation system.
|
||||
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.
|
||||
Copyright (C) 1989, 92, 96, 97, 98, 99 Free Software Foundation, Inc.
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this manual provided the copyright notice and this permission notice
|
||||
@ -44,10 +44,9 @@ by the Free Software Foundation.
|
||||
@author Brian Fox
|
||||
@page
|
||||
@vskip 0pt plus 1filll
|
||||
Copyright @copyright{} 1989, 1992, 1993, 1996, 1997 Free Software
|
||||
Copyright @copyright{} 1989, 92, 93, 96, 97, 98, 99 Free Software
|
||||
Foundation, Inc.
|
||||
@sp 2
|
||||
|
||||
Published by the Free Software Foundation @*
|
||||
59 Temple Place - Suite 330 @*
|
||||
Boston, MA 02111-1307, USA.
|
||||
@ -67,31 +66,20 @@ 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)
|
||||
@ifnottex
|
||||
@node Top
|
||||
@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
|
||||
@end ifnottex
|
||||
|
||||
@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).
|
||||
* Creating an Info File:: How to make your own Info file.
|
||||
@end menu
|
||||
|
||||
@node Getting Started, Advanced Info, Top, Top
|
||||
@ -101,7 +89,7 @@ To learn advanced Info commands, type @kbd{n} twice. This brings you to
|
||||
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
|
||||
file. The third part is about how to generate Info files from
|
||||
Texinfo files.
|
||||
|
||||
@iftex
|
||||
@ -110,7 +98,7 @@ 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.
|
||||
well.
|
||||
|
||||
There are two ways of looking at the online version of this manual:
|
||||
|
||||
@ -340,7 +328,7 @@ 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.
|
||||
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
|
||||
@ -427,16 +415,14 @@ what you have entered.
|
||||
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!@*
|
||||
Here is a menu to give you a chance to practice. This menu gives you
|
||||
three ways of going to one place, Help-FOO:
|
||||
|
||||
@menu
|
||||
* 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!
|
||||
@end menu
|
||||
|
||||
>> Now type just an @kbd{m} and see what happens:
|
||||
|
||||
@ -559,17 +545,16 @@ to cancel the @samp{f}.
|
||||
@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
|
||||
@subsection 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.
|
||||
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.
|
||||
|
||||
@ -590,15 +575,15 @@ manner.
|
||||
@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
|
||||
|
||||
@node Advanced Info
|
||||
@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}.)
|
||||
Texinfo, texinfo, Texinfo}.)
|
||||
|
||||
@menu
|
||||
* Expert:: Advanced Info commands: g, s, e, and 1 - 5.
|
||||
@ -639,12 +624,12 @@ 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).
|
||||
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}, ...
|
||||
@ -652,9 +637,9 @@ might like to use the commands @kbd{1}, @kbd{2}, @kbd{3}, @kbd{4}, ...
|
||||
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
|
||||
If your 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
|
||||
underlined, 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
|
||||
@ -678,12 +663,12 @@ Create some nodes, in some file, to document that topic.
|
||||
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.
|
||||
Usually, the way to create the nodes is with Texinfo (@pxref{Top,,
|
||||
Overview of Texinfo, texinfo, Texinfo}); this has the advantage that you
|
||||
can also make a printed manual from them. However, if you want to edit
|
||||
an Info file, here is how.
|
||||
|
||||
The new node can live in an existing documentation file, or in a new
|
||||
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
|
||||
@ -693,12 +678,12 @@ 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}.
|
||||
@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
|
||||
@ -728,10 +713,10 @@ 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.
|
||||
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
|
||||
@ -741,7 +726,7 @@ to help identify the node for the user.
|
||||
@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.
|
||||
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.
|
||||
|
||||
@ -766,11 +751,11 @@ 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 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
|
||||
@ -816,7 +801,7 @@ They are just examples. The places they ``lead to'' do not really exist!
|
||||
|
||||
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
|
||||
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
|
||||
@ -847,24 +832,24 @@ 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
|
||||
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.
|
||||
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.
|
||||
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
|
||||
@ -894,18 +879,17 @@ 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.
|
||||
@node Creating an Info File
|
||||
@chapter Creating an Info File
|
||||
|
||||
@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}, to learn how to
|
||||
write a Texinfo file.
|
||||
|
||||
@xref{Top,, Overview of Texinfo, texinfo, Texinfo: The GNU Documentation
|
||||
Format}, to learn how to write a Texinfo file.
|
||||
@xref{Creating an Info File,,, texinfo, Texinfo}, to learn how to create
|
||||
an Info file from a Texinfo file.
|
||||
|
||||
@xref{Installing an Info File,,, texinfo, Texinfo}, to learn how to
|
||||
install an Info file after you have created one.
|
||||
|
||||
@bye
|
||||
|
84
contrib/texinfo/doc/install-info.1
Normal file
84
contrib/texinfo/doc/install-info.1
Normal file
@ -0,0 +1,84 @@
|
||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.013.
|
||||
.TH INSTALL-INFO "1" "September 1999" "GNU texinfo 4.0" FSF
|
||||
.SH NAME
|
||||
install-info \- update info/dir entries
|
||||
.SH SYNOPSIS
|
||||
.B install-info
|
||||
[\fIOPTION\fR]... [\fIINFO-FILE \fR[\fIDIR-FILE\fR]]
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
Install or delete dir entries from INFO-FILE in the Info directory file
|
||||
DIR-FILE.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\fB\-\-delete\fR
|
||||
delete existing entries for INFO-FILE from DIR-FILE;
|
||||
.IP
|
||||
don't insert any new entries.
|
||||
.TP
|
||||
\fB\-\-dir\-file\fR=\fINAME\fR
|
||||
specify file name of Info directory file.
|
||||
.IP
|
||||
This is equivalent to using the DIR-FILE argument.
|
||||
.TP
|
||||
\fB\-\-entry\fR=\fITEXT\fR
|
||||
insert TEXT as an Info directory entry.
|
||||
.IP
|
||||
TEXT should have the form of an Info menu item line
|
||||
plus zero or more extra lines starting with whitespace.
|
||||
If you specify more than one entry, they are all added.
|
||||
If you don't specify any entries, they are determined
|
||||
from information in the Info file itself.
|
||||
.TP
|
||||
\fB\-\-help\fR
|
||||
display this help and exit.
|
||||
.TP
|
||||
\fB\-\-info\-file\fR=\fIFILE\fR
|
||||
specify Info file to install in the directory.
|
||||
.IP
|
||||
This is equivalent to using the INFO-FILE argument.
|
||||
.TP
|
||||
\fB\-\-info\-dir\fR=\fIDIR\fR
|
||||
same as \fB\-\-dir\-file\fR=\fIDIR\fR/dir.
|
||||
.TP
|
||||
\fB\-\-item\fR=\fITEXT\fR
|
||||
same as \fB\-\-entry\fR TEXT.
|
||||
.IP
|
||||
An Info directory entry is actually a menu item.
|
||||
.TP
|
||||
\fB\-\-quiet\fR
|
||||
suppress warnings.
|
||||
.TP
|
||||
\fB\-\-remove\fR
|
||||
same as \fB\-\-delete\fR.
|
||||
.TP
|
||||
\fB\-\-section\fR=\fISEC\fR
|
||||
put this file's entries in section SEC of the directory.
|
||||
.IP
|
||||
If you specify more than one section, all the entries
|
||||
are added in each of the sections.
|
||||
If you don't specify any sections, they are determined
|
||||
from information in the Info file itself.
|
||||
.TP
|
||||
\fB\-\-version\fR
|
||||
display version information and exit.
|
||||
.SH "REPORTING BUGS"
|
||||
Email bug reports to bug-texinfo@gnu.org,
|
||||
general questions and discussion to help-texinfo@gnu.org.
|
||||
.SH "SEE ALSO"
|
||||
The full documentation for
|
||||
.B install-info
|
||||
is maintained as a Texinfo manual. If the
|
||||
.B info
|
||||
and
|
||||
.B install-info
|
||||
programs are properly installed at your site, the command
|
||||
.IP
|
||||
.B info install-info
|
||||
.PP
|
||||
should give you access to the complete manual.
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 1999 Free Software Foundation, Inc.
|
||||
There is NO warranty. You may redistribute this software
|
||||
under the terms of the GNU General Public License.
|
||||
For more information about these matters, see the files named COPYING.
|
152
contrib/texinfo/doc/makeinfo.1
Normal file
152
contrib/texinfo/doc/makeinfo.1
Normal file
@ -0,0 +1,152 @@
|
||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.013.
|
||||
.TH MAKEINFO "1" "September 1999" "GNU texinfo 4.0" FSF
|
||||
.SH NAME
|
||||
makeinfo \- translate Texinfo documents
|
||||
.SH SYNOPSIS
|
||||
.B makeinfo
|
||||
[\fIOPTION\fR]...\fI TEXINFO-FILE\fR...
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
Translate Texinfo source documentation to various other formats:
|
||||
Info files suitable for reading online with Emacs or standalone GNU Info
|
||||
(by default); plain text (with \fB\-\-no\-headers\fR); or HTML (with \fB\-\-html\fR).
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\fB\-\-commands\-in\-node\-names\fR
|
||||
allow @ commands in node names.
|
||||
.TP
|
||||
\fB\-D\fR VAR
|
||||
define a variable, as with @set.
|
||||
.TP
|
||||
\fB\-E\fR, \fB\-\-macro\-expand\fR FILE
|
||||
output macro-expanded source to FILE.
|
||||
.TP
|
||||
\fB\-\-error\-limit\fR=\fINUM\fR
|
||||
quit after NUM errors (default 100).
|
||||
.TP
|
||||
\fB\-\-fill\-column\fR=\fINUM\fR
|
||||
break Info lines at NUM characters (default 72).
|
||||
.TP
|
||||
\fB\-\-footnote\-style\fR=\fISTYLE\fR
|
||||
output footnotes according to STYLE:
|
||||
.IP
|
||||
`separate' to place footnotes in their own node,
|
||||
`end' to place the footnotes at the end of the
|
||||
.IP
|
||||
node in which they are defined (the default).
|
||||
.TP
|
||||
\fB\-\-force\fR
|
||||
preserve output even if errors.
|
||||
.TP
|
||||
\fB\-\-help\fR
|
||||
display this help and exit.
|
||||
.TP
|
||||
\fB\-\-html\fR
|
||||
output HTML rather than Info format;
|
||||
.TP
|
||||
\fB\-I\fR DIR
|
||||
append DIR to the @include search path.
|
||||
.TP
|
||||
\fB\-\-ifhtml\fR
|
||||
process @ifhtml and @html text even when not
|
||||
.IP
|
||||
generating HTML.
|
||||
.TP
|
||||
\fB\-\-ifinfo\fR
|
||||
process @ifinfo text even when generating HTML.
|
||||
.TP
|
||||
\fB\-\-iftex\fR
|
||||
process @iftex and @tex text.
|
||||
.IP
|
||||
implies \fB\-\-no\-split\fR.
|
||||
.TP
|
||||
\fB\-\-no\-headers\fR
|
||||
suppress Info node separators and Node: lines and
|
||||
.IP
|
||||
write to standard output without \fB\-\-output\fR.
|
||||
.TP
|
||||
\fB\-\-no\-ifhtml\fR
|
||||
do not process @ifhtml and @html text.
|
||||
.TP
|
||||
\fB\-\-no\-ifinfo\fR
|
||||
do not process @ifinfo text.
|
||||
.TP
|
||||
\fB\-\-no\-iftex\fR
|
||||
do not process @iftex and @tex text.
|
||||
.TP
|
||||
\fB\-\-no\-split\fR
|
||||
suppress splitting of large Info output files or
|
||||
generation of one HTML file per node.
|
||||
.TP
|
||||
\fB\-\-no\-validate\fR
|
||||
suppress node cross-reference validation.
|
||||
.TP
|
||||
\fB\-\-no\-warn\fR
|
||||
suppress warnings (but not errors).
|
||||
.TP
|
||||
\fB\-\-number\-sections\fR
|
||||
include chapter, section, etc. numbers in output.
|
||||
.TP
|
||||
\fB\-o\fR, \fB\-\-output\fR=\fIFILE\fR
|
||||
output to FILE, ignoring any @setfilename.
|
||||
.TP
|
||||
\fB\-P\fR DIR
|
||||
prepend DIR to the @include search path.
|
||||
.TP
|
||||
\fB\-\-paragraph\-indent\fR=\fIVAL\fR
|
||||
indent Info paragraphs by VAL spaces (default 3).
|
||||
.IP
|
||||
if VAL is `none', do not indent;
|
||||
if VAL is `asis', preserve existing indentation.
|
||||
.TP
|
||||
\fB\-\-reference\-limit\fR=\fINUM\fR
|
||||
warn about at most NUM references (default 1000).
|
||||
.TP
|
||||
\fB\-U\fR VAR
|
||||
undefine a variable, as with @clear.
|
||||
.TP
|
||||
\fB\-v\fR, \fB\-\-verbose\fR
|
||||
explain what is being done.
|
||||
.TP
|
||||
\fB\-\-version\fR
|
||||
display version information and exit.
|
||||
.PP
|
||||
The defaults for the @if... conditionals depend on the output format:
|
||||
if generating HTML, \fB\-\-ifhtml\fR is on and the others are off;
|
||||
if generating Info or plain text, \fB\-\-ifinfo\fR is on and the others are off.
|
||||
.SH EXAMPLES
|
||||
.TP
|
||||
makeinfo foo.texi
|
||||
write Info to foo's @setfilename
|
||||
.TP
|
||||
makeinfo \fB\-\-html\fR foo.texi
|
||||
write HTML to foo's @setfilename
|
||||
.TP
|
||||
makeinfo \fB\-\-no\-headers\fR \fB\-o\fR - foo.texi
|
||||
write plain text to standard output
|
||||
.TP
|
||||
makeinfo \fB\-\-number\-sections\fR foo.texi
|
||||
write Info with numbered sections
|
||||
.TP
|
||||
makeinfo \fB\-\-no\-split\fR foo.texi
|
||||
write one Info file however big
|
||||
.SH "REPORTING BUGS"
|
||||
Email bug reports to bug-texinfo@gnu.org,
|
||||
general questions and discussion to help-texinfo@gnu.org.
|
||||
.SH "SEE ALSO"
|
||||
The full documentation for
|
||||
.B makeinfo
|
||||
is maintained as a Texinfo manual. If the
|
||||
.B info
|
||||
and
|
||||
.B makeinfo
|
||||
programs are properly installed at your site, the command
|
||||
.IP
|
||||
.B info makeinfo
|
||||
.PP
|
||||
should give you access to the complete manual.
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 1999 Free Software Foundation, Inc.
|
||||
There is NO warranty. You may redistribute this software
|
||||
under the terms of the GNU General Public License.
|
||||
For more information about these matters, see the files named COPYING.
|
47
contrib/texinfo/doc/texindex.1
Normal file
47
contrib/texinfo/doc/texindex.1
Normal file
@ -0,0 +1,47 @@
|
||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.013.
|
||||
.TH TEXINDEX "1" "September 1999" "GNU texinfo 4.0" FSF
|
||||
.SH NAME
|
||||
texindex \- sort Texinfo index files
|
||||
.SH SYNOPSIS
|
||||
.B texindex
|
||||
[\fIOPTION\fR]...\fI FILE\fR...
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
Generate a sorted index for each TeX output FILE.
|
||||
Usually FILE... is specified as `foo.??' for a document `foo.texi'.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\fB\-h\fR, \fB\-\-help\fR
|
||||
display this help and exit
|
||||
.TP
|
||||
\fB\-k\fR, \fB\-\-keep\fR
|
||||
keep temporary files around after processing
|
||||
.TP
|
||||
\fB\-\-no\-keep\fR
|
||||
do not keep temporary files around after processing (default)
|
||||
.TP
|
||||
\fB\-o\fR, \fB\-\-output\fR FILE
|
||||
send output to FILE
|
||||
.TP
|
||||
\fB\-\-version\fR
|
||||
display version information and exit
|
||||
.SH "REPORTING BUGS"
|
||||
Email bug reports to bug-texinfo@gnu.org,
|
||||
general questions and discussion to help-texinfo@gnu.org.
|
||||
.SH "SEE ALSO"
|
||||
The full documentation for
|
||||
.B texindex
|
||||
is maintained as a Texinfo manual. If the
|
||||
.B info
|
||||
and
|
||||
.B texindex
|
||||
programs are properly installed at your site, the command
|
||||
.IP
|
||||
.B info texindex
|
||||
.PP
|
||||
should give you access to the complete manual.
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 1999 Free Software Foundation, Inc.
|
||||
There is NO warranty. You may redistribute this software
|
||||
under the terms of the GNU General Public License.
|
||||
For more information about these matters, see the files named COPYING.
|
51
contrib/texinfo/doc/texinfo.5
Normal file
51
contrib/texinfo/doc/texinfo.5
Normal file
@ -0,0 +1,51 @@
|
||||
.\" texinfo(5)
|
||||
.\" $Id: texinfo.5,v 1.3 1999/03/25 21:28:25 karl Exp $
|
||||
.\"
|
||||
.\" Copyright (C) 1998, 99 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.
|
||||
.\"
|
||||
.\" 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 Foundation.
|
||||
.\"
|
||||
.TH TEXINFO 5 "GNU Texinfo" "FSF"
|
||||
.SH NAME
|
||||
Texinfo \- software documentation system
|
||||
.SH DESCRIPTION
|
||||
Texinfo is a documentation system that uses a single source file to
|
||||
produce both online information and printed output. It is primarily
|
||||
designed for writing software manuals.
|
||||
.PP
|
||||
For a full description of the Texinfo language and associated tools,
|
||||
please see the Texinfo manual (written in Texinfo itself). Most likely,
|
||||
running this command from your shell:
|
||||
.RS
|
||||
.I info texinfo
|
||||
.RE
|
||||
or this key sequence from inside Emacs:
|
||||
.RS
|
||||
.I M-x info RET m texinfo RET
|
||||
.RE
|
||||
will get you there.
|
||||
.SH AVAILABILITY
|
||||
ftp://ftp.gnu.org/gnu/texinfo/
|
||||
.br
|
||||
or any GNU mirror site.
|
||||
.SH "REPORTING BUGS"
|
||||
Please send bug reports to bug-texinfo@gnu.org,
|
||||
general questions and discussion to help-texinfo@gnu.org.
|
||||
.SH "SEE ALSO"
|
||||
info(1), install-info(1), makeinfo(1), texi2dvi(1), texindex(1).
|
||||
.br
|
||||
emacs(1), tex(1).
|
||||
.br
|
||||
info(5).
|
File diff suppressed because it is too large
Load Diff
3
contrib/texinfo/doc/version.texi
Normal file
3
contrib/texinfo/doc/version.texi
Normal file
@ -0,0 +1,3 @@
|
||||
@set UPDATED 28 September 1999
|
||||
@set EDITION 4.0
|
||||
@set VERSION 4.0
|
@ -14,11 +14,6 @@ the advantages of smaller size, ease of portability, and a built in library
|
||||
which can be used in other programs (to get or display documentation from
|
||||
Info files, for example).
|
||||
|
||||
I eagerly await responses to this newer version of Info; comments on its
|
||||
portability, ease of use and user interface, code quality, and general
|
||||
usefulness are all of interest to me, and I will appreciate any comments
|
||||
that you would care to make.
|
||||
|
||||
A full listing of the commands available in Info can be gotten by typing
|
||||
`?' while within an Info window. This produces a node in a window which
|
||||
can be viewed just like any Info node.
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* 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 $
|
||||
/* dir.c -- how to build a special "dir" node from "localdir" files.
|
||||
$Id: dir.c,v 1.7 1998/06/28 19:51:36 karl Exp $
|
||||
|
||||
Copyright (C) 1993, 97 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
|
||||
@ -125,7 +125,7 @@ maybe_build_dir_node (dirname)
|
||||
char *fullpath = xmalloc (3 + strlen (this_dir) + namelen);
|
||||
|
||||
strcpy (fullpath, this_dir);
|
||||
if (fullpath[strlen (fullpath) - 1] != '/')
|
||||
if (!IS_SLASH (fullpath[strlen (fullpath) - 1]))
|
||||
strcat (fullpath, "/");
|
||||
strcat (fullpath, from_file);
|
||||
|
||||
@ -135,8 +135,9 @@ maybe_build_dir_node (dirname)
|
||||
if (statable && S_ISREG (finfo.st_mode) && new_dir_file_p (&finfo))
|
||||
{
|
||||
long filesize;
|
||||
int compressed;
|
||||
char *contents = filesys_read_info_file (fullpath, &filesize,
|
||||
&finfo);
|
||||
&finfo, &compressed);
|
||||
if (contents)
|
||||
{
|
||||
update_tags++;
|
||||
|
@ -35,21 +35,28 @@ FUNCTION_DOC function_doc_array[] = {
|
||||
{ info_global_next_node, "global-next-node", "Move forwards or down through node structure" },
|
||||
{ info_global_prev_node, "global-prev-node", "Move backwards or up through node structure" },
|
||||
{ info_scroll_forward, "scroll-forward", "Scroll forward in this window" },
|
||||
{ info_scroll_forward_set_window, "scroll-forward-set-window", "Scroll forward in this window and set default window size" },
|
||||
{ info_scroll_backward, "scroll-backward", "Scroll backward in this window" },
|
||||
{ info_scroll_backward_set_window, "scroll-backward-set-window", "Scroll backward in this window and set default window size" },
|
||||
{ info_beginning_of_node, "beginning-of-node", "Move to the start of this node" },
|
||||
{ info_end_of_node, "end-of-node", "Move to the end of this node" },
|
||||
{ info_down_line, "down-line", "Scroll down by lines" },
|
||||
{ info_up_line, "up-line", "Scroll up by lines" },
|
||||
{ info_scroll_half_screen_down, "scroll-half-screen-down", "Scroll down by half screen size" },
|
||||
{ info_scroll_half_screen_up, "scroll-half-screen-up", "Scroll up by half screen size" },
|
||||
{ info_next_window, "next-window", "Select the next window" },
|
||||
{ info_prev_window, "prev-window", "Select the previous window" },
|
||||
{ info_split_window, "split-window", "Split the current window" },
|
||||
{ info_delete_window, "delete-window", "Delete the current window" },
|
||||
{ info_keep_one_window, "keep-one-window", "Delete all other windows" },
|
||||
{ info_scroll_other_window, "scroll-other-window", "Scroll the other window" },
|
||||
{ info_scroll_other_window_backward, "scroll-other-window-backward", "Scroll the other window backward" },
|
||||
{ info_grow_window, "grow-window", "Grow (or shrink) this window" },
|
||||
{ info_tile_windows, "tile-windows", "Divide the available screen space among the visible windows" },
|
||||
{ info_toggle_wrap, "toggle-wrap", "Toggle the state of line wrapping in the current window" },
|
||||
{ info_next_node, "next-node", "Select the `Next' node" },
|
||||
{ info_prev_node, "prev-node", "Select the `Prev' node" },
|
||||
{ info_up_node, "up-node", "Select the `Up' node" },
|
||||
{ info_next_node, "next-node", "Select the Next node" },
|
||||
{ info_prev_node, "prev-node", "Select the Prev node" },
|
||||
{ info_up_node, "up-node", "Select the Up node" },
|
||||
{ info_last_node, "last-node", "Select the last node in this file" },
|
||||
{ info_first_node, "first-node", "Select the first node in this file" },
|
||||
{ info_last_menu_item, "last-menu-item", "Select the last item in this node's menu" },
|
||||
@ -59,6 +66,8 @@ FUNCTION_DOC function_doc_array[] = {
|
||||
{ info_find_menu, "find-menu", "Move to the start of this node's menu" },
|
||||
{ info_visit_menu, "visit-menu", "Visit as many menu items at once as possible" },
|
||||
{ info_goto_node, "goto-node", "Read a node name and select it" },
|
||||
{ info_menu_sequence, "menu-sequence", "Read a list of menus starting from dir and follow them" },
|
||||
{ info_goto_invocation_node, "goto-invocation-node", "Find the node describing program invocation" },
|
||||
{ info_man, "man", "Read a manpage reference and select it" },
|
||||
{ info_top_node, "top-node", "Select the node `Top' in this file" },
|
||||
{ info_dir_node, "dir-node", "Select the node `(dir)'" },
|
||||
@ -66,14 +75,18 @@ FUNCTION_DOC function_doc_array[] = {
|
||||
{ info_kill_node, "kill-node", "Kill this node" },
|
||||
{ info_view_file, "view-file", "Read the name of a file and select it" },
|
||||
{ info_print_node, "print-node", "Pipe the contents of this node through INFO_PRINT_COMMAND" },
|
||||
{ info_search_case_sensitively, "search-case-sensitively", "Read a string and search for it case-sensitively" },
|
||||
{ info_search, "search", "Read a string and search for it" },
|
||||
{ info_search_backward, "search-backward", "Read a string and search backward for it" },
|
||||
{ info_search_next, "search-next", "Repeat last search in the same direction" },
|
||||
{ info_search_previous, "search-previous", "Repeat last search in the reverse direction" },
|
||||
{ isearch_forward, "isearch-forward", "Search interactively for a string as you type it" },
|
||||
{ isearch_backward, "isearch-backward", "Search interactively for a string as you type it" },
|
||||
{ info_move_to_prev_xref, "move-to-prev-xref", "Move to the previous cross reference" },
|
||||
{ info_move_to_next_xref, "move-to-next-xref", "Move to the next cross reference" },
|
||||
{ info_select_reference_this_line, "select-reference-this-line", "Select reference or menu item appearing on this line" },
|
||||
{ info_abort_key, "abort-key", "Cancel current operation" },
|
||||
{ info_move_to_window_line, "move-to-window-line", "Move to the cursor to a specific line of the window" },
|
||||
{ info_move_to_window_line, "move-to-window-line", "Move the cursor to a specific line of the window" },
|
||||
{ info_redraw_display, "redraw-display", "Redraw the display" },
|
||||
{ info_quit, "quit", "Quit using Info" },
|
||||
{ info_do_lowercase_version, "do-lowercase-version", "" },
|
||||
|
@ -1,9 +1,6 @@
|
||||
/* dribble.c -- Dribble files for Info. */
|
||||
/* dribble.c -- dribble files for Info.
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
Copyright (C) 1993, 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
|
||||
@ -37,7 +34,8 @@ open_dribble_file (name)
|
||||
/* Perhaps close existing dribble file. */
|
||||
close_dribble_file ();
|
||||
|
||||
info_dribble_file = fopen (name, "w");
|
||||
/* Keystrokes can be non-printable characters, so we need binary I/O. */
|
||||
info_dribble_file = fopen (name, FOPEN_WBIN);
|
||||
|
||||
#if defined (HAVE_SETVBUF)
|
||||
if (info_dribble_file)
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* echo-area.c -- How to read a line in the echo area.
|
||||
$Id: echo-area.c,v 1.10 1998/02/26 22:47:02 karl Exp $
|
||||
/* echo-area.c -- how to read a line in the echo area.
|
||||
$Id: echo-area.c,v 1.12 1999/03/03 22:22:14 karl Exp $
|
||||
|
||||
Copyright (C) 1993, 97, 98 Free Software Foundation, Inc.
|
||||
Copyright (C) 1993, 97, 98, 99 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
|
||||
@ -940,7 +940,8 @@ DECLARE_INFO_COMMAND (ea_possible_completions, _("List possible completions"))
|
||||
initialize_message_buffer ();
|
||||
printf_to_message_buffer (completions_found_index == 1
|
||||
? _("One completion:\n")
|
||||
: _("%d completions:\n"));
|
||||
: _("%d completions:\n"),
|
||||
completions_found_index);
|
||||
|
||||
/* Find the maximum length of a label. */
|
||||
for (i = 0; i < completions_found_index; i++)
|
||||
@ -1462,7 +1463,7 @@ echo_area_stack_contains_completions_p ()
|
||||
static void
|
||||
pause_or_input ()
|
||||
{
|
||||
#if defined (FD_SET)
|
||||
#ifdef FD_SET
|
||||
struct timeval timer;
|
||||
fd_set readfds;
|
||||
int ready;
|
||||
@ -1470,14 +1471,14 @@ pause_or_input ()
|
||||
FD_ZERO (&readfds);
|
||||
FD_SET (fileno (stdin), &readfds);
|
||||
timer.tv_sec = 2;
|
||||
timer.tv_usec = 750;
|
||||
timer.tv_usec = 0;
|
||||
ready = select (fileno (stdin) + 1, &readfds, (fd_set *) NULL,
|
||||
(fd_set *) NULL, &timer);
|
||||
#endif /* FD_SET */
|
||||
}
|
||||
|
||||
/* Print MESSAGE right after the end of the current line, and wait
|
||||
for input or 2.75 seconds, whichever comes first. Then flush the
|
||||
for input or a couple of seconds, whichever comes first. Then flush the
|
||||
informational message that was printed. */
|
||||
void
|
||||
inform_in_echo_area (message)
|
||||
@ -1487,8 +1488,9 @@ inform_in_echo_area (message)
|
||||
char *text;
|
||||
|
||||
text = xstrdup (message);
|
||||
for (i = 0; text[i] && text[i] != '\n'; i++);
|
||||
text[i] = '\0';
|
||||
for (i = 0; text[i] && text[i] != '\n'; i++)
|
||||
;
|
||||
text[i] = 0;
|
||||
|
||||
echo_area_initialize_node ();
|
||||
sprintf (&input_line[input_line_end], "%s[%s]\n",
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* filesys.c -- File system specific functions for hacking this system.
|
||||
$Id: filesys.c,v 1.6 1998/02/21 22:52:46 karl Exp $
|
||||
/* filesys.c -- filesystem specific functions.
|
||||
$Id: filesys.c,v 1.10 1998/12/06 21:58:30 karl Exp $
|
||||
|
||||
Copyright (C) 1993, 97, 98 Free Software Foundation, Inc.
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
|
||||
/* Local to this file. */
|
||||
static char *info_file_in_path (), *lookup_info_filename ();
|
||||
static char *info_absolute_file ();
|
||||
static void remember_info_filename (), maybe_initialize_infopath ();
|
||||
|
||||
typedef struct
|
||||
@ -35,18 +36,29 @@ typedef struct
|
||||
} COMPRESSION_ALIST;
|
||||
|
||||
static char *info_suffixes[] = {
|
||||
"",
|
||||
".info",
|
||||
"-info",
|
||||
"/index",
|
||||
(char *)NULL
|
||||
".inf", /* 8+3 file on filesystem which supports long file names */
|
||||
#ifdef __MSDOS__
|
||||
/* 8+3 file names strike again... */
|
||||
".in", /* for .inz, .igz etc. */
|
||||
".i",
|
||||
#endif
|
||||
"",
|
||||
NULL
|
||||
};
|
||||
|
||||
static COMPRESSION_ALIST compress_suffixes[] = {
|
||||
{ ".gz", "gunzip" },
|
||||
{ ".bz2", "bunzip2" },
|
||||
{ ".z", "gunzip" },
|
||||
{ ".Z", "uncompress" },
|
||||
{ ".Y", "unyabba" },
|
||||
{ ".z", "gunzip" },
|
||||
{ ".gz", "gunzip" },
|
||||
#ifdef __MSDOS__
|
||||
{ "gz", "gunzip" },
|
||||
{ "z", "gunzip" },
|
||||
#endif
|
||||
{ (char *)NULL, (char *)NULL }
|
||||
};
|
||||
|
||||
@ -86,21 +98,22 @@ info_find_fullpath (partial)
|
||||
/* If we have the full path to this file, we still may have to add
|
||||
various extensions to it. I guess we have to stat this file
|
||||
after all. */
|
||||
if (initial_character == '/')
|
||||
temp = info_file_in_path (partial + 1, "/");
|
||||
if (IS_ABSOLUTE (partial))
|
||||
temp = info_absolute_file (partial);
|
||||
else if (initial_character == '~')
|
||||
{
|
||||
expansion = tilde_expand_word (partial);
|
||||
if (*expansion == '/')
|
||||
if (IS_ABSOLUTE (expansion))
|
||||
{
|
||||
temp = info_file_in_path (expansion + 1, "/");
|
||||
temp = info_absolute_file (expansion);
|
||||
free (expansion);
|
||||
}
|
||||
else
|
||||
temp = expansion;
|
||||
}
|
||||
else if (initial_character == '.' &&
|
||||
(partial[1] == '/' || (partial[1] == '.' && partial[2] == '/')))
|
||||
(IS_SLASH (partial[1]) ||
|
||||
(partial[1] == '.' && IS_SLASH (partial[2]))))
|
||||
{
|
||||
if (local_temp_filename_size < 1024)
|
||||
local_temp_filename = (char *)xrealloc
|
||||
@ -117,7 +130,9 @@ info_find_fullpath (partial)
|
||||
|
||||
strcat (local_temp_filename, "/");
|
||||
strcat (local_temp_filename, partial);
|
||||
return (local_temp_filename);
|
||||
temp = info_absolute_file (local_temp_filename); /* try extensions */
|
||||
if (!temp)
|
||||
partial = local_temp_filename;
|
||||
}
|
||||
else
|
||||
temp = info_file_in_path (partial, infopath);
|
||||
@ -167,7 +182,7 @@ info_file_in_path (filename, path)
|
||||
|
||||
temp = (char *)xmalloc (30 + strlen (temp_dirname) + strlen (filename));
|
||||
strcpy (temp, temp_dirname);
|
||||
if (temp[(strlen (temp)) - 1] != '/')
|
||||
if (!IS_SLASH (temp[(strlen (temp)) - 1]))
|
||||
strcat (temp, "/");
|
||||
strcat (temp, filename);
|
||||
|
||||
@ -229,8 +244,26 @@ info_file_in_path (filename, path)
|
||||
return ((char *)NULL);
|
||||
}
|
||||
|
||||
/* Given a string containing units of information separated by colons,
|
||||
return the next one pointed to by IDX, or NULL if there are no more.
|
||||
/* Assume FNAME is an absolute file name, and check whether it is
|
||||
a regular file. If it is, return it as a new string; otherwise
|
||||
return a NULL pointer. We do it by taking the file name apart
|
||||
into its directory and basename parts, and calling info_file_in_path.*/
|
||||
static char *
|
||||
info_absolute_file (fname)
|
||||
char *fname;
|
||||
{
|
||||
char *containing_dir = xstrdup (fname);
|
||||
char *base = filename_non_directory (containing_dir);
|
||||
|
||||
if (base > containing_dir)
|
||||
base[-1] = '\0';
|
||||
|
||||
return info_file_in_path (filename_non_directory (fname), containing_dir);
|
||||
}
|
||||
|
||||
/* Given a string containing units of information separated by
|
||||
the PATH_SEP character, return the next one pointed to by
|
||||
IDX, or NULL if there are no more.
|
||||
Advance IDX to the character after the colon. */
|
||||
char *
|
||||
extract_colon_unit (string, idx)
|
||||
@ -243,7 +276,7 @@ extract_colon_unit (string, idx)
|
||||
if ((i >= strlen (string)) || !string)
|
||||
return ((char *) NULL);
|
||||
|
||||
while (string[i] && string[i] != ':')
|
||||
while (string[i] && string[i] != PATH_SEP[0])
|
||||
i++;
|
||||
if (i == start)
|
||||
{
|
||||
@ -285,7 +318,7 @@ lookup_info_filename (filename)
|
||||
register int i;
|
||||
for (i = 0; names_and_files[i]; i++)
|
||||
{
|
||||
if (strcmp (names_and_files[i]->filename, filename) == 0)
|
||||
if (FILENAME_CMP (names_and_files[i]->filename, filename) == 0)
|
||||
return (names_and_files[i]->expansion);
|
||||
}
|
||||
}
|
||||
@ -354,14 +387,14 @@ info_add_path (path, where)
|
||||
strcpy (infopath, path);
|
||||
else if (where == INFOPATH_APPEND)
|
||||
{
|
||||
strcat (infopath, ":");
|
||||
strcat (infopath, PATH_SEP);
|
||||
strcat (infopath, path);
|
||||
}
|
||||
else if (where == INFOPATH_PREPEND)
|
||||
{
|
||||
char *temp = xstrdup (infopath);
|
||||
strcpy (infopath, path);
|
||||
strcat (infopath, ":");
|
||||
strcat (infopath, PATH_SEP);
|
||||
strcat (infopath, temp);
|
||||
free (temp);
|
||||
}
|
||||
@ -378,28 +411,70 @@ zap_infopath ()
|
||||
infopath_size = 0;
|
||||
}
|
||||
|
||||
/* Given a chunk of text and its length, convert all CRLF pairs at every
|
||||
end-of-line into a single Newline character. Return the length of
|
||||
produced text.
|
||||
|
||||
This is required because the rest of code is too entrenched in having
|
||||
a single newline at each EOL; in particular, searching for various
|
||||
Info headers and cookies can become extremely tricky if that assumption
|
||||
breaks.
|
||||
|
||||
FIXME: this could also support Mac-style text files with a single CR
|
||||
at the EOL, but what about random CR characters in non-Mac files? Can
|
||||
we afford converting them into newlines as well? Maybe implement some
|
||||
heuristics here, like in Emacs 20.
|
||||
|
||||
FIXME: is it a good idea to show the EOL type on the modeline? */
|
||||
long
|
||||
convert_eols (text, textlen)
|
||||
char *text;
|
||||
long textlen;
|
||||
{
|
||||
register char *s = text;
|
||||
register char *d = text;
|
||||
|
||||
while (textlen--)
|
||||
{
|
||||
if (*s == '\r' && textlen && s[1] == '\n')
|
||||
{
|
||||
s++;
|
||||
textlen--;
|
||||
}
|
||||
*d++ = *s++;
|
||||
}
|
||||
|
||||
return (long)(d - text);
|
||||
}
|
||||
|
||||
/* Read the contents of PATHNAME, returning a buffer with the contents of
|
||||
that file in it, and returning the size of that buffer in FILESIZE.
|
||||
FINFO is a stat struct which has already been filled in by the caller.
|
||||
If the file turns out to be compressed, set IS_COMPRESSED to non-zero.
|
||||
If the file cannot be read, return a NULL pointer. */
|
||||
char *
|
||||
filesys_read_info_file (pathname, filesize, finfo)
|
||||
filesys_read_info_file (pathname, filesize, finfo, is_compressed)
|
||||
char *pathname;
|
||||
long *filesize;
|
||||
struct stat *finfo;
|
||||
int *is_compressed;
|
||||
{
|
||||
long st_size;
|
||||
|
||||
*filesize = filesys_error_number = 0;
|
||||
|
||||
if (compressed_filename_p (pathname))
|
||||
return (filesys_read_compressed (pathname, filesize, finfo));
|
||||
{
|
||||
*is_compressed = 1;
|
||||
return (filesys_read_compressed (pathname, filesize, finfo));
|
||||
}
|
||||
else
|
||||
{
|
||||
int descriptor;
|
||||
char *contents;
|
||||
|
||||
descriptor = open (pathname, O_RDONLY, 0666);
|
||||
*is_compressed = 0;
|
||||
descriptor = open (pathname, O_RDONLY | O_BINARY, 0666);
|
||||
|
||||
/* If the file couldn't be opened, give up. */
|
||||
if (descriptor < 0)
|
||||
@ -413,15 +488,24 @@ filesys_read_info_file (pathname, filesize, finfo)
|
||||
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);
|
||||
|
||||
*filesize = st_size;
|
||||
/* Convert any DOS-style CRLF EOLs into Unix-style NL.
|
||||
Seems like a good idea to have even on Unix, in case the Info
|
||||
files are coming from some Windows system across a network. */
|
||||
*filesize = convert_eols (contents, st_size);
|
||||
|
||||
/* EOL conversion can shrink the text quite a bit. We don't
|
||||
want to waste storage. */
|
||||
if (*filesize < st_size)
|
||||
contents = (char *)xrealloc (contents, 1 + *filesize);
|
||||
|
||||
return (contents);
|
||||
}
|
||||
}
|
||||
@ -449,8 +533,11 @@ filesys_read_compressed (pathname, filesize, finfo)
|
||||
if (!decompressor)
|
||||
return ((char *)NULL);
|
||||
|
||||
command = (char *)xmalloc (10 + strlen (pathname) + strlen (decompressor));
|
||||
sprintf (command, "%s < %s", decompressor, pathname);
|
||||
command = (char *)xmalloc (15 + strlen (pathname) + strlen (decompressor));
|
||||
/* Explicit .exe suffix makes the diagnostics of `popen'
|
||||
better on systems where COMMAND.COM is the stock shell. */
|
||||
sprintf (command, "%s%s < %s",
|
||||
decompressor, STRIP_DOT_EXE ? ".exe" : "", pathname);
|
||||
|
||||
#if !defined (BUILDING_LIBRARY)
|
||||
if (info_windows_initialized_p)
|
||||
@ -464,7 +551,7 @@ filesys_read_compressed (pathname, filesize, finfo)
|
||||
}
|
||||
#endif /* !BUILDING_LIBRARY */
|
||||
|
||||
stream = popen (command, "r");
|
||||
stream = popen (command, FOPEN_RBIN);
|
||||
free (command);
|
||||
|
||||
/* Read chunks from this file until there are none left to read. */
|
||||
@ -493,9 +580,18 @@ filesys_read_compressed (pathname, filesize, finfo)
|
||||
}
|
||||
|
||||
free (chunk);
|
||||
pclose (stream);
|
||||
contents = (char *)xrealloc (contents, offset + 1);
|
||||
*filesize = offset;
|
||||
if (pclose (stream) == -1)
|
||||
{
|
||||
if (contents)
|
||||
free (contents);
|
||||
contents = (char *)NULL;
|
||||
filesys_error_number = errno;
|
||||
}
|
||||
else
|
||||
{
|
||||
*filesize = convert_eols (contents, offset);
|
||||
contents = (char *)xrealloc (contents, 1 + *filesize);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -547,9 +643,19 @@ filesys_decompressor_for_file (filename)
|
||||
return ((char *)NULL);
|
||||
|
||||
for (i = 0; compress_suffixes[i].suffix; i++)
|
||||
if (strcmp (extension, compress_suffixes[i].suffix) == 0)
|
||||
if (FILENAME_CMP (extension, compress_suffixes[i].suffix) == 0)
|
||||
return (compress_suffixes[i].decompressor);
|
||||
|
||||
#if defined (__MSDOS__)
|
||||
/* If no other suffix matched, allow any extension which ends
|
||||
with `z' to be decompressed by gunzip. Due to limited 8+3 DOS
|
||||
file namespace, we can expect many such cases, and supporting
|
||||
every weird suffix thus produced would be a pain. */
|
||||
if (extension[strlen (extension) - 1] == 'z' ||
|
||||
extension[strlen (extension) - 1] == 'Z')
|
||||
return "gunzip";
|
||||
#endif
|
||||
|
||||
return ((char *)NULL);
|
||||
}
|
||||
|
||||
@ -582,3 +688,26 @@ filesys_error_string (filename, error_num)
|
||||
return (errmsg_buf);
|
||||
}
|
||||
|
||||
|
||||
/* Check for FILENAME eq "dir" first, then all the compression
|
||||
suffixes. */
|
||||
|
||||
int
|
||||
is_dir_name (filename)
|
||||
char *filename;
|
||||
{
|
||||
unsigned i;
|
||||
if (strcasecmp (filename, "dir") == 0)
|
||||
return 1;
|
||||
|
||||
for (i = 0; compress_suffixes[i].suffix; i++)
|
||||
{
|
||||
char dir_compressed[50]; /* can be short */
|
||||
strcpy (dir_compressed, "dir");
|
||||
strcat (dir_compressed, compress_suffixes[i].suffix);
|
||||
if (strcasecmp (filename, dir_compressed) == 0)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,10 +1,7 @@
|
||||
/* 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 $
|
||||
/* filesys.h -- external declarations for filesys.c.
|
||||
$Id: filesys.h,v 1.5 1998/07/21 22:25:44 karl Exp $
|
||||
|
||||
This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993, 97 Free Software Foundation, Inc.
|
||||
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
|
||||
@ -46,6 +43,11 @@ extern void info_add_path ();
|
||||
If it can't find the file, it returns NULL. */
|
||||
extern char *info_find_fullpath ();
|
||||
|
||||
/* Given a chunk of text and its length, convert all CRLF pairs at the
|
||||
EOLs into a single Newline character. Return the length of produced
|
||||
text. */
|
||||
long convert_eols ();
|
||||
|
||||
/* Read the contents of PATHNAME, returning a buffer with the contents of
|
||||
that file in it, and returning the size of that buffer in FILESIZE.
|
||||
FINFO is a stat struct which has already been filled in by the caller.
|
||||
@ -69,6 +71,9 @@ extern int filesys_error_number;
|
||||
Advance IDX to the character after the colon. */
|
||||
extern char *extract_colon_unit ();
|
||||
|
||||
/* Return true if FILENAME is `dir', with a possible compression suffix. */
|
||||
extern int is_dir_name ();
|
||||
|
||||
/* 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:."
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* footnotes.c -- Some functions for manipulating footnotes.
|
||||
$Id: footnotes.c,v 1.4 1997/07/24 21:23:33 karl Exp $
|
||||
$Id: footnotes.c,v 1.9 1999/09/25 16:10:04 karl Exp $
|
||||
|
||||
Copyright (C) 1993, 97 Free Software Foundation, Inc.
|
||||
Copyright (C) 1993, 97, 98, 99 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
|
||||
@ -60,7 +60,7 @@ make_footnotes_node (node)
|
||||
|
||||
/* See if this node contains the magic footnote label. */
|
||||
fn_start =
|
||||
info_search_in_node (FOOTNOTE_LABEL, node, 0, (WINDOW *)NULL, 1);
|
||||
info_search_in_node (FOOTNOTE_LABEL, node, 0, (WINDOW *)NULL, 1, 0);
|
||||
|
||||
/* If it doesn't, check to see if it has an associated footnotes node. */
|
||||
if (fn_start == -1)
|
||||
@ -73,16 +73,21 @@ make_footnotes_node (node)
|
||||
{
|
||||
register int i;
|
||||
char *refname;
|
||||
int reflen = strlen ("-Footnotes") + strlen (node->nodename);
|
||||
|
||||
refname = (char *)xmalloc
|
||||
(1 + strlen ("-Footnotes") + strlen (node->nodename));
|
||||
refname = (char *)xmalloc (reflen + 1);
|
||||
|
||||
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))
|
||||
/* Support both the older "foo-Footnotes" and the new
|
||||
style "foo-Footnote-NN" references. */
|
||||
(strcmp (refs[i]->nodename, refname) == 0 ||
|
||||
(strncmp (refs[i]->nodename, refname, reflen - 1) == 0 &&
|
||||
refs[i]->nodename[reflen - 1] == '-' &&
|
||||
isdigit (refs[i]->nodename[reflen]))))
|
||||
{
|
||||
char *filename;
|
||||
|
||||
@ -110,6 +115,7 @@ make_footnotes_node (node)
|
||||
/* Make the new node. */
|
||||
result = (NODE *)xmalloc (sizeof (NODE));
|
||||
result->flags = 0;
|
||||
result->display_pos = 0;
|
||||
|
||||
/* Get the size of the footnotes appearing within this node. */
|
||||
{
|
||||
@ -250,11 +256,11 @@ DECLARE_INFO_COMMAND (info_show_footnotes,
|
||||
switch (result)
|
||||
{
|
||||
case FN_UNFOUND:
|
||||
info_error (NO_FOOT_NODE);
|
||||
info_error (msg_no_foot_node);
|
||||
break;
|
||||
|
||||
case FN_UNABLE:
|
||||
info_error (WIN_TOO_SMALL);
|
||||
info_error (msg_win_too_small);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,7 @@
|
||||
/* footnotes.h -- Some functions for manipulating footnotes.
|
||||
$Id: footnotes.h,v 1.3 1997/07/15 18:40:27 karl Exp $
|
||||
$Id: footnotes.h,v 1.4 1998/11/29 21:44:49 karl Exp $
|
||||
|
||||
This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993, 97 Free Software Foundation, Inc.
|
||||
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
|
||||
@ -26,7 +23,7 @@
|
||||
#define INFO_FOOTNOTES_H
|
||||
|
||||
/* Magic string which indicates following text is footnotes. */
|
||||
#define FOOTNOTE_LABEL _("---------- Footnotes ----------")
|
||||
#define FOOTNOTE_LABEL N_("---------- Footnotes ----------")
|
||||
|
||||
#define FN_FOUND 0
|
||||
#define FN_UNFOUND 1
|
||||
|
@ -12,15 +12,22 @@ extern void info_backward_word ();
|
||||
extern void info_global_next_node ();
|
||||
extern void info_global_prev_node ();
|
||||
extern void info_scroll_forward ();
|
||||
extern void info_scroll_forward_set_window ();
|
||||
extern void info_scroll_backward ();
|
||||
extern void info_scroll_backward_set_window ();
|
||||
extern void info_beginning_of_node ();
|
||||
extern void info_end_of_node ();
|
||||
extern void info_down_line ();
|
||||
extern void info_up_line ();
|
||||
extern void info_scroll_half_screen_down ();
|
||||
extern void info_scroll_half_screen_up ();
|
||||
extern void info_next_window ();
|
||||
extern void info_prev_window ();
|
||||
extern void info_split_window ();
|
||||
extern void info_delete_window ();
|
||||
extern void info_keep_one_window ();
|
||||
extern void info_scroll_other_window ();
|
||||
extern void info_scroll_other_window_backward ();
|
||||
extern void info_grow_window ();
|
||||
extern void info_tile_windows ();
|
||||
extern void info_toggle_wrap ();
|
||||
@ -36,6 +43,8 @@ extern void info_xref_item ();
|
||||
extern void info_find_menu ();
|
||||
extern void info_visit_menu ();
|
||||
extern void info_goto_node ();
|
||||
extern void info_menu_sequence ();
|
||||
extern void info_goto_invocation_node ();
|
||||
extern void info_man ();
|
||||
extern void info_top_node ();
|
||||
extern void info_dir_node ();
|
||||
@ -43,7 +52,11 @@ extern void info_history_node ();
|
||||
extern void info_kill_node ();
|
||||
extern void info_view_file ();
|
||||
extern void info_print_node ();
|
||||
extern void info_search_case_sensitively ();
|
||||
extern void info_search ();
|
||||
extern void info_search_backward ();
|
||||
extern void info_search_next ();
|
||||
extern void info_search_previous ();
|
||||
extern void isearch_forward ();
|
||||
extern void isearch_backward ();
|
||||
extern void info_move_to_prev_xref ();
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* indices.c -- Commands for dealing with an Info file Index.
|
||||
$Id: indices.c,v 1.6 1997/07/24 21:25:53 karl Exp $
|
||||
/* indices.c -- deal with an Info file index.
|
||||
$Id: indices.c,v 1.14 1999/09/25 16:10:04 karl Exp $
|
||||
|
||||
Copyright (C) 1993, 97 Free Software Foundation, Inc.
|
||||
Copyright (C) 1993, 97, 98, 99 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
|
||||
@ -199,7 +199,7 @@ do_info_index_search (window, count, search_string)
|
||||
index for, build and remember an index now. */
|
||||
fb = file_buffer_of_window (window);
|
||||
if (!initial_index_filename ||
|
||||
(strcmp (initial_index_filename, fb->filename) != 0))
|
||||
(FILENAME_CMP (initial_index_filename, fb->filename) != 0))
|
||||
{
|
||||
info_free_references (index_index);
|
||||
window_message_in_echo_area (_("Finding index entries..."));
|
||||
@ -296,7 +296,7 @@ index_entry_exists (window, string)
|
||||
|
||||
fb = file_buffer_of_window (window);
|
||||
if (!initial_index_filename
|
||||
|| (strcmp (initial_index_filename, fb->filename) != 0))
|
||||
|| (FILENAME_CMP (initial_index_filename, fb->filename) != 0))
|
||||
{
|
||||
info_free_references (index_index);
|
||||
index_index = info_indices_of_file_buffer (fb);
|
||||
@ -439,15 +439,12 @@ DECLARE_INFO_COMMAND (info_next_index_match,
|
||||
|
||||
if (!node)
|
||||
{
|
||||
info_error (CANT_FILE_NODE,
|
||||
info_error (msg_cant_file_node,
|
||||
index_index[i]->filename, index_index[i]->nodename);
|
||||
return;
|
||||
}
|
||||
|
||||
set_remembered_pagetop_and_point (window);
|
||||
window_set_node_of_window (window, node);
|
||||
remember_window_and_node (window, node);
|
||||
|
||||
info_set_node_of_window (1, window, node);
|
||||
|
||||
/* Try to find an occurence of LABEL in this node. */
|
||||
{
|
||||
@ -497,11 +494,13 @@ apropos_in_all_indices (search_string, inform)
|
||||
REFERENCE **this_index, *this_item;
|
||||
NODE *this_node;
|
||||
FILE_BUFFER *this_fb;
|
||||
int dir_node_duplicated = 0;
|
||||
|
||||
this_item = dir_menu[dir_index];
|
||||
|
||||
if (!this_item->filename)
|
||||
{
|
||||
dir_node_duplicated = 1;
|
||||
if (dir_node->parent)
|
||||
this_item->filename = xstrdup (dir_node->parent);
|
||||
else
|
||||
@ -517,7 +516,11 @@ apropos_in_all_indices (search_string, inform)
|
||||
this_node = info_get_node (this_item->label, "Top");
|
||||
|
||||
if (!this_node)
|
||||
continue;
|
||||
{
|
||||
if (dir_node_duplicated)
|
||||
free (this_item->filename);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Get the file buffer associated with this node. */
|
||||
{
|
||||
@ -529,6 +532,19 @@ apropos_in_all_indices (search_string, inform)
|
||||
|
||||
this_fb = info_find_file (files_name);
|
||||
|
||||
/* If we already scanned this file, don't do that again.
|
||||
In addition to being faster, this also avoids having
|
||||
multiple identical entries in the *Apropos* menu. */
|
||||
for (i = 0; i < dir_index; i++)
|
||||
if (FILENAME_CMP (this_fb->filename, dir_menu[i]->filename) == 0)
|
||||
break;
|
||||
if (i < dir_index)
|
||||
{
|
||||
if (dir_node_duplicated)
|
||||
free (this_item->filename);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (this_fb && inform)
|
||||
message_in_echo_area (_("Scanning indices of \"%s\"..."), files_name);
|
||||
|
||||
@ -584,7 +600,7 @@ apropos_in_all_indices (search_string, inform)
|
||||
}
|
||||
|
||||
#define APROPOS_NONE \
|
||||
_("No available info files reference \"%s\" in their indices.")
|
||||
N_("No available info files have \"%s\" in their indices.")
|
||||
|
||||
void
|
||||
info_apropos (string)
|
||||
@ -596,7 +612,7 @@ info_apropos (string)
|
||||
|
||||
if (!apropos_list)
|
||||
{
|
||||
info_error (APROPOS_NONE, string);
|
||||
info_error (_(APROPOS_NONE), string);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -604,7 +620,7 @@ info_apropos (string)
|
||||
REFERENCE *entry;
|
||||
|
||||
for (i = 0; (entry = apropos_list[i]); i++)
|
||||
fprintf (stderr, "\"(%s)%s\" -- %s\n",
|
||||
fprintf (stdout, "\"(%s)%s\" -- %s\n",
|
||||
entry->filename, entry->nodename, entry->label);
|
||||
}
|
||||
info_free_references (apropos_list);
|
||||
@ -638,7 +654,7 @@ DECLARE_INFO_COMMAND (info_index_apropos,
|
||||
|
||||
if (!apropos_list)
|
||||
{
|
||||
info_error (APROPOS_NONE, line);
|
||||
info_error (_(APROPOS_NONE), line);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -653,10 +669,14 @@ DECLARE_INFO_COMMAND (info_index_apropos,
|
||||
for (i = 0; apropos_list[i]; i++)
|
||||
{
|
||||
int len;
|
||||
sprintf (line_buffer, "* (%s)%s::",
|
||||
/* The label might be identical to that of another index
|
||||
entry in another Info file. Therefore, we make the file
|
||||
name part of the menu entry, to make them all distinct. */
|
||||
sprintf (line_buffer, "* %s [%s]: ",
|
||||
apropos_list[i]->label, apropos_list[i]->filename);
|
||||
len = pad_to (40, line_buffer);
|
||||
sprintf (line_buffer + len, "(%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);
|
||||
|
@ -1,9 +1,7 @@
|
||||
/* info-utils.c -- Useful functions for manipulating Info file quirks. */
|
||||
/* info-utils.c -- miscellanous.
|
||||
$Id: info-utils.c,v 1.7 1998/08/10 18:07:47 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, 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
|
||||
@ -29,7 +27,7 @@
|
||||
|
||||
/* When non-zero, various display and input functions handle ISO Latin
|
||||
character sets correctly. */
|
||||
int ISO_Latin_p = 0;
|
||||
int ISO_Latin_p = 1;
|
||||
|
||||
/* Variable which holds the most recent filename parsed as a result of
|
||||
calling info_parse_xxx (). */
|
||||
@ -300,8 +298,8 @@ info_references_internal (label, binding)
|
||||
return (refs);
|
||||
}
|
||||
|
||||
/* Get the entry associated with LABEL in MENU. Return a pointer to the
|
||||
REFERENCE if found, or NULL. */
|
||||
/* Get the entry associated with LABEL in REFERENCES. Return a pointer
|
||||
to the ENTRY if found, or NULL. */
|
||||
REFERENCE *
|
||||
info_get_labeled_reference (label, references)
|
||||
char *label;
|
||||
@ -444,19 +442,10 @@ printed_representation (character, hpos)
|
||||
int hpos;
|
||||
{
|
||||
register int i = 0;
|
||||
int printable_limit;
|
||||
|
||||
if (ISO_Latin_p)
|
||||
printable_limit = 160;
|
||||
else
|
||||
printable_limit = 127;
|
||||
|
||||
if (character == '\177')
|
||||
{
|
||||
the_rep[i++] = '^';
|
||||
the_rep[i++] = '?';
|
||||
}
|
||||
else if (iscntrl (character))
|
||||
int printable_limit = ISO_Latin_p ? 255 : 127;
|
||||
|
||||
/* Show CTRL-x as ^X. */
|
||||
if (iscntrl (character) && character < 127)
|
||||
{
|
||||
switch (character)
|
||||
{
|
||||
@ -480,17 +469,23 @@ printed_representation (character, hpos)
|
||||
the_rep[i++] = (character | 0x40);
|
||||
}
|
||||
}
|
||||
/* Show META-x as 0370. */
|
||||
else if (character > printable_limit)
|
||||
{
|
||||
sprintf (the_rep + i, "\\%0o", character);
|
||||
i = strlen (the_rep);
|
||||
}
|
||||
else if (character == DEL)
|
||||
{
|
||||
the_rep[i++] = '^';
|
||||
the_rep[i++] = '?';
|
||||
}
|
||||
else
|
||||
the_rep[i++] = character;
|
||||
|
||||
the_rep[i] = '\0';
|
||||
the_rep[i] = 0;
|
||||
|
||||
return (the_rep);
|
||||
return the_rep;
|
||||
}
|
||||
|
||||
|
||||
@ -604,14 +599,13 @@ char *
|
||||
filename_non_directory (pathname)
|
||||
char *pathname;
|
||||
{
|
||||
char *filename;
|
||||
register char *filename = pathname + strlen (pathname);
|
||||
|
||||
filename = (char *) strrchr (pathname, '/');
|
||||
if (HAVE_DRIVE (pathname))
|
||||
pathname += 2;
|
||||
|
||||
if (filename)
|
||||
filename++;
|
||||
else
|
||||
filename = pathname;
|
||||
while (filename > pathname && !IS_SLASH (filename[-1]))
|
||||
filename--;
|
||||
|
||||
return (filename);
|
||||
}
|
||||
@ -663,3 +657,17 @@ get_internal_info_window (name)
|
||||
|
||||
return (win);
|
||||
}
|
||||
|
||||
/* Return a window displaying the node NODE. */
|
||||
WINDOW *
|
||||
get_window_of_node (node)
|
||||
NODE *node;
|
||||
{
|
||||
WINDOW *win = (WINDOW *)NULL;
|
||||
|
||||
for (win = windows; win; win = win->next)
|
||||
if (win->node == node)
|
||||
break;
|
||||
|
||||
return (win);
|
||||
}
|
||||
|
@ -1,10 +1,7 @@
|
||||
/* info-utils.h -- Exported functions and variables from info-util.c.
|
||||
$Id: info-utils.h,v 1.3 1997/07/15 18:42:20 karl Exp $
|
||||
/* info-utils.h -- Exported functions and variables from info-utils.c.
|
||||
$Id: info-utils.h,v 1.5 1998/08/10 18:07:28 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, 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
|
||||
@ -25,13 +22,6 @@
|
||||
#ifndef INFO_UTILS_H
|
||||
#define INFO_UTILS_H
|
||||
|
||||
#if !defined (HAVE_STRCHR)
|
||||
# undef strchr
|
||||
# undef strrchr
|
||||
# define strchr index
|
||||
# define strrchr rindex
|
||||
#endif /* !HAVE_STRCHR */
|
||||
|
||||
#include "nodes.h"
|
||||
#include "window.h"
|
||||
#include "search.h"
|
||||
@ -118,22 +108,22 @@ extern void name_internal_node ();
|
||||
Info window. */
|
||||
extern WINDOW *get_internal_info_window ();
|
||||
|
||||
/* Return a window displaying the node NODE. */
|
||||
extern WINDOW *get_window_of_node ();
|
||||
|
||||
/* Return the node addressed by LABEL in NODE (usually one of "Prev:",
|
||||
"Next:", "Up:", "File:", or "Node:". After a call to this function,
|
||||
the global INFO_PARSED_NODENAME and INFO_PARSED_FILENAME contain
|
||||
the globals `info_parsed_nodename' and `info_parsed_filename' contain
|
||||
the information. */
|
||||
extern void info_parse_label (/* label, node */);
|
||||
|
||||
#define info_label_was_found \
|
||||
(info_parsed_nodename != NULL || info_parsed_filename != NULL)
|
||||
|
||||
#define info_file_label_of_node(n) info_parse_label (INFO_FILE_LABEL, n)
|
||||
#define info_next_label_of_node(n) info_parse_label (INFO_NEXT_LABEL, n)
|
||||
#define info_up_label_of_node(n) info_parse_label (INFO_UP_LABEL, n)
|
||||
#define info_prev_label_of_node(n) \
|
||||
do { \
|
||||
info_parse_label (INFO_PREV_LABEL, n); \
|
||||
if (!info_label_was_found) \
|
||||
if (!info_parsed_nodename && !info_parsed_filename) \
|
||||
info_parse_label (INFO_ALTPREV_LABEL, n); \
|
||||
} while (0)
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* info.c -- Display nodes of Info files in multiple windows.
|
||||
$Id: info.c,v 1.18 1998/02/27 21:37:27 karl Exp $
|
||||
$Id: info.c,v 1.41 1999/09/25 16:10:04 karl Exp $
|
||||
|
||||
Copyright (C) 1993, 96, 97, 98 Free Software Foundation, Inc.
|
||||
Copyright (C) 1993, 96, 97, 98, 99 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
|
||||
@ -27,12 +27,7 @@
|
||||
# include "man.h"
|
||||
#endif /* HANDLE_MAN_PAGES */
|
||||
|
||||
/* The version numbers of this version of Info. */
|
||||
int info_major_version = 2;
|
||||
int info_minor_version = 18;
|
||||
|
||||
/* basename (argv[0]) */
|
||||
static char *program_name = NULL;
|
||||
static char *program_name = "info";
|
||||
|
||||
/* Non-zero means search all indices for APROPOS_SEARCH_STRING. */
|
||||
static int apropos_p = 0;
|
||||
@ -44,8 +39,13 @@ static char *apropos_search_string = (char *)NULL;
|
||||
apropos, this puts the user at the node, running info. */
|
||||
static int index_search_p = 0;
|
||||
|
||||
/* Non-zero means look for the node which describes the invocation
|
||||
and command-line options of the program, and start the info
|
||||
session at that node. */
|
||||
static int goto_invocation_p = 0;
|
||||
|
||||
/* Variable containing the string to search for when index_search_p is
|
||||
non-zero. */
|
||||
non-zero. */
|
||||
static char *index_search_string = (char *)NULL;
|
||||
|
||||
/* Non-zero means print version info only. */
|
||||
@ -73,6 +73,18 @@ static char *user_output_filename = (char *)NULL;
|
||||
dumped in the order encountered. This basically can print a book. */
|
||||
int dump_subnodes = 0;
|
||||
|
||||
/* Non-zero means make default keybindings be loosely modeled on vi(1). */
|
||||
int vi_keys_p = 0;
|
||||
|
||||
#ifdef __MSDOS__
|
||||
/* Non-zero indicates that screen output should be made 'speech-friendly'.
|
||||
Since on MSDOS the usual behavior is to write directly to the video
|
||||
memory, speech synthesizer software cannot grab the output. Therefore,
|
||||
we provide a user option which tells us to avoid direct screen output
|
||||
and use stdout instead (which loses the color output). */
|
||||
int speech_friendly = 0;
|
||||
#endif
|
||||
|
||||
/* Structure describing the options that Info accepts. We pass this structure
|
||||
to getopt_long (). If you add or otherwise change this structure, you must
|
||||
also change the string which follows it. */
|
||||
@ -87,22 +99,33 @@ static struct option long_options[] = {
|
||||
{ "file", 1, 0, 'f' },
|
||||
{ "subnodes", 0, &dump_subnodes, 1 },
|
||||
{ "output", 1, 0, 'o' },
|
||||
{ "show-options", 0, 0, 'O' },
|
||||
{ "usage", 0, 0, 'O' },
|
||||
{ "vi-keys", 0, &vi_keys_p, 1 },
|
||||
{ "help", 0, &print_help_p, 1 },
|
||||
{ "version", 0, &print_version_p, 1 },
|
||||
{ "dribble", 1, 0, DRIBBLE_OPTION },
|
||||
{ "restore", 1, 0, RESTORE_OPTION },
|
||||
#ifdef __MSDOS__
|
||||
{ "speech-friendly", 0, &speech_friendly, 1 },
|
||||
#endif
|
||||
{ "index-search", 1, 0, IDXSRCH_OPTION },
|
||||
{NULL, 0, NULL, 0}
|
||||
};
|
||||
|
||||
/* String describing the shorthand versions of the long options found above. */
|
||||
static char *short_options = "d:n:f:o:s";
|
||||
#ifdef __MSDOS__
|
||||
static char *short_options = "d:n:f:o:Osb";
|
||||
#else
|
||||
static char *short_options = "d:n:f:o:Os";
|
||||
#endif
|
||||
|
||||
/* When non-zero, the Info window system has been initialized. */
|
||||
int info_windows_initialized_p = 0;
|
||||
|
||||
/* Some "forward" declarations. */
|
||||
static void info_short_help (), remember_info_program_name ();
|
||||
static void init_messages ();
|
||||
|
||||
|
||||
/* **************************************************************** */
|
||||
@ -119,8 +142,6 @@ main (argc, argv)
|
||||
int getopt_long_index; /* Index returned by getopt_long (). */
|
||||
NODE *initial_node; /* First node loaded by Info. */
|
||||
|
||||
remember_info_program_name (argv[0]);
|
||||
|
||||
#ifdef HAVE_SETLOCALE
|
||||
/* Set locale via LC_ALL. */
|
||||
setlocale (LC_ALL, "");
|
||||
@ -130,6 +151,8 @@ main (argc, argv)
|
||||
bindtextdomain (PACKAGE, LOCALEDIR);
|
||||
textdomain (PACKAGE);
|
||||
|
||||
init_messages ();
|
||||
|
||||
while (1)
|
||||
{
|
||||
int option_character;
|
||||
@ -177,12 +200,25 @@ main (argc, argv)
|
||||
user_output_filename = xstrdup (optarg);
|
||||
break;
|
||||
|
||||
/* User has specified that she wants to find the "Options"
|
||||
or "Invocation" node for the program. */
|
||||
case 'O':
|
||||
goto_invocation_p = 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;
|
||||
|
||||
#ifdef __MSDOS__
|
||||
/* User specifies that she wants speech-friendly output. */
|
||||
case 'b':
|
||||
speech_friendly = 1;
|
||||
break;
|
||||
#endif /* __MSDOS__ */
|
||||
|
||||
/* User has specified a string to search all indices for. */
|
||||
case APROPOS_OPTION:
|
||||
apropos_p = 1;
|
||||
@ -209,8 +245,8 @@ main (argc, argv)
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf (stderr, _("Try --help for more information."));
|
||||
exit (1);
|
||||
fprintf (stderr, _("Try --help for more information.\n"));
|
||||
xexit (1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -226,23 +262,23 @@ main (argc, argv)
|
||||
/* If the user specified --version, then show the version and exit. */
|
||||
if (print_version_p)
|
||||
{
|
||||
printf ("%s (GNU %s %s) %s\n", program_name, PACKAGE, VERSION,
|
||||
version_string ());
|
||||
printf ("%s (GNU %s) %s\n", program_name, PACKAGE, VERSION);
|
||||
puts ("");
|
||||
printf (_("Copyright (C) %s Free Software Foundation, Inc.\n\
|
||||
There is NO warranty. You may redistribute this software\n\
|
||||
under the terms of the GNU General Public License.\n\
|
||||
For more information about these matters, see the files named COPYING.\n"),
|
||||
"1998");
|
||||
exit (0);
|
||||
"1999");
|
||||
xexit (0);
|
||||
}
|
||||
|
||||
/* If the `--help' option was present, show the help and exit. */
|
||||
if (print_help_p)
|
||||
{
|
||||
info_short_help ();
|
||||
exit (0);
|
||||
xexit (0);
|
||||
}
|
||||
|
||||
|
||||
/* If the user hasn't specified a path for Info files, default it.
|
||||
Lowest priority is our messy hardwired list in filesys.h.
|
||||
Then comes the user's INFODIR from the Makefile.
|
||||
@ -255,7 +291,7 @@ For more information about these matters, see the files named COPYING.\n"),
|
||||
{
|
||||
unsigned len = strlen (path_from_env);
|
||||
/* Trailing : on INFOPATH means insert the default path. */
|
||||
if (len && path_from_env[len - 1] == ':')
|
||||
if (len && path_from_env[len - 1] == PATH_SEP[0])
|
||||
{
|
||||
path_from_env[len - 1] = 0;
|
||||
info_add_path (DEFAULT_INFOPATH, INFOPATH_PREPEND);
|
||||
@ -283,7 +319,14 @@ For more information about these matters, see the files named COPYING.\n"),
|
||||
|
||||
if (temp != directory_name)
|
||||
{
|
||||
*temp = 0;
|
||||
if (HAVE_DRIVE (directory_name) && temp == directory_name + 2)
|
||||
{
|
||||
/* The directory of "d:foo" is stored as "d:.", to avoid
|
||||
mixing it with "d:/" when a slash is appended. */
|
||||
*temp = '.';
|
||||
temp += 2;
|
||||
}
|
||||
temp[-1] = 0;
|
||||
info_add_path (directory_name, INFOPATH_PREPEND);
|
||||
}
|
||||
|
||||
@ -295,13 +338,13 @@ For more information about these matters, see the files named COPYING.\n"),
|
||||
if (apropos_p)
|
||||
{
|
||||
info_apropos (apropos_search_string);
|
||||
exit (0);
|
||||
xexit (0);
|
||||
}
|
||||
|
||||
/* Get the initial Info node. It is either "(dir)Top", or what the user
|
||||
specifed with values in user_filename and user_nodenames. */
|
||||
initial_node = info_get_node (user_filename,
|
||||
user_nodenames ? user_nodenames[0] : NULL);
|
||||
user_nodenames ? user_nodenames[0] : 0);
|
||||
|
||||
/* If we couldn't get the initial node, this user is in trouble. */
|
||||
if (!initial_node)
|
||||
@ -309,9 +352,9 @@ For more information about these matters, see the files named COPYING.\n"),
|
||||
if (info_recent_file_error)
|
||||
info_error (info_recent_file_error);
|
||||
else
|
||||
info_error
|
||||
(CANT_FIND_NODE, user_nodenames ? user_nodenames[0] : "Top");
|
||||
exit (1);
|
||||
info_error (msg_cant_find_node,
|
||||
user_nodenames ? user_nodenames[0] : "Top");
|
||||
xexit (1);
|
||||
}
|
||||
|
||||
/* Special cases for when the user specifies multiple nodes. If we
|
||||
@ -328,228 +371,112 @@ For more information about these matters, see the files named COPYING.\n"),
|
||||
else
|
||||
begin_multiple_window_info_session (user_filename, user_nodenames);
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
/* If the user specified `--index-search=STRING', start the info
|
||||
session in the node corresponding to the first match. */
|
||||
if (index_search_p)
|
||||
{
|
||||
int status = 0;
|
||||
|
||||
initialize_info_session (initial_node, 0);
|
||||
|
||||
if (index_entry_exists (windows, index_search_string))
|
||||
{
|
||||
terminal_clear_screen ();
|
||||
terminal_prep_terminal ();
|
||||
display_update_display (windows);
|
||||
info_last_executed_command = (VFunction *)NULL;
|
||||
|
||||
do_info_index_search (windows, 0, index_search_string);
|
||||
|
||||
info_read_and_dispatch ();
|
||||
|
||||
terminal_unprep_terminal ();
|
||||
|
||||
/* On program exit, leave the cursor at the bottom of the
|
||||
window, and restore the terminal IO. */
|
||||
terminal_goto_xy (0, screenheight - 1);
|
||||
terminal_clear_to_eol ();
|
||||
fflush (stdout);
|
||||
}
|
||||
else
|
||||
{
|
||||
fputs (_("no entries found\n"), stderr);
|
||||
status = 2;
|
||||
}
|
||||
|
||||
close_dribble_file ();
|
||||
exit (status);
|
||||
xexit (0);
|
||||
}
|
||||
|
||||
/* If there are arguments remaining, they are the names of menu items
|
||||
in sequential info files starting from the first one loaded. That
|
||||
file name is either "dir", or the contents of user_filename if one
|
||||
was specified. */
|
||||
while (optind != argc)
|
||||
{
|
||||
REFERENCE **menu;
|
||||
REFERENCE *entry;
|
||||
NODE *node;
|
||||
char *arg;
|
||||
static char *first_arg = (char *)NULL;
|
||||
{
|
||||
char *errstr, *errarg1, *errarg2;
|
||||
NODE *new_initial_node = info_follow_menus (initial_node, argv + optind,
|
||||
&errstr, &errarg1, &errarg2);
|
||||
if (new_initial_node && new_initial_node != initial_node)
|
||||
initial_node = new_initial_node;
|
||||
|
||||
/* Remember the name of the menu entry we want. */
|
||||
arg = argv[optind++];
|
||||
/* If the user specified that this node should be output, then do that
|
||||
now. Otherwise, start the Info session with this node. Or act
|
||||
accordingly if the initial node was not found. */
|
||||
if (user_output_filename)
|
||||
{
|
||||
if (!errstr)
|
||||
dump_node_to_file (initial_node, user_output_filename,
|
||||
dump_subnodes);
|
||||
else
|
||||
info_error (errstr, errarg1, errarg2);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if (!first_arg)
|
||||
first_arg = arg;
|
||||
if (errstr)
|
||||
begin_info_session_with_error (initial_node, errstr,
|
||||
errarg1, errarg2);
|
||||
/* If the user specified `--index-search=STRING' or
|
||||
--show-options, start the info session in the node
|
||||
corresponding to what they want. */
|
||||
else if (index_search_p || goto_invocation_p)
|
||||
{
|
||||
int status = 0;
|
||||
|
||||
/* Build and return a list of the menu items in this node. */
|
||||
menu = info_menu_of_node (initial_node);
|
||||
initialize_info_session (initial_node, 0);
|
||||
|
||||
/* If there wasn't a menu item in this node, stop here, but let
|
||||
the user continue to use Info. Perhaps they wanted this node
|
||||
and didn't realize it. */
|
||||
if (!menu)
|
||||
{
|
||||
#if defined (HANDLE_MAN_PAGES)
|
||||
if (first_arg == arg)
|
||||
{
|
||||
node = make_manpage_node (first_arg);
|
||||
if (node)
|
||||
goto maybe_got_node;
|
||||
}
|
||||
#endif /* HANDLE_MAN_PAGES */
|
||||
begin_info_session_with_error
|
||||
(initial_node, _("There is no menu in this node."));
|
||||
exit (0);
|
||||
}
|
||||
if (goto_invocation_p
|
||||
|| index_entry_exists (windows, index_search_string))
|
||||
{
|
||||
terminal_prep_terminal ();
|
||||
terminal_clear_screen ();
|
||||
info_last_executed_command = (VFunction *)NULL;
|
||||
|
||||
/* Find the specified menu item. */
|
||||
entry = info_get_labeled_reference (arg, menu);
|
||||
if (index_search_p)
|
||||
do_info_index_search (windows, 0, index_search_string);
|
||||
else
|
||||
{
|
||||
/* If they said "info --show-options foo bar baz",
|
||||
the last of the arguments is the program whose
|
||||
options they want to see. */
|
||||
char **p = argv + optind;
|
||||
char *program;
|
||||
|
||||
/* If the item wasn't found, search the list sloppily. Perhaps this
|
||||
user typed "buffer" when they really meant "Buffers". */
|
||||
if (!entry)
|
||||
{
|
||||
register int i;
|
||||
int best_guess = -1;
|
||||
if (*p)
|
||||
{
|
||||
while (p[1])
|
||||
p++;
|
||||
program = xstrdup (*p);
|
||||
}
|
||||
else if (user_filename)
|
||||
/* If there's no command-line arguments to
|
||||
supply the program name, use the Info file
|
||||
name (sans extension and leading directories)
|
||||
instead. */
|
||||
program = program_name_from_file_name (user_filename);
|
||||
else
|
||||
program = xstrdup ("");
|
||||
|
||||
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;
|
||||
}
|
||||
info_intuit_options_node (windows, initial_node, program);
|
||||
free (program);
|
||||
}
|
||||
|
||||
if (!entry && best_guess != -1)
|
||||
entry = menu[best_guess];
|
||||
}
|
||||
info_read_and_dispatch ();
|
||||
|
||||
/* If we failed to find the reference, start Info with the current
|
||||
node anyway. It is probably a misspelling. */
|
||||
if (!entry)
|
||||
{
|
||||
char *error_message = _("There is no menu item \"%s\" in this node.");
|
||||
/* 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);
|
||||
terminal_unprep_terminal ();
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (stderr, _("no index entries found for `%s'\n"),
|
||||
index_search_string);
|
||||
status = 2;
|
||||
}
|
||||
|
||||
#if defined (HANDLE_MAN_PAGES)
|
||||
if (first_arg == arg)
|
||||
{
|
||||
node = make_manpage_node (first_arg);
|
||||
if (node)
|
||||
goto maybe_got_node;
|
||||
}
|
||||
#endif /* HANDLE_MAN_PAGES */
|
||||
close_dribble_file ();
|
||||
xexit (status);
|
||||
}
|
||||
else
|
||||
begin_info_session (initial_node);
|
||||
}
|
||||
|
||||
info_free_references (menu);
|
||||
|
||||
/* If we were supposed to dump this node, complain. */
|
||||
if (user_output_filename)
|
||||
info_error (error_message, arg);
|
||||
else
|
||||
begin_info_session_with_error (initial_node, error_message, arg);
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
/* We have found the reference that the user specified. Clean it
|
||||
up a little bit. */
|
||||
if (!entry->filename)
|
||||
{
|
||||
if (initial_node->parent)
|
||||
entry->filename = xstrdup (initial_node->parent);
|
||||
else
|
||||
entry->filename = xstrdup (initial_node->filename);
|
||||
}
|
||||
|
||||
/* Find this node. If we can find it, then turn the initial_node
|
||||
into this one. If we cannot find it, try using the label of the
|
||||
entry as a file (i.e., "(LABEL)Top"). Otherwise the Info file is
|
||||
malformed in some way, and we will just use the current value of
|
||||
initial node. */
|
||||
node = info_get_node (entry->filename, entry->nodename);
|
||||
|
||||
#if defined (HANDLE_MAN_PAGES)
|
||||
if ((first_arg == arg) && !node)
|
||||
{
|
||||
node = make_manpage_node (first_arg);
|
||||
if (node)
|
||||
goto maybe_got_node;
|
||||
}
|
||||
#endif /* HANDLE_MAN_PAGES */
|
||||
|
||||
if (!node && entry->nodename &&
|
||||
(strcmp (entry->label, entry->nodename) == 0))
|
||||
node = info_get_node (entry->label, "Top");
|
||||
|
||||
maybe_got_node:
|
||||
if (node)
|
||||
{
|
||||
free (initial_node);
|
||||
initial_node = node;
|
||||
info_free_references (menu);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *temp = xstrdup (entry->label);
|
||||
char *error_message;
|
||||
|
||||
error_message = _("Unable to find the node referenced by \"%s\".");
|
||||
|
||||
info_free_references (menu);
|
||||
|
||||
/* If we were trying to dump the node, then give up. Otherwise,
|
||||
start the session with an error message. */
|
||||
if (user_output_filename)
|
||||
info_error (error_message, temp);
|
||||
else
|
||||
begin_info_session_with_error (initial_node, error_message, temp);
|
||||
|
||||
exit (0);
|
||||
}
|
||||
}
|
||||
|
||||
/* If the user specified that this node should be output, then do that
|
||||
now. Otherwise, start the Info session with this node. */
|
||||
if (user_output_filename)
|
||||
dump_node_to_file (initial_node, user_output_filename, dump_subnodes);
|
||||
else
|
||||
begin_info_session (initial_node);
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
/* Return a string describing the current version of Info. */
|
||||
char *
|
||||
version_string ()
|
||||
{
|
||||
static char *vstring = (char *)NULL;
|
||||
|
||||
if (!vstring)
|
||||
{
|
||||
vstring = (char *)xmalloc (50);
|
||||
sprintf (vstring, "%d.%d", info_major_version, info_minor_version);
|
||||
}
|
||||
return (vstring);
|
||||
xexit (0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Error handling. */
|
||||
|
||||
static void
|
||||
remember_info_program_name (fullpath)
|
||||
char *fullpath;
|
||||
{
|
||||
char *filename;
|
||||
|
||||
filename = filename_non_directory (fullpath);
|
||||
program_name = xstrdup (filename);
|
||||
}
|
||||
|
||||
/* Non-zero if an error has been signalled. */
|
||||
int info_error_was_printed = 0;
|
||||
|
||||
@ -595,33 +522,99 @@ info_error (format, arg1, arg2)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Produce a scaled down description of the available options to Info. */
|
||||
static void
|
||||
info_short_help ()
|
||||
{
|
||||
printf (_("\
|
||||
Usage: %s [OPTION]... [INFO-FILE [MENU-ITEM...]]\n\
|
||||
Usage: %s [OPTION]... [MENU-ITEM...]\n\
|
||||
\n\
|
||||
Read documentation in Info format.\n\
|
||||
For more complete documentation on how to use Info, run `info info options'.\n\
|
||||
\n\
|
||||
Options:\n\
|
||||
--directory DIR add DIR to INFOPATH.\n\
|
||||
--dribble FILENAME remember user keystrokes in FILENAME.\n\
|
||||
--file FILENAME specify Info file to visit.\n\
|
||||
--node NODENAME specify nodes in first visited Info file.\n\
|
||||
--output FILENAME output selected nodes to FILENAME.\n\
|
||||
--restore FILENAME read initial keystrokes from FILENAME.\n\
|
||||
--subnodes recursively output menu items.\n\
|
||||
--help display this help and exit.\n\
|
||||
--version display version information and exit.\n\
|
||||
--apropos=SUBJECT look up SUBJECT in all indices of all manuals.\n\
|
||||
--directory=DIR add DIR to INFOPATH.\n\
|
||||
--dribble=FILENAME remember user keystrokes in FILENAME.\n\
|
||||
--file=FILENAME specify Info file to visit.\n\
|
||||
--help display this help and exit.\n\
|
||||
--index-search=STRING go to node pointed by index entry STRING.\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\
|
||||
--show-options, --usage go to command-line options node.\n\
|
||||
--subnodes recursively output menu items.\n%s\
|
||||
--vi-keys use vi-like and less-like key bindings.\n\
|
||||
--version display version information and exit.\n\
|
||||
\n\
|
||||
The first argument, if present, is the name of the Info file to read.\n\
|
||||
The first non-option argument, if present, is the menu entry to start from;\n\
|
||||
it is searched for in all `dir' files along INFOPATH.\n\
|
||||
If it is not present, info merges all `dir' files and shows the result.\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\
|
||||
items relative to the initial node visited.\n\
|
||||
\n\
|
||||
Email bug reports to bug-texinfo@gnu.org."), program_name);
|
||||
Examples:\n\
|
||||
info show top-level dir menu\n\
|
||||
info emacs start at emacs node from top-level dir\n\
|
||||
info emacs buffers start at buffers node within emacs manual\n\
|
||||
info --show-options emacs start at node with emacs' command line options\n\
|
||||
info -f ./foo.info show file ./foo.info, not searching dir\n\
|
||||
\n\
|
||||
Email bug reports to bug-texinfo@gnu.org,\n\
|
||||
general questions and discussion to help-texinfo@gnu.org.\n\
|
||||
"),
|
||||
program_name,
|
||||
#ifdef __MSDOS__
|
||||
"\
|
||||
--speech-friendly be friendly to speech synthesizers.\n"
|
||||
#else
|
||||
""
|
||||
#endif
|
||||
);
|
||||
|
||||
exit (0);
|
||||
xexit (0);
|
||||
}
|
||||
|
||||
|
||||
/* Initialize strings for gettext. Because gettext doesn't handle N_ or
|
||||
_ within macro definitions, we put shared messages into variables and
|
||||
use them that way. This also has the advantage that there's only one
|
||||
copy of the strings. */
|
||||
|
||||
char *msg_cant_find_node;
|
||||
char *msg_cant_file_node;
|
||||
char *msg_cant_find_window;
|
||||
char *msg_cant_find_point;
|
||||
char *msg_cant_kill_last;
|
||||
char *msg_no_menu_node;
|
||||
char *msg_no_foot_node;
|
||||
char *msg_no_xref_node;
|
||||
char *msg_no_pointer;
|
||||
char *msg_unknown_command;
|
||||
char *msg_term_too_dumb;
|
||||
char *msg_at_node_bottom;
|
||||
char *msg_at_node_top;
|
||||
char *msg_one_window;
|
||||
char *msg_win_too_small;
|
||||
char *msg_cant_make_help;
|
||||
|
||||
static void
|
||||
init_messages ()
|
||||
{
|
||||
msg_cant_find_node = _("Cannot find node `%s'.");
|
||||
msg_cant_file_node = _("Cannot find node `(%s)%s'.");
|
||||
msg_cant_find_window = _("Cannot find a window!");
|
||||
msg_cant_find_point = _("Point doesn't appear within this window's node!");
|
||||
msg_cant_kill_last = _("Cannot delete the last window.");
|
||||
msg_no_menu_node = _("No menu in this node.");
|
||||
msg_no_foot_node = _("No footnotes in this node.");
|
||||
msg_no_xref_node = _("No cross references in this node.");
|
||||
msg_no_pointer = _("No `%s' pointer for this node.");
|
||||
msg_unknown_command = _("Unknown Info command `%c'; try `?' for help.");
|
||||
msg_term_too_dumb = _("Terminal type `%s' is not smart enough to run Info.");
|
||||
msg_at_node_bottom = _("You are already at the last page of this node.");
|
||||
msg_at_node_top = _("You are already at the first page of this node.");
|
||||
msg_one_window = _("Only one window.");
|
||||
msg_win_too_small = _("Resulting window would be too small.");
|
||||
msg_cant_make_help = _("Not enough room for a help window, please delete a window.");
|
||||
}
|
||||
|
@ -1,10 +1,7 @@
|
||||
/* 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 $
|
||||
$Id: info.h,v 1.14 1999/09/25 16:10:04 karl Exp $
|
||||
|
||||
This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993, 97, 98 Free Software Foundation, Inc.
|
||||
Copyright (C) 1993, 97, 98, 99 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,7 +19,7 @@
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#if !defined (INFO_H)
|
||||
#ifndef INFO_H
|
||||
#define INFO_H
|
||||
|
||||
/* We always want these, so why clutter up the compile command? */
|
||||
@ -119,6 +116,9 @@ extern int info_error_was_printed;
|
||||
/* Non-zero means ring terminal bell on errors. */
|
||||
extern int info_error_rings_bell_p;
|
||||
|
||||
/* Non-zero means default keybindings are loosely modeled on vi(1). */
|
||||
extern int vi_keys_p;
|
||||
|
||||
/* Print FORMAT with ARG1 and ARG2. If the window system was initialized,
|
||||
then the message is printed in the echo area. Otherwise, a message is
|
||||
output to stderr. */
|
||||
@ -127,28 +127,23 @@ extern void info_error ();
|
||||
/* The version numbers of Info. */
|
||||
extern int info_major_version, info_minor_version;
|
||||
|
||||
/* How to get the version string for this version of Info. Returns
|
||||
something similar to "2.11". */
|
||||
extern char *version_string ();
|
||||
|
||||
/* Error message defines. */
|
||||
#define CANT_FIND_NODE _("Cannot find the node \"%s\".")
|
||||
#define CANT_FILE_NODE _("Cannot find the node \"(%s)%s\".")
|
||||
#define CANT_FIND_WIND _("Cannot find a window!")
|
||||
#define CANT_FIND_POINT _("Point doesn't appear within this window's node!")
|
||||
#define CANT_KILL_LAST _("Cannot delete the last window.")
|
||||
#define NO_MENU_NODE _("No menu in this node.")
|
||||
#define NO_FOOT_NODE _("No footnotes in this node.")
|
||||
#define NO_XREF_NODE _("No cross references in this node.")
|
||||
#define NO_POINTER _("No \"%s\" pointer for this node.")
|
||||
#define UNKNOWN_COMMAND _("Unknown Info command `%c'. `?' for help.")
|
||||
#define TERM_TOO_DUMB _("Terminal type \"%s\" is not smart enough to run Info.")
|
||||
#define AT_NODE_BOTTOM _("You are already at the last page of this node.")
|
||||
#define AT_NODE_TOP _("You are already at the first page of this node.")
|
||||
#define ONE_WINDOW _("Only one window.")
|
||||
#define WIN_TOO_SMALL _("Resulting window would be too small.")
|
||||
#define CANT_MAKE_HELP \
|
||||
_("There isn't enough room to make a help window. Please delete a window.")
|
||||
extern char *msg_cant_find_node;
|
||||
extern char *msg_cant_file_node;
|
||||
extern char *msg_cant_find_window;
|
||||
extern char *msg_cant_find_point;
|
||||
extern char *msg_cant_kill_last;
|
||||
extern char *msg_no_menu_node;
|
||||
extern char *msg_no_foot_node;
|
||||
extern char *msg_no_xref_node;
|
||||
extern char *msg_no_pointer;
|
||||
extern char *msg_unknown_command;
|
||||
extern char *msg_term_too_dumb;
|
||||
extern char *msg_at_node_bottom;
|
||||
extern char *msg_at_node_top;
|
||||
extern char *msg_one_window;
|
||||
extern char *msg_win_too_small;
|
||||
extern char *msg_cant_make_help;
|
||||
|
||||
|
||||
/* Found in info-utils.c. */
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* infodoc.c -- Functions which build documentation nodes.
|
||||
$Id: infodoc.c,v 1.4 1997/07/25 21:08:40 karl Exp $
|
||||
$Id: infodoc.c,v 1.23 1999/09/25 16:10:04 karl Exp $
|
||||
|
||||
Copyright (C) 1993, 97 Free Software Foundation, Inc.
|
||||
Copyright (C) 1993, 97, 98, 99 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,14 +21,9 @@
|
||||
|
||||
#include "info.h"
|
||||
|
||||
/* Normally we do not define HELP_NODE_GETS_REGENERATED because the
|
||||
contents of the help node currently can never change once an info
|
||||
session has been started. You should consider defining this in
|
||||
the case that you place information about dynamic variables in the
|
||||
help text. When that happens, the contents of the help node will
|
||||
change dependent on the value of those variables, and the user will
|
||||
expect to see those changes. */
|
||||
/* #define HELP_NODE_GETS_REGENERATED 1 */
|
||||
/* HELP_NODE_GETS_REGENERATED is always defined now that keys may get
|
||||
rebound, or other changes in the help text may occur. */
|
||||
#define HELP_NODE_GETS_REGENERATED 1
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
@ -47,40 +42,94 @@ static char *internal_info_help_node_contents = (char *)NULL;
|
||||
|
||||
/* The static text which appears in the internal info help node. */
|
||||
static char *info_internal_help_text[] = {
|
||||
N_ ("Basic Commands in Info Windows"),
|
||||
"******************************",
|
||||
"",
|
||||
" h Invoke the Info tutorial.",
|
||||
" CTRL-x 0 Quit this help.",
|
||||
" q Quit Info altogether.",
|
||||
"",
|
||||
"Selecting other nodes:",
|
||||
"----------------------",
|
||||
" n Move to the \"next\" node of this node.",
|
||||
" p Move to the \"previous\" node of this node.",
|
||||
" u Move \"up\" from this node.",
|
||||
" m Pick menu item specified by name.",
|
||||
" Picking a menu item causes another node to be selected.",
|
||||
" f Follow a cross reference. Reads name of reference.",
|
||||
" l Move to the last node seen in this window.",
|
||||
" d Move to the `directory' node. Equivalent to `g(DIR)'.",
|
||||
"",
|
||||
"Moving within a node:",
|
||||
"---------------------",
|
||||
" SPC Scroll forward a page.",
|
||||
" DEL Scroll backward a page.",
|
||||
" b Go to the beginning of this node.",
|
||||
" e Go to the end of this node.",
|
||||
"",
|
||||
"Other commands:",
|
||||
"--------------------",
|
||||
" 1 Pick first item in node's menu.",
|
||||
" 2-9 Pick second ... ninth item in node's menu.",
|
||||
" 0 Pick last item in node's menu.",
|
||||
" g Move to node specified by name.",
|
||||
" You may include a filename as well, as in (FILENAME)NODENAME.",
|
||||
" s Search through this Info file for a specified string,",
|
||||
" and select the node in which the next occurrence is found.",
|
||||
N_("Basic Commands in Info Windows\n"),
|
||||
N_("******************************\n"),
|
||||
"\n",
|
||||
N_(" %-10s Quit this help.\n"),
|
||||
N_(" %-10s Quit Info altogether.\n"),
|
||||
N_(" %-10s Invoke the Info tutorial.\n"),
|
||||
"\n",
|
||||
N_("Moving within a node:\n"),
|
||||
N_("---------------------\n"),
|
||||
N_(" %-10s Scroll forward a page.\n"),
|
||||
N_(" %-10s Scroll backward a page.\n"),
|
||||
N_(" %-10s Go to the beginning of this node.\n"),
|
||||
N_(" %-10s Go to the end of this node.\n"),
|
||||
N_(" %-10s Scroll forward 1 line.\n"),
|
||||
N_(" %-10s Scroll backward 1 line.\n"),
|
||||
"\n",
|
||||
N_("Selecting other nodes:\n"),
|
||||
N_("----------------------\n"),
|
||||
N_(" %-10s Move to the `next' node of this node.\n"),
|
||||
N_(" %-10s Move to the `previous' node of this node.\n"),
|
||||
N_(" %-10s Move `up' from this node.\n"),
|
||||
N_(" %-10s Pick menu item specified by name.\n"),
|
||||
N_(" Picking a menu item causes another node to be selected.\n"),
|
||||
N_(" %-10s Follow a cross reference. Reads name of reference.\n"),
|
||||
N_(" %-10s Move to the last node seen in this window.\n"),
|
||||
N_(" %-10s Skip to next hypertext link within this node.\n"),
|
||||
N_(" %-10s Follow the hypertext link under cursor.\n"),
|
||||
N_(" %-10s Move to the `directory' node. Equivalent to `g (DIR)'.\n"),
|
||||
N_(" %-10s Move to the Top node. Equivalent to `g Top'.\n"),
|
||||
"\n",
|
||||
N_("Other commands:\n"),
|
||||
N_("---------------\n"),
|
||||
N_(" %-10s Pick first ... ninth item in node's menu.\n"),
|
||||
N_(" %-10s Pick last item in node's menu.\n"),
|
||||
N_(" %-10s Search for a specified string in the index entries of this Info\n"),
|
||||
N_(" file, and select the node referenced by the first entry found.\n"),
|
||||
N_(" %-10s Move to node specified by name.\n"),
|
||||
N_(" You may include a filename as well, as in (FILENAME)NODENAME.\n"),
|
||||
N_(" %-10s Search forward through this Info file for a specified string,\n"),
|
||||
N_(" and select the node in which the next occurrence is found.\n"),
|
||||
N_(" %-10s Search backward in this Info file for a specified string,\n"),
|
||||
N_(" and select the node in which the next occurrence is found.\n"),
|
||||
NULL
|
||||
};
|
||||
|
||||
static char *info_help_keys_text[][2] = {
|
||||
{ "", "" },
|
||||
{ "", "" },
|
||||
{ "", "" },
|
||||
{ "CTRL-x 0", "CTRL-x 0" },
|
||||
{ "q", "q" },
|
||||
{ "h", "ESC h" },
|
||||
{ "", "" },
|
||||
{ "", "" },
|
||||
{ "", "" },
|
||||
{ "SPC", "SPC" },
|
||||
{ "DEL", "b" },
|
||||
{ "b", "ESC b" },
|
||||
{ "e", "ESC e" },
|
||||
{ "ESC 1 SPC", "RET" },
|
||||
{ "ESC 1 DEL", "y" },
|
||||
{ "", "" },
|
||||
{ "", "" },
|
||||
{ "", "" },
|
||||
{ "n", "CTRL-x n" },
|
||||
{ "p", "CTRL-x p" },
|
||||
{ "u", "CTRL-x u" },
|
||||
{ "m", "ESC m" },
|
||||
{ "", "" },
|
||||
{ "f", "ESC f" },
|
||||
{ "l", "l" },
|
||||
{ "TAB", "TAB" },
|
||||
{ "RET", "CTRL-x RET" },
|
||||
{ "d", "ESC d" },
|
||||
{ "t", "ESC t" },
|
||||
{ "", "" },
|
||||
{ "", "" },
|
||||
{ "", "" },
|
||||
{ "1-9", "ESC 1-9" },
|
||||
{ "0", "ESC 0" },
|
||||
{ "i", "CTRL-x i" },
|
||||
{ "", "" },
|
||||
{ "g", "CTRL-x g" },
|
||||
{ "", "" },
|
||||
{ "s", "/" },
|
||||
{ "", "" },
|
||||
{ "ESC - s", "?" },
|
||||
{ "", "" },
|
||||
NULL
|
||||
};
|
||||
|
||||
@ -163,15 +212,21 @@ dump_map_to_message_buffer (prefix, map)
|
||||
}
|
||||
}
|
||||
|
||||
/* How to create internal_info_help_node. */
|
||||
/* How to create internal_info_help_node. HELP_IS_ONLY_WINDOW_P says
|
||||
whether we're going to end up in a second (or more) window of our
|
||||
own, or whether there's only one window and we're going to usurp it.
|
||||
This determines how to quit the help window. Maybe we should just
|
||||
make q do the right thing in both cases. */
|
||||
|
||||
static void
|
||||
create_internal_info_help_node ()
|
||||
create_internal_info_help_node (help_is_only_window_p)
|
||||
int help_is_only_window_p;
|
||||
{
|
||||
register int i;
|
||||
char *contents = (char *)NULL;
|
||||
NODE *node;
|
||||
char *contents = NULL;
|
||||
|
||||
#if !defined (HELP_NODE_GETS_REGENERATED)
|
||||
#ifndef HELP_NODE_GETS_REGENERATED
|
||||
if (internal_info_help_node_contents)
|
||||
contents = internal_info_help_node_contents;
|
||||
#endif /* !HELP_NODE_GETS_REGENERATED */
|
||||
@ -183,16 +238,30 @@ 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]);
|
||||
{
|
||||
/* Don't translate blank lines, gettext outputs the po file
|
||||
header in that case. We want a blank line. */
|
||||
char *msg = *(info_internal_help_text[i])
|
||||
? _(info_internal_help_text[i])
|
||||
: info_internal_help_text[i];
|
||||
char *key = info_help_keys_text[i][vi_keys_p];
|
||||
|
||||
/* If we have only one window (because the window size was too
|
||||
small to split it), CTRL-x 0 doesn't work to `quit' help. */
|
||||
if (STREQ (key, "CTRL-x 0") && help_is_only_window_p)
|
||||
key = "l";
|
||||
|
||||
printf_to_message_buffer (msg, key);
|
||||
}
|
||||
|
||||
printf_to_message_buffer ("---------------------\n\n");
|
||||
printf_to_message_buffer ("The current search path is:\n");
|
||||
printf_to_message_buffer (" \"%s\"\n", infopath);
|
||||
printf_to_message_buffer (_("The current search path is:\n"));
|
||||
printf_to_message_buffer (" %s\n", infopath);
|
||||
printf_to_message_buffer ("---------------------\n\n");
|
||||
printf_to_message_buffer ("Commands available in Info windows:\n\n");
|
||||
printf_to_message_buffer (_("Commands available in Info windows:\n\n"));
|
||||
dump_map_to_message_buffer ("", info_keymap);
|
||||
printf_to_message_buffer ("---------------------\n\n");
|
||||
printf_to_message_buffer ("Commands available in the echo area:\n\n");
|
||||
printf_to_message_buffer (_("Commands available in the echo area:\n\n"));
|
||||
dump_map_to_message_buffer ("", echo_area_keymap);
|
||||
|
||||
#if defined (NAMED_FUNCTIONS)
|
||||
@ -215,7 +284,11 @@ create_internal_info_help_node ()
|
||||
printf_to_message_buffer
|
||||
("M-x %s\n %s\n",
|
||||
function_doc_array[i].func_name,
|
||||
replace_in_documentation (function_doc_array[i].doc));
|
||||
replace_in_documentation (strlen (function_doc_array[i].doc)
|
||||
== 0
|
||||
? function_doc_array[i].doc
|
||||
: _(function_doc_array[i].doc)));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -258,17 +331,22 @@ create_internal_info_help_node ()
|
||||
}
|
||||
|
||||
/* Return a window which is the window showing help in this Info. */
|
||||
|
||||
/* If the eligible window's height is >= this, split it to make the help
|
||||
window. Otherwise display the help window in the current window. */
|
||||
#define HELP_SPLIT_SIZE 24
|
||||
|
||||
static WINDOW *
|
||||
info_find_or_create_help_window ()
|
||||
{
|
||||
WINDOW *help_window, *eligible, *window;
|
||||
|
||||
eligible = (WINDOW *)NULL;
|
||||
help_window = get_internal_info_window (info_help_nodename);
|
||||
int help_is_only_window_p;
|
||||
WINDOW *eligible = NULL;
|
||||
WINDOW *help_window = get_window_of_node (internal_info_help_node);
|
||||
|
||||
/* If we couldn't find the help window, then make it. */
|
||||
if (!help_window)
|
||||
{
|
||||
WINDOW *window;
|
||||
int max = 0;
|
||||
|
||||
for (window = windows; window; window = window->next)
|
||||
@ -281,23 +359,29 @@ info_find_or_create_help_window ()
|
||||
}
|
||||
|
||||
if (!eligible)
|
||||
return ((WINDOW *)NULL);
|
||||
return NULL;
|
||||
}
|
||||
#if !defined (HELP_NODE_GETS_REGENERATED)
|
||||
#ifndef HELP_NODE_GETS_REGENERATED
|
||||
else
|
||||
return (help_window);
|
||||
#endif /* !HELP_NODE_GETS_REGENERATED */
|
||||
/* help window is static, just return it. */
|
||||
return help_window;
|
||||
#endif /* not HELP_NODE_GETS_REGENERATED */
|
||||
|
||||
/* Make sure that we have a node containing the help text. */
|
||||
create_internal_info_help_node ();
|
||||
/* Make sure that we have a node containing the help text. The
|
||||
argument is false if help will be the only window (so l must be used
|
||||
to quit help), true if help will be one of several visible windows
|
||||
(so CTRL-x 0 must be used to quit help). */
|
||||
help_is_only_window_p
|
||||
= (help_window && !windows->next
|
||||
|| !help_window && eligible->height < HELP_SPLIT_SIZE);
|
||||
create_internal_info_help_node (help_is_only_window_p);
|
||||
|
||||
/* Either use the existing window to display the help node, or create
|
||||
a new window if there was no existing help window. */
|
||||
if (!help_window)
|
||||
{
|
||||
/* Split the largest window into 2 windows, and show the help text
|
||||
{ /* Split the largest window into 2 windows, and show the help text
|
||||
in that window. */
|
||||
if (eligible->height > 30)
|
||||
if (eligible->height >= HELP_SPLIT_SIZE)
|
||||
{
|
||||
active_window = eligible;
|
||||
help_window = window_make_window (internal_info_help_node);
|
||||
@ -310,8 +394,7 @@ info_find_or_create_help_window ()
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Case where help node always gets regenerated, and we have an
|
||||
{ /* Case where help node always gets regenerated, and we have an
|
||||
existing window in which to place the node. */
|
||||
if (active_window != help_window)
|
||||
{
|
||||
@ -321,7 +404,7 @@ info_find_or_create_help_window ()
|
||||
window_set_node_of_window (active_window, internal_info_help_node);
|
||||
}
|
||||
remember_window_and_node (help_window, help_window->node);
|
||||
return (help_window);
|
||||
return help_window;
|
||||
}
|
||||
|
||||
/* Create or move to the help window. */
|
||||
@ -337,7 +420,7 @@ DECLARE_INFO_COMMAND (info_get_help_window, _("Display help message"))
|
||||
}
|
||||
else
|
||||
{
|
||||
info_error (CANT_MAKE_HELP);
|
||||
info_error (msg_cant_make_help);
|
||||
}
|
||||
}
|
||||
|
||||
@ -381,7 +464,7 @@ DECLARE_INFO_COMMAND (info_get_info_help_node, _("Visit Info node `(info)Help'")
|
||||
if (info_recent_file_error)
|
||||
info_error (info_recent_file_error);
|
||||
else
|
||||
info_error (CANT_FILE_NODE, "Info", nodename);
|
||||
info_error (msg_cant_file_node, "Info", nodename);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -418,7 +501,9 @@ function_documentation (function)
|
||||
if (function == function_doc_array[i].func)
|
||||
break;
|
||||
|
||||
return (replace_in_documentation (function_doc_array[i].doc));
|
||||
return replace_in_documentation ((strlen (function_doc_array[i].doc) == 0)
|
||||
? function_doc_array[i].doc
|
||||
: _(function_doc_array[i].doc));
|
||||
}
|
||||
|
||||
#if defined (NAMED_FUNCTIONS)
|
||||
@ -475,21 +560,21 @@ DECLARE_INFO_COMMAND (describe_key, _("Print documentation for KEY"))
|
||||
char *rep;
|
||||
Keymap map;
|
||||
|
||||
keyname[0] = '\0';
|
||||
keyname[0] = 0;
|
||||
map = window->keymap;
|
||||
|
||||
while (1)
|
||||
for (;;)
|
||||
{
|
||||
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 (Meta_p (keystroke))
|
||||
{
|
||||
if (map[ESC].type != ISKMAP)
|
||||
{
|
||||
window_message_in_echo_area
|
||||
(_("ESC %s is undefined."), pretty_keyname (UnMeta (keystroke)));
|
||||
(_("ESC %s is undefined."), pretty_keyname (UnMeta (keystroke)));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -627,7 +712,7 @@ replace_in_documentation (string)
|
||||
/* 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
|
||||
/* 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)
|
||||
@ -687,7 +772,7 @@ where_is_internal (map, function)
|
||||
VFunction *function;
|
||||
{
|
||||
register int i;
|
||||
|
||||
|
||||
/* If the function is directly invokable in MAP, return the representation
|
||||
of that keystroke. */
|
||||
for (i = 0; i < 256; i++)
|
||||
@ -718,13 +803,13 @@ where_is_internal (map, function)
|
||||
}
|
||||
}
|
||||
|
||||
return ((char *)NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
extern char *read_function_name ();
|
||||
|
||||
DECLARE_INFO_COMMAND (info_where_is,
|
||||
"Show what to type to execute a given command")
|
||||
_("Show what to type to execute a given command"))
|
||||
{
|
||||
char *command_name;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* infomap.c -- Keymaps for Info.
|
||||
$Id: infomap.c,v 1.7 1997/07/31 20:37:32 karl Exp $
|
||||
$Id: infomap.c,v 1.20 1999/06/25 21:57:40 karl Exp $
|
||||
|
||||
Copyright (C) 1993, 97 Free Software Foundation, Inc.
|
||||
Copyright (C) 1993, 97, 98, 99 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
|
||||
@ -67,7 +67,7 @@ keymap_copy_keymap (map)
|
||||
return (keymap);
|
||||
}
|
||||
|
||||
/* Free the keymap and it's descendents. */
|
||||
/* Free the keymap and its descendants. */
|
||||
void
|
||||
keymap_discard_keymap (map)
|
||||
Keymap (map);
|
||||
@ -141,49 +141,54 @@ keymap_bind_keyseq (map, keyseq, keyentry)
|
||||
|
||||
/* Initialize the standard info keymaps. */
|
||||
|
||||
Keymap info_keymap = (Keymap)NULL;
|
||||
Keymap echo_area_keymap = (Keymap)NULL;
|
||||
Keymap info_keymap = NULL;
|
||||
Keymap echo_area_keymap = NULL;
|
||||
|
||||
void
|
||||
initialize_info_keymaps ()
|
||||
static void
|
||||
initialize_emacs_like_keymaps ()
|
||||
{
|
||||
register int i;
|
||||
int i;
|
||||
Keymap map;
|
||||
|
||||
if (!info_keymap)
|
||||
{
|
||||
info_keymap = keymap_make_keymap ();
|
||||
info_keymap[ESC].type = ISKMAP;
|
||||
info_keymap[ESC].function = (VFunction *)keymap_make_keymap ();
|
||||
info_keymap[Control ('x')].type = ISKMAP;
|
||||
info_keymap[Control ('x')].function = (VFunction *)keymap_make_keymap ();
|
||||
echo_area_keymap = keymap_make_keymap ();
|
||||
echo_area_keymap[ESC].type = ISKMAP;
|
||||
echo_area_keymap[ESC].function = (VFunction *)keymap_make_keymap ();
|
||||
echo_area_keymap[Control ('x')].type = ISKMAP;
|
||||
echo_area_keymap[Control ('x')].function =
|
||||
(VFunction *)keymap_make_keymap ();
|
||||
}
|
||||
|
||||
info_keymap[ESC].type = ISKMAP;
|
||||
info_keymap[ESC].function = (VFunction *)keymap_make_keymap ();
|
||||
info_keymap[Control ('x')].type = ISKMAP;
|
||||
info_keymap[Control ('x')].function = (VFunction *)keymap_make_keymap ();
|
||||
|
||||
/* Bind the echo area insert routines. Let's make all characters
|
||||
insertable by default, regardless of which character set we might
|
||||
be using. */
|
||||
for (i = 0; i < 256; i++)
|
||||
echo_area_keymap[i].function = ea_insert;
|
||||
|
||||
echo_area_keymap[ESC].type = ISKMAP;
|
||||
echo_area_keymap[ESC].function = (VFunction *) keymap_make_keymap ();
|
||||
echo_area_keymap[Control ('x')].type = ISKMAP;
|
||||
echo_area_keymap[Control ('x')].function
|
||||
= (VFunction *) keymap_make_keymap ();
|
||||
|
||||
/* Bind numeric arg functions for both echo area and info window maps. */
|
||||
for (i = '0'; i < '9' + 1; i++)
|
||||
{
|
||||
((Keymap) info_keymap[ESC].function)[i].function =
|
||||
((Keymap) echo_area_keymap[ESC].function)[i].function =
|
||||
info_add_digit_to_numeric_arg;
|
||||
((Keymap) info_keymap[ESC].function)[i].function
|
||||
= ((Keymap) echo_area_keymap[ESC].function)[i].function
|
||||
= info_add_digit_to_numeric_arg;
|
||||
}
|
||||
((Keymap) info_keymap[ESC].function)['-'].function =
|
||||
((Keymap) echo_area_keymap[ESC].function)['-'].function =
|
||||
info_add_digit_to_numeric_arg;
|
||||
|
||||
info_keymap['-'].function = info_add_digit_to_numeric_arg;
|
||||
|
||||
/* Bind the echo area routines. */
|
||||
map = echo_area_keymap;
|
||||
|
||||
/* Bind the echo area insert routines. */
|
||||
for (i = 0; i < 160; i++)
|
||||
if (isprint (i))
|
||||
map[i].function = ea_insert;
|
||||
|
||||
map[Control ('a')].function = ea_beg_of_line;
|
||||
map[Control ('b')].function = ea_backward;
|
||||
map[Control ('d')].function = ea_delete;
|
||||
@ -203,7 +208,12 @@ initialize_info_keymaps ()
|
||||
map[SPC].function = ea_complete;
|
||||
map[TAB].function = ea_complete;
|
||||
map['?'].function = ea_possible_completions;
|
||||
#ifdef __MSDOS__
|
||||
/* PC users will lynch me if I don't give them their usual DEL effect... */
|
||||
map[DEL].function = ea_delete;
|
||||
#else
|
||||
map[DEL].function = ea_rubout;
|
||||
#endif
|
||||
|
||||
/* Bind the echo area ESC keymap. */
|
||||
map = (Keymap)echo_area_keymap[ESC].function;
|
||||
@ -272,6 +282,7 @@ initialize_info_keymaps ()
|
||||
map[Control ('u')].function = info_universal_argument;
|
||||
map[Control ('v')].function = info_scroll_forward;
|
||||
map[','].function = info_next_index_match;
|
||||
map['/'].function = info_search;
|
||||
|
||||
for (i = '1'; i < '9' + 1; i++)
|
||||
map[i].function = info_menu_digit;
|
||||
@ -288,15 +299,19 @@ initialize_info_keymaps ()
|
||||
map['e'].function = info_end_of_node;
|
||||
map['f'].function = info_xref_item;
|
||||
map['g'].function = info_goto_node;
|
||||
map['G'].function = info_menu_sequence;
|
||||
map['h'].function = info_get_info_help_node;
|
||||
map['i'].function = info_index_search;
|
||||
map['I'].function = info_goto_invocation_node;
|
||||
map['l'].function = info_history_node;
|
||||
map['m'].function = info_menu_item;
|
||||
map['n'].function = info_next_node;
|
||||
map['O'].function = info_goto_invocation_node;
|
||||
map['p'].function = info_prev_node;
|
||||
map['q'].function = info_quit;
|
||||
map['r'].function = info_xref_item;
|
||||
map['s'].function = info_search;
|
||||
map['S'].function = info_search_case_sensitively;
|
||||
map['t'].function = info_top_node;
|
||||
map['u'].function = info_up_node;
|
||||
map[DEL].function = info_scroll_backward;
|
||||
@ -316,6 +331,7 @@ initialize_info_keymaps ()
|
||||
#if defined (NAMED_FUNCTIONS)
|
||||
map['x'].function = info_execute_command;
|
||||
#endif /* NAMED_FUNCTIONS */
|
||||
map[DEL].function = info_scroll_other_window_backward;
|
||||
|
||||
/* Bind members in the Control-X map for Info windows. */
|
||||
map = (Keymap)info_keymap[Control ('x')].function;
|
||||
@ -331,6 +347,8 @@ initialize_info_keymaps ()
|
||||
map['^'].function = info_grow_window;
|
||||
map['b'].function = select_visited_node;
|
||||
map['k'].function = info_kill_node;
|
||||
map['n'].function = info_search_next;
|
||||
map['N'].function = info_search_previous;
|
||||
map['o'].function = info_next_window;
|
||||
map['t'].function = info_tile_windows;
|
||||
map['w'].function = info_toggle_wrap;
|
||||
@ -359,6 +377,7 @@ initialize_info_keymaps ()
|
||||
keymap_bind_keyseq (map, "\033OB", &map['f']);
|
||||
keymap_bind_keyseq (map, "\033[B", &map['f']);
|
||||
keymap_bind_keyseq (map, term_kN, &map[Control ('v')]); /* pagedown */
|
||||
keymap_bind_keyseq (map, term_kP, &map[DEL]); /* pageup */
|
||||
|
||||
/* The alternative to this definition of a `main map' key in the
|
||||
`ESC map' section, is something like:
|
||||
@ -366,3 +385,297 @@ initialize_info_keymaps ()
|
||||
*/
|
||||
keymap_bind_keyseq (info_keymap/*sic*/, term_kP, &map['v']); /* pageup */
|
||||
}
|
||||
|
||||
static void
|
||||
initialize_vi_like_keymaps ()
|
||||
{
|
||||
register int i;
|
||||
Keymap map;
|
||||
|
||||
if (!info_keymap)
|
||||
{
|
||||
info_keymap = keymap_make_keymap ();
|
||||
echo_area_keymap = keymap_make_keymap ();
|
||||
}
|
||||
|
||||
info_keymap[ESC].type = ISKMAP;
|
||||
info_keymap[ESC].function = (VFunction *)keymap_make_keymap ();
|
||||
info_keymap[Control ('x')].type = ISKMAP;
|
||||
info_keymap[Control ('x')].function = (VFunction *)keymap_make_keymap ();
|
||||
|
||||
/* Bind the echo area insert routines. */
|
||||
for (i = 0; i < 256; i++)
|
||||
echo_area_keymap[i].function = ea_insert;
|
||||
|
||||
echo_area_keymap[ESC].type = ISKMAP;
|
||||
echo_area_keymap[ESC].function = (VFunction *)keymap_make_keymap ();
|
||||
echo_area_keymap[Control ('x')].type = ISKMAP;
|
||||
echo_area_keymap[Control ('x')].function =
|
||||
(VFunction *)keymap_make_keymap ();
|
||||
|
||||
/* Bind numeric arg functions for both echo area and info window maps. */
|
||||
for (i = '0'; i < '9' + 1; i++)
|
||||
{
|
||||
info_keymap[i].function =
|
||||
((Keymap) echo_area_keymap[ESC].function)[i].function =
|
||||
info_add_digit_to_numeric_arg;
|
||||
}
|
||||
info_keymap['-'].function =
|
||||
((Keymap) echo_area_keymap[ESC].function)['-'].function =
|
||||
info_add_digit_to_numeric_arg;
|
||||
|
||||
/* Bind the echo area routines. */
|
||||
map = echo_area_keymap;
|
||||
|
||||
map[Control ('a')].function = ea_beg_of_line;
|
||||
map[Control ('b')].function = ea_backward;
|
||||
map[Control ('d')].function = ea_delete;
|
||||
map[Control ('e')].function = ea_end_of_line;
|
||||
map[Control ('f')].function = ea_forward;
|
||||
map[Control ('g')].function = ea_abort;
|
||||
map[Control ('h')].function = ea_rubout;
|
||||
map[Control ('k')].function = ea_kill_line;
|
||||
map[Control ('l')].function = info_redraw_display;
|
||||
map[Control ('q')].function = ea_quoted_insert;
|
||||
map[Control ('t')].function = ea_transpose_chars;
|
||||
map[Control ('u')].function = ea_abort;
|
||||
map[Control ('v')].function = ea_quoted_insert;
|
||||
map[Control ('y')].function = ea_yank;
|
||||
|
||||
map[LFD].function = ea_newline;
|
||||
map[RET].function = ea_newline;
|
||||
map[SPC].function = ea_complete;
|
||||
map[TAB].function = ea_complete;
|
||||
map['?'].function = ea_possible_completions;
|
||||
#ifdef __MSDOS__
|
||||
/* PC users will lynch me if I don't give them their usual DEL effect... */
|
||||
map[DEL].function = ea_delete;
|
||||
#else
|
||||
map[DEL].function = ea_rubout;
|
||||
#endif
|
||||
|
||||
/* Bind the echo area ESC keymap. */
|
||||
map = (Keymap)echo_area_keymap[ESC].function;
|
||||
|
||||
map[Control ('g')].function = ea_abort;
|
||||
map[Control ('h')].function = ea_backward_kill_word;
|
||||
map[Control ('v')].function = ea_scroll_completions_window;
|
||||
map['0'].function = ea_beg_of_line;
|
||||
map['$'].function = ea_end_of_line;
|
||||
map['b'].function = ea_backward_word;
|
||||
map['d'].function = ea_kill_word;
|
||||
map['f'].function = ea_forward_word;
|
||||
map['h'].function = ea_forward;
|
||||
map['l'].function = ea_backward;
|
||||
map['w'].function = ea_forward_word;
|
||||
map['x'].function = ea_delete;
|
||||
map['X'].function = ea_kill_word;
|
||||
map['y'].function = ea_yank_pop;
|
||||
map['?'].function = ea_possible_completions;
|
||||
map[TAB].function = ea_tab_insert;
|
||||
map[DEL].function = ea_kill_word;
|
||||
|
||||
/* Bind the echo area Control-x keymap. */
|
||||
map = (Keymap)echo_area_keymap[Control ('x')].function;
|
||||
|
||||
map['o'].function = info_next_window;
|
||||
map[DEL].function = ea_backward_kill_line;
|
||||
|
||||
/* Arrow key bindings for echo area keymaps. It seems that some
|
||||
terminals do not match their termcap entries, so it's best to just
|
||||
define everything with both of the usual prefixes. */
|
||||
map = echo_area_keymap;
|
||||
keymap_bind_keyseq (map, term_ku, &map[Control ('p')]); /* up */
|
||||
keymap_bind_keyseq (map, "\033OA", &map[Control ('p')]);
|
||||
keymap_bind_keyseq (map, "\033[A", &map[Control ('p')]);
|
||||
keymap_bind_keyseq (map, term_kd, &map[Control ('n')]); /* down */
|
||||
keymap_bind_keyseq (map, "\033OB", &map[Control ('n')]);
|
||||
keymap_bind_keyseq (map, "\033[B", &map[Control ('n')]);
|
||||
keymap_bind_keyseq (map, term_kr, &map[Control ('f')]); /* right */
|
||||
keymap_bind_keyseq (map, "\033OC", &map[Control ('f')]);
|
||||
keymap_bind_keyseq (map, "\033[C", &map[Control ('f')]);
|
||||
keymap_bind_keyseq (map, term_kl, &map[Control ('b')]); /* left */
|
||||
keymap_bind_keyseq (map, "\033OD", &map[Control ('b')]);
|
||||
keymap_bind_keyseq (map, "\033[D", &map[Control ('b')]);
|
||||
|
||||
map = (Keymap)echo_area_keymap[ESC].function;
|
||||
keymap_bind_keyseq (map, term_kl, &map['b']); /* left */
|
||||
keymap_bind_keyseq (map, "\033OA", &map['b']);
|
||||
keymap_bind_keyseq (map, "\033[A", &map['b']);
|
||||
keymap_bind_keyseq (map, term_kr, &map['f']); /* right */
|
||||
keymap_bind_keyseq (map, "\033OB", &map['f']);
|
||||
keymap_bind_keyseq (map, "\033[B", &map['f']);
|
||||
|
||||
/* Bind commands for Info window keymaps. */
|
||||
map = info_keymap;
|
||||
map[TAB].function = info_move_to_next_xref;
|
||||
map[LFD].function = info_down_line;
|
||||
map[RET].function = info_down_line;
|
||||
map[SPC].function = info_scroll_forward;
|
||||
map[Control ('a')].function = info_beginning_of_line;
|
||||
map[Control ('b')].function = info_scroll_backward;
|
||||
map[Control ('d')].function = info_scroll_half_screen_down;
|
||||
map[Control ('e')].function = info_down_line;
|
||||
map[Control ('f')].function = info_scroll_forward;
|
||||
map[Control ('g')].function = info_abort_key;
|
||||
map[Control ('k')].function = info_up_line;
|
||||
map[Control ('l')].function = info_redraw_display;
|
||||
map[Control ('n')].function = info_down_line;
|
||||
map[Control ('p')].function = info_up_line;
|
||||
map[Control ('r')].function = info_redraw_display;
|
||||
map[Control ('s')].function = isearch_forward;
|
||||
map[Control ('u')].function = info_scroll_half_screen_up;
|
||||
map[Control ('v')].function = info_scroll_forward;
|
||||
map[Control ('y')].function = info_up_line;
|
||||
map[','].function = info_next_index_match;
|
||||
map['/'].function = info_search;
|
||||
|
||||
for (i = '1'; i < '9' + 1; i++)
|
||||
((Keymap) info_keymap[ESC].function)[i].function = info_menu_digit;
|
||||
((Keymap) info_keymap[ESC].function)['0'].function = info_last_menu_item;
|
||||
|
||||
map['<'].function = info_first_node;
|
||||
map['>'].function = info_last_node;
|
||||
map['?'].function = info_search_backward;
|
||||
map['['].function = info_global_prev_node;
|
||||
map[']'].function = info_global_next_node;
|
||||
map['\''].function = info_history_node;
|
||||
|
||||
map['b'].function = info_scroll_backward;
|
||||
map['d'].function = info_scroll_half_screen_down;
|
||||
map['e'].function = info_down_line;
|
||||
map['E'].function = info_view_file;
|
||||
map['f'].function = info_scroll_forward;
|
||||
map['F'].function = info_scroll_forward;
|
||||
map['g'].function = info_first_node;
|
||||
map['G'].function = info_last_node;
|
||||
map['h'].function = info_get_help_window;
|
||||
map['H'].function = info_get_help_window;
|
||||
map['i'].function = info_index_search;
|
||||
map['I'].function = info_goto_invocation_node;
|
||||
map['j'].function = info_down_line;
|
||||
map['k'].function = info_up_line;
|
||||
map['l'].function = info_history_node;
|
||||
map['m'].function = info_menu_item;
|
||||
map['n'].function = info_search_next;
|
||||
map['N'].function = info_search_previous;
|
||||
map['O'].function = info_goto_invocation_node;
|
||||
map['p'].function = info_prev_node;
|
||||
map['q'].function = info_quit;
|
||||
map['Q'].function = info_quit;
|
||||
map['r'].function = info_redraw_display;
|
||||
map['R'].function = info_redraw_display;
|
||||
map['s'].function = info_search;
|
||||
map['S'].function = info_search_case_sensitively;
|
||||
map['t'].function = info_top_node;
|
||||
map['u'].function = info_scroll_half_screen_up;
|
||||
map['w'].function = info_scroll_backward_set_window;
|
||||
map['y'].function = info_up_line;
|
||||
map['z'].function = info_scroll_forward_set_window;
|
||||
map['Z'].function = NULL; /* unbind, so it works to bind "ZZ" below */
|
||||
map[DEL].function = info_scroll_backward;
|
||||
keymap_bind_keyseq (map, ":q", &map['q']);
|
||||
keymap_bind_keyseq (map, ":Q", &map['q']);
|
||||
keymap_bind_keyseq (map, "ZZ", &map['q']);
|
||||
|
||||
/* Bind members in the ESC map for Info windows. */
|
||||
map = (Keymap)info_keymap[ESC].function;
|
||||
map[Control ('f')].function = info_show_footnotes;
|
||||
map[Control ('g')].function = info_abort_key;
|
||||
map[TAB].function = info_move_to_prev_xref;
|
||||
map[SPC].function = info_scroll_forward;
|
||||
map[Control ('v')].function = info_scroll_other_window;
|
||||
map['<'].function = info_beginning_of_node;
|
||||
map['>'].function = info_end_of_node;
|
||||
map['/'].function = info_search;
|
||||
map['?'].function = info_search_backward;
|
||||
map['b'].function = info_beginning_of_node;
|
||||
map['d'].function = info_dir_node;
|
||||
map['e'].function = info_end_of_node;
|
||||
map['f'].function = info_xref_item;
|
||||
map['g'].function = info_select_reference_this_line;
|
||||
map['h'].function = info_get_info_help_node;
|
||||
map['m'].function = info_menu_item;
|
||||
map['n'].function = info_search;
|
||||
map['N'].function = info_search_backward;
|
||||
map['r'].function = isearch_backward;
|
||||
map['s'].function = isearch_forward;
|
||||
map['t'].function = info_top_node;
|
||||
map['v'].function = info_scroll_backward;
|
||||
#if defined (NAMED_FUNCTIONS)
|
||||
map['x'].function = info_execute_command;
|
||||
#endif /* NAMED_FUNCTIONS */
|
||||
map[DEL].function = info_scroll_other_window_backward;
|
||||
|
||||
/* Bind members in the Control-X map for Info windows. */
|
||||
map = (Keymap)info_keymap[Control ('x')].function;
|
||||
|
||||
map[Control ('b')].function = list_visited_nodes;
|
||||
map[Control ('c')].function = info_quit;
|
||||
map[Control ('f')].function = info_view_file;
|
||||
map[Control ('g')].function = info_abort_key;
|
||||
map[Control ('v')].function = info_view_file;
|
||||
map[LFD].function = info_select_reference_this_line;
|
||||
map[RET].function = info_select_reference_this_line;
|
||||
map['0'].function = info_delete_window;
|
||||
map['1'].function = info_keep_one_window;
|
||||
map['2'].function = info_split_window;
|
||||
map['^'].function = info_grow_window;
|
||||
map['b'].function = select_visited_node;
|
||||
map['g'].function = info_goto_node;
|
||||
map['i'].function = info_index_search;
|
||||
map['I'].function = info_goto_invocation_node;
|
||||
map['k'].function = info_kill_node;
|
||||
map['n'].function = info_next_node;
|
||||
map['o'].function = info_next_window;
|
||||
map['O'].function = info_goto_invocation_node;
|
||||
map['p'].function = info_prev_node;
|
||||
map['r'].function = info_xref_item;
|
||||
map['t'].function = info_tile_windows;
|
||||
map['u'].function = info_up_node;
|
||||
map['w'].function = info_toggle_wrap;
|
||||
map[','].function = info_next_index_match;
|
||||
keymap_bind_keyseq (info_keymap, ":e", &map[Control ('v')]);
|
||||
|
||||
/* Arrow key bindings for Info windows keymap. */
|
||||
map = info_keymap;
|
||||
keymap_bind_keyseq (map, term_kN, &map[Control ('v')]); /* pagedown */
|
||||
keymap_bind_keyseq (map, term_ku, &map[Control ('p')]); /* up */
|
||||
keymap_bind_keyseq (map, "\033OA", &map[Control ('p')]);
|
||||
keymap_bind_keyseq (map, "\033[A", &map[Control ('p')]);
|
||||
keymap_bind_keyseq (map, term_kd, &map[Control ('n')]); /* down */
|
||||
keymap_bind_keyseq (map, "\033OB", &map[Control ('n')]);
|
||||
keymap_bind_keyseq (map, "\033[B", &map[Control ('n')]);
|
||||
keymap_bind_keyseq (map, term_kr, &map[Control ('f')]); /* right */
|
||||
keymap_bind_keyseq (map, "\033OC", &map[Control ('f')]);
|
||||
keymap_bind_keyseq (map, "\033[C", &map[Control ('f')]);
|
||||
keymap_bind_keyseq (map, term_kl, &map[Control ('b')]); /* left */
|
||||
keymap_bind_keyseq (map, "\033OD", &map[Control ('b')]);
|
||||
keymap_bind_keyseq (map, "\033[D", &map[Control ('b')]);
|
||||
|
||||
map = (Keymap)info_keymap[ESC].function;
|
||||
keymap_bind_keyseq (map, term_kl, &map['b']); /* left */
|
||||
keymap_bind_keyseq (map, "\033OA", &map['b']);
|
||||
keymap_bind_keyseq (map, "\033[A", &map['b']);
|
||||
keymap_bind_keyseq (map, term_kr, &map['f']); /* right */
|
||||
keymap_bind_keyseq (map, "\033OB", &map['f']);
|
||||
keymap_bind_keyseq (map, "\033[B", &map['f']);
|
||||
keymap_bind_keyseq (map, term_kN, &map[Control ('v')]); /* pagedown */
|
||||
keymap_bind_keyseq (map, term_kP, &map[DEL]); /* pageup */
|
||||
|
||||
/* The alternative to this definition of a `main map' key in the
|
||||
`ESC map' section, is something like:
|
||||
keymap_bind_keyseq (map, term_kP, &((KeyMap)map[ESC].function).map['v']);
|
||||
*/
|
||||
keymap_bind_keyseq (info_keymap/*sic*/, term_kP, &map['v']); /* pageup */
|
||||
}
|
||||
|
||||
void
|
||||
initialize_info_keymaps ()
|
||||
{
|
||||
if (vi_keys_p)
|
||||
initialize_vi_like_keymaps ();
|
||||
else
|
||||
initialize_emacs_like_keymaps ();
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* m-x.c -- Meta-X minibuffer reader.
|
||||
$Id: m-x.c,v 1.5 1997/07/24 21:28:00 karl Exp $
|
||||
/* m-x.c -- Meta-x minibuffer reader.
|
||||
$Id: m-x.c,v 1.8 1999/06/25 21:57:40 karl Exp $
|
||||
|
||||
Copyright (C) 1993, 97 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
|
||||
@ -149,7 +149,7 @@ DECLARE_INFO_COMMAND (info_execute_command,
|
||||
DECLARE_INFO_COMMAND (set_screen_height,
|
||||
_("Set the height of the displayed window"))
|
||||
{
|
||||
int new_height;
|
||||
int new_height, old_height = screenheight;
|
||||
|
||||
if (info_explicit_arg || count != 1)
|
||||
new_height = count;
|
||||
@ -185,6 +185,20 @@ DECLARE_INFO_COMMAND (set_screen_height,
|
||||
terminal_clear_screen ();
|
||||
display_clear_display (the_display);
|
||||
screenheight = new_height;
|
||||
display_initialize_display (screenwidth, screenheight);
|
||||
window_new_screen_size (screenwidth, screenheight);
|
||||
#ifdef SET_SCREEN_SIZE_HELPER
|
||||
SET_SCREEN_SIZE_HELPER;
|
||||
#endif
|
||||
if (screenheight == old_height)
|
||||
{
|
||||
/* Display dimensions didn't actually change, so
|
||||
window_new_screen_size won't do anything, but we've
|
||||
already cleared the display above. Undo the damage. */
|
||||
window_mark_chain (windows, W_UpdateWindow);
|
||||
display_update_display (windows);
|
||||
}
|
||||
else
|
||||
{
|
||||
display_initialize_display (screenwidth, screenheight);
|
||||
window_new_screen_size (screenwidth, screenheight);
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* man.c: How to read and format man files.
|
||||
$Id: man.c,v 1.6 1997/07/31 23:49:59 karl Exp $
|
||||
$Id: man.c,v 1.13 1999/07/05 20:43:23 karl Exp $
|
||||
|
||||
Copyright (C) 1995, 97 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995, 97, 98, 99 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
|
||||
@ -44,6 +44,14 @@
|
||||
# endif /* !hpux */
|
||||
#endif /* FD_SET */
|
||||
|
||||
#if STRIP_DOT_EXE
|
||||
static char const * const exec_extensions[] = {
|
||||
".exe", ".com", ".bat", ".btm", ".sh", ".ksh", ".pl", ".sed", "", NULL
|
||||
};
|
||||
#else
|
||||
static char const * const exec_extensions[] = { "", NULL };
|
||||
#endif
|
||||
|
||||
static char *read_from_fd ();
|
||||
static void clean_manpage ();
|
||||
static NODE *manpage_node_of_file_buffer ();
|
||||
@ -76,6 +84,7 @@ get_manpage_node (file_buffer, pagename)
|
||||
char header[1024];
|
||||
long oldsize, newsize;
|
||||
int hlen, plen;
|
||||
char *old_contents = file_buffer->contents;
|
||||
|
||||
sprintf (header, "\n\n%c\n%s %s, %s %s, %s (dir)\n\n",
|
||||
INFO_COOKIE,
|
||||
@ -89,13 +98,49 @@ get_manpage_node (file_buffer, pagename)
|
||||
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);
|
||||
memcpy (file_buffer->contents + oldsize + hlen, 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);
|
||||
/* We have just relocated file_buffer->contents from under
|
||||
the feet of info_windows[] array. Therefore, all the
|
||||
nodes on that list which are showing man pages have their
|
||||
contents member pointing into the blue. Undo that harm. */
|
||||
if (old_contents && oldsize && old_contents != file_buffer->contents)
|
||||
{
|
||||
int iw;
|
||||
INFO_WINDOW *info_win;
|
||||
char *old_contents_end = old_contents + oldsize;
|
||||
|
||||
for (iw = 0; (info_win = info_windows[iw]); iw++)
|
||||
{
|
||||
int in;
|
||||
|
||||
for (in = 0; in < info_win->nodes_index; in++)
|
||||
{
|
||||
NODE *node = info_win->nodes[in];
|
||||
|
||||
/* It really only suffices to see that node->filename
|
||||
is "*manpages*". But after several hours of
|
||||
debugging this, would you blame me for being a bit
|
||||
paranoid? */
|
||||
if (node && node->filename && node->contents &&
|
||||
strcmp (node->filename,
|
||||
MANPAGE_FILE_BUFFER_NAME) == 0 &&
|
||||
node->contents >= old_contents &&
|
||||
node->contents + node->nodelen <= old_contents_end)
|
||||
{
|
||||
info_win->nodes[in] =
|
||||
manpage_node_of_file_buffer (file_buffer,
|
||||
node->nodename);
|
||||
free (node->nodename);
|
||||
free (node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
node = manpage_node_of_file_buffer (file_buffer, pagename);
|
||||
@ -134,6 +179,8 @@ executable_file_in_path (filename, path)
|
||||
while ((temp_dirname = extract_colon_unit (path, &dirname_index)))
|
||||
{
|
||||
char *temp;
|
||||
char *temp_end;
|
||||
int i;
|
||||
|
||||
/* Expand a leading tilde if one is present. */
|
||||
if (*temp_dirname == '~')
|
||||
@ -145,22 +192,30 @@ executable_file_in_path (filename, path)
|
||||
temp_dirname = expanded_dirname;
|
||||
}
|
||||
|
||||
temp = (char *)xmalloc (30 + strlen (temp_dirname) + strlen (filename));
|
||||
temp = (char *)xmalloc (34 + strlen (temp_dirname) + strlen (filename));
|
||||
strcpy (temp, temp_dirname);
|
||||
if (temp[(strlen (temp)) - 1] != '/')
|
||||
if (!IS_SLASH (temp[(strlen (temp)) - 1]))
|
||||
strcat (temp, "/");
|
||||
strcat (temp, filename);
|
||||
temp_end = temp + strlen (temp);
|
||||
|
||||
free (temp_dirname);
|
||||
|
||||
statable = (stat (temp, &finfo) == 0);
|
||||
/* Look for FILENAME, possibly with any of the extensions
|
||||
in EXEC_EXTENSIONS[]. */
|
||||
for (i = 0; exec_extensions[i]; i++)
|
||||
{
|
||||
if (exec_extensions[i][0])
|
||||
strcpy (temp_end, exec_extensions[i]);
|
||||
statable = (stat (temp, &finfo) == 0);
|
||||
|
||||
/* If we have found a regular executable file, then use it. */
|
||||
if ((statable) && (S_ISREG (finfo.st_mode)) &&
|
||||
(access (temp, X_OK) == 0))
|
||||
return (temp);
|
||||
else
|
||||
free (temp);
|
||||
/* 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);
|
||||
}
|
||||
|
||||
free (temp);
|
||||
}
|
||||
return ((char *)NULL);
|
||||
}
|
||||
@ -210,13 +265,14 @@ get_page_and_section (pagename)
|
||||
}
|
||||
}
|
||||
|
||||
#if PIPE_USE_FORK
|
||||
static void
|
||||
reap_children (sig)
|
||||
int sig;
|
||||
{
|
||||
int status;
|
||||
wait (&status);
|
||||
wait (NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
static char *
|
||||
get_manpage_contents (pagename)
|
||||
@ -225,7 +281,8 @@ get_manpage_contents (pagename)
|
||||
static char *formatter_args[4] = { (char *)NULL };
|
||||
int pipes[2];
|
||||
pid_t child;
|
||||
char *formatted_page = (char *)NULL;
|
||||
RETSIGTYPE (*sigsave) ();
|
||||
char *formatted_page = NULL;
|
||||
int arg_index = 1;
|
||||
|
||||
if (formatter_args[0] == (char *)NULL)
|
||||
@ -245,12 +302,12 @@ get_manpage_contents (pagename)
|
||||
/* Open a pipe to this program, read the output, and save it away
|
||||
in FORMATTED_PAGE. The reader end of the pipe is pipes[0]; the
|
||||
writer end is pipes[1]. */
|
||||
#if PIPE_USE_FORK
|
||||
pipe (pipes);
|
||||
|
||||
signal (SIGCHLD, reap_children);
|
||||
sigsave = signal (SIGCHLD, reap_children);
|
||||
|
||||
child = fork ();
|
||||
|
||||
if (child == -1)
|
||||
return ((char *)NULL);
|
||||
|
||||
@ -261,14 +318,14 @@ get_manpage_contents (pagename)
|
||||
close (pipes[1]);
|
||||
formatted_page = read_from_fd (pipes[0]);
|
||||
close (pipes[0]);
|
||||
signal (SIGCHLD, sigsave);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* In the child, close the read end of the pipe, make the write end
|
||||
{ /* In the child, close the read end of the pipe, make the write end
|
||||
of the pipe be stdout, and execute the man page formatter. */
|
||||
close (pipes[0]);
|
||||
close (fileno (stderr));
|
||||
close (fileno (stdin)); /* Don't print errors. */
|
||||
freopen (NULL_DEVICE, "w", stderr);
|
||||
freopen (NULL_DEVICE, "r", stdin);
|
||||
dup2 (pipes[1], fileno (stdout));
|
||||
|
||||
execv (formatter_args[0], formatter_args);
|
||||
@ -276,8 +333,39 @@ get_manpage_contents (pagename)
|
||||
/* If we get here, we couldn't exec, so close out the pipe and
|
||||
exit. */
|
||||
close (pipes[1]);
|
||||
exit (0);
|
||||
xexit (0);
|
||||
}
|
||||
#else /* !PIPE_USE_FORK */
|
||||
/* Cannot fork/exec, but can popen/pclose. */
|
||||
{
|
||||
FILE *fpipe;
|
||||
char *cmdline = xmalloc (strlen (formatter_args[0])
|
||||
+ strlen (manpage_pagename)
|
||||
+ (arg_index > 2 ? strlen (manpage_section) : 0)
|
||||
+ 3);
|
||||
int save_stderr = dup (fileno (stderr));
|
||||
int fd_err = open (NULL_DEVICE, O_WRONLY, 0666);
|
||||
|
||||
if (fd_err > 2)
|
||||
dup2 (fd_err, fileno (stderr)); /* Don't print errors. */
|
||||
sprintf (cmdline, "%s %s %s", formatter_args[0], manpage_pagename,
|
||||
arg_index > 2 ? manpage_section : "");
|
||||
fpipe = popen (cmdline, "r");
|
||||
free (cmdline);
|
||||
if (fd_err > 2)
|
||||
close (fd_err);
|
||||
dup2 (save_stderr, fileno (stderr));
|
||||
if (fpipe == 0)
|
||||
return ((char *)NULL);
|
||||
formatted_page = read_from_fd (fileno (fpipe));
|
||||
if (pclose (fpipe) == -1)
|
||||
{
|
||||
if (formatted_page)
|
||||
free (formatted_page);
|
||||
return ((char *)NULL);
|
||||
}
|
||||
}
|
||||
#endif /* !PIPE_USE_FORK */
|
||||
|
||||
/* If we have the page, then clean it up. */
|
||||
if (formatted_page)
|
||||
@ -342,10 +430,11 @@ manpage_node_of_file_buffer (file_buffer, pagename)
|
||||
{
|
||||
node = (NODE *)xmalloc (sizeof (NODE));
|
||||
node->filename = file_buffer->filename;
|
||||
node->nodename = tag->nodename;
|
||||
node->nodename = xstrdup (tag->nodename);
|
||||
node->contents = file_buffer->contents + tag->nodestart;
|
||||
node->nodelen = tag->nodelen;
|
||||
node->flags = 0;
|
||||
node->display_pos = 0;
|
||||
node->parent = (char *)NULL;
|
||||
node->flags = (N_HasTagsTable | N_IsManPage);
|
||||
node->contents += skip_node_separator (node->contents);
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* nodemenu.c -- Produce a menu of all visited nodes.
|
||||
$Id: nodemenu.c,v 1.7 1997/07/24 21:30:30 karl Exp $
|
||||
/* nodemenu.c -- produce a menu of all visited nodes.
|
||||
$Id: nodemenu.c,v 1.8 1998/06/28 19:54:27 karl Exp $
|
||||
|
||||
Copyright (C) 1993, 97 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
|
||||
@ -168,7 +168,9 @@ get_visited_nodes (filter_func)
|
||||
/* Delete duplicates. */
|
||||
for (i = 0, newlen = 1; i < lines_index - 1; i++)
|
||||
{
|
||||
if (strcmp (lines[i], lines[i + 1]) == 0)
|
||||
/* Use FILENAME_CMP here, since the most important piece
|
||||
of info in each line is the file name of the node. */
|
||||
if (FILENAME_CMP (lines[i], lines[i + 1]) == 0)
|
||||
{
|
||||
free (lines[i]);
|
||||
lines[i] = (char *)NULL;
|
||||
|
@ -1,9 +1,7 @@
|
||||
/* nodes.c -- How to get an Info file and node. */
|
||||
/* nodes.c -- how to get an Info file and node.
|
||||
$Id: nodes.c,v 1.14 1999/08/15 10:18:09 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, 98, 99 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
|
||||
@ -32,12 +30,6 @@
|
||||
# include "man.h"
|
||||
#endif /* HANDLE_MAN_PAGES */
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Functions Static to this File */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
static void forget_info_file (), remember_info_file ();
|
||||
static void free_file_buffer_tags (), free_info_tag ();
|
||||
static void get_nodes_of_tags_table (), get_nodes_of_info_file ();
|
||||
@ -50,8 +42,7 @@ static NODE *info_node_of_file_buffer_tags ();
|
||||
static long get_node_length ();
|
||||
|
||||
/* Magic number that RMS used to decide how much a tags table pointer could
|
||||
be off by. I feel that it should be much smaller, like on the order of
|
||||
4. */
|
||||
be off by. I feel that it should be much smaller, like 4. */
|
||||
#define DEFAULT_INFO_FUDGE 1000
|
||||
|
||||
/* Passed to *_internal functions. INFO_GET_TAGS says to do what is
|
||||
@ -59,46 +50,36 @@ static long get_node_length ();
|
||||
#define INFO_NO_TAGS 0
|
||||
#define INFO_GET_TAGS 1
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Global Variables */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
/* Global variables. */
|
||||
|
||||
/* When non-zero, this is a string describing the recent file error. */
|
||||
char *info_recent_file_error = (char *)NULL;
|
||||
char *info_recent_file_error = NULL;
|
||||
|
||||
/* The list of already loaded nodes. */
|
||||
FILE_BUFFER **info_loaded_files = (FILE_BUFFER **)NULL;
|
||||
FILE_BUFFER **info_loaded_files = NULL;
|
||||
|
||||
/* The number of slots currently allocated to LOADED_FILES. */
|
||||
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. */
|
||||
/* Used to build `dir' menu from `localdir' files found in INFOPATH. */
|
||||
extern void maybe_build_dir_node ();
|
||||
|
||||
/* Return a pointer to a NODE structure for the Info node (FILENAME)NODENAME.
|
||||
FILENAME can be passed as NULL, in which case the filename of "dir" is used.
|
||||
NODENAME can be passed as NULL, in which case the nodename of "Top" is used.
|
||||
If the node cannot be found, return a NULL pointer. */
|
||||
If FILENAME is NULL, `dir' is used.
|
||||
IF NODENAME is NULL, `Top' is used.
|
||||
If the node cannot be found, return NULL. */
|
||||
NODE *
|
||||
info_get_node (filename, nodename)
|
||||
char *filename, *nodename;
|
||||
{
|
||||
FILE_BUFFER *file_buffer;
|
||||
NODE *node;
|
||||
FILE_BUFFER *file_buffer = NULL;
|
||||
|
||||
file_buffer = (FILE_BUFFER *)NULL;
|
||||
info_recent_file_error = (char *)NULL;
|
||||
|
||||
info_recent_file_error = NULL;
|
||||
info_parse_node (nodename, DONT_SKIP_NEWLINES);
|
||||
nodename = (char *)NULL;
|
||||
nodename = NULL;
|
||||
|
||||
if (info_parsed_filename)
|
||||
filename = info_parsed_filename;
|
||||
@ -112,23 +93,23 @@ info_get_node (filename, nodename)
|
||||
|
||||
/* If the file to be looked up is "dir", build the contents from all of
|
||||
the "dir"s and "localdir"s found in INFOPATH. */
|
||||
if (strcasecmp (filename, "dir") == 0)
|
||||
if (is_dir_name (filename))
|
||||
maybe_build_dir_node (filename);
|
||||
|
||||
/* Find the correct info file. */
|
||||
/* Find the correct info file, or give up. */
|
||||
file_buffer = info_find_file (filename);
|
||||
|
||||
if (!file_buffer)
|
||||
{
|
||||
if (filesys_error_number)
|
||||
info_recent_file_error =
|
||||
filesys_error_string (filename, filesys_error_number);
|
||||
return ((NODE *)NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Look for the node. */
|
||||
node = info_get_node_of_file_buffer (nodename, file_buffer);
|
||||
/* If the node looked for was "Top", try again looking for the node under
|
||||
a slightly different name. */
|
||||
|
||||
/* If the node not found was "Top", try again with different case. */
|
||||
if (!node && (nodename == NULL || strcasecmp (nodename, "Top") == 0))
|
||||
{
|
||||
node = info_get_node_of_file_buffer ("Top", file_buffer);
|
||||
@ -137,7 +118,8 @@ info_get_node (filename, nodename)
|
||||
if (!node)
|
||||
node = info_get_node_of_file_buffer ("TOP", file_buffer);
|
||||
}
|
||||
return (node);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/* Return a pointer to a NODE structure for the Info node NODENAME in
|
||||
@ -149,12 +131,12 @@ info_get_node_of_file_buffer (nodename, file_buffer)
|
||||
char *nodename;
|
||||
FILE_BUFFER *file_buffer;
|
||||
{
|
||||
NODE *node = (NODE *)NULL;
|
||||
NODE *node = NULL;
|
||||
|
||||
/* If we are unable to find the file, we have to give up. There isn't
|
||||
anything else we can do. */
|
||||
if (!file_buffer)
|
||||
return ((NODE *)NULL);
|
||||
return NULL;
|
||||
|
||||
/* If the file buffer was gc'ed, reload the contents now. */
|
||||
if (!file_buffer->contents)
|
||||
@ -171,11 +153,12 @@ info_get_node_of_file_buffer (nodename, file_buffer)
|
||||
{
|
||||
node = (NODE *)xmalloc (sizeof (NODE));
|
||||
node->filename = file_buffer->fullpath;
|
||||
node->parent = (char *)NULL;
|
||||
node->parent = NULL;
|
||||
node->nodename = xstrdup ("*");
|
||||
node->contents = file_buffer->contents;
|
||||
node->nodelen = file_buffer->filesize;
|
||||
node->flags = 0;
|
||||
node->display_pos = 0;
|
||||
}
|
||||
#if defined (HANDLE_MAN_PAGES)
|
||||
/* If the file buffer is the magic one associated with manpages, call
|
||||
@ -195,7 +178,7 @@ info_get_node_of_file_buffer (nodename, file_buffer)
|
||||
}
|
||||
|
||||
/* Return the results of our node search. */
|
||||
return (node);
|
||||
return node;
|
||||
}
|
||||
|
||||
/* Locate the file named by FILENAME, and return the information structure
|
||||
@ -207,7 +190,7 @@ FILE_BUFFER *
|
||||
info_find_file (filename)
|
||||
char *filename;
|
||||
{
|
||||
return (info_find_file_internal (filename, INFO_GET_TAGS));
|
||||
return info_find_file_internal (filename, INFO_GET_TAGS);
|
||||
}
|
||||
|
||||
/* Load the info file FILENAME, remembering information about it in a
|
||||
@ -216,15 +199,11 @@ FILE_BUFFER *
|
||||
info_load_file (filename)
|
||||
char *filename;
|
||||
{
|
||||
return (info_load_file_internal (filename, INFO_GET_TAGS));
|
||||
return info_load_file_internal (filename, INFO_GET_TAGS);
|
||||
}
|
||||
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Private Functions Implementation */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
/* Private functions implementation. */
|
||||
|
||||
/* The workhorse for info_find_file (). Non-zero 2nd argument says to
|
||||
try to build a tags table (or otherwise glean the nodes) for this
|
||||
@ -236,30 +215,30 @@ info_find_file_internal (filename, get_tags)
|
||||
char *filename;
|
||||
int get_tags;
|
||||
{
|
||||
register int i;
|
||||
register FILE_BUFFER *file_buffer;
|
||||
int i;
|
||||
FILE_BUFFER *file_buffer;
|
||||
|
||||
/* First try to find the file in our list of already loaded files. */
|
||||
if (info_loaded_files)
|
||||
{
|
||||
for (i = 0; (file_buffer = info_loaded_files[i]); i++)
|
||||
if ((strcmp (filename, file_buffer->filename) == 0) ||
|
||||
(strcmp (filename, file_buffer->fullpath) == 0) ||
|
||||
((*filename != '/') &&
|
||||
strcmp (filename,
|
||||
filename_non_directory (file_buffer->fullpath)) == 0))
|
||||
if ((FILENAME_CMP (filename, file_buffer->filename) == 0) ||
|
||||
(FILENAME_CMP (filename, file_buffer->fullpath) == 0) ||
|
||||
(!IS_ABSOLUTE (filename) &&
|
||||
FILENAME_CMP (filename,
|
||||
filename_non_directory (file_buffer->fullpath)) == 0))
|
||||
{
|
||||
struct stat new_info, *old_info;
|
||||
|
||||
/* This file is loaded. If the filename that we want is
|
||||
specifically "dir", then simply return the file buffer. */
|
||||
if (strcasecmp (filename_non_directory (filename), "dir") == 0)
|
||||
return (file_buffer);
|
||||
if (is_dir_name (filename_non_directory (filename)))
|
||||
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);
|
||||
return file_buffer;
|
||||
#endif /* HANDLE_MAN_PAGES */
|
||||
|
||||
/* The file appears to be already loaded, and it is not "dir".
|
||||
@ -268,7 +247,7 @@ info_find_file_internal (filename, get_tags)
|
||||
if (stat (file_buffer->fullpath, &new_info) == -1)
|
||||
{
|
||||
filesys_error_number = errno;
|
||||
return ((FILE_BUFFER *)NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
old_info = &file_buffer->finfo;
|
||||
@ -288,10 +267,18 @@ info_find_file_internal (filename, get_tags)
|
||||
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 (!file_buffer->contents)
|
||||
{
|
||||
/* The file's contents have been gc'ed. Reload it. */
|
||||
info_reload_file_buffer_contents (file_buffer);
|
||||
if (!file_buffer->contents)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (get_tags && !file_buffer->tags)
|
||||
build_tags_and_nodes (file_buffer);
|
||||
|
||||
return (file_buffer);
|
||||
return file_buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -310,7 +297,7 @@ info_find_file_internal (filename, get_tags)
|
||||
if (file_buffer)
|
||||
remember_info_file (file_buffer);
|
||||
|
||||
return (file_buffer);
|
||||
return file_buffer;
|
||||
}
|
||||
|
||||
/* The workhorse function for info_load_file (). Non-zero second argument
|
||||
@ -325,8 +312,8 @@ info_load_file_internal (filename, get_tags)
|
||||
char *fullpath, *contents;
|
||||
long filesize;
|
||||
struct stat finfo;
|
||||
int retcode;
|
||||
FILE_BUFFER *file_buffer = (FILE_BUFFER *)NULL;
|
||||
int retcode, compressed;
|
||||
FILE_BUFFER *file_buffer = NULL;
|
||||
|
||||
/* Get the full pathname of this file, as known by the info system.
|
||||
That is to say, search along INFOPATH and expand tildes, etc. */
|
||||
@ -338,18 +325,16 @@ info_load_file_internal (filename, get_tags)
|
||||
/* If the file referenced by the name returned from info_find_fullpath ()
|
||||
doesn't exist, then try again with the last part of the filename
|
||||
appearing in lowercase. */
|
||||
/* This is probably not needed at all on those systems which define
|
||||
FILENAME_CMP to be strcasecmp. But let's do it anyway, lest some
|
||||
network redirector supports case sensitivity. */
|
||||
if (retcode < 0)
|
||||
{
|
||||
char *lowered_name;
|
||||
char *basename;
|
||||
|
||||
lowered_name = xstrdup (filename);
|
||||
basename = (char *) strrchr (lowered_name, '/');
|
||||
|
||||
if (basename)
|
||||
basename++;
|
||||
else
|
||||
basename = lowered_name;
|
||||
basename = filename_non_directory (lowered_name);
|
||||
|
||||
while (*basename)
|
||||
{
|
||||
@ -369,14 +354,14 @@ info_load_file_internal (filename, get_tags)
|
||||
if (retcode < 0)
|
||||
{
|
||||
filesys_error_number = errno;
|
||||
return ((FILE_BUFFER *)NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Otherwise, try to load the file. */
|
||||
contents = filesys_read_info_file (fullpath, &filesize, &finfo);
|
||||
contents = filesys_read_info_file (fullpath, &filesize, &finfo, &compressed);
|
||||
|
||||
if (!contents)
|
||||
return ((FILE_BUFFER *)NULL);
|
||||
return NULL;
|
||||
|
||||
/* The file was found, and can be read. Allocate FILE_BUFFER and fill
|
||||
in the various members. */
|
||||
@ -386,16 +371,16 @@ info_load_file_internal (filename, get_tags)
|
||||
file_buffer->finfo = finfo;
|
||||
file_buffer->filesize = filesize;
|
||||
file_buffer->contents = contents;
|
||||
if (file_buffer->filesize != file_buffer->finfo.st_size)
|
||||
if (compressed)
|
||||
file_buffer->flags |= N_IsCompressed;
|
||||
|
||||
/* If requested, build the tags and nodes for this file buffer. */
|
||||
if (get_tags)
|
||||
build_tags_and_nodes (file_buffer);
|
||||
|
||||
return (file_buffer);
|
||||
return file_buffer;
|
||||
}
|
||||
|
||||
|
||||
/* Grovel FILE_BUFFER->contents finding tags and nodes, and filling in the
|
||||
various slots. This can also be used to rebuild a tag or node table. */
|
||||
void
|
||||
@ -527,6 +512,7 @@ get_nodes_of_info_file (file_buffer)
|
||||
int start, end;
|
||||
char *nodeline;
|
||||
TAG *entry;
|
||||
int anchor = 0;
|
||||
|
||||
/* Skip past the characters just found. */
|
||||
binding.start = nodestart;
|
||||
@ -537,6 +523,13 @@ get_nodes_of_info_file (file_buffer)
|
||||
|
||||
/* Find "Node:" */
|
||||
start = string_in_line (INFO_NODE_LABEL, nodeline);
|
||||
/* No Node:. Maybe it's a Ref:. */
|
||||
if (start == -1)
|
||||
{
|
||||
start = string_in_line (INFO_REF_LABEL, nodeline);
|
||||
if (start != -1)
|
||||
anchor = 1;
|
||||
}
|
||||
|
||||
/* If not there, this is not the start of a node. */
|
||||
if (start == -1)
|
||||
@ -550,21 +543,24 @@ get_nodes_of_info_file (file_buffer)
|
||||
skip_node_characters (nodeline + start, DONT_SKIP_NEWLINES);
|
||||
|
||||
/* Okay, we have isolated the node name, and we know where the
|
||||
node starts. Remember this information in a NODE structure. */
|
||||
entry = (TAG *)xmalloc (sizeof (TAG));
|
||||
entry->nodename = (char *)xmalloc (1 + (end - start));
|
||||
node starts. Remember this information. */
|
||||
entry = xmalloc (sizeof (TAG));
|
||||
entry->nodename = xmalloc (1 + (end - start));
|
||||
strncpy (entry->nodename, nodeline + start, end - start);
|
||||
entry->nodename[end - start] = '\0';
|
||||
entry->nodename[end - start] = 0;
|
||||
entry->nodestart = nodestart;
|
||||
{
|
||||
SEARCH_BINDING node_body;
|
||||
if (anchor)
|
||||
entry->nodelen = 0;
|
||||
else
|
||||
{
|
||||
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;
|
||||
|
||||
@ -579,17 +575,16 @@ static long
|
||||
get_node_length (binding)
|
||||
SEARCH_BINDING *binding;
|
||||
{
|
||||
register int i;
|
||||
int i;
|
||||
char *body;
|
||||
|
||||
/* From the Info-RFC file:
|
||||
[A node] ends with either a ^_, a ^L, or the end of file. */
|
||||
/* [A node] ends with either a ^_, a ^L, or end of file. */
|
||||
for (i = binding->start, body = binding->buffer; i < binding->end; i++)
|
||||
{
|
||||
if (body[i] == INFO_FF || body[i] == INFO_COOKIE)
|
||||
break;
|
||||
}
|
||||
return ((long) i - binding->start);
|
||||
return i - binding->start;
|
||||
}
|
||||
|
||||
/* Build and save the array of nodes in FILE_BUFFER by searching through the
|
||||
@ -599,9 +594,10 @@ get_nodes_of_tags_table (file_buffer, buffer_binding)
|
||||
FILE_BUFFER *file_buffer;
|
||||
SEARCH_BINDING *buffer_binding;
|
||||
{
|
||||
int offset, tags_index = 0;
|
||||
int name_offset;
|
||||
SEARCH_BINDING *search;
|
||||
long position;
|
||||
int tags_index = 0;
|
||||
|
||||
search = copy_binding (buffer_binding);
|
||||
|
||||
@ -624,6 +620,8 @@ get_nodes_of_tags_table (file_buffer, buffer_binding)
|
||||
{
|
||||
TAG *entry;
|
||||
char *nodedef;
|
||||
unsigned p;
|
||||
int anchor = 0;
|
||||
|
||||
/* Prepare to skip this line. */
|
||||
search->start = position;
|
||||
@ -634,36 +632,45 @@ get_nodes_of_tags_table (file_buffer, buffer_binding)
|
||||
continue;
|
||||
|
||||
/* Find the label preceding the node name. */
|
||||
offset =
|
||||
name_offset =
|
||||
string_in_line (INFO_NODE_LABEL, search->buffer + search->start);
|
||||
|
||||
/* If no node label, maybe it's an anchor. */
|
||||
if (name_offset == -1)
|
||||
{
|
||||
name_offset = string_in_line (INFO_REF_LABEL,
|
||||
search->buffer + search->start);
|
||||
if (name_offset != -1)
|
||||
anchor = 1;
|
||||
}
|
||||
|
||||
/* If not there, not a defining line, so we must be out of the
|
||||
tags table. */
|
||||
if (offset == -1)
|
||||
tags table. */
|
||||
if (name_offset == -1)
|
||||
break;
|
||||
|
||||
/* Point to the beginning of the node definition. */
|
||||
search->start += offset;
|
||||
entry = xmalloc (sizeof (TAG));
|
||||
|
||||
/* Find the beginning of the node definition. */
|
||||
search->start += name_offset;
|
||||
nodedef = search->buffer + search->start;
|
||||
nodedef += skip_whitespace (nodedef);
|
||||
|
||||
/* Move past the node's name. */
|
||||
for (offset = 0;
|
||||
(nodedef[offset]) && (nodedef[offset] != INFO_TAGSEP);
|
||||
offset++);
|
||||
|
||||
if (nodedef[offset] != INFO_TAGSEP)
|
||||
/* Move past the node's name in this tag to the TAGSEP character. */
|
||||
for (p = 0; nodedef[p] && nodedef[p] != INFO_TAGSEP; p++)
|
||||
;
|
||||
if (nodedef[p] != INFO_TAGSEP)
|
||||
continue;
|
||||
|
||||
entry = (TAG *)xmalloc (sizeof (TAG));
|
||||
entry->nodename = (char *)xmalloc (1 + offset);
|
||||
strncpy (entry->nodename, nodedef, offset);
|
||||
entry->nodename[offset] = '\0';
|
||||
offset++;
|
||||
entry->nodestart = (long) atol (nodedef + offset);
|
||||
entry->nodename = xmalloc (p + 1);
|
||||
strncpy (entry->nodename, nodedef, p);
|
||||
entry->nodename[p] = 0;
|
||||
p++;
|
||||
entry->nodestart = atol (nodedef + p);
|
||||
|
||||
/* We don't know the length of this node yet. */
|
||||
entry->nodelen = -1;
|
||||
/* If a node, we don't know the length yet, but if it's an
|
||||
anchor, the length is 0. */
|
||||
entry->nodelen = anchor ? 0 : -1;
|
||||
|
||||
/* The filename of this node is currently known as the same as the
|
||||
name of this file. */
|
||||
@ -677,7 +684,7 @@ get_nodes_of_tags_table (file_buffer, buffer_binding)
|
||||
free (search);
|
||||
}
|
||||
|
||||
/* A structure used only in get_tags_of_indirect_tags_table () to hold onto
|
||||
/* A structure used only in `get_tags_of_indirect_tags_table' to hold onto
|
||||
an intermediate value. */
|
||||
typedef struct {
|
||||
char *filename;
|
||||
@ -692,8 +699,8 @@ get_tags_of_indirect_tags_table (file_buffer, indirect_binding, tags_binding)
|
||||
FILE_BUFFER *file_buffer;
|
||||
SEARCH_BINDING *indirect_binding, *tags_binding;
|
||||
{
|
||||
register int i;
|
||||
SUBFILE **subfiles = (SUBFILE **)NULL;
|
||||
int i;
|
||||
SUBFILE **subfiles = NULL;
|
||||
int subfiles_index = 0, subfiles_slots = 0;
|
||||
TAG *entry;
|
||||
|
||||
@ -723,7 +730,7 @@ get_tags_of_indirect_tags_table (file_buffer, indirect_binding, tags_binding)
|
||||
subfile = (SUBFILE *)xmalloc (sizeof (SUBFILE));
|
||||
subfile->filename = (char *)xmalloc (colon);
|
||||
strncpy (subfile->filename, line, colon - 1);
|
||||
subfile->filename[colon - 1] = '\0';
|
||||
subfile->filename[colon - 1] = 0;
|
||||
subfile->first_byte = (long) atol (line + colon);
|
||||
|
||||
add_pointer_to_array
|
||||
@ -742,7 +749,7 @@ get_tags_of_indirect_tags_table (file_buffer, indirect_binding, tags_binding)
|
||||
}
|
||||
else
|
||||
{
|
||||
register int tags_index;
|
||||
int tags_index;
|
||||
long header_length;
|
||||
SEARCH_BINDING binding;
|
||||
|
||||
@ -762,14 +769,21 @@ get_tags_of_indirect_tags_table (file_buffer, indirect_binding, tags_binding)
|
||||
|
||||
/* Build the file buffer's list of subfiles. */
|
||||
{
|
||||
char *containing_dir, *temp;
|
||||
char *containing_dir = xstrdup (file_buffer->fullpath);
|
||||
char *temp = filename_non_directory (containing_dir);
|
||||
int len_containing_dir;
|
||||
|
||||
containing_dir = xstrdup (file_buffer->fullpath);
|
||||
temp = (char *) strrchr (containing_dir, '/');
|
||||
|
||||
if (temp)
|
||||
*temp = '\0';
|
||||
if (temp > containing_dir)
|
||||
{
|
||||
if (HAVE_DRIVE (file_buffer->fullpath) &&
|
||||
temp == containing_dir + 2)
|
||||
{
|
||||
/* Avoid converting "d:foo" into "d:/foo" below. */
|
||||
*temp = '.';
|
||||
temp += 2;
|
||||
}
|
||||
temp[-1] = 0;
|
||||
}
|
||||
|
||||
len_containing_dir = strlen (containing_dir);
|
||||
|
||||
@ -789,7 +803,7 @@ get_tags_of_indirect_tags_table (file_buffer, indirect_binding, tags_binding)
|
||||
|
||||
file_buffer->subfiles[i] = fullpath;
|
||||
}
|
||||
file_buffer->subfiles[i] = (char *)NULL;
|
||||
file_buffer->subfiles[i] = NULL;
|
||||
free (containing_dir);
|
||||
}
|
||||
|
||||
@ -814,7 +828,7 @@ get_tags_of_indirect_tags_table (file_buffer, indirect_binding, tags_binding)
|
||||
free (subfiles[i]);
|
||||
free (file_buffer->subfiles[i]);
|
||||
}
|
||||
file_buffer->subfiles = (char **)NULL;
|
||||
file_buffer->subfiles = NULL;
|
||||
free_file_buffer_tags (file_buffer);
|
||||
return;
|
||||
}
|
||||
@ -825,9 +839,8 @@ get_tags_of_indirect_tags_table (file_buffer, indirect_binding, tags_binding)
|
||||
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 -= subfiles[i - 1]->first_byte;
|
||||
entry->nodestart += header_length;
|
||||
entry->nodelen = -1;
|
||||
}
|
||||
|
||||
/* We have successfully built the tags table. Remember that it
|
||||
@ -845,18 +858,89 @@ get_tags_of_indirect_tags_table (file_buffer, indirect_binding, tags_binding)
|
||||
free (subfiles);
|
||||
}
|
||||
|
||||
|
||||
/* Return the node that contains TAG in FILE_BUFFER, else
|
||||
(pathologically) NULL. Called from info_node_of_file_buffer_tags. */
|
||||
static NODE *
|
||||
find_node_of_anchor (file_buffer, tag)
|
||||
FILE_BUFFER *file_buffer;
|
||||
TAG *tag;
|
||||
{
|
||||
int anchor_pos, node_pos;
|
||||
TAG *node_tag;
|
||||
NODE *node;
|
||||
|
||||
/* Look through the tag list for the anchor. */
|
||||
for (anchor_pos = 0; file_buffer->tags[anchor_pos]; anchor_pos++)
|
||||
{
|
||||
TAG *t = file_buffer->tags[anchor_pos];
|
||||
if (t->nodestart == tag->nodestart)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Should not happen, because we should always find the anchor. */
|
||||
if (!file_buffer->tags[anchor_pos])
|
||||
return NULL;
|
||||
|
||||
/* We've found the anchor. Look backwards in the tag table for the
|
||||
preceding node (we're assuming the tags are given in order),
|
||||
skipping over any preceding anchors. */
|
||||
for (node_pos = anchor_pos - 1;
|
||||
node_pos >= 0 && file_buffer->tags[node_pos]->nodelen == 0;
|
||||
node_pos--)
|
||||
;
|
||||
|
||||
/* An info file with an anchor before any nodes is pathological, but
|
||||
it's possible, so don't crash. */
|
||||
if (node_pos < 0)
|
||||
return NULL;
|
||||
|
||||
/* We have the tag for the node that contained the anchor tag. */
|
||||
node_tag = file_buffer->tags[node_pos];
|
||||
|
||||
/* Look up the node name in the tag table to get the actual node.
|
||||
This is a recursive call, but it can't recurse again, because we
|
||||
call it with a real node. */
|
||||
node = info_node_of_file_buffer_tags (file_buffer, node_tag->nodename);
|
||||
|
||||
/* Start displaying the node at the anchor position. */
|
||||
if (node)
|
||||
{ /* The nodestart for real nodes is three characters before the `F'
|
||||
in the `File:' line (a newline, the CTRL-_, and another
|
||||
newline). The nodestart for anchors is the actual position.
|
||||
But we offset by only 2, rather than 3, because if an anchor is
|
||||
at the beginning of a paragraph, it's nicer for it to end up on
|
||||
the beginning of the first line of the paragraph rather than
|
||||
the blank line before it. (makeinfo has no way of knowing that
|
||||
a paragraph is going to start, so we can't fix it there.) */
|
||||
node->display_pos = file_buffer->tags[anchor_pos]->nodestart
|
||||
- (node_tag->nodestart + 2);
|
||||
|
||||
/* Otherwise an anchor at the end of a node ends up displaying at
|
||||
the end of the last line of the node (way over on the right of
|
||||
the screen), which looks wrong. */
|
||||
if (node->display_pos >= node->nodelen)
|
||||
node->display_pos = node->nodelen - 1;
|
||||
|
||||
/* Don't search in the node for the xref text, it's not there. */
|
||||
node->flags |= N_FromAnchor;
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
/* Return the node from FILE_BUFFER which matches NODENAME by searching
|
||||
the tags table in FILE_BUFFER. If the node could not be found, return
|
||||
a NULL pointer. */
|
||||
the tags table in FILE_BUFFER, or NULL. */
|
||||
static NODE *
|
||||
info_node_of_file_buffer_tags (file_buffer, nodename)
|
||||
FILE_BUFFER *file_buffer;
|
||||
char *nodename;
|
||||
{
|
||||
register int i;
|
||||
TAG *tag;
|
||||
int i;
|
||||
|
||||
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;
|
||||
@ -864,27 +948,26 @@ info_node_of_file_buffer_tags (file_buffer, nodename)
|
||||
subfile = info_find_file_internal (tag->filename, INFO_NO_TAGS);
|
||||
|
||||
if (!subfile)
|
||||
return ((NODE *)NULL);
|
||||
return NULL;
|
||||
|
||||
if (!subfile->contents)
|
||||
{
|
||||
info_reload_file_buffer_contents (subfile);
|
||||
|
||||
if (!subfile->contents)
|
||||
return ((NODE *)NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* If we were able to find this file and load it, then return
|
||||
the node within it. */
|
||||
{
|
||||
NODE *node;
|
||||
|
||||
node = (NODE *)xmalloc (sizeof (NODE));
|
||||
node->filename = (subfile->fullpath);
|
||||
node->nodename = tag->nodename;
|
||||
node->contents = subfile->contents + tag->nodestart;
|
||||
node->flags = 0;
|
||||
node->parent = (char *)NULL;
|
||||
NODE *node = xmalloc (sizeof (NODE));
|
||||
node->filename = subfile->fullpath;
|
||||
node->parent = NULL;
|
||||
node->nodename = tag->nodename;
|
||||
node->contents = subfile->contents + tag->nodestart;
|
||||
node->display_pos = 0;
|
||||
node->flags = 0;
|
||||
|
||||
if (file_buffer->flags & N_HasTagsTable)
|
||||
{
|
||||
@ -923,14 +1006,14 @@ info_node_of_file_buffer_tags (file_buffer, nodename)
|
||||
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.
|
||||
this node, or 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)
|
||||
if (node_sep == NULL)
|
||||
{
|
||||
free (node);
|
||||
return ((NODE *)NULL);
|
||||
return NULL;
|
||||
}
|
||||
/* Readjust tag->nodestart. */
|
||||
tag->nodestart = node_sep - subfile->contents;
|
||||
@ -943,46 +1026,49 @@ info_node_of_file_buffer_tags (file_buffer, nodename)
|
||||
node_body.end = buff_end - node_body.buffer;
|
||||
node_body.flags = 0;
|
||||
tag->nodelen = get_node_length (&node_body);
|
||||
node->nodelen = tag->nodelen;
|
||||
}
|
||||
|
||||
else if (tag->nodelen == 0) /* anchor, return containing node */
|
||||
{
|
||||
free (node);
|
||||
node = find_node_of_anchor (file_buffer, tag);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
node->nodelen = tag->nodelen;
|
||||
return (node);
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
/* There was a tag table for this file, and the node wasn't found.
|
||||
Return NULL, since this file doesn't contain the desired node. */
|
||||
return ((NODE *)NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Managing file_buffers, nodes, and tags. */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
/* Managing file_buffers, nodes, and tags. */
|
||||
|
||||
/* Create a new, empty file buffer. */
|
||||
FILE_BUFFER *
|
||||
make_file_buffer ()
|
||||
{
|
||||
FILE_BUFFER *file_buffer;
|
||||
FILE_BUFFER *file_buffer = xmalloc (sizeof (FILE_BUFFER));
|
||||
|
||||
file_buffer = (FILE_BUFFER *)xmalloc (sizeof (FILE_BUFFER));
|
||||
file_buffer->filename = file_buffer->fullpath = (char *)NULL;
|
||||
file_buffer->contents = (char *)NULL;
|
||||
file_buffer->tags = (TAG **)NULL;
|
||||
file_buffer->subfiles = (char **)NULL;
|
||||
file_buffer->filename = file_buffer->fullpath = NULL;
|
||||
file_buffer->contents = NULL;
|
||||
file_buffer->tags = NULL;
|
||||
file_buffer->subfiles = NULL;
|
||||
file_buffer->tags_slots = 0;
|
||||
file_buffer->flags = 0;
|
||||
|
||||
return (file_buffer);
|
||||
return file_buffer;
|
||||
}
|
||||
|
||||
/* Add FILE_BUFFER to our list of already loaded info files. */
|
||||
@ -1004,15 +1090,15 @@ static void
|
||||
forget_info_file (filename)
|
||||
char *filename;
|
||||
{
|
||||
register int i;
|
||||
int i;
|
||||
FILE_BUFFER *file_buffer;
|
||||
|
||||
if (!info_loaded_files)
|
||||
return;
|
||||
|
||||
for (i = 0; (file_buffer = info_loaded_files[i]); i++)
|
||||
if ((strcmp (filename, file_buffer->filename) == 0) ||
|
||||
(strcmp (filename, file_buffer->fullpath) == 0))
|
||||
for (i = 0; file_buffer = info_loaded_files[i]; i++)
|
||||
if (FILENAME_CMP (filename, file_buffer->filename) == 0
|
||||
|| FILENAME_CMP (filename, file_buffer->fullpath) == 0)
|
||||
{
|
||||
free (file_buffer->filename);
|
||||
free (file_buffer->fullpath);
|
||||
@ -1020,13 +1106,17 @@ forget_info_file (filename)
|
||||
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 () 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]))
|
||||
;
|
||||
/* Move rest of list down. */
|
||||
while (info_loaded_files[i + 1])
|
||||
{
|
||||
info_loaded_files[i] = info_loaded_files[i + 1];
|
||||
i++;
|
||||
}
|
||||
info_loaded_files[i] = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
@ -1037,17 +1127,17 @@ static void
|
||||
free_file_buffer_tags (file_buffer)
|
||||
FILE_BUFFER *file_buffer;
|
||||
{
|
||||
register int i;
|
||||
int i;
|
||||
|
||||
if (file_buffer->tags)
|
||||
{
|
||||
register TAG *tag;
|
||||
TAG *tag;
|
||||
|
||||
for (i = 0; (tag = file_buffer->tags[i]); i++)
|
||||
free_info_tag (tag);
|
||||
|
||||
free (file_buffer->tags);
|
||||
file_buffer->tags = (TAG **)NULL;
|
||||
file_buffer->tags = NULL;
|
||||
file_buffer->tags_slots = 0;
|
||||
}
|
||||
|
||||
@ -1057,7 +1147,7 @@ free_file_buffer_tags (file_buffer)
|
||||
free (file_buffer->subfiles[i]);
|
||||
|
||||
free (file_buffer->subfiles);
|
||||
file_buffer->subfiles = (char **)NULL;
|
||||
file_buffer->subfiles = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1084,6 +1174,7 @@ static void
|
||||
info_reload_file_buffer_contents (fb)
|
||||
FILE_BUFFER *fb;
|
||||
{
|
||||
int is_compressed;
|
||||
|
||||
#if defined (HANDLE_MAN_PAGES)
|
||||
/* If this is the magic manpage node, don't try to reload, just give up. */
|
||||
@ -1095,8 +1186,9 @@ info_reload_file_buffer_contents (fb)
|
||||
|
||||
/* Let the filesystem do all the work for us. */
|
||||
fb->contents =
|
||||
filesys_read_info_file (fb->fullpath, &(fb->filesize), &(fb->finfo));
|
||||
if (fb->filesize != (long) (fb->finfo.st_size))
|
||||
filesys_read_info_file (fb->fullpath, &(fb->filesize), &(fb->finfo),
|
||||
&is_compressed);
|
||||
if (is_compressed)
|
||||
fb->flags |= N_IsCompressed;
|
||||
}
|
||||
|
||||
@ -1157,7 +1249,7 @@ adjust_nodestart (node, min, max)
|
||||
(strncmp (node->nodename, nodedef, offset) == 0))
|
||||
{
|
||||
node->contents = nodestart;
|
||||
return (node_body.buffer + position);
|
||||
return node_body.buffer + position;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1173,7 +1265,7 @@ adjust_nodestart (node, min, max)
|
||||
|
||||
/* If the node couldn't be found, we lose big. */
|
||||
if (position == -1)
|
||||
return ((char *)NULL);
|
||||
return NULL;
|
||||
|
||||
/* Otherwise, the node was found, but the tags table could need updating
|
||||
(if we used a tag to get here, that is). Set the flag in NODE->flags. */
|
||||
@ -1181,5 +1273,5 @@ adjust_nodestart (node, min, max)
|
||||
node->contents += skip_node_separator (node->contents);
|
||||
if (node->flags & N_HasTagsTable)
|
||||
node->flags |= N_UpdateTags;
|
||||
return (node_body.buffer + position);
|
||||
return node_body.buffer + position;
|
||||
}
|
||||
|
@ -1,10 +1,7 @@
|
||||
/* nodes.h -- How we represent nodes internally.
|
||||
$Id: nodes.h,v 1.5 1997/07/18 14:33:44 karl Exp $
|
||||
$Id: nodes.h,v 1.8 1998/07/10 20:28:43 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.
|
||||
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
|
||||
@ -22,16 +19,12 @@
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#if !defined (NODES_H)
|
||||
#ifndef NODES_H
|
||||
#define NODES_H
|
||||
|
||||
#include "info.h"
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* User Code Interface */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
/* User code interface. */
|
||||
|
||||
/* Callers generally only want the node itself. This structure is used
|
||||
to pass node information around. None of the information in this
|
||||
@ -47,6 +40,7 @@ typedef struct {
|
||||
char *nodename; /* The name of this node. */
|
||||
char *contents; /* Characters appearing in this node. */
|
||||
long nodelen; /* The length of the CONTENTS member. */
|
||||
unsigned long display_pos; /* Where to display at, if nonzero. */
|
||||
int flags; /* See immediately below. */
|
||||
} NODE;
|
||||
|
||||
@ -57,18 +51,14 @@ typedef struct {
|
||||
#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_IsManPage 0x40 /* This node is a manpage. */
|
||||
#define N_FromAnchor 0x80 /* Synthesized for an anchor reference. */
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Internal Data Structures */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
/* Internal data structures. */
|
||||
|
||||
/* Some defines describing details about Info file contents. */
|
||||
|
||||
/* String Constants. */
|
||||
/* String constants. */
|
||||
#define INFO_FILE_LABEL "File:"
|
||||
#define INFO_REF_LABEL "Ref:"
|
||||
#define INFO_NODE_LABEL "Node:"
|
||||
#define INFO_PREV_LABEL "Prev:"
|
||||
#define INFO_ALTPREV_LABEL "Previous:"
|
||||
@ -82,7 +72,7 @@ typedef struct {
|
||||
#define INDIRECT_TAGS_TABLE_LABEL "Indirect:\n"
|
||||
#define TAGS_TABLE_IS_INDIRECT_LABEL "(Indirect)"
|
||||
|
||||
/* Character Constants. */
|
||||
/* Character constants. */
|
||||
#define INFO_COOKIE '\037'
|
||||
#define INFO_FF '\014'
|
||||
#define INFO_TAGSEP '\177'
|
||||
@ -119,12 +109,8 @@ typedef struct {
|
||||
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. */
|
||||
extern FILE_BUFFER **info_loaded_files;
|
||||
@ -166,4 +152,4 @@ extern char *info_recent_file_error;
|
||||
/* Create a new, empty file buffer. */
|
||||
extern FILE_BUFFER *make_file_buffer ();
|
||||
|
||||
#endif /* !NODES_H */
|
||||
#endif /* not NODES_H */
|
||||
|
@ -1,9 +1,7 @@
|
||||
/* search.c -- How to search large bodies of text. */
|
||||
/* search.c -- searching large bodies of text.
|
||||
$Id: search.c,v 1.5 1999/03/05 19:56:59 karl Exp $
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993, 97 Free Software Foundation, Inc.
|
||||
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
|
||||
@ -198,7 +196,7 @@ search_backward (input_string, binding)
|
||||
{
|
||||
c = *(buff - i);
|
||||
|
||||
if (c != string[i] && (alternate && c != alternate[i]))
|
||||
if (c != string[i] && (!alternate || c != alternate[i]))
|
||||
break;
|
||||
}
|
||||
|
||||
@ -292,7 +290,7 @@ skip_whitespace_and_newlines (string)
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; string && (whitespace (string[i]) || string[i] == '\n'); i++);
|
||||
for (i = 0; string && whitespace_or_newline (string[i]); i++);
|
||||
return (i);
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,7 @@
|
||||
/* 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 $
|
||||
$Id: search.h,v 1.4 1998/04/19 20:50:23 karl Exp $
|
||||
|
||||
This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993, 97 Free Software Foundation, Inc.
|
||||
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
|
||||
@ -53,11 +50,6 @@ extern int looking_at ();
|
||||
after the string. */
|
||||
extern int string_in_line ();
|
||||
|
||||
/* Some unixes don't have strcasecmp or strncasecmp. */
|
||||
#if !defined (HAVE_STRCASECMP)
|
||||
extern int strcasecmp (), strncasecmp ();
|
||||
#endif /* !HAVE_STRCASECMP */
|
||||
|
||||
/* Function names that start with "skip" are passed a string, and return
|
||||
an offset from the start of that string. Function names that start
|
||||
with "find" are passed a SEARCH_BINDING, and return an absolute position
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,9 +1,7 @@
|
||||
/* session.h -- Functions found in session.c. */
|
||||
/* session.h -- Functions found in session.c.
|
||||
$Id: session.h,v 1.9 1999/06/25 21:57: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, 98, 99 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,7 +19,7 @@
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#if !defined (SESSION_H)
|
||||
#ifndef SESSION_H
|
||||
#define SESSION_H
|
||||
|
||||
#include "info.h"
|
||||
@ -76,6 +74,7 @@ extern void info_select_reference ();
|
||||
extern int info_any_buffered_input_p ();
|
||||
extern void print_node ();
|
||||
extern void dump_node_to_file (), dump_nodes_to_file ();
|
||||
extern char *program_name_from_file_name ();
|
||||
|
||||
/* Do the physical deletion of WINDOW, and forget this window and
|
||||
associated nodes. */
|
||||
@ -110,6 +109,8 @@ extern void info_move_to_prev_xref (), info_move_to_next_xref ();
|
||||
extern void info_scroll_forward (), info_scroll_backward ();
|
||||
extern void info_redraw_display (), info_toggle_wrap ();
|
||||
extern void info_move_to_window_line ();
|
||||
extern void info_up_line (), info_down_line ();
|
||||
extern void info_scroll_half_screen_down (), info_scroll_half_screen_up ();
|
||||
|
||||
/* Manipulating multiple windows. */
|
||||
extern void info_split_window (), info_delete_window ();
|
||||
@ -123,6 +124,8 @@ extern void info_last_node (), info_first_node (), info_history_node ();
|
||||
extern void info_goto_node (), info_top_node (), info_dir_node ();
|
||||
extern void info_global_next_node (), info_global_prev_node ();
|
||||
extern void info_kill_node (), info_view_file ();
|
||||
extern void info_menu_sequence ();
|
||||
extern NODE *info_follow_menus (/* initial_node, menus, errstr, errarg */);
|
||||
|
||||
/* Selecting cross references. */
|
||||
extern void info_menu_digit (), info_menu_item (), info_xref_item ();
|
||||
@ -136,6 +139,8 @@ extern void info_initialize_numeric_arg (), info_numeric_arg_digit_loop ();
|
||||
|
||||
/* Searching commands. */
|
||||
extern void info_search (), isearch_forward (), isearch_backward ();
|
||||
extern void info_search_case_sensitively (), info_search_backward ();
|
||||
extern void info_search_next (), info_search_previous ();
|
||||
|
||||
/* Dumping and printing nodes. */
|
||||
extern void info_print_node ();
|
||||
@ -143,4 +148,4 @@ extern void info_print_node ();
|
||||
/* Miscellaneous commands. */
|
||||
extern void info_abort_key (), info_quit (), info_do_lowercase_version ();
|
||||
|
||||
#endif /* SESSION_H */
|
||||
#endif /* not SESSION_H */
|
||||
|
@ -1,9 +1,7 @@
|
||||
/* signals.c -- Install and maintain Info signal handlers. */
|
||||
/* signals.c -- install and maintain Info signal handlers.
|
||||
$Id: signals.c,v 1.6 1998/12/06 22:00:04 karl Exp $
|
||||
|
||||
/* 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, 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
|
||||
@ -30,6 +28,9 @@
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Non-zero when our signal handler has been called to handle SIGWINCH. */
|
||||
static int in_sigwinch = 0;
|
||||
|
||||
#if !defined (HAVE_SIGPROCMASK) && defined (HAVE_SIGSETMASK)
|
||||
/* Perform OPERATION on NEWSET, perhaps leaving information in OLDSET. */
|
||||
static void
|
||||
@ -66,7 +67,7 @@ typedef RETSIGTYPE signal_handler ();
|
||||
|
||||
static RETSIGTYPE info_signal_handler ();
|
||||
static signal_handler *old_TSTP, *old_TTOU, *old_TTIN;
|
||||
static signal_handler *old_WINCH, *old_INT;
|
||||
static signal_handler *old_WINCH, *old_INT, *old_USR1;
|
||||
|
||||
void
|
||||
initialize_info_signal_handler ()
|
||||
@ -84,6 +85,11 @@ initialize_info_signal_handler ()
|
||||
#if defined (SIGINT)
|
||||
old_INT = (signal_handler *) signal (SIGINT, info_signal_handler);
|
||||
#endif
|
||||
|
||||
#if defined (SIGUSR1)
|
||||
/* Used by DJGPP to simulate SIGTSTP on Ctrl-Z. */
|
||||
old_USR1 = (signal_handler *) signal (SIGUSR1, info_signal_handler);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
@ -97,6 +103,19 @@ redisplay_after_signal ()
|
||||
fflush (stdout);
|
||||
}
|
||||
|
||||
static void
|
||||
reset_info_window_sizes ()
|
||||
{
|
||||
terminal_goto_xy (0, 0);
|
||||
fflush (stdout);
|
||||
terminal_unprep_terminal ();
|
||||
terminal_get_screen_size ();
|
||||
terminal_prep_terminal ();
|
||||
display_initialize_display (screenwidth, screenheight);
|
||||
window_new_screen_size (screenwidth, screenheight, NULL);
|
||||
redisplay_after_signal ();
|
||||
}
|
||||
|
||||
static RETSIGTYPE
|
||||
info_signal_handler (sig)
|
||||
int sig;
|
||||
@ -145,28 +164,43 @@ info_signal_handler (sig)
|
||||
}
|
||||
break;
|
||||
|
||||
#if defined (SIGWINCH)
|
||||
#if defined (SIGWINCH) || defined (SIGUSR1)
|
||||
#ifdef SIGWINCH
|
||||
case SIGWINCH:
|
||||
#endif
|
||||
#ifdef SIGUSR1
|
||||
case SIGUSR1:
|
||||
#endif
|
||||
{
|
||||
/* Turn off terminal IO, tell our parent that the window has changed,
|
||||
then reinitialize the terminal and rebuild our windows. */
|
||||
old_signal_handler = &old_WINCH;
|
||||
terminal_goto_xy (0, 0);
|
||||
fflush (stdout);
|
||||
terminal_unprep_terminal ();
|
||||
signal (sig, *old_signal_handler);
|
||||
UNBLOCK_SIGNAL (sig);
|
||||
kill (getpid (), sig);
|
||||
if (!in_sigwinch) {
|
||||
in_sigwinch++;
|
||||
|
||||
/* Turn off terminal IO, tell our parent that the window has changed,
|
||||
then reinitialize the terminal and rebuild our windows. */
|
||||
#ifdef SIGWINCH
|
||||
if (sig == SIGWINCH)
|
||||
old_signal_handler = &old_WINCH;
|
||||
#endif
|
||||
#ifdef SIGUSR1
|
||||
if (sig == SIGUSR1)
|
||||
old_signal_handler = &old_USR1;
|
||||
#endif
|
||||
terminal_goto_xy (0, 0);
|
||||
fflush (stdout);
|
||||
terminal_unprep_terminal ();
|
||||
signal (sig, *old_signal_handler);
|
||||
UNBLOCK_SIGNAL (sig);
|
||||
kill (getpid (), sig);
|
||||
|
||||
/* After our old signal handler returns... */
|
||||
terminal_get_screen_size ();
|
||||
terminal_prep_terminal ();
|
||||
display_initialize_display (screenwidth, screenheight);
|
||||
window_new_screen_size (screenwidth, screenheight, (VFunction *)NULL);
|
||||
*old_signal_handler = (signal_handler *) signal (sig, info_signal_handler);
|
||||
redisplay_after_signal ();
|
||||
/* After our old signal handler returns... */
|
||||
*old_signal_handler
|
||||
= (signal_handler *) signal (sig, info_signal_handler);
|
||||
terminal_prep_terminal ();
|
||||
reset_info_window_sizes ();
|
||||
in_sigwinch--;
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif /* SIGWINCH */
|
||||
#endif /* SIGWINCH || SIGUSR1 */
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,7 @@
|
||||
/* termdep.h -- System things that terminal.c depends on.
|
||||
$Id: termdep.h,v 1.3 1997/07/05 21:17:14 karl Exp $
|
||||
$Id: termdep.h,v 1.4 1998/04/13 22:02:57 karl Exp $
|
||||
|
||||
This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993, 96, 97 Free Software Foundation, Inc.
|
||||
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
|
||||
@ -33,6 +30,9 @@
|
||||
|
||||
#ifdef HAVE_TERMIOS_H
|
||||
# include <termios.h>
|
||||
# ifdef GWINSZ_IN_SYS_IOCTL
|
||||
# include <sys/ioctl.h>
|
||||
# endif
|
||||
#else
|
||||
# if defined (HAVE_TERMIO_H)
|
||||
# include <termio.h>
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* terminal.c -- How to handle the physical terminal for Info.
|
||||
$Id: terminal.c,v 1.9 1998/02/22 00:05:15 karl Exp $
|
||||
$Id: terminal.c,v 1.19 1999/09/20 12:28:54 karl Exp $
|
||||
|
||||
Copyright (C) 1988, 89, 90, 91, 92, 93, 96, 97, 98
|
||||
Copyright (C) 1988, 89, 90, 91, 92, 93, 96, 97, 98, 99
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
@ -26,6 +26,7 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#include <sys/ioctl.h> /* TIOCGWINSZ on LynxOS, at least */
|
||||
|
||||
/* The Unix termcap interface code. */
|
||||
#ifdef HAVE_NCURSES_TERMCAP_H
|
||||
@ -76,9 +77,10 @@ VFunction *terminal_scroll_terminal_hook = (VFunction *)NULL;
|
||||
/* **************************************************************** */
|
||||
|
||||
/* A buffer which holds onto the current terminal description, and a pointer
|
||||
used to float within it. */
|
||||
static char *term_buffer = (char *)NULL;
|
||||
static char *term_string_buffer = (char *)NULL;
|
||||
used to float within it. And the name of the terminal. */
|
||||
static char *term_buffer = NULL;
|
||||
static char *term_string_buffer = NULL;
|
||||
static char *term_name;
|
||||
|
||||
/* Some strings to control terminal actions. These are output by tputs (). */
|
||||
static char *term_goto, *term_clreol, *term_cr, *term_clrpag;
|
||||
@ -146,12 +148,13 @@ terminal_begin_using_terminal ()
|
||||
#endif
|
||||
|
||||
send_to_terminal (term_begin_use);
|
||||
/* Without this fflush and sleep, running info in a shelltool or
|
||||
cmdtool (TERM=sun-cmd) with scrollbars loses -- the scrollbars are
|
||||
not restored properly.
|
||||
From: strube@physik3.gwdg.de (Hans Werner Strube). */
|
||||
fflush (stdout);
|
||||
sleep (1);
|
||||
if (STREQ (term_name, "sun-cmd"))
|
||||
/* Without this fflush and sleep, running info in a shelltool or
|
||||
cmdtool (TERM=sun-cmd) with scrollbars loses -- the scrollbars are
|
||||
not restored properly.
|
||||
From: strube@physik3.gwdg.de (Hans Werner Strube). */
|
||||
sleep (1);
|
||||
|
||||
#ifdef SIGWINCH
|
||||
signal (SIGWINCH, sigsave);
|
||||
@ -177,7 +180,9 @@ terminal_end_using_terminal ()
|
||||
|
||||
send_to_terminal (term_end_use);
|
||||
fflush (stdout);
|
||||
sleep (1);
|
||||
if (STREQ (term_name, "sun-cmd"))
|
||||
/* See comments at other sleep. */
|
||||
sleep (1);
|
||||
|
||||
#ifdef SIGWINCH
|
||||
signal (SIGWINCH, sigsave);
|
||||
@ -516,7 +521,7 @@ void
|
||||
terminal_initialize_terminal (terminal_name)
|
||||
char *terminal_name;
|
||||
{
|
||||
char *term, *buffer;
|
||||
char *buffer;
|
||||
|
||||
terminal_is_dumb_p = 0;
|
||||
|
||||
@ -526,37 +531,46 @@ terminal_initialize_terminal (terminal_name)
|
||||
return;
|
||||
}
|
||||
|
||||
term = terminal_name ? terminal_name : getenv ("TERM");
|
||||
term_name = terminal_name ? terminal_name : getenv ("TERM");
|
||||
if (!term_name)
|
||||
term_name = "dumb";
|
||||
|
||||
if (!term_string_buffer)
|
||||
term_string_buffer = (char *)xmalloc (2048);
|
||||
term_string_buffer = xmalloc (2048);
|
||||
|
||||
if (!term_buffer)
|
||||
term_buffer = (char *)xmalloc (2048);
|
||||
term_buffer = xmalloc (2048);
|
||||
|
||||
buffer = term_string_buffer;
|
||||
|
||||
term_clrpag = term_cr = term_clreol = (char *)NULL;
|
||||
term_clrpag = term_cr = term_clreol = NULL;
|
||||
|
||||
if (!term)
|
||||
term = "dumb";
|
||||
|
||||
if (tgetent (term_buffer, term) <= 0)
|
||||
/* HP-UX 11.x returns 0 for OK --jeff.hull@state.co.us. */
|
||||
if (tgetent (term_buffer, term_name) < 0)
|
||||
{
|
||||
terminal_is_dumb_p = 1;
|
||||
screenwidth = 80;
|
||||
screenheight = 24;
|
||||
term_cr = "\r";
|
||||
term_up = term_dn = audible_bell = visible_bell = (char *)NULL;
|
||||
term_ku = term_kd = term_kl = term_kr = (char *)NULL;
|
||||
term_kP = term_kN = (char *)NULL;
|
||||
term_up = term_dn = audible_bell = visible_bell = NULL;
|
||||
term_ku = term_kd = term_kl = term_kr = NULL;
|
||||
term_kP = term_kN = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
BC = tgetstr ("pc", &buffer);
|
||||
PC = BC ? *BC : 0;
|
||||
|
||||
#if defined (TIOCGETP)
|
||||
#if defined (HAVE_TERMIOS_H)
|
||||
{
|
||||
struct termios ti;
|
||||
if (tcgetattr (fileno(stdout), &ti) != -1)
|
||||
ospeed = cfgetospeed (&ti);
|
||||
else
|
||||
ospeed = B9600;
|
||||
}
|
||||
#else
|
||||
# if defined (TIOCGETP)
|
||||
{
|
||||
struct sgttyb sg;
|
||||
|
||||
@ -565,16 +579,17 @@ terminal_initialize_terminal (terminal_name)
|
||||
else
|
||||
ospeed = B9600;
|
||||
}
|
||||
#else
|
||||
# else
|
||||
ospeed = B9600;
|
||||
#endif /* !TIOCGETP */
|
||||
# endif /* !TIOCGETP */
|
||||
#endif
|
||||
|
||||
term_cr = tgetstr ("cr", &buffer);
|
||||
term_clreol = tgetstr ("ce", &buffer);
|
||||
term_clrpag = tgetstr ("cl", &buffer);
|
||||
term_goto = tgetstr ("cm", &buffer);
|
||||
|
||||
/* Find out about this terminals scrolling capability. */
|
||||
/* Find out about this terminal's scrolling capability. */
|
||||
term_AL = tgetstr ("AL", &buffer);
|
||||
term_DL = tgetstr ("DL", &buffer);
|
||||
term_al = tgetstr ("al", &buffer);
|
||||
@ -633,23 +648,7 @@ terminal_initialize_terminal (terminal_name)
|
||||
terminal_is_dumb_p = 1;
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* How to Read Characters From the Terminal */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
#if defined (TIOCGETC)
|
||||
/* A buffer containing the terminal interrupt characters upon entry
|
||||
to Info. */
|
||||
struct tchars original_tchars;
|
||||
#endif
|
||||
|
||||
#if defined (TIOCGLTC)
|
||||
/* A buffer containing the local terminal mode characters upon entry
|
||||
to Info. */
|
||||
struct ltchars original_ltchars;
|
||||
#endif
|
||||
/* How to read characters from the terminal. */
|
||||
|
||||
#if defined (HAVE_TERMIOS_H)
|
||||
struct termios original_termios, ttybuff;
|
||||
@ -662,6 +661,25 @@ struct termio original_termio, ttybuff;
|
||||
int original_tty_flags = 0;
|
||||
int original_lmode;
|
||||
struct sgttyb ttybuff;
|
||||
|
||||
# if defined(TIOCGETC) && defined(M_XENIX)
|
||||
/* SCO 3.2v5.0.2 defines but does not support TIOCGETC. Gak. Maybe
|
||||
better fix would be to use Posix termios in preference. --gildea,
|
||||
1jul99. */
|
||||
# undef TIOCGETC
|
||||
# endif
|
||||
|
||||
# if defined (TIOCGETC)
|
||||
/* A buffer containing the terminal interrupt characters upon entry
|
||||
to Info. */
|
||||
struct tchars original_tchars;
|
||||
# endif
|
||||
|
||||
# if defined (TIOCGLTC)
|
||||
/* A buffer containing the local terminal mode characters upon entry
|
||||
to Info. */
|
||||
struct ltchars original_ltchars;
|
||||
# endif
|
||||
# endif /* !HAVE_TERMIO_H */
|
||||
#endif /* !HAVE_TERMIOS_H */
|
||||
|
||||
@ -835,3 +853,6 @@ terminal_unprep_terminal ()
|
||||
terminal_end_using_terminal ();
|
||||
}
|
||||
|
||||
#ifdef __MSDOS__
|
||||
# include "pcterm.c"
|
||||
#endif
|
||||
|
@ -1,10 +1,7 @@
|
||||
/* tilde.c -- Tilde expansion code (~/foo := $HOME/foo).
|
||||
$Id: tilde.c,v 1.9 1998/02/22 23:03:21 karl Exp $
|
||||
/* tilde.c -- tilde expansion code (~/foo := $HOME/foo).
|
||||
$Id: tilde.c,v 1.13 1999/03/03 22:42:21 karl Exp $
|
||||
|
||||
This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1988, 89, 90, 91, 92, 93, 96, 98
|
||||
Copyright (C) 1988, 89, 90, 91, 92, 93, 96, 98, 99
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
@ -23,27 +20,9 @@
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
/* Indent #pragma so that older Cpp's don't try to parse it. */
|
||||
#ifdef _AIX
|
||||
#pragma alloca
|
||||
#endif /* _AIX */
|
||||
|
||||
/* Include config.h before doing alloca. */
|
||||
#include "info.h"
|
||||
|
||||
#ifdef __GNUC__
|
||||
# undef alloca
|
||||
# define alloca __builtin_alloca
|
||||
#else
|
||||
# ifdef HAVE_ALLOCA_H
|
||||
# include <alloca.h>
|
||||
# else
|
||||
# ifndef _AIX
|
||||
char *alloca ();
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined (TEST) || defined (STATIC_MALLOC)
|
||||
static void *xmalloc (), *xrealloc ();
|
||||
#endif /* TEST || STATIC_MALLOC */
|
||||
@ -123,7 +102,7 @@ tilde_find_suffix (string)
|
||||
|
||||
for (i = 0; i < string_len; i++)
|
||||
{
|
||||
if (string[i] == '/' || !string[i])
|
||||
if (IS_SLASH (string[i]) || !string[i])
|
||||
break;
|
||||
|
||||
for (j = 0; suffixes && suffixes[j]; j++)
|
||||
@ -203,14 +182,12 @@ char *
|
||||
tilde_expand_word (filename)
|
||||
char *filename;
|
||||
{
|
||||
char *dirname;
|
||||
|
||||
dirname = filename ? xstrdup (filename) : (char *)NULL;
|
||||
char *dirname = filename ? xstrdup (filename) : NULL;
|
||||
|
||||
if (dirname && *dirname == '~')
|
||||
{
|
||||
char *temp_name;
|
||||
if (!dirname[1] || dirname[1] == '/')
|
||||
if (!dirname[1] || IS_SLASH (dirname[1]))
|
||||
{
|
||||
/* Prepend $HOME to the rest of the string. */
|
||||
char *temp_home = getenv ("HOME");
|
||||
@ -226,30 +203,31 @@ tilde_expand_word (filename)
|
||||
temp_home = entry->pw_dir;
|
||||
}
|
||||
|
||||
temp_name = (char *)
|
||||
alloca (1 + strlen (&dirname[1])
|
||||
+ (temp_home ? strlen (temp_home) : 0));
|
||||
temp_name[0] = '\0';
|
||||
temp_name = xmalloc (1 + strlen (&dirname[1])
|
||||
+ (temp_home ? strlen (temp_home) : 0));
|
||||
if (temp_home)
|
||||
strcpy (temp_name, temp_home);
|
||||
else
|
||||
temp_name[0] = 0;
|
||||
strcat (temp_name, &dirname[1]);
|
||||
free (dirname);
|
||||
dirname = xstrdup (temp_name);
|
||||
free (temp_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct passwd *user_entry;
|
||||
char *username = (char *)alloca (257);
|
||||
char *username = xmalloc (257);
|
||||
int i, c;
|
||||
|
||||
for (i = 1; (c = dirname[i]); i++)
|
||||
{
|
||||
if (c == '/')
|
||||
if (IS_SLASH (c))
|
||||
break;
|
||||
else
|
||||
username[i - 1] = c;
|
||||
}
|
||||
username[i - 1] = '\0';
|
||||
username[i - 1] = 0;
|
||||
|
||||
if (!(user_entry = (struct passwd *) getpwnam (username)))
|
||||
{
|
||||
@ -264,8 +242,8 @@ tilde_expand_word (filename)
|
||||
|
||||
if (expansion)
|
||||
{
|
||||
temp_name = (char *)alloca
|
||||
(1 + strlen (expansion) + strlen (&dirname[i]));
|
||||
temp_name = xmalloc (1 + strlen (expansion)
|
||||
+ strlen (&dirname[i]));
|
||||
strcpy (temp_name, expansion);
|
||||
strcat (temp_name, &dirname[i]);
|
||||
free (expansion);
|
||||
@ -276,18 +254,22 @@ tilde_expand_word (filename)
|
||||
}
|
||||
else
|
||||
{
|
||||
temp_name = (char *)alloca
|
||||
(1 + strlen (user_entry->pw_dir) + strlen (&dirname[i]));
|
||||
temp_name = xmalloc (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);
|
||||
free (temp_name);
|
||||
}
|
||||
endpwent ();
|
||||
|
||||
endpwent ();
|
||||
free (username);
|
||||
}
|
||||
}
|
||||
return (dirname);
|
||||
return dirname;
|
||||
}
|
||||
|
||||
|
||||
@ -322,7 +304,7 @@ main (argc, argv)
|
||||
printf (" --> %s\n", result);
|
||||
free (result);
|
||||
}
|
||||
exit (0);
|
||||
xexit (0);
|
||||
}
|
||||
|
||||
static void memory_error_and_abort ();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* variables.c -- How to manipulate user visible variables in Info.
|
||||
$Id: variables.c,v 1.5 1997/07/18 14:34:23 karl Exp $
|
||||
$Id: variables.c,v 1.7 1999/06/25 21:57:40 karl Exp $
|
||||
|
||||
This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
@ -1,10 +1,7 @@
|
||||
/* window.c -- Windows in Info.
|
||||
$Id: window.c,v 1.5 1998/02/23 22:43:38 karl Exp $
|
||||
/* window.c -- windows in Info.
|
||||
$Id: window.c,v 1.11 1999/06/25 21:57:40 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.
|
||||
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
|
||||
@ -30,16 +27,16 @@
|
||||
#include "infomap.h"
|
||||
|
||||
/* The window which describes the screen. */
|
||||
WINDOW *the_screen = (WINDOW *)NULL;
|
||||
WINDOW *the_screen = NULL;
|
||||
|
||||
/* The window which describes the echo area. */
|
||||
WINDOW *the_echo_area = (WINDOW *)NULL;
|
||||
WINDOW *the_echo_area = NULL;
|
||||
|
||||
/* The list of windows in Info. */
|
||||
WINDOW *windows = (WINDOW *)NULL;
|
||||
WINDOW *windows = NULL;
|
||||
|
||||
/* Pointer to the active window in WINDOW_LIST. */
|
||||
WINDOW *active_window = (WINDOW *)NULL;
|
||||
WINDOW *active_window = NULL;
|
||||
|
||||
/* The size of the echo area in Info. It never changes, irregardless of the
|
||||
size of the screen. */
|
||||
@ -56,9 +53,9 @@ void
|
||||
window_initialize_windows (width, height)
|
||||
int width, height;
|
||||
{
|
||||
the_screen = (WINDOW *)xmalloc (sizeof (WINDOW));
|
||||
the_echo_area = (WINDOW *)xmalloc (sizeof (WINDOW));
|
||||
windows = (WINDOW *)xmalloc (sizeof (WINDOW));
|
||||
the_screen = xmalloc (sizeof (WINDOW));
|
||||
the_echo_area = xmalloc (sizeof (WINDOW));
|
||||
windows = xmalloc (sizeof (WINDOW));
|
||||
active_window = windows;
|
||||
|
||||
zero_mem (the_screen, sizeof (WINDOW));
|
||||
@ -85,7 +82,7 @@ window_initialize_windows (width, height)
|
||||
area. */
|
||||
the_echo_area->height = ECHO_AREA_HEIGHT;
|
||||
active_window->height = the_screen->height - 1 - the_echo_area->height;
|
||||
window_new_screen_size (width, height, (VFunction *)NULL);
|
||||
window_new_screen_size (width, height, NULL);
|
||||
|
||||
/* The echo area uses a different keymap than normal info windows. */
|
||||
the_echo_area->keymap = echo_area_keymap;
|
||||
@ -102,7 +99,7 @@ window_initialize_windows (width, height)
|
||||
|
||||
/* If non-null, a function to call with WINDOW as argument when the function
|
||||
window_new_screen_size () has deleted WINDOW. */
|
||||
VFunction *window_deletion_notifier = (VFunction *)NULL;
|
||||
VFunction *window_deletion_notifier = NULL;
|
||||
|
||||
void
|
||||
window_new_screen_size (width, height)
|
||||
@ -139,7 +136,7 @@ window_new_screen_size (width, height)
|
||||
{
|
||||
windows->height = 0;
|
||||
maybe_free (windows->line_starts);
|
||||
windows->line_starts = (char **)NULL;
|
||||
windows->line_starts = NULL;
|
||||
windows->line_count = 0;
|
||||
break;
|
||||
}
|
||||
@ -187,7 +184,7 @@ window_new_screen_size (width, height)
|
||||
{
|
||||
win->width = width;
|
||||
maybe_free (win->modeline);
|
||||
win->modeline = (char *)xmalloc (1 + width);
|
||||
win->modeline = xmalloc (1 + width);
|
||||
}
|
||||
|
||||
win->height += delta_each;
|
||||
@ -274,14 +271,14 @@ window_make_window (node)
|
||||
|
||||
/* If there isn't enough room to make another window, return now. */
|
||||
if ((active_window->height / 2) < WINDOW_MIN_SIZE)
|
||||
return ((WINDOW *)NULL);
|
||||
return (NULL);
|
||||
|
||||
/* Make and initialize the new window.
|
||||
The fudging about with -1 and +1 is because the following window in the
|
||||
chain cannot start at window->height, since that is where the modeline
|
||||
for the previous window is displayed. The inverse adjustment is made
|
||||
in window_delete_window (). */
|
||||
window = (WINDOW *)xmalloc (sizeof (WINDOW));
|
||||
window = xmalloc (sizeof (WINDOW));
|
||||
window->width = the_screen->width;
|
||||
window->height = (active_window->height / 2) - 1;
|
||||
#if defined (SPLIT_BEFORE_ACTIVE)
|
||||
@ -292,8 +289,8 @@ window_make_window (node)
|
||||
#endif
|
||||
window->keymap = info_keymap;
|
||||
window->goal_column = -1;
|
||||
window->modeline = (char *)xmalloc (1 + window->width);
|
||||
window->line_starts = (char **)NULL;
|
||||
window->modeline = xmalloc (1 + window->width);
|
||||
window->line_starts = NULL;
|
||||
window->flags = W_UpdateWindow | W_WindowVisible;
|
||||
window_set_node_of_window (window, node);
|
||||
|
||||
@ -538,7 +535,7 @@ window_tile_windows (style)
|
||||
per_win_height = avail / numwins;
|
||||
leftover = avail - (per_win_height * numwins);
|
||||
|
||||
last_adjusted = (WINDOW *)NULL;
|
||||
last_adjusted = NULL;
|
||||
for (win = windows; win; win = win->next)
|
||||
{
|
||||
if (do_internals || !win->node ||
|
||||
@ -610,10 +607,12 @@ window_set_node_of_window (window, node)
|
||||
window->point = 0;
|
||||
recalculate_line_starts (window);
|
||||
window->flags |= W_UpdateWindow;
|
||||
/* The display_pos member is nonzero if we're displaying an anchor. */
|
||||
window->point = node ? node->display_pos : 0;
|
||||
window_adjust_pagetop (window);
|
||||
window_make_modeline (window);
|
||||
}
|
||||
|
||||
|
||||
/* Delete WINDOW from the list of known windows. If this window was the
|
||||
active window, make the next window in the chain be the active window.
|
||||
If the active window is the next or previous window, choose that window
|
||||
@ -766,7 +765,7 @@ string_width (string, hpos)
|
||||
return (width);
|
||||
}
|
||||
|
||||
/* Quickly guess the approximate number of lines to that NODE would
|
||||
/* Quickly guess the approximate number of lines that NODE would
|
||||
take to display. This really only counts carriage returns. */
|
||||
int
|
||||
window_physical_lines (node)
|
||||
@ -793,12 +792,12 @@ calculate_line_starts (window)
|
||||
WINDOW *window;
|
||||
{
|
||||
register int i, hpos;
|
||||
char **line_starts = (char **)NULL;
|
||||
char **line_starts = NULL;
|
||||
int line_starts_index = 0, line_starts_slots = 0;
|
||||
int bump_index;
|
||||
NODE *node;
|
||||
|
||||
window->line_starts = (char **)NULL;
|
||||
window->line_starts = NULL;
|
||||
window->line_count = 0;
|
||||
node = window->node;
|
||||
|
||||
@ -1079,9 +1078,9 @@ window_make_modeline (window)
|
||||
/* Calculate the maximum size of the information to stick in MODELINE. */
|
||||
{
|
||||
int modeline_len = 0;
|
||||
char *parent = (char *)NULL, *filename = "*no file*";
|
||||
char *parent = NULL, *filename = "*no file*";
|
||||
char *nodename = "*no node*";
|
||||
char *update_message = (char *)NULL;
|
||||
char *update_message = NULL;
|
||||
NODE *node = window->node;
|
||||
|
||||
if (node)
|
||||
@ -1113,7 +1112,7 @@ window_make_modeline (window)
|
||||
modeline_len += 10 + strlen (_("-----Info: (), lines ----, "));
|
||||
modeline_len += window->width;
|
||||
|
||||
modeline = (char *)xmalloc (1 + modeline_len);
|
||||
modeline = xmalloc (1 + modeline_len);
|
||||
|
||||
/* Special internal windows have no filename. */
|
||||
if (!parent && !*filename)
|
||||
@ -1194,14 +1193,10 @@ window_set_state (window, state)
|
||||
}
|
||||
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Manipulating Home-Made Nodes */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
/* Manipulating home-made nodes. */
|
||||
|
||||
/* A place to buffer echo area messages. */
|
||||
static NODE *echo_area_node = (NODE *)NULL;
|
||||
static NODE *echo_area_node = NULL;
|
||||
|
||||
/* Make the node of the_echo_area be an empty one. */
|
||||
static void
|
||||
@ -1213,7 +1208,7 @@ free_echo_area ()
|
||||
free (echo_area_node);
|
||||
}
|
||||
|
||||
echo_area_node = (NODE *)NULL;
|
||||
echo_area_node = NULL;
|
||||
window_set_node_of_window (the_echo_area, echo_area_node);
|
||||
}
|
||||
|
||||
@ -1245,7 +1240,7 @@ window_message_in_echo_area (format, arg1, arg2)
|
||||
and ARG2. The message appears immediately, but does not destroy
|
||||
any existing message. A future call to unmessage_in_echo_area ()
|
||||
restores the old contents. */
|
||||
static NODE **old_echo_area_nodes = (NODE **)NULL;
|
||||
static NODE **old_echo_area_nodes = NULL;
|
||||
static int old_echo_area_nodes_index = 0;
|
||||
static int old_echo_area_nodes_slots = 0;
|
||||
|
||||
@ -1260,7 +1255,7 @@ message_in_echo_area (format, arg1, arg2)
|
||||
old_echo_area_nodes, old_echo_area_nodes_slots,
|
||||
4, NODE *);
|
||||
}
|
||||
echo_area_node = (NODE *)NULL;
|
||||
echo_area_node = NULL;
|
||||
window_message_in_echo_area (format, arg1, arg2);
|
||||
}
|
||||
|
||||
@ -1277,7 +1272,7 @@ unmessage_in_echo_area ()
|
||||
}
|
||||
|
||||
/* A place to build a message. */
|
||||
static char *message_buffer = (char *)NULL;
|
||||
static char *message_buffer = NULL;
|
||||
static int message_buffer_index = 0;
|
||||
static int message_buffer_size = 0;
|
||||
|
||||
@ -1290,7 +1285,7 @@ message_buffer_resize (length)
|
||||
if (!message_buffer)
|
||||
{
|
||||
message_buffer_size = length + 1;
|
||||
message_buffer = (char *)xmalloc (message_buffer_size);
|
||||
message_buffer = xmalloc (message_buffer_size);
|
||||
message_buffer_index = 0;
|
||||
}
|
||||
|
||||
@ -1328,14 +1323,44 @@ build_message_buffer (format, arg1, arg2)
|
||||
else
|
||||
{
|
||||
char c;
|
||||
char *fmt_start = format + i;
|
||||
char *fmt;
|
||||
int fmt_len, formatted_len;
|
||||
|
||||
c = format[++i];
|
||||
i++;
|
||||
while (format[i] && strchr ("-. +0123456789", format[i]))
|
||||
i++;
|
||||
c = format[i];
|
||||
|
||||
if (c == '\0')
|
||||
abort ();
|
||||
|
||||
fmt_len = format + i - fmt_start + 1;
|
||||
fmt = (char *) xmalloc (fmt_len + 1);
|
||||
strncpy (fmt, fmt_start, fmt_len);
|
||||
fmt[fmt_len] = '\0';
|
||||
|
||||
/* If we have "%-98s", maybe 98 calls for a longer string. */
|
||||
if (fmt_len > 2)
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = 0; j < fmt_len; j++)
|
||||
if (isdigit (fmt[j]))
|
||||
break;
|
||||
|
||||
formatted_len = atoi (fmt + j);
|
||||
}
|
||||
else
|
||||
formatted_len = c == 's' ? 0 : 1; /* %s can produce empty string */
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '%': /* Insert a percent sign. */
|
||||
message_buffer_resize (len + 1);
|
||||
message_buffer[message_buffer_index++] = '%';
|
||||
message_buffer_resize (len + formatted_len);
|
||||
sprintf
|
||||
(message_buffer + message_buffer_index, fmt, "%");
|
||||
message_buffer_index += formatted_len;
|
||||
break;
|
||||
|
||||
case 's': /* Insert the current arg as a string. */
|
||||
@ -1346,9 +1371,11 @@ build_message_buffer (format, arg1, arg2)
|
||||
string = (char *)args[arg_index++];
|
||||
string_len = strlen (string);
|
||||
|
||||
if (formatted_len > string_len)
|
||||
string_len = formatted_len;
|
||||
message_buffer_resize (len + string_len);
|
||||
sprintf
|
||||
(message_buffer + message_buffer_index, "%s", string);
|
||||
(message_buffer + message_buffer_index, fmt, string);
|
||||
message_buffer_index += string_len;
|
||||
}
|
||||
break;
|
||||
@ -1361,9 +1388,10 @@ build_message_buffer (format, arg1, arg2)
|
||||
long_val = (long)args[arg_index++];
|
||||
integer = (int)long_val;
|
||||
|
||||
message_buffer_resize (len + 32);
|
||||
message_buffer_resize (len + formatted_len > 32
|
||||
? formatted_len : 32);
|
||||
sprintf
|
||||
(message_buffer + message_buffer_index, "%d", integer);
|
||||
(message_buffer + message_buffer_index, fmt, integer);
|
||||
message_buffer_index = strlen (message_buffer);
|
||||
}
|
||||
break;
|
||||
@ -1376,14 +1404,17 @@ build_message_buffer (format, arg1, arg2)
|
||||
long_val = (long)args[arg_index++];
|
||||
character = (int)long_val;
|
||||
|
||||
message_buffer_resize (len + 1);
|
||||
message_buffer[message_buffer_index++] = character;
|
||||
message_buffer_resize (len + formatted_len);
|
||||
sprintf
|
||||
(message_buffer + message_buffer_index, fmt, character);
|
||||
message_buffer_index += formatted_len;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
free (fmt);
|
||||
}
|
||||
}
|
||||
message_buffer[message_buffer_index] = '\0';
|
||||
@ -1411,15 +1442,16 @@ message_buffer_to_node ()
|
||||
{
|
||||
NODE *node;
|
||||
|
||||
node = (NODE *)xmalloc (sizeof (NODE));
|
||||
node->filename = (char *)NULL;
|
||||
node->parent = (char *)NULL;
|
||||
node->nodename = (char *)NULL;
|
||||
node = xmalloc (sizeof (NODE));
|
||||
node->filename = NULL;
|
||||
node->parent = NULL;
|
||||
node->nodename = NULL;
|
||||
node->flags = 0;
|
||||
node->display_pos =0;
|
||||
|
||||
/* Make sure that this buffer ends with a newline. */
|
||||
node->nodelen = 1 + strlen (message_buffer);
|
||||
node->contents = (char *)xmalloc (1 + node->nodelen);
|
||||
node->contents = xmalloc (1 + node->nodelen);
|
||||
strcpy (node->contents, message_buffer);
|
||||
node->contents[node->nodelen - 1] = '\n';
|
||||
node->contents[node->nodelen] = '\0';
|
||||
|
@ -1,13 +1,13 @@
|
||||
/* Getopt for GNU.
|
||||
NOTE: getopt is now part of the C library, so if you don't know what
|
||||
"Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
|
||||
"Keep this file name-space clean" means, talk to drepper@gnu.org
|
||||
before changing it!
|
||||
|
||||
Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97
|
||||
Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98
|
||||
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.
|
||||
Bugs can be reported to bug-glibc@gnu.org.
|
||||
|
||||
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
|
||||
@ -27,19 +27,19 @@
|
||||
/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
|
||||
Ditto for AIX 3.2 and <stdlib.h>. */
|
||||
#ifndef _NO_PROTO
|
||||
#define _NO_PROTO
|
||||
# define _NO_PROTO
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#if !defined (__STDC__) || !__STDC__
|
||||
#if !defined __STDC__ || !__STDC__
|
||||
/* This is a separate conditional since some stdc systems
|
||||
reject `defined (const)'. */
|
||||
#ifndef const
|
||||
#define const
|
||||
#endif
|
||||
# ifndef const
|
||||
# define const
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
@ -53,11 +53,11 @@
|
||||
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
|
||||
#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
|
||||
@ -68,26 +68,26 @@
|
||||
#ifdef __GNU_LIBRARY__
|
||||
/* Don't include stdlib.h for non-GNU C libraries because some of them
|
||||
contain conflicting prototypes for getopt. */
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
# include <stdlib.h>
|
||||
# include <unistd.h>
|
||||
#endif /* GNU C library. */
|
||||
|
||||
#ifdef VMS
|
||||
#include <unixlib.h>
|
||||
#if HAVE_STRING_H - 0
|
||||
#include <string.h>
|
||||
#endif
|
||||
# include <unixlib.h>
|
||||
# if HAVE_STRING_H - 0
|
||||
# include <string.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef _
|
||||
/* This is for other GNU distributions with internationalized messages.
|
||||
When compiling libc, the _ macro is predefined. */
|
||||
#ifdef HAVE_LIBINTL_H
|
||||
# include <libintl.h>
|
||||
# define _(msgid) gettext (msgid)
|
||||
#else
|
||||
# define _(msgid) (msgid)
|
||||
#endif
|
||||
# ifdef HAVE_LIBINTL_H
|
||||
# include <libintl.h>
|
||||
# define _(msgid) gettext (msgid)
|
||||
# else
|
||||
# define _(msgid) (msgid)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* This version of `getopt' appears to the caller like standard Unix `getopt'
|
||||
@ -197,14 +197,22 @@ static char *posixly_correct;
|
||||
because there are many ways it can cause trouble.
|
||||
On some systems, it contains special magic macros that don't work
|
||||
in GCC. */
|
||||
#include <string.h>
|
||||
#define my_index strchr
|
||||
# include <string.h>
|
||||
# define my_index strchr
|
||||
#else
|
||||
|
||||
# if HAVE_STRING_H
|
||||
# include <string.h>
|
||||
# else
|
||||
# include <strings.h>
|
||||
# endif
|
||||
|
||||
/* Avoid depending on library functions or files
|
||||
whose names are inconsistent. */
|
||||
|
||||
char *getenv ();
|
||||
#ifndef getenv
|
||||
extern char *getenv ();
|
||||
#endif
|
||||
|
||||
static char *
|
||||
my_index (str, chr)
|
||||
@ -225,11 +233,11 @@ my_index (str, chr)
|
||||
#ifdef __GNUC__
|
||||
/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
|
||||
That was relevant to code that was here before. */
|
||||
#if !defined (__STDC__) || !__STDC__
|
||||
# if (!defined __STDC__ || !__STDC__) && !defined strlen
|
||||
/* gcc with -traditional declares the built-in strlen to return int,
|
||||
and has done so at least since version 2.4.5. -- rms. */
|
||||
extern int strlen (const char *);
|
||||
#endif /* not __STDC__ */
|
||||
# endif /* not __STDC__ */
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#endif /* not __GNU_LIBRARY__ */
|
||||
@ -292,7 +300,7 @@ text_set_element (__libc_subinit, store_args_and_env);
|
||||
`first_nonopt' and `last_nonopt' are relocated so that they describe
|
||||
the new indices of the non-options in ARGV after they are moved. */
|
||||
|
||||
#if defined (__STDC__) && __STDC__
|
||||
#if defined __STDC__ && __STDC__
|
||||
static void exchange (char **);
|
||||
#endif
|
||||
|
||||
@ -378,7 +386,7 @@ exchange (argv)
|
||||
|
||||
/* Initialize the internal data when the first call is made. */
|
||||
|
||||
#if defined (__STDC__) && __STDC__
|
||||
#if defined __STDC__ && __STDC__
|
||||
static const char *_getopt_initialize (int, char *const *, const char *);
|
||||
#endif
|
||||
static const char *
|
||||
@ -527,11 +535,11 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||
from the shell indicating it is not an option. The later information
|
||||
is only used when the used in the GNU libc. */
|
||||
#ifdef _LIBC
|
||||
#define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \
|
||||
|| (optind < nonoption_flags_len \
|
||||
&& __getopt_nonoption_flags[optind] == '1'))
|
||||
# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \
|
||||
|| (optind < nonoption_flags_len \
|
||||
&& __getopt_nonoption_flags[optind] == '1'))
|
||||
#else
|
||||
#define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
|
||||
# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
|
||||
#endif
|
||||
|
||||
if (nextchar == NULL || *nextchar == '\0')
|
||||
|
@ -2,7 +2,7 @@
|
||||
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.
|
||||
Bugs can be reported to bug-glibc@gnu.org.
|
||||
|
||||
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
|
||||
|
@ -1,8 +1,9 @@
|
||||
/* 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.
|
||||
Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98
|
||||
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.
|
||||
Bugs can be reported to bug-glibc@gnu.org.
|
||||
|
||||
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
|
||||
@ -25,7 +26,7 @@
|
||||
|
||||
#include "getopt.h"
|
||||
|
||||
#if !defined (__STDC__) || !__STDC__
|
||||
#if !defined __STDC__ || !__STDC__
|
||||
/* This is a separate conditional since some stdc systems
|
||||
reject `defined (const)'. */
|
||||
#ifndef const
|
||||
@ -44,7 +45,7 @@
|
||||
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
|
||||
#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
|
||||
#include <gnu-versions.h>
|
||||
#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
|
||||
#define ELIDE_CODE
|
||||
|
182
contrib/texinfo/lib/libintl.h
Normal file
182
contrib/texinfo/lib/libintl.h
Normal file
@ -0,0 +1,182 @@
|
||||
/* Message catalogs for internationalization.
|
||||
Copyright (C) 1995, 1996, 1997, 1998 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
|
||||
#ifndef _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__ || defined __cplusplus
|
||||
# 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) ((char *) Domainname)
|
||||
# define bindtextdomain(Domainname, Dirname) ((char *) Dirname)
|
||||
|
||||
#endif
|
||||
|
||||
/* @@ begin of epilog @@ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
37
contrib/texinfo/lib/substring.c
Normal file
37
contrib/texinfo/lib/substring.c
Normal file
@ -0,0 +1,37 @@
|
||||
/* substring.c -- extract substring.
|
||||
$Id: substring.c,v 1.1 1999/02/17 22:30:10 karl Exp $
|
||||
|
||||
Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "system.h"
|
||||
|
||||
char *
|
||||
substring (start, end)
|
||||
char *start;
|
||||
char *end;
|
||||
{
|
||||
char *result = xmalloc (end - start + 1);
|
||||
char *scan_result = result;
|
||||
char *scan = start;
|
||||
|
||||
while (scan < end)
|
||||
*scan_result++ = *scan++;
|
||||
|
||||
*scan_result = 0;
|
||||
return result;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* system.h: System-dependent declarations. Include this first.
|
||||
$Id: system.h,v 1.5 1997/07/31 20:34:36 karl Exp $
|
||||
/* system.h: system-dependent declarations; include this first.
|
||||
$Id: system.h,v 1.14 1999/07/17 21:11:34 karl Exp $
|
||||
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 98, 99 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
|
||||
@ -37,7 +37,22 @@
|
||||
#ifdef HAVE_LOCALE_H
|
||||
#include <locale.h>
|
||||
#endif
|
||||
#ifndef HAVE_SETLOCALE
|
||||
#define setlocale(category,locale) /* empty */
|
||||
#endif
|
||||
|
||||
/* For gettext (NLS). */
|
||||
#include <libintl.h>
|
||||
#define _(String) gettext (String)
|
||||
#define N_(String) (String)
|
||||
|
||||
#ifdef STDC_HEADERS
|
||||
#define getopt system_getopt
|
||||
#include <stdlib.h>
|
||||
#undef getopt
|
||||
#else
|
||||
extern char *getenv ();
|
||||
#endif
|
||||
|
||||
/* Don't use bcopy! Use memmove if source and destination may overlap,
|
||||
memcpy otherwise. */
|
||||
@ -51,18 +66,6 @@
|
||||
char *memchr ();
|
||||
#endif
|
||||
|
||||
#ifdef STDC_HEADERS
|
||||
#define getopt system_getopt
|
||||
#include <stdlib.h>
|
||||
#undef getopt
|
||||
#else
|
||||
extern char *getenv ();
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRERROR
|
||||
extern char *strerror ();
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#ifndef errno
|
||||
extern int errno;
|
||||
@ -71,7 +74,29 @@ extern int errno;
|
||||
#include <perror.h>
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_DECL_STRERROR
|
||||
extern char *strerror ();
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_DECL_STRCASECMP
|
||||
extern int strcasecmp ();
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_DECL_STRNCASECMP
|
||||
extern int strncasecmp ();
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_DECL_STRCOLL
|
||||
extern int strcoll ();
|
||||
#endif
|
||||
|
||||
#include <sys/stat.h>
|
||||
#if STAT_MACROS_BROKEN
|
||||
# undef S_ISDIR
|
||||
#endif
|
||||
#if !defined(S_ISDIR) && defined(S_IFDIR)
|
||||
# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_FILE_H
|
||||
#include <sys/file.h>
|
||||
@ -89,6 +114,77 @@ extern int errno;
|
||||
#endif /* not HAVE_FCNTL_H */
|
||||
#endif /* not O_RDONLY */
|
||||
|
||||
/* MS-DOS and similar non-Posix systems have some peculiarities:
|
||||
- they distinguish between binary and text files;
|
||||
- they use both `/' and `\\' as directory separator in file names;
|
||||
- they can have a drive letter X: prepended to a file name;
|
||||
- they have a separate root directory on each drive;
|
||||
- their filesystems are case-insensitive;
|
||||
- directories in environment variables (like INFOPATH) are separated
|
||||
by `;' rather than `:';
|
||||
- text files can have their lines ended either with \n or with \r\n pairs;
|
||||
|
||||
These are all parameterized here except the last, which is
|
||||
handled by the source code as appropriate (mostly, in info/). */
|
||||
#ifndef O_BINARY
|
||||
# ifdef _O_BINARY
|
||||
# define O_BINARY _O_BINARY
|
||||
# else
|
||||
# define O_BINARY 0
|
||||
# endif
|
||||
#endif /* O_BINARY */
|
||||
|
||||
#if O_BINARY
|
||||
# include <io.h>
|
||||
# ifdef __MSDOS__
|
||||
# include <limits.h>
|
||||
# ifdef __DJGPP__
|
||||
# define HAVE_LONG_FILENAMES(dir) (pathconf (dir, _PC_NAME_MAX) > 12)
|
||||
# define NULL_DEVICE "/dev/null"
|
||||
# else /* !__DJGPP__ */
|
||||
# define HAVE_LONG_FILENAMES(dir) (0)
|
||||
# define NULL_DEVICE "NUL"
|
||||
# endif /* !__DJGPP__ */
|
||||
# define SET_SCREEN_SIZE_HELPER terminal_prep_terminal()
|
||||
# define DEFAULT_INFO_PRINT_COMMAND ">PRN"
|
||||
# else /* !__MSDOS__ */
|
||||
# define setmode(f,m) _setmode(f,m)
|
||||
# define HAVE_LONG_FILENAMES(dir) (1)
|
||||
# define NULL_DEVICE "NUL"
|
||||
# endif /* !__MSDOS__ */
|
||||
# define SET_BINARY(f) do {if (!isatty(f)) setmode(f,O_BINARY);} while(0)
|
||||
# define FOPEN_RBIN "rb"
|
||||
# define FOPEN_WBIN "wb"
|
||||
# define IS_SLASH(c) ((c) == '/' || (c) == '\\')
|
||||
# define HAVE_DRIVE(n) ((n)[0] && (n)[1] == ':')
|
||||
# define IS_ABSOLUTE(n) (IS_SLASH((n)[0]) || ((n)[0] && (n)[1] == ':'))
|
||||
# define FILENAME_CMP strcasecmp
|
||||
# define FILENAME_CMPN strncasecmp
|
||||
# define PATH_SEP ";"
|
||||
# define STRIP_DOT_EXE 1
|
||||
# define DEFAULT_TMPDIR "c:/"
|
||||
# define PIPE_USE_FORK 0
|
||||
#else /* not O_BINARY */
|
||||
# define SET_BINARY(f) (void)0
|
||||
# define FOPEN_RBIN "r"
|
||||
# define FOPEN_WBIN "w"
|
||||
# define IS_SLASH(c) ((c) == '/')
|
||||
# define HAVE_DRIVE(n) (0)
|
||||
# define IS_ABSOLUTE(n) ((n)[0] == '/')
|
||||
# define FILENAME_CMP strcmp
|
||||
# define FILENAME_CMPN strncmp
|
||||
# define HAVE_LONG_FILENAMES(dir) (1)
|
||||
# define PATH_SEP ":"
|
||||
# define STRIP_DOT_EXE 0
|
||||
# ifdef VMS
|
||||
# define DEFAULT_TMPDIR "sys$scratch:"
|
||||
# else
|
||||
# define DEFAULT_TMPDIR "/tmp/"
|
||||
# endif
|
||||
# define NULL_DEVICE "/dev/null"
|
||||
# define PIPE_USE_FORK 1
|
||||
#endif /* not O_BINARY */
|
||||
|
||||
#ifdef HAVE_PWD_H
|
||||
#include <pwd.h>
|
||||
#endif
|
||||
@ -98,5 +194,10 @@ struct passwd *getpwnam ();
|
||||
/* Our library routines not included in any system library. */
|
||||
extern void *xmalloc (), *xrealloc ();
|
||||
extern char *xstrdup ();
|
||||
extern void xexit ();
|
||||
extern char *substring ();
|
||||
|
||||
/* For convenience. */
|
||||
#define STREQ(s1,s2) (strcmp (s1, s2) == 0)
|
||||
|
||||
#endif /* TEXINFO_SYSTEM_H */
|
||||
|
86
contrib/texinfo/lib/xexit.c
Normal file
86
contrib/texinfo/lib/xexit.c
Normal file
@ -0,0 +1,86 @@
|
||||
/* xexit.c -- exit with attention to return values and closing stdout.
|
||||
$Id: xexit.c,v 1.5 1999/02/19 14:13:51 karl Exp $
|
||||
|
||||
Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "system.h"
|
||||
|
||||
/* SunOS 4.1.1 gets STDC_HEADERS defined, but it doesn't provide
|
||||
EXIT_FAILURE. So far no system has defined one of EXIT_FAILURE and
|
||||
EXIT_SUCCESS without the other. */
|
||||
#ifdef EXIT_SUCCESS
|
||||
/* The following test is to work around the gross typo in
|
||||
systems like Sony NEWS-OS Release 4.0C, whereby EXIT_FAILURE
|
||||
is defined to 0, not 1. */
|
||||
# if !EXIT_FAILURE
|
||||
# undef EXIT_FAILURE
|
||||
# define EXIT_FAILURE 1
|
||||
# endif
|
||||
#else /* not EXIT_SUCCESS */
|
||||
# ifdef VMS /* these values suppress some messages; from gnuplot */
|
||||
# define EXIT_SUCCESS 1
|
||||
# define EXIT_FAILURE 0x10000002
|
||||
# else /* not VMS */
|
||||
# define EXIT_SUCCESS 0
|
||||
# define EXIT_FAILURE 1
|
||||
# endif /* not VMS */
|
||||
#endif /* not EXIT_SUCCESS */
|
||||
|
||||
|
||||
/* Flush stdout first, exit if failure. Otherwise, if EXIT_STATUS is
|
||||
zero, exit successfully, else unsuccessfully. */
|
||||
|
||||
void
|
||||
xexit (exit_status)
|
||||
int exit_status;
|
||||
{
|
||||
if (ferror (stdout))
|
||||
{
|
||||
fprintf (stderr, "ferror on stdout");
|
||||
exit_status = 1;
|
||||
}
|
||||
else if (fflush (stdout) != 0)
|
||||
{
|
||||
fprintf (stderr, "fflush error on stdout");
|
||||
exit_status = 1;
|
||||
}
|
||||
|
||||
exit_status = exit_status == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
|
||||
exit (exit_status);
|
||||
}
|
||||
|
||||
|
||||
/* Why do we care about stdout you may ask? Here's why, from Jim
|
||||
Meyering in the lib/closeout.c file. */
|
||||
|
||||
/* If a program writes *anything* to stdout, that program should close
|
||||
stdout and make sure that the close succeeds. Otherwise, suppose that
|
||||
you go to the extreme of checking the return status of every function
|
||||
that does an explicit write to stdout. The last printf can succeed in
|
||||
writing to the internal stream buffer, and yet the fclose(stdout) could
|
||||
still fail (due e.g., to a disk full error) when it tries to write
|
||||
out that buffered data. Thus, you would be left with an incomplete
|
||||
output file and the offending program would exit successfully.
|
||||
|
||||
Besides, it's wasteful to check the return value from every call
|
||||
that writes to stdout -- just let the internal stream state record
|
||||
the failure. That's what the ferror test is checking below.
|
||||
|
||||
It's important to detect such failures and exit nonzero because many
|
||||
tools (most notably `make' and other build-management systems) depend
|
||||
on being able to detect failure in other tools via their exit status. */
|
@ -1,8 +1,8 @@
|
||||
makeinfo is a standalone program to convert Texinfo source into Info
|
||||
files readable with standalone info or M-x info in Emacs.
|
||||
|
||||
makeinfo can also output plain ASCII. Work to support HTML and Troff
|
||||
output is almost complete.
|
||||
makeinfo can also output plain ASCII (with --no-headers)
|
||||
or HTML (with --html).
|
||||
|
||||
The Emacs function M-x texinfo-format-buffer does more or less the same
|
||||
job, but makeinfo is faster and gives better error messages.
|
||||
|
1121
contrib/texinfo/makeinfo/cmds.c
Normal file
1121
contrib/texinfo/makeinfo/cmds.c
Normal file
File diff suppressed because it is too large
Load Diff
50
contrib/texinfo/makeinfo/cmds.h
Normal file
50
contrib/texinfo/makeinfo/cmds.h
Normal file
@ -0,0 +1,50 @@
|
||||
/* cmds.h -- declarations for cmds.c.
|
||||
$Id: cmds.h,v 1.4 1999/04/25 20:43:51 karl Exp $
|
||||
|
||||
Copyright (C) 1998, 99 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 CMDS_H
|
||||
#define CMDS_H
|
||||
|
||||
/* The three arguments a command can get are a flag saying whether it is
|
||||
before argument parsing (START) or after (END), the starting position
|
||||
of the arguments, and the ending position. */
|
||||
typedef void COMMAND_FUNCTION (); /* So we can say COMMAND_FUNCTION *foo; */
|
||||
|
||||
/* Each command has an associated function. When the command is
|
||||
encountered in the text, the associated function is called with START
|
||||
as the argument. If the function expects arguments in braces, it
|
||||
remembers itself on the stack. When the corresponding close brace is
|
||||
encountered, the function is called with END as the argument. */
|
||||
#define START 0
|
||||
#define END 1
|
||||
|
||||
/* Does the command expect braces? */
|
||||
#define NO_BRACE_ARGS 0
|
||||
#define BRACE_ARGS 1
|
||||
#define MAYBE_BRACE_ARGS 2
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *name;
|
||||
COMMAND_FUNCTION *proc;
|
||||
int argument_in_braces;
|
||||
} COMMAND;
|
||||
|
||||
extern COMMAND command_table[];
|
||||
|
||||
#endif /* !CMDS_H */
|
663
contrib/texinfo/makeinfo/defun.c
Normal file
663
contrib/texinfo/makeinfo/defun.c
Normal file
@ -0,0 +1,663 @@
|
||||
/* defun.c -- @defun and friends.
|
||||
$Id: defun.c,v 1.11 1999/07/11 16:50:19 karl Exp $
|
||||
|
||||
Copyright (C) 1998, 99 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "system.h"
|
||||
#include "defun.h"
|
||||
#include "insertion.h"
|
||||
#include "makeinfo.h"
|
||||
|
||||
|
||||
#define DEFUN_SELF_DELIMITING(c) \
|
||||
((c) == '(' || (c) == ')' || (c) == '[' || (c) == ']')
|
||||
|
||||
struct token_accumulator
|
||||
{
|
||||
unsigned int length;
|
||||
unsigned int index;
|
||||
char **tokens;
|
||||
};
|
||||
|
||||
static void
|
||||
initialize_token_accumulator (accumulator)
|
||||
struct token_accumulator *accumulator;
|
||||
{
|
||||
accumulator->length = 0;
|
||||
accumulator->index = 0;
|
||||
accumulator->tokens = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
accumulate_token (accumulator, token)
|
||||
struct token_accumulator *accumulator;
|
||||
char *token;
|
||||
{
|
||||
if (accumulator->index >= accumulator->length)
|
||||
{
|
||||
accumulator->length += 10;
|
||||
accumulator->tokens = xrealloc (accumulator->tokens,
|
||||
(accumulator->length * sizeof (char *)));
|
||||
}
|
||||
accumulator->tokens[accumulator->index] = token;
|
||||
accumulator->index += 1;
|
||||
}
|
||||
|
||||
/* Given STRING_POINTER pointing at an open brace, skip forward and return a
|
||||
pointer to just past the matching close brace. */
|
||||
static int
|
||||
scan_group_in_string (string_pointer)
|
||||
char **string_pointer;
|
||||
{
|
||||
char *scan_string = (*string_pointer) + 1;
|
||||
unsigned int level = 1;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
int c;
|
||||
if (level == 0)
|
||||
{
|
||||
*string_pointer = scan_string;
|
||||
return 1;
|
||||
}
|
||||
c = *scan_string++;
|
||||
if (c == 0)
|
||||
{
|
||||
/* Tweak line_number to compensate for fact that
|
||||
we gobbled the whole line before coming here. */
|
||||
line_number -= 1;
|
||||
line_error (_("Missing `}' in @def arg"));
|
||||
line_number += 1;
|
||||
*string_pointer = scan_string - 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (c == '{')
|
||||
level += 1;
|
||||
if (c == '}')
|
||||
level -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return a list of tokens from the contents of STRING.
|
||||
Commands and brace-delimited groups count as single tokens.
|
||||
Contiguous whitespace characters are converted to a token
|
||||
consisting of a single space. */
|
||||
static char **
|
||||
args_from_string (string)
|
||||
char *string;
|
||||
{
|
||||
struct token_accumulator accumulator;
|
||||
char *token_start, *token_end;
|
||||
char *scan_string = string;
|
||||
|
||||
initialize_token_accumulator (&accumulator);
|
||||
|
||||
while (*scan_string)
|
||||
{ /* Replace arbitrary whitespace by a single space. */
|
||||
if (whitespace (*scan_string))
|
||||
{
|
||||
scan_string += 1;
|
||||
while (whitespace (*scan_string))
|
||||
scan_string += 1;
|
||||
accumulate_token ((&accumulator), (xstrdup (" ")));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Commands count as single tokens. */
|
||||
if (*scan_string == COMMAND_PREFIX)
|
||||
{
|
||||
token_start = scan_string;
|
||||
scan_string += 1;
|
||||
if (self_delimiting (*scan_string))
|
||||
scan_string += 1;
|
||||
else
|
||||
{
|
||||
int c;
|
||||
while (1)
|
||||
{
|
||||
c = *scan_string++;
|
||||
|
||||
if ((c == 0) || (c == '{') || (whitespace (c)))
|
||||
{
|
||||
scan_string -= 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (*scan_string == '{')
|
||||
{
|
||||
char *s = scan_string;
|
||||
(void) scan_group_in_string (&s);
|
||||
scan_string = s;
|
||||
}
|
||||
}
|
||||
token_end = scan_string;
|
||||
}
|
||||
|
||||
/* Parentheses and brackets are self-delimiting. */
|
||||
else if (DEFUN_SELF_DELIMITING (*scan_string))
|
||||
{
|
||||
token_start = scan_string;
|
||||
scan_string += 1;
|
||||
token_end = scan_string;
|
||||
}
|
||||
|
||||
/* Open brace introduces a group that is a single token. */
|
||||
else if (*scan_string == '{')
|
||||
{
|
||||
char *s = scan_string;
|
||||
int balanced = scan_group_in_string (&s);
|
||||
|
||||
token_start = scan_string + 1;
|
||||
scan_string = s;
|
||||
token_end = balanced ? (scan_string - 1) : scan_string;
|
||||
}
|
||||
|
||||
/* Otherwise a token is delimited by whitespace, parentheses,
|
||||
brackets, or braces. A token is also ended by a command. */
|
||||
else
|
||||
{
|
||||
token_start = scan_string;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
int c;
|
||||
|
||||
c = *scan_string++;
|
||||
|
||||
/* Do not back up if we're looking at a }; since the only
|
||||
valid }'s are those matched with {'s, we want to give
|
||||
an error. If we back up, we go into an infinite loop. */
|
||||
if (!c || whitespace (c) || DEFUN_SELF_DELIMITING (c)
|
||||
|| c == '{')
|
||||
{
|
||||
scan_string--;
|
||||
break;
|
||||
}
|
||||
|
||||
/* If we encounter a command embedded within a token,
|
||||
then end the token. */
|
||||
if (c == COMMAND_PREFIX)
|
||||
{
|
||||
scan_string--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
token_end = scan_string;
|
||||
}
|
||||
|
||||
accumulate_token (&accumulator, substring (token_start, token_end));
|
||||
}
|
||||
accumulate_token (&accumulator, NULL);
|
||||
return accumulator.tokens;
|
||||
}
|
||||
|
||||
static void
|
||||
process_defun_args (defun_args, auto_var_p)
|
||||
char **defun_args;
|
||||
int auto_var_p;
|
||||
{
|
||||
int pending_space = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
char *defun_arg = *defun_args++;
|
||||
|
||||
if (defun_arg == NULL)
|
||||
break;
|
||||
|
||||
if (defun_arg[0] == ' ')
|
||||
{
|
||||
pending_space = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pending_space)
|
||||
{
|
||||
add_char (' ');
|
||||
pending_space = 0;
|
||||
}
|
||||
|
||||
if (DEFUN_SELF_DELIMITING (defun_arg[0]))
|
||||
add_char (defun_arg[0]);
|
||||
else if (defun_arg[0] == '&')
|
||||
if (html)
|
||||
{
|
||||
defun_arg = escape_string (xstrdup (defun_arg));
|
||||
add_word (defun_arg);
|
||||
free (defun_arg);
|
||||
}
|
||||
else
|
||||
add_word (defun_arg);
|
||||
else if (defun_arg[0] == COMMAND_PREFIX)
|
||||
execute_string ("%s", defun_arg);
|
||||
else if (auto_var_p)
|
||||
if (html)
|
||||
{
|
||||
defun_arg = escape_string (xstrdup (defun_arg));
|
||||
add_word (defun_arg);
|
||||
free (defun_arg);
|
||||
}
|
||||
else
|
||||
add_word (defun_arg);
|
||||
else
|
||||
add_word (defun_arg);
|
||||
}
|
||||
}
|
||||
|
||||
static char *
|
||||
next_nonwhite_defun_arg (arg_pointer)
|
||||
char ***arg_pointer;
|
||||
{
|
||||
char **scan = (*arg_pointer);
|
||||
char *arg = (*scan++);
|
||||
|
||||
if ((arg != 0) && (*arg == ' '))
|
||||
arg = *scan++;
|
||||
|
||||
if (arg == 0)
|
||||
scan -= 1;
|
||||
|
||||
*arg_pointer = scan;
|
||||
|
||||
return (arg == 0) ? "" : arg;
|
||||
}
|
||||
|
||||
|
||||
/* This is needed also in insertion.c. */
|
||||
|
||||
enum insertion_type
|
||||
get_base_type (type)
|
||||
enum insertion_type type;
|
||||
{
|
||||
enum insertion_type base_type;
|
||||
switch (type)
|
||||
{
|
||||
case defivar: base_type = defcv; break;
|
||||
case defmac: base_type = deffn; break;
|
||||
case defmethod: base_type = defop; break;
|
||||
case defopt: base_type = defvr; break;
|
||||
case defspec: base_type = deffn; break;
|
||||
case deftypefun: base_type = deftypefn; break;
|
||||
case deftypeivar: base_type = deftypeivar; break;
|
||||
case deftypemethod: base_type = deftypemethod; break;
|
||||
case deftypeop: base_type = deftypeop; break;
|
||||
case deftypevar: base_type = deftypevr; break;
|
||||
case defun: base_type = deffn; break;
|
||||
case defvar: base_type = defvr; break;
|
||||
default:
|
||||
base_type = type;
|
||||
break;
|
||||
}
|
||||
|
||||
return base_type;
|
||||
}
|
||||
|
||||
/* Make the defun type insertion.
|
||||
TYPE says which insertion this is.
|
||||
X_P, if nonzero, says not to start a new insertion. */
|
||||
static void
|
||||
defun_internal (type, x_p)
|
||||
enum insertion_type type;
|
||||
int x_p;
|
||||
{
|
||||
enum insertion_type base_type;
|
||||
char **defun_args, **scan_args;
|
||||
char *category, *defined_name, *type_name, *type_name2;
|
||||
|
||||
{
|
||||
char *line;
|
||||
|
||||
/* The @def.. line is the only place in Texinfo where you are
|
||||
allowed to use unquoted braces that don't delimit arguments of
|
||||
a command or a macro; in any other place it will trigger an
|
||||
error message from the reader loop. The special handling of
|
||||
this case inside `args_from_string' is an extra special hack
|
||||
which allows this. The side effect is that if we try to expand
|
||||
the rest of the line below, the recursive reader loop will
|
||||
signal an error if there are brace-delimited arguments on that line.
|
||||
|
||||
The best solution to this would be to change the syntax of
|
||||
@def.. commands so that it doesn't violate Texinfo's own rules.
|
||||
But it's probably too late for this now, as it will break a lot
|
||||
of existing manuals.
|
||||
|
||||
Unfortunately, this means that you can't call macros, use @value, etc.
|
||||
inside @def.. commands, sigh. */
|
||||
get_rest_of_line (0, &line);
|
||||
defun_args = (args_from_string (line));
|
||||
free (line);
|
||||
}
|
||||
|
||||
scan_args = defun_args;
|
||||
|
||||
/* Get base type and category string. */
|
||||
base_type = get_base_type (type);
|
||||
|
||||
/* xx all these const strings should be determined upon
|
||||
documentlanguage argument and NOT via gettext (kama). */
|
||||
switch (type)
|
||||
{
|
||||
case defun:
|
||||
case deftypefun:
|
||||
category = _("Function");
|
||||
break;
|
||||
case defmac:
|
||||
category = _("Macro");
|
||||
break;
|
||||
case defspec:
|
||||
category = _("Special Form");
|
||||
break;
|
||||
case defvar:
|
||||
case deftypevar:
|
||||
category = _("Variable");
|
||||
break;
|
||||
case defopt:
|
||||
category = _("User Option");
|
||||
break;
|
||||
case defivar:
|
||||
case deftypeivar:
|
||||
category = _("Instance Variable");
|
||||
break;
|
||||
case defmethod:
|
||||
case deftypemethod:
|
||||
category = _("Method");
|
||||
break;
|
||||
default:
|
||||
category = next_nonwhite_defun_arg (&scan_args);
|
||||
break;
|
||||
}
|
||||
|
||||
/* The class name. */
|
||||
if ((base_type == deftypefn)
|
||||
|| (base_type == deftypevr)
|
||||
|| (base_type == defcv)
|
||||
|| (base_type == defop)
|
||||
|| (base_type == deftypeivar)
|
||||
|| (base_type == deftypemethod)
|
||||
|| (base_type == deftypeop)
|
||||
)
|
||||
type_name = next_nonwhite_defun_arg (&scan_args);
|
||||
|
||||
/* The type name for typed languages. */
|
||||
if (base_type == deftypemethod
|
||||
|| base_type == deftypeivar
|
||||
|| base_type == deftypeop
|
||||
)
|
||||
type_name2 = next_nonwhite_defun_arg (&scan_args);
|
||||
|
||||
/* The function or whatever that's actually being defined. */
|
||||
defined_name = next_nonwhite_defun_arg (&scan_args);
|
||||
|
||||
/* This hack exists solely for the purposes of formatting the Texinfo
|
||||
manual. I couldn't think of a better way. The token might be a
|
||||
simple @@ followed immediately by more text. If this is the case,
|
||||
then the next defun arg is part of this one, and we should
|
||||
concatenate them. */
|
||||
if (*scan_args && **scan_args && !whitespace (**scan_args)
|
||||
&& STREQ (defined_name, "@@"))
|
||||
{
|
||||
char *tem = xmalloc (3 + strlen (scan_args[0]));
|
||||
|
||||
sprintf (tem, "@@%s", scan_args[0]);
|
||||
|
||||
free (scan_args[0]);
|
||||
scan_args[0] = tem;
|
||||
scan_args++;
|
||||
defined_name = tem;
|
||||
}
|
||||
|
||||
if (!x_p)
|
||||
begin_insertion (type);
|
||||
|
||||
/* Write the definition header line.
|
||||
This should start at the normal indentation. */
|
||||
current_indent -= default_indentation_increment;
|
||||
start_paragraph ();
|
||||
|
||||
if (html && !x_p)
|
||||
/* Start the definition on new paragraph. */
|
||||
add_word ("<p>\n");
|
||||
|
||||
if (!html)
|
||||
switch (base_type)
|
||||
{
|
||||
case deffn:
|
||||
case defvr:
|
||||
case deftp:
|
||||
execute_string (" -- %s: %s", category, defined_name);
|
||||
break;
|
||||
case deftypefn:
|
||||
case deftypevr:
|
||||
execute_string (" -- %s: %s %s", category, type_name, defined_name);
|
||||
break;
|
||||
case defcv:
|
||||
execute_string (" -- %s %s %s: %s", category, _("of"), type_name,
|
||||
defined_name);
|
||||
break;
|
||||
case deftypeivar:
|
||||
execute_string (" -- %s %s %s: %s %s", category, _("of"), type_name,
|
||||
type_name2, defined_name);
|
||||
break;
|
||||
case defop:
|
||||
execute_string (" -- %s %s %s: %s", category, _("on"), type_name,
|
||||
defined_name);
|
||||
break;
|
||||
case deftypeop:
|
||||
execute_string (" -- %s %s %s: %s %s", category, _("on"), type_name,
|
||||
type_name2, defined_name);
|
||||
break;
|
||||
case deftypemethod:
|
||||
execute_string (" -- %s %s %s: %s %s", category, _("on"), type_name,
|
||||
type_name2, defined_name);
|
||||
break;
|
||||
}
|
||||
|
||||
if (html)
|
||||
{
|
||||
/* If this is not a @def...x version, it could only
|
||||
be a normal version @def.... So start the table here. */
|
||||
if (!x_p)
|
||||
add_word ("<table width=\"100%\">\n");
|
||||
|
||||
/* If this is an @def...x there has to be an other @def... before
|
||||
it, so this is only a new row within an existing table. With
|
||||
two complete standalone tables the gap between them is too big. */
|
||||
add_word ("<tr>\n");
|
||||
add_word ("<td align=\"left\">");
|
||||
|
||||
switch (base_type)
|
||||
{
|
||||
case deffn:
|
||||
case defvr:
|
||||
case deftp:
|
||||
/* <i> is for the following function arguments. */
|
||||
add_word_args ("<b>%s</b><i>", defined_name);
|
||||
break;
|
||||
case deftypefn:
|
||||
case deftypevr:
|
||||
add_word_args ("%s <b>%s</b><i>", type_name, defined_name);
|
||||
break;
|
||||
case defcv:
|
||||
case defop:
|
||||
add_word_args ("<b>%s</b><i>", defined_name);
|
||||
break;
|
||||
case deftypemethod:
|
||||
case deftypeop:
|
||||
case deftypeivar:
|
||||
add_word_args ("%s <b>%s</b><i>", type_name2, defined_name);
|
||||
break;
|
||||
}
|
||||
} /* if (html)... */
|
||||
|
||||
current_indent += default_indentation_increment;
|
||||
|
||||
/* Now process the function arguments, if any. If these carry onto
|
||||
the next line, they should be indented by two increments to
|
||||
distinguish them from the body of the definition, which is indented
|
||||
by one increment. */
|
||||
current_indent += default_indentation_increment;
|
||||
|
||||
switch (base_type)
|
||||
{
|
||||
case deffn:
|
||||
case defop:
|
||||
process_defun_args (scan_args, 1);
|
||||
break;
|
||||
|
||||
/* Through Makeinfo 1.67 we processed remaining args only for deftp,
|
||||
deftypefn, and deftypemethod. But the libc manual, for example,
|
||||
needs to say:
|
||||
@deftypevar {char *} tzname[2]
|
||||
And simply allowing the extra text seems far simpler than trying
|
||||
to invent yet more defn commands. In any case, we should either
|
||||
output it or give an error, not silently ignore it. */
|
||||
default:
|
||||
process_defun_args (scan_args, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
current_indent -= default_indentation_increment;
|
||||
close_single_paragraph ();
|
||||
|
||||
if (html)
|
||||
{
|
||||
/* xx The single words (on, off) used here, should depend on
|
||||
documentlanguage and NOT on gettext --kama. */
|
||||
switch (base_type)
|
||||
{
|
||||
case deffn:
|
||||
case defvr:
|
||||
case deftp:
|
||||
case deftypefn:
|
||||
case deftypevr:
|
||||
add_word ("</i>"); /* close italic area for arguments */
|
||||
/* put the rest into the second column */
|
||||
add_word_args ("</td>\n<td align=\"right\">%s", category);
|
||||
break;
|
||||
|
||||
case defcv:
|
||||
add_word ("</td>\n<td align=\"right\">");
|
||||
add_word_args ("%s %s %s", category, _("of"), type_name);
|
||||
break;
|
||||
|
||||
case defop:
|
||||
case deftypemethod:
|
||||
case deftypeop:
|
||||
add_word ("</i>");
|
||||
add_word ("</td>\n<td align=\"right\">");
|
||||
add_word_args ("%s %s %s", category, _("on"), type_name);
|
||||
break;
|
||||
|
||||
case deftypeivar:
|
||||
add_word ("</i>");
|
||||
add_word ("</td>\n<td align=\"right\">");
|
||||
add_word_args ("%s %s %s", category, _("of"), type_name);
|
||||
break;
|
||||
} /* switch (base_type)... */
|
||||
|
||||
add_word ("</td>\n"); /* close second column */
|
||||
add_word ("</tr>\n"); /* close row */
|
||||
|
||||
/* This is needed because I have to know if the next line is
|
||||
normal text or another @def..x. If text follows, create a new
|
||||
table to get the indentation for the following text.
|
||||
|
||||
This construction would fail if someone uses:
|
||||
@deffn
|
||||
@sp 2
|
||||
@deffnx
|
||||
.
|
||||
@end deffn
|
||||
But we don't care. */
|
||||
if (!looking_at ("@def"))
|
||||
{
|
||||
add_word ("</table>\n");
|
||||
add_word ("<table width=\"95%\" align=\"center\">\n");
|
||||
add_word ("<tr><td>\n");
|
||||
}
|
||||
|
||||
} /* if (html)... */
|
||||
|
||||
/* Make an entry in the appropriate index. */
|
||||
switch (base_type)
|
||||
{
|
||||
case deffn:
|
||||
case deftypefn:
|
||||
execute_string ("@findex %s\n", defined_name);
|
||||
break;
|
||||
case defvr:
|
||||
case deftypevr:
|
||||
case defcv:
|
||||
execute_string ("@vindex %s\n", defined_name);
|
||||
break;
|
||||
case deftypeivar:
|
||||
execute_string ("@vindex %s %s %s\n", defined_name, _("of"), type_name);
|
||||
break;
|
||||
case defop:
|
||||
case deftypeop:
|
||||
case deftypemethod:
|
||||
execute_string ("@findex %s %s %s\n", defined_name, _("on"), type_name);
|
||||
break;
|
||||
case deftp:
|
||||
execute_string ("@tindex %s\n", defined_name);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Deallocate the token list. */
|
||||
scan_args = defun_args;
|
||||
while (1)
|
||||
{
|
||||
char * arg = (*scan_args++);
|
||||
if (arg == NULL)
|
||||
break;
|
||||
free (arg);
|
||||
}
|
||||
free (defun_args);
|
||||
}
|
||||
|
||||
/* Add an entry for a function, macro, special form, variable, or option.
|
||||
If the name of the calling command ends in `x', then this is an extra
|
||||
entry included in the body of an insertion of the same type. */
|
||||
void
|
||||
cm_defun ()
|
||||
{
|
||||
int x_p;
|
||||
enum insertion_type type;
|
||||
char *temp = xstrdup (command);
|
||||
|
||||
x_p = (command[strlen (command) - 1] == 'x');
|
||||
|
||||
if (x_p)
|
||||
temp[strlen (temp) - 1] = 0;
|
||||
|
||||
type = find_type_from_name (temp);
|
||||
free (temp);
|
||||
|
||||
/* If we are adding to an already existing insertion, then make sure
|
||||
that we are already in an insertion of type TYPE. */
|
||||
if (x_p && (!insertion_level || insertion_stack->insertion != type))
|
||||
{
|
||||
line_error (_("Must be in `%s' insertion to use `%sx'"),
|
||||
command, command);
|
||||
discard_until ("\n");
|
||||
return;
|
||||
}
|
||||
|
||||
defun_internal (type, x_p);
|
||||
}
|
31
contrib/texinfo/makeinfo/defun.h
Normal file
31
contrib/texinfo/makeinfo/defun.h
Normal file
@ -0,0 +1,31 @@
|
||||
/* defun.h -- declaration for defuns.
|
||||
$Id: defun.h,v 1.2 1999/03/25 22:49:10 karl Exp $
|
||||
|
||||
Copyright (C) 1999 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 Karl Heinz Marbaise <kama@hippo.fido.de>. */
|
||||
|
||||
#ifndef DEFUN_H
|
||||
#define DEFUN_H
|
||||
|
||||
#include "insertion.h"
|
||||
|
||||
extern enum insertion_type get_base_type ();
|
||||
extern void cm_defun ();
|
||||
|
||||
#endif /* !DEFUN_H */
|
||||
|
529
contrib/texinfo/makeinfo/files.c
Normal file
529
contrib/texinfo/makeinfo/files.c
Normal file
@ -0,0 +1,529 @@
|
||||
/* files.c -- file-related functions for Texinfo.
|
||||
$Id: files.c,v 1.5 1999/03/23 21:42:44 karl Exp $
|
||||
|
||||
Copyright (C) 1998, 99 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "system.h"
|
||||
#include "files.h"
|
||||
#include "macro.h"
|
||||
#include "makeinfo.h"
|
||||
|
||||
FSTACK *filestack = NULL;
|
||||
|
||||
static int node_filename_stack_index = 0;
|
||||
static int node_filename_stack_size = 0;
|
||||
static char **node_filename_stack = NULL;
|
||||
|
||||
|
||||
/* Looking for include files. */
|
||||
|
||||
/* Given a string containing units of information separated by colons,
|
||||
return the next one pointed to by INDEX, or NULL if there are no more.
|
||||
Advance INDEX to the character after the colon. */
|
||||
static char *
|
||||
extract_colon_unit (string, index)
|
||||
char *string;
|
||||
int *index;
|
||||
{
|
||||
int start;
|
||||
int path_sep_char = PATH_SEP[0];
|
||||
int i = *index;
|
||||
|
||||
if (!string || (i >= strlen (string)))
|
||||
return NULL;
|
||||
|
||||
/* Each call to this routine leaves the index pointing at a colon if
|
||||
there is more to the path. If i > 0, then increment past the
|
||||
`:'. If i == 0, then the path has a leading colon. Trailing colons
|
||||
are handled OK by the `else' part of the if statement; an empty
|
||||
string is returned in that case. */
|
||||
if (i && string[i] == path_sep_char)
|
||||
i++;
|
||||
|
||||
start = i;
|
||||
while (string[i] && string[i] != path_sep_char) i++;
|
||||
*index = i;
|
||||
|
||||
if (i == start)
|
||||
{
|
||||
if (string[i])
|
||||
(*index)++;
|
||||
|
||||
/* Return "" in the case of a trailing `:'. */
|
||||
return xstrdup ("");
|
||||
}
|
||||
else
|
||||
{
|
||||
char *value;
|
||||
|
||||
value = xmalloc (1 + (i - start));
|
||||
memcpy (value, &string[start], (i - start));
|
||||
value [i - start] = 0;
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the full pathname for FILENAME by searching along PATH.
|
||||
When found, return the stat () info for FILENAME in FINFO.
|
||||
If PATH is NULL, only the current directory is searched.
|
||||
If the file could not be found, return a NULL pointer. */
|
||||
static char *
|
||||
get_file_info_in_path (filename, path, finfo)
|
||||
char *filename, *path;
|
||||
struct stat *finfo;
|
||||
{
|
||||
char *dir;
|
||||
int result, index = 0;
|
||||
|
||||
if (path == NULL)
|
||||
path = ".";
|
||||
|
||||
/* Handle absolute pathnames. */
|
||||
if (IS_ABSOLUTE (filename)
|
||||
|| (*filename == '.'
|
||||
&& (IS_SLASH (filename[1])
|
||||
|| (filename[1] == '.' && IS_SLASH (filename[2])))))
|
||||
{
|
||||
if (stat (filename, finfo) == 0)
|
||||
return xstrdup (filename);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while ((dir = extract_colon_unit (path, &index)))
|
||||
{
|
||||
char *fullpath;
|
||||
|
||||
if (!*dir)
|
||||
{
|
||||
free (dir);
|
||||
dir = xstrdup (".");
|
||||
}
|
||||
|
||||
fullpath = xmalloc (2 + strlen (dir) + strlen (filename));
|
||||
sprintf (fullpath, "%s/%s", dir, filename);
|
||||
free (dir);
|
||||
|
||||
result = stat (fullpath, finfo);
|
||||
|
||||
if (result == 0)
|
||||
return fullpath;
|
||||
else
|
||||
free (fullpath);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Find and load the file named FILENAME. Return a pointer to
|
||||
the loaded file, or NULL if it can't be loaded. */
|
||||
char *
|
||||
find_and_load (filename)
|
||||
char *filename;
|
||||
{
|
||||
struct stat fileinfo;
|
||||
long file_size;
|
||||
int file = -1, count = 0;
|
||||
char *fullpath, *result;
|
||||
#if O_BINARY || defined (VMS)
|
||||
int n;
|
||||
#endif
|
||||
|
||||
result = fullpath = NULL;
|
||||
|
||||
fullpath = get_file_info_in_path (filename, include_files_path, &fileinfo);
|
||||
|
||||
if (!fullpath)
|
||||
goto error_exit;
|
||||
|
||||
filename = fullpath;
|
||||
file_size = (long) fileinfo.st_size;
|
||||
|
||||
file = open (filename, O_RDONLY);
|
||||
if (file < 0)
|
||||
goto error_exit;
|
||||
|
||||
/* Load the file, with enough room for a newline and a null. */
|
||||
result = xmalloc (file_size + 2);
|
||||
|
||||
/* VMS stat lies about the st_size value. The actual number of
|
||||
readable bytes is always less than this value. The arcane
|
||||
mysteries of VMS/RMS are too much to probe, so this hack
|
||||
suffices to make things work. */
|
||||
#if O_BINARY || defined (VMS)
|
||||
#ifdef VMS
|
||||
while ((n = read (file, result + count, file_size)) > 0)
|
||||
#else /* !VMS */
|
||||
#ifndef WIN32
|
||||
while ((n = read (file, result + count, file_size)) > 0)
|
||||
#else /* WIN32 */
|
||||
/* Does WIN32 really need reading 1 character at a time?? */
|
||||
while ((n = read (file, result + count, 1)) > 0)
|
||||
#endif /* WIN32 */
|
||||
#endif /* !VMS */
|
||||
count += n;
|
||||
if (0 < count && count < file_size)
|
||||
result = xrealloc (result, count + 2); /* why waste the slack? */
|
||||
else if (n == -1)
|
||||
#else /* !VMS && !O_BINARY */
|
||||
count = file_size;
|
||||
if (read (file, result, file_size) != file_size)
|
||||
#endif /* !VMS && !WIN32 */
|
||||
|
||||
error_exit:
|
||||
{
|
||||
if (result)
|
||||
free (result);
|
||||
|
||||
if (fullpath)
|
||||
free (fullpath);
|
||||
|
||||
if (file != -1)
|
||||
close (file);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
close (file);
|
||||
|
||||
/* Set the globals to the new file. */
|
||||
input_text = result;
|
||||
input_text_length = count;
|
||||
input_filename = fullpath;
|
||||
node_filename = xstrdup (fullpath);
|
||||
input_text_offset = 0;
|
||||
line_number = 1;
|
||||
/* Not strictly necessary. This magic prevents read_token () from doing
|
||||
extra unnecessary work each time it is called (that is a lot of times).
|
||||
INPUT_TEXT_LENGTH is one past the actual end of the text. */
|
||||
input_text[input_text_length] = '\n';
|
||||
/* This, on the other hand, is always necessary. */
|
||||
input_text[input_text_length+1] = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Pushing and popping files. */
|
||||
void
|
||||
push_node_filename ()
|
||||
{
|
||||
if (node_filename_stack_index + 1 > node_filename_stack_size)
|
||||
node_filename_stack = xrealloc
|
||||
(node_filename_stack, (node_filename_stack_size += 10) * sizeof (char *));
|
||||
|
||||
node_filename_stack[node_filename_stack_index] = node_filename;
|
||||
node_filename_stack_index++;
|
||||
}
|
||||
|
||||
void
|
||||
pop_node_filename ()
|
||||
{
|
||||
node_filename = node_filename_stack[--node_filename_stack_index];
|
||||
}
|
||||
|
||||
/* Save the state of the current input file. */
|
||||
void
|
||||
pushfile ()
|
||||
{
|
||||
FSTACK *newstack = xmalloc (sizeof (FSTACK));
|
||||
newstack->filename = input_filename;
|
||||
newstack->text = input_text;
|
||||
newstack->size = input_text_length;
|
||||
newstack->offset = input_text_offset;
|
||||
newstack->line_number = line_number;
|
||||
newstack->next = filestack;
|
||||
|
||||
filestack = newstack;
|
||||
push_node_filename ();
|
||||
}
|
||||
|
||||
/* Make the current file globals be what is on top of the file stack. */
|
||||
void
|
||||
popfile ()
|
||||
{
|
||||
FSTACK *tos = filestack;
|
||||
|
||||
if (!tos)
|
||||
abort (); /* My fault. I wonder what I did? */
|
||||
|
||||
if (macro_expansion_output_stream)
|
||||
{
|
||||
maybe_write_itext (input_text, input_text_offset);
|
||||
forget_itext (input_text);
|
||||
}
|
||||
|
||||
/* Pop the stack. */
|
||||
filestack = filestack->next;
|
||||
|
||||
/* Make sure that commands with braces have been satisfied. */
|
||||
if (!executing_string && !me_executing_string)
|
||||
discard_braces ();
|
||||
|
||||
/* Get the top of the stack into the globals. */
|
||||
input_filename = tos->filename;
|
||||
input_text = tos->text;
|
||||
input_text_length = tos->size;
|
||||
input_text_offset = tos->offset;
|
||||
line_number = tos->line_number;
|
||||
free (tos);
|
||||
|
||||
/* Go back to the (now) current node. */
|
||||
pop_node_filename ();
|
||||
}
|
||||
|
||||
/* Flush all open files on the file stack. */
|
||||
void
|
||||
flush_file_stack ()
|
||||
{
|
||||
while (filestack)
|
||||
{
|
||||
char *fname = input_filename;
|
||||
char *text = input_text;
|
||||
popfile ();
|
||||
free (fname);
|
||||
free (text);
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the index of the first character in the filename
|
||||
which is past all the leading directory characters. */
|
||||
static int
|
||||
skip_directory_part (filename)
|
||||
char *filename;
|
||||
{
|
||||
int i = strlen (filename) - 1;
|
||||
|
||||
while (i && !IS_SLASH (filename[i]))
|
||||
i--;
|
||||
if (IS_SLASH (filename[i]))
|
||||
i++;
|
||||
else if (filename[i] && HAVE_DRIVE (filename))
|
||||
i = 2;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
char *
|
||||
filename_non_directory (name)
|
||||
char *name;
|
||||
{
|
||||
return xstrdup (name + skip_directory_part (name));
|
||||
}
|
||||
|
||||
/* Return just the simple part of the filename; i.e. the
|
||||
filename without the path information, or extensions.
|
||||
This conses up a new string. */
|
||||
char *
|
||||
filename_part (filename)
|
||||
char *filename;
|
||||
{
|
||||
char *basename = filename_non_directory (filename);
|
||||
|
||||
#ifdef REMOVE_OUTPUT_EXTENSIONS
|
||||
/* See if there is an extension to remove. If so, remove it. */
|
||||
{
|
||||
char *temp;
|
||||
|
||||
temp = strrchr (basename, '.');
|
||||
if (temp)
|
||||
*temp = 0;
|
||||
}
|
||||
#endif /* REMOVE_OUTPUT_EXTENSIONS */
|
||||
return basename;
|
||||
}
|
||||
|
||||
/* Return the pathname part of filename. This can be NULL. */
|
||||
char *
|
||||
pathname_part (filename)
|
||||
char *filename;
|
||||
{
|
||||
char *expand_filename ();
|
||||
char *result = NULL;
|
||||
int i;
|
||||
|
||||
filename = expand_filename (filename, "");
|
||||
|
||||
i = skip_directory_part (filename);
|
||||
if (i)
|
||||
{
|
||||
result = xmalloc (1 + i);
|
||||
strncpy (result, filename, i);
|
||||
result[i] = 0;
|
||||
}
|
||||
free (filename);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Return the expansion of FILENAME. */
|
||||
char *
|
||||
expand_filename (filename, input_name)
|
||||
char *filename, *input_name;
|
||||
{
|
||||
int i;
|
||||
char *full_pathname ();
|
||||
|
||||
if (filename)
|
||||
{
|
||||
filename = full_pathname (filename);
|
||||
if (IS_ABSOLUTE (filename)
|
||||
|| (*filename == '.' &&
|
||||
(IS_SLASH (filename[1]) ||
|
||||
(filename[1] == '.' && IS_SLASH (filename[2])))))
|
||||
return filename;
|
||||
}
|
||||
else
|
||||
{
|
||||
filename = filename_non_directory (input_name);
|
||||
|
||||
if (!*filename)
|
||||
{
|
||||
free (filename);
|
||||
filename = xstrdup ("noname.texi");
|
||||
}
|
||||
|
||||
for (i = strlen (filename) - 1; i; i--)
|
||||
if (filename[i] == '.')
|
||||
break;
|
||||
|
||||
if (!i)
|
||||
i = strlen (filename);
|
||||
|
||||
if (i + 6 > (strlen (filename)))
|
||||
filename = xrealloc (filename, i + 6);
|
||||
strcpy (filename + i, html ? ".html" : ".info");
|
||||
return filename;
|
||||
}
|
||||
|
||||
if (IS_ABSOLUTE (input_name))
|
||||
{
|
||||
/* Make it so that relative names work. */
|
||||
char *result;
|
||||
|
||||
i = strlen (input_name) - 1;
|
||||
|
||||
result = xmalloc (1 + strlen (input_name) + strlen (filename));
|
||||
strcpy (result, input_name);
|
||||
|
||||
while (!IS_SLASH (result[i]) && i)
|
||||
i--;
|
||||
if (IS_SLASH (result[i]))
|
||||
i++;
|
||||
|
||||
strcpy (&result[i], filename);
|
||||
free (filename);
|
||||
return result;
|
||||
}
|
||||
return filename;
|
||||
}
|
||||
|
||||
/* Return the full path to FILENAME. */
|
||||
char *
|
||||
full_pathname (filename)
|
||||
char *filename;
|
||||
{
|
||||
int initial_character;
|
||||
char *result;
|
||||
|
||||
/* No filename given? */
|
||||
if (!filename || !*filename)
|
||||
return xstrdup ("");
|
||||
|
||||
/* Already absolute? */
|
||||
if (IS_ABSOLUTE (filename) ||
|
||||
(*filename == '.' &&
|
||||
(IS_SLASH (filename[1]) ||
|
||||
(filename[1] == '.' && IS_SLASH (filename[2])))))
|
||||
return xstrdup (filename);
|
||||
|
||||
initial_character = *filename;
|
||||
if (initial_character != '~')
|
||||
{
|
||||
char *localdir = xmalloc (1025);
|
||||
#ifdef HAVE_GETCWD
|
||||
if (!getcwd (localdir, 1024))
|
||||
#else
|
||||
if (!getwd (localdir))
|
||||
#endif
|
||||
{
|
||||
fprintf (stderr, _("%s: getwd: %s, %s\n"),
|
||||
progname, filename, localdir);
|
||||
xexit (1);
|
||||
}
|
||||
|
||||
strcat (localdir, "/");
|
||||
strcat (localdir, filename);
|
||||
result = xstrdup (localdir);
|
||||
free (localdir);
|
||||
}
|
||||
else
|
||||
{ /* Does anybody know why WIN32 doesn't want to support $HOME?
|
||||
If the reason is they don't have getpwnam, they should
|
||||
only disable the else clause below. */
|
||||
#ifndef WIN32
|
||||
if (IS_SLASH (filename[1]))
|
||||
{
|
||||
/* Return the concatenation of the environment variable HOME
|
||||
and the rest of the string. */
|
||||
char *temp_home;
|
||||
|
||||
temp_home = (char *) getenv ("HOME");
|
||||
result = xmalloc (strlen (&filename[1])
|
||||
+ 1
|
||||
+ temp_home ? strlen (temp_home)
|
||||
: 0);
|
||||
*result = 0;
|
||||
|
||||
if (temp_home)
|
||||
strcpy (result, temp_home);
|
||||
|
||||
strcat (result, &filename[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct passwd *user_entry;
|
||||
int i, c;
|
||||
char *username = xmalloc (257);
|
||||
|
||||
for (i = 1; (c = filename[i]); i++)
|
||||
{
|
||||
if (IS_SLASH (c))
|
||||
break;
|
||||
else
|
||||
username[i - 1] = c;
|
||||
}
|
||||
if (c)
|
||||
username[i - 1] = 0;
|
||||
|
||||
user_entry = getpwnam (username);
|
||||
|
||||
if (!user_entry)
|
||||
return xstrdup (filename);
|
||||
|
||||
result = xmalloc (1 + strlen (user_entry->pw_dir)
|
||||
+ strlen (&filename[i]));
|
||||
strcpy (result, user_entry->pw_dir);
|
||||
strcat (result, &filename[i]);
|
||||
}
|
||||
#endif /* not WIN32 */
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
char *
|
||||
output_name_from_input_name (name)
|
||||
char *name;
|
||||
{
|
||||
return expand_filename (NULL, name);
|
||||
}
|
45
contrib/texinfo/makeinfo/files.h
Normal file
45
contrib/texinfo/makeinfo/files.h
Normal file
@ -0,0 +1,45 @@
|
||||
/* files.h -- declarations for files.c.
|
||||
$Id: files.h,v 1.1 1998/10/24 21:37:25 karl Exp $
|
||||
|
||||
Copyright (C) 1998 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 FILES_H
|
||||
#define FILES_H
|
||||
|
||||
/* A stack of file information records. If a new file is read in with
|
||||
"@input", we remember the old input file state on this stack. */
|
||||
typedef struct fstack
|
||||
{
|
||||
struct fstack *next;
|
||||
char *filename;
|
||||
char *text;
|
||||
int size;
|
||||
int offset;
|
||||
int line_number;
|
||||
} FSTACK;
|
||||
extern FSTACK *filestack;
|
||||
|
||||
extern void pushfile (), popfile ();
|
||||
extern void flush_file_stack ();
|
||||
extern char *find_and_load ();
|
||||
extern char *output_name_from_input_name ();
|
||||
extern char *expand_filename ();
|
||||
extern char *filename_part ();
|
||||
extern char *pathname_part ();
|
||||
|
||||
#endif /* !FILES_H */
|
359
contrib/texinfo/makeinfo/footnote.c
Normal file
359
contrib/texinfo/makeinfo/footnote.c
Normal file
@ -0,0 +1,359 @@
|
||||
/* footnote.c -- footnotes for Texinfo.
|
||||
$Id: footnote.c,v 1.10 1999/09/20 12:20:52 karl Exp $
|
||||
|
||||
Copyright (C) 1998, 99 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "system.h"
|
||||
#include "footnote.h"
|
||||
#include "macro.h"
|
||||
#include "makeinfo.h"
|
||||
|
||||
/* Nonzero means that the footnote style for this document was set on
|
||||
the command line, which overrides any other settings. */
|
||||
int footnote_style_preset = 0;
|
||||
|
||||
/* The current footnote number in this node. Each time a new node is
|
||||
started this is reset to 1. */
|
||||
int current_footnote_number = 1;
|
||||
|
||||
/* Nonzero means we automatically number footnotes with no specified marker. */
|
||||
int number_footnotes = 1;
|
||||
|
||||
/* Nonzero means we are currently outputting footnotes. */
|
||||
int already_outputting_pending_notes = 0;
|
||||
|
||||
|
||||
/* Footnotes can be handled in one of two ways:
|
||||
|
||||
separate_node:
|
||||
Make them look like followed references, with the reference
|
||||
destinations in a makeinfo manufactured node or,
|
||||
end_node:
|
||||
Make them appear at the bottom of the node that they originally
|
||||
appeared in. */
|
||||
|
||||
#define separate_node 0
|
||||
#define end_node 1
|
||||
|
||||
int footnote_style = end_node;
|
||||
int first_footnote_this_node = 1;
|
||||
int footnote_count = 0;
|
||||
|
||||
/* Set the footnote style based on the style identifier in STRING. */
|
||||
int
|
||||
set_footnote_style (string)
|
||||
char *string;
|
||||
{
|
||||
if (strcasecmp (string, "separate") == 0)
|
||||
footnote_style = separate_node;
|
||||
else if (strcasecmp (string, "end") == 0)
|
||||
footnote_style = end_node;
|
||||
else
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
cm_footnotestyle ()
|
||||
{
|
||||
char *arg;
|
||||
|
||||
get_rest_of_line (1, &arg);
|
||||
|
||||
/* If set on command line, do not change the footnote style. */
|
||||
if (!footnote_style_preset && set_footnote_style (arg) != 0)
|
||||
line_error (_("Bad argument to %c%s"), COMMAND_PREFIX, command);
|
||||
|
||||
free (arg);
|
||||
}
|
||||
|
||||
typedef struct fn
|
||||
{
|
||||
struct fn *next;
|
||||
char *marker;
|
||||
char *note;
|
||||
int number;
|
||||
} FN;
|
||||
|
||||
FN *pending_notes = NULL;
|
||||
|
||||
/* A method for remembering footnotes. Note that this list gets output
|
||||
at the end of the current node. */
|
||||
void
|
||||
remember_note (marker, note)
|
||||
char *marker, *note;
|
||||
{
|
||||
FN *temp = xmalloc (sizeof (FN));
|
||||
|
||||
temp->marker = xstrdup (marker);
|
||||
temp->note = xstrdup (note);
|
||||
temp->next = pending_notes;
|
||||
temp->number = current_footnote_number;
|
||||
pending_notes = temp;
|
||||
footnote_count++;
|
||||
}
|
||||
|
||||
/* How to get rid of existing footnotes. */
|
||||
static void
|
||||
free_pending_notes ()
|
||||
{
|
||||
FN *temp;
|
||||
|
||||
while ((temp = pending_notes))
|
||||
{
|
||||
free (temp->marker);
|
||||
free (temp->note);
|
||||
pending_notes = pending_notes->next;
|
||||
free (temp);
|
||||
}
|
||||
first_footnote_this_node = 1;
|
||||
footnote_count = 0;
|
||||
current_footnote_number = 1; /* for html */
|
||||
}
|
||||
|
||||
/* What to do when you see a @footnote construct. */
|
||||
|
||||
/* Handle a "footnote".
|
||||
footnote *{this is a footnote}
|
||||
where "*" is the (optional) marker character for this note. */
|
||||
void
|
||||
cm_footnote ()
|
||||
{
|
||||
char *marker;
|
||||
char *note;
|
||||
|
||||
get_until ("{", &marker);
|
||||
canon_white (marker);
|
||||
|
||||
if (macro_expansion_output_stream && !executing_string)
|
||||
append_to_expansion_output (input_text_offset + 1); /* include the { */
|
||||
|
||||
/* Read the argument in braces. */
|
||||
if (curchar () != '{')
|
||||
{
|
||||
line_error (_("`%c%s' needs an argument `{...}', not just `%s'"),
|
||||
COMMAND_PREFIX, command, marker);
|
||||
free (marker);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
int len;
|
||||
int braces = 1;
|
||||
int loc = ++input_text_offset;
|
||||
|
||||
while (braces)
|
||||
{
|
||||
if (loc == input_text_length)
|
||||
{
|
||||
line_error (_("No closing brace for footnote `%s'"), marker);
|
||||
return;
|
||||
}
|
||||
|
||||
if (input_text[loc] == '{')
|
||||
braces++;
|
||||
else if (input_text[loc] == '}')
|
||||
braces--;
|
||||
else if (input_text[loc] == '\n')
|
||||
line_number++;
|
||||
|
||||
loc++;
|
||||
}
|
||||
|
||||
len = (loc - input_text_offset) - 1;
|
||||
note = xmalloc (len + 1);
|
||||
memcpy (note, &input_text[input_text_offset], len);
|
||||
note[len] = 0;
|
||||
input_text_offset = loc;
|
||||
}
|
||||
|
||||
/* Must write the macro-expanded argument to the macro expansion
|
||||
output stream. This is like the case in index_add_arg. */
|
||||
if (macro_expansion_output_stream && !executing_string)
|
||||
{
|
||||
/* Calling me_execute_string on a lone } provokes an error, since
|
||||
as far as the reader knows there is no matching {. We wrote
|
||||
the { above in the call to append_to_expansion_output. */
|
||||
me_execute_string_keep_state (note, "}");
|
||||
}
|
||||
|
||||
if (!current_node || !*current_node)
|
||||
{
|
||||
line_error (_("Footnote defined without parent node"));
|
||||
free (marker);
|
||||
free (note);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!*marker)
|
||||
{
|
||||
free (marker);
|
||||
|
||||
if (number_footnotes)
|
||||
{
|
||||
marker = xmalloc (10);
|
||||
sprintf (marker, "%d", current_footnote_number);
|
||||
}
|
||||
else
|
||||
marker = xstrdup ("*");
|
||||
}
|
||||
|
||||
remember_note (marker, note);
|
||||
|
||||
/* fixme: html: footnote processing needs work; we currently ignore
|
||||
the style requested; we could clash with a node name of the form
|
||||
`fn-<n>', though that's unlikely. */
|
||||
if (html)
|
||||
add_word_args ("<a rel=footnote href=\"#fn-%d\"><sup>%s</sup></a>",
|
||||
current_footnote_number, marker);
|
||||
else
|
||||
/* Your method should at least insert MARKER. */
|
||||
switch (footnote_style)
|
||||
{
|
||||
case separate_node:
|
||||
add_word_args ("(%s)", marker);
|
||||
execute_string (" (*note %s-Footnote-%d::)",
|
||||
current_node, current_footnote_number);
|
||||
if (first_footnote_this_node)
|
||||
{
|
||||
char *temp_string, *expanded_ref;
|
||||
|
||||
temp_string = xmalloc (strlen (current_node)
|
||||
+ strlen ("-Footnotes") + 1);
|
||||
|
||||
strcpy (temp_string, current_node);
|
||||
strcat (temp_string, "-Footnotes");
|
||||
expanded_ref = expansion (temp_string, 0);
|
||||
remember_node_reference (expanded_ref, line_number,
|
||||
followed_reference);
|
||||
free (temp_string);
|
||||
free (expanded_ref);
|
||||
first_footnote_this_node = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case end_node:
|
||||
add_word_args ("(%s)", marker);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
current_footnote_number++;
|
||||
|
||||
free (marker);
|
||||
free (note);
|
||||
}
|
||||
|
||||
/* Output the footnotes. We are at the end of the current node. */
|
||||
void
|
||||
output_pending_notes ()
|
||||
{
|
||||
FN *footnote = pending_notes;
|
||||
|
||||
if (!pending_notes)
|
||||
return;
|
||||
|
||||
if (html)
|
||||
{ /* The type= attribute is used just in case some weirdo browser
|
||||
out there doesn't use numbers by default. Since we rely on the
|
||||
browser to produce the footnote numbers, we need to make sure
|
||||
they ARE indeed numbers. Pre-HTML4 browsers seem to not care. */
|
||||
add_word ("<hr><h4>");
|
||||
add_word (_("Footnotes"));
|
||||
add_word ("</h4>\n<ol type=\"1\">\n");
|
||||
}
|
||||
else
|
||||
switch (footnote_style)
|
||||
{
|
||||
case separate_node:
|
||||
{
|
||||
char *old_current_node = current_node;
|
||||
char *old_command = xstrdup (command);
|
||||
|
||||
already_outputting_pending_notes++;
|
||||
execute_string ("%cnode %s-Footnotes,,,%s\n",
|
||||
COMMAND_PREFIX, current_node, current_node);
|
||||
already_outputting_pending_notes--;
|
||||
current_node = old_current_node;
|
||||
free (command);
|
||||
command = old_command;
|
||||
}
|
||||
break;
|
||||
|
||||
case end_node:
|
||||
close_paragraph ();
|
||||
in_fixed_width_font++;
|
||||
/* This string should be translated according to the
|
||||
@documentlanguage, not the current LANG. We can't do that
|
||||
yet, so leave it in English. */
|
||||
execute_string ("---------- Footnotes ----------\n\n");
|
||||
in_fixed_width_font--;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Handle the footnotes in reverse order. */
|
||||
{
|
||||
FN **array = xmalloc ((footnote_count + 1) * sizeof (FN *));
|
||||
array[footnote_count] = NULL;
|
||||
|
||||
while (--footnote_count > -1)
|
||||
{
|
||||
array[footnote_count] = footnote;
|
||||
footnote = footnote->next;
|
||||
}
|
||||
|
||||
filling_enabled = 1;
|
||||
indented_fill = 1;
|
||||
|
||||
while ((footnote = array[++footnote_count]))
|
||||
{
|
||||
if (html)
|
||||
{
|
||||
/* Make the text of every footnote begin a separate paragraph. */
|
||||
add_word_args ("<li><a name=\"fn-%d\"></a>\n<p>",
|
||||
footnote->number);
|
||||
execute_string ("%s", footnote->note);
|
||||
add_word ("</p>\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
char *old_current_node = current_node;
|
||||
char *old_command = xstrdup (command);
|
||||
|
||||
already_outputting_pending_notes++;
|
||||
execute_string ("%canchor{%s-Footnote-%d}(%s) %s",
|
||||
COMMAND_PREFIX, current_node, footnote->number,
|
||||
footnote->marker, footnote->note);
|
||||
already_outputting_pending_notes--;
|
||||
current_node = old_current_node;
|
||||
free (command);
|
||||
command = old_command;
|
||||
}
|
||||
|
||||
close_paragraph ();
|
||||
}
|
||||
|
||||
if (html)
|
||||
add_word ("</ol><hr>");
|
||||
close_paragraph ();
|
||||
free (array);
|
||||
}
|
||||
|
||||
free_pending_notes ();
|
||||
}
|
37
contrib/texinfo/makeinfo/footnote.h
Normal file
37
contrib/texinfo/makeinfo/footnote.h
Normal file
@ -0,0 +1,37 @@
|
||||
/* footnote.h -- declarations for footnote.c.
|
||||
$Id: footnote.h,v 1.2 1998/10/26 22:16:15 karl Exp $
|
||||
|
||||
Copyright (C) 1998 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 FOOTNOTE_H
|
||||
#define FOOTNOTE_H
|
||||
|
||||
extern int footnote_style_preset;
|
||||
extern int current_footnote_number;
|
||||
extern int number_footnotes;
|
||||
extern int already_outputting_pending_notes;
|
||||
|
||||
/* The Texinfo @commands. */
|
||||
extern void cm_footnote ();
|
||||
extern void cm_footnotestyle ();
|
||||
|
||||
extern int set_footnote_style (); /* called for -s option */
|
||||
|
||||
extern void output_pending_notes (); /* called for output */
|
||||
|
||||
#endif /* !FOOTNOTE_H */
|
182
contrib/texinfo/makeinfo/html.c
Normal file
182
contrib/texinfo/makeinfo/html.c
Normal file
@ -0,0 +1,182 @@
|
||||
/* html.c -- html-related utilities.
|
||||
$Id: html.c,v 1.5 1999/09/18 19:27:41 karl Exp $
|
||||
|
||||
Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "system.h"
|
||||
#include "cmds.h"
|
||||
#include "html.h"
|
||||
#include "lang.h"
|
||||
#include "makeinfo.h"
|
||||
#include "sectioning.h"
|
||||
|
||||
/* See html.h. */
|
||||
int html_output_head_p = 0;
|
||||
|
||||
void
|
||||
html_output_head ()
|
||||
{
|
||||
char *html_title;
|
||||
|
||||
if (html_output_head_p)
|
||||
return;
|
||||
html_output_head_p = 1;
|
||||
|
||||
/* The <title> should not have markup. */
|
||||
html_title = title ? text_expansion (title) : _("Untitled");
|
||||
|
||||
add_word_args ("<html lang=\"%s\"><head>\n<title>%s</title>\n",
|
||||
language_table[language_code].abbrev, html_title);
|
||||
|
||||
add_word ("<meta http-equiv=\"Content-Type\" content=\"text/html");
|
||||
if (document_encoding)
|
||||
add_word_args ("; charset=%s", document_encoding);
|
||||
add_word ("\">\n");
|
||||
|
||||
add_word_args ("<meta name=description content=\"%s\">\n", html_title);
|
||||
add_word_args ("<meta name=generator content=\"makeinfo %s\">\n", VERSION);
|
||||
add_word ("<link href=\"http://texinfo.org/\" rel=generator-home>\n");
|
||||
add_word ("</head><body>\n\n");
|
||||
}
|
||||
|
||||
|
||||
/* Escape HTML special characters in the string if necessary,
|
||||
returning a pointer to a possibly newly-allocated one. */
|
||||
char *
|
||||
escape_string (string)
|
||||
char * string;
|
||||
{
|
||||
int i=0, newlen=0;
|
||||
char * newstring;
|
||||
|
||||
do
|
||||
{
|
||||
/* Find how much to allocate. */
|
||||
switch (string[i])
|
||||
{
|
||||
case '&':
|
||||
newlen += 5; /* `&' */
|
||||
break;
|
||||
case '<':
|
||||
case '>':
|
||||
newlen += 4; /* `<', `>' */
|
||||
break;
|
||||
default:
|
||||
newlen++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
while (string[i]);
|
||||
|
||||
if (newlen == i) return string; /* Already OK. */
|
||||
|
||||
newstring = xmalloc (newlen + 2);
|
||||
i = 0;
|
||||
do
|
||||
{
|
||||
switch (string[i])
|
||||
{
|
||||
case '&':
|
||||
strcpy (newstring, "&");
|
||||
newstring += 5;
|
||||
break;
|
||||
case '<':
|
||||
strcpy (newstring, "<");
|
||||
newstring += 4;
|
||||
break;
|
||||
case '>':
|
||||
strcpy (newstring, ">");
|
||||
newstring += 4;
|
||||
break;
|
||||
default:
|
||||
newstring[0] = string[i];
|
||||
newstring++;
|
||||
}
|
||||
}
|
||||
while (string[i++]);
|
||||
free (string);
|
||||
return newstring - newlen -1;
|
||||
}
|
||||
|
||||
/* Open or close TAG according to START_OR_END. */
|
||||
void
|
||||
insert_html_tag (start_or_end, tag)
|
||||
int start_or_end;
|
||||
char *tag;
|
||||
{
|
||||
if (!paragraph_is_open && (start_or_end == START))
|
||||
{
|
||||
/* Need to compensate for the <p> we are about to insert, or
|
||||
else cm_xxx functions that call us will get wrong text
|
||||
between START and END. */
|
||||
adjust_braces_following (output_paragraph_offset, 3);
|
||||
add_word ("<p>");
|
||||
}
|
||||
add_char ('<');
|
||||
if (start_or_end != START)
|
||||
add_char ('/');
|
||||
add_word (tag);
|
||||
add_char ('>');
|
||||
}
|
||||
|
||||
/* Output an HTML <link> to the filename for NODE, including the
|
||||
other string as extra attributes. */
|
||||
void
|
||||
add_link (node, attributes)
|
||||
char *node, *attributes;
|
||||
{
|
||||
if (node)
|
||||
{
|
||||
add_word_args ("<link %s href=\"", attributes);
|
||||
add_anchor_name (node, 1);
|
||||
add_word ("\">\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Output NAME with characters escaped as appropriate for an anchor
|
||||
name, i.e., escape URL special characters as %<n>. */
|
||||
void
|
||||
add_escaped_anchor_name (name)
|
||||
char *name;
|
||||
{
|
||||
for (; *name; name++)
|
||||
{
|
||||
if (*name == '&')
|
||||
add_word ("&");
|
||||
else if (! URL_SAFE_CHAR (*name))
|
||||
/* Cast so characters with the high bit set are treated as >128,
|
||||
for example o-umlaut should be 246, not -10. */
|
||||
add_word_args ("%%%x", (unsigned char) *name);
|
||||
else
|
||||
add_char (*name);
|
||||
}
|
||||
}
|
||||
|
||||
/* Insert the text for the name of a reference in an HTML anchor
|
||||
appropriate for NODENAME. If HREF is nonzero, it will be
|
||||
appropriate for a href= attribute, rather than name= i.e., including
|
||||
the `#' if it's an internal reference. */
|
||||
void
|
||||
add_anchor_name (nodename, href)
|
||||
char *nodename;
|
||||
int href;
|
||||
{
|
||||
if (href)
|
||||
add_char ('#');
|
||||
|
||||
add_escaped_anchor_name (nodename);
|
||||
}
|
44
contrib/texinfo/makeinfo/html.h
Normal file
44
contrib/texinfo/makeinfo/html.h
Normal file
@ -0,0 +1,44 @@
|
||||
/* html.h -- declarations for html-related utilities.
|
||||
$Id: html.h,v 1.1 1999/04/25 20:53:33 karl Exp $
|
||||
|
||||
Copyright (C) 1999 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 HTML_H
|
||||
#define HTML_H
|
||||
|
||||
/* Nonzero if we have output the <head>. */
|
||||
extern int html_output_head_p;
|
||||
|
||||
/* Perform the <head> output. */
|
||||
extern void html_output_head ();
|
||||
|
||||
/* Escape &<>. */
|
||||
extern char *escape_string (/* char * */);
|
||||
|
||||
/* Open or close TAG according to START_OR_END. */
|
||||
extern void insert_html_tag (/* int start_or_end, char *tag */);
|
||||
|
||||
/* Output HTML <link> to NODE, plus extra ATTRIBUTES. */
|
||||
extern void add_link (/* char *node, char *attributes */);
|
||||
|
||||
/* Escape URL-special characters as %xy. */
|
||||
extern void add_escaped_anchor_name (/* char *name */);
|
||||
|
||||
/* See html.c. */
|
||||
extern void add_anchor_name (/* nodename, href */);
|
||||
|
||||
#endif /* !HTML_H */
|
823
contrib/texinfo/makeinfo/index.c
Normal file
823
contrib/texinfo/makeinfo/index.c
Normal file
@ -0,0 +1,823 @@
|
||||
/* index.c -- indexing for Texinfo.
|
||||
$Id: index.c,v 1.21 1999/07/18 18:50:02 karl Exp $
|
||||
|
||||
Copyright (C) 1998, 99 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "system.h"
|
||||
#include "index.h"
|
||||
#include "lang.h"
|
||||
#include "macro.h"
|
||||
#include "toc.h"
|
||||
|
||||
/* An index element... */
|
||||
typedef struct index_elt
|
||||
{
|
||||
struct index_elt *next;
|
||||
char *entry; /* The index entry itself, after expansion. */
|
||||
char *entry_text; /* The original, non-expanded entry text. */
|
||||
char *node; /* The node from whence it came. */
|
||||
int code; /* Nonzero means add `@code{...}' when
|
||||
printing this element. */
|
||||
int defining_line; /* Line number where this entry was written. */
|
||||
char *defining_file; /* Source file for defining_line. */
|
||||
} INDEX_ELT;
|
||||
|
||||
|
||||
/* A list of short-names for each index.
|
||||
There are two indices into the the_indices array.
|
||||
* read_index is the index that points to the list of index
|
||||
entries that we will find if we ask for the list of entries for
|
||||
this name.
|
||||
* write_index is the index that points to the list of index entries
|
||||
that we will add new entries to.
|
||||
|
||||
Initially, read_index and write_index are the same, but the
|
||||
@syncodeindex and @synindex commands can change the list we add
|
||||
entries to.
|
||||
|
||||
For example, after the commands
|
||||
@cindex foo
|
||||
@defindex ii
|
||||
@synindex cp ii
|
||||
@cindex bar
|
||||
|
||||
the cp index will contain the entry `foo', and the new ii
|
||||
index will contain the entry `bar'. This is consistent with the
|
||||
way texinfo.tex handles the same situation.
|
||||
|
||||
In addition, for each index, it is remembered whether that index is
|
||||
a code index or not. Code indices have @code{} inserted around the
|
||||
first word when they are printed with printindex. */
|
||||
typedef struct
|
||||
{
|
||||
char *name;
|
||||
int read_index; /* index entries for `name' */
|
||||
int write_index; /* store index entries here, @synindex can change it */
|
||||
int code;
|
||||
} INDEX_ALIST;
|
||||
|
||||
INDEX_ALIST **name_index_alist = NULL;
|
||||
|
||||
/* An array of pointers. Each one is for a different index. The
|
||||
"synindex" command changes which array slot is pointed to by a
|
||||
given "index". */
|
||||
INDEX_ELT **the_indices = NULL;
|
||||
|
||||
/* The number of defined indices. */
|
||||
int defined_indices = 0;
|
||||
|
||||
/* Stuff for defining commands on the fly. */
|
||||
COMMAND **user_command_array = NULL;
|
||||
int user_command_array_len = 0;
|
||||
|
||||
/* How to compare index entries for sorting. May be set to strcoll. */
|
||||
int (*index_compare_fn) () = strcasecmp;
|
||||
|
||||
/* Find which element in the known list of indices has this name.
|
||||
Returns -1 if NAME isn't found. */
|
||||
static int
|
||||
find_index_offset (name)
|
||||
char *name;
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < defined_indices; i++)
|
||||
if (name_index_alist[i] && STREQ (name, name_index_alist[i]->name))
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Return a pointer to the entry of (name . index) for this name.
|
||||
Return NULL if the index doesn't exist. */
|
||||
INDEX_ALIST *
|
||||
find_index (name)
|
||||
char *name;
|
||||
{
|
||||
int offset = find_index_offset (name);
|
||||
if (offset > -1)
|
||||
return name_index_alist[offset];
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* User-defined commands, which happens only from user-defined indexes.
|
||||
Used to initialize the builtin indices, too. */
|
||||
void
|
||||
define_user_command (name, proc, needs_braces_p)
|
||||
char *name;
|
||||
COMMAND_FUNCTION *proc;
|
||||
int needs_braces_p;
|
||||
{
|
||||
int slot = user_command_array_len;
|
||||
user_command_array_len++;
|
||||
|
||||
if (!user_command_array)
|
||||
user_command_array = xmalloc (1 * sizeof (COMMAND *));
|
||||
|
||||
user_command_array = xrealloc (user_command_array,
|
||||
(1 + user_command_array_len) * sizeof (COMMAND *));
|
||||
|
||||
user_command_array[slot] = xmalloc (sizeof (COMMAND));
|
||||
user_command_array[slot]->name = xstrdup (name);
|
||||
user_command_array[slot]->proc = proc;
|
||||
user_command_array[slot]->argument_in_braces = needs_braces_p;
|
||||
}
|
||||
|
||||
/* Please release me, let me go... */
|
||||
static void
|
||||
free_index (index)
|
||||
INDEX_ELT *index;
|
||||
{
|
||||
INDEX_ELT *temp;
|
||||
|
||||
while ((temp = index))
|
||||
{
|
||||
free (temp->entry);
|
||||
free (temp->entry_text);
|
||||
/* Do not free the node, because we already freed the tag table,
|
||||
which freed all the node names. */
|
||||
/* free (temp->node); */
|
||||
index = index->next;
|
||||
free (temp);
|
||||
}
|
||||
}
|
||||
|
||||
/* Flush an index by name. This will delete the list of entries that
|
||||
would be written by a @printindex command for this index. */
|
||||
static void
|
||||
undefindex (name)
|
||||
char *name;
|
||||
{
|
||||
int i;
|
||||
int which = find_index_offset (name);
|
||||
|
||||
/* The index might have already been freed if this was the target of
|
||||
an @synindex. */
|
||||
if (which < 0 || !name_index_alist[which])
|
||||
return;
|
||||
|
||||
i = name_index_alist[which]->read_index;
|
||||
|
||||
free_index (the_indices[i]);
|
||||
the_indices[i] = NULL;
|
||||
|
||||
free (name_index_alist[which]->name);
|
||||
free (name_index_alist[which]);
|
||||
name_index_alist[which] = NULL;
|
||||
}
|
||||
|
||||
/* Add the arguments to the current index command to the index NAME.
|
||||
html fixxme generate specific html anchor */
|
||||
static void
|
||||
index_add_arg (name)
|
||||
char *name;
|
||||
{
|
||||
int which;
|
||||
char *index_entry;
|
||||
INDEX_ALIST *tem;
|
||||
|
||||
tem = find_index (name);
|
||||
|
||||
which = tem ? tem->write_index : -1;
|
||||
|
||||
if (macro_expansion_output_stream && !executing_string)
|
||||
append_to_expansion_output (input_text_offset + 1);
|
||||
|
||||
get_rest_of_line (0, &index_entry);
|
||||
ignore_blank_line ();
|
||||
|
||||
if (macro_expansion_output_stream && !executing_string)
|
||||
{
|
||||
char *index_line = xmalloc (strlen (index_entry) + 2);
|
||||
sprintf (index_line, "%s\n", index_entry);
|
||||
me_execute_string_keep_state (index_line, NULL);
|
||||
free (index_line);
|
||||
}
|
||||
|
||||
if (which < 0)
|
||||
{
|
||||
line_error (_("Unknown index `%s'"), name);
|
||||
free (index_entry);
|
||||
}
|
||||
else
|
||||
{
|
||||
INDEX_ELT *new = xmalloc (sizeof (INDEX_ELT));
|
||||
new->next = the_indices[which];
|
||||
new->entry_text = index_entry;
|
||||
new->entry = NULL;
|
||||
new->node = current_node ? current_node : xstrdup ("");
|
||||
new->code = tem->code;
|
||||
new->defining_line = line_number - 1;
|
||||
/* We need to make a copy since input_filename may point to
|
||||
something that goes away, for example, inside a macro.
|
||||
(see the findexerr test). */
|
||||
new->defining_file = xstrdup (input_filename);
|
||||
the_indices[which] = new;
|
||||
}
|
||||
}
|
||||
|
||||
/* The function which user defined index commands call. */
|
||||
static void
|
||||
gen_index ()
|
||||
{
|
||||
char *name = xstrdup (command);
|
||||
if (strlen (name) >= strlen ("index"))
|
||||
name[strlen (name) - strlen ("index")] = 0;
|
||||
index_add_arg (name);
|
||||
free (name);
|
||||
}
|
||||
|
||||
/* Define an index known as NAME. We assign the slot number.
|
||||
If CODE is nonzero, make this a code index. */
|
||||
static void
|
||||
defindex (name, code)
|
||||
char *name;
|
||||
int code;
|
||||
{
|
||||
int i, slot;
|
||||
|
||||
/* If it already exists, flush it. */
|
||||
undefindex (name);
|
||||
|
||||
/* Try to find an empty slot. */
|
||||
slot = -1;
|
||||
for (i = 0; i < defined_indices; i++)
|
||||
if (!name_index_alist[i])
|
||||
{
|
||||
slot = i;
|
||||
break;
|
||||
}
|
||||
|
||||
if (slot < 0)
|
||||
{ /* No such luck. Make space for another index. */
|
||||
slot = defined_indices;
|
||||
defined_indices++;
|
||||
|
||||
name_index_alist = (INDEX_ALIST **)
|
||||
xrealloc (name_index_alist, (1 + defined_indices)
|
||||
* sizeof (INDEX_ALIST *));
|
||||
the_indices = (INDEX_ELT **)
|
||||
xrealloc (the_indices, (1 + defined_indices) * sizeof (INDEX_ELT *));
|
||||
}
|
||||
|
||||
/* We have a slot. Start assigning. */
|
||||
name_index_alist[slot] = xmalloc (sizeof (INDEX_ALIST));
|
||||
name_index_alist[slot]->name = xstrdup (name);
|
||||
name_index_alist[slot]->read_index = slot;
|
||||
name_index_alist[slot]->write_index = slot;
|
||||
name_index_alist[slot]->code = code;
|
||||
|
||||
the_indices[slot] = NULL;
|
||||
}
|
||||
|
||||
/* Define an index NAME, implicitly @code if CODE is nonzero. */
|
||||
static void
|
||||
top_defindex (name, code)
|
||||
char *name;
|
||||
int code;
|
||||
{
|
||||
char *temp;
|
||||
|
||||
temp = xmalloc (1 + strlen (name) + strlen ("index"));
|
||||
sprintf (temp, "%sindex", name);
|
||||
define_user_command (temp, gen_index, 0);
|
||||
defindex (name, code);
|
||||
free (temp);
|
||||
}
|
||||
|
||||
/* Set up predefined indices. */
|
||||
void
|
||||
init_indices ()
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Create the default data structures. */
|
||||
|
||||
/* Initialize data space. */
|
||||
if (!the_indices)
|
||||
{
|
||||
the_indices = xmalloc ((1 + defined_indices) * sizeof (INDEX_ELT *));
|
||||
the_indices[defined_indices] = NULL;
|
||||
|
||||
name_index_alist = xmalloc ((1 + defined_indices)
|
||||
* sizeof (INDEX_ALIST *));
|
||||
name_index_alist[defined_indices] = NULL;
|
||||
}
|
||||
|
||||
/* If there were existing indices, get rid of them now. */
|
||||
for (i = 0; i < defined_indices; i++)
|
||||
{
|
||||
undefindex (name_index_alist[i]->name);
|
||||
if (name_index_alist[i])
|
||||
{ /* Suppose we're called with two input files, and the first
|
||||
does a @synindex pg cp. Then, when we get here to start
|
||||
the second file, the "pg" element won't get freed by
|
||||
undefindex (because it's pointing to "cp"). So free it
|
||||
here; otherwise, when we try to define the pg index again
|
||||
just below, it will still point to cp. */
|
||||
free (name_index_alist[i]->name);
|
||||
free (name_index_alist[i]);
|
||||
name_index_alist[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add the default indices. */
|
||||
top_defindex ("cp", 0); /* cp is the only non-code index. */
|
||||
top_defindex ("fn", 1);
|
||||
top_defindex ("ky", 1);
|
||||
top_defindex ("pg", 1);
|
||||
top_defindex ("tp", 1);
|
||||
top_defindex ("vr", 1);
|
||||
}
|
||||
|
||||
/* Given an index name, return the offset in the_indices of this index,
|
||||
or -1 if there is no such index. */
|
||||
int
|
||||
translate_index (name)
|
||||
char *name;
|
||||
{
|
||||
INDEX_ALIST *which = find_index (name);
|
||||
|
||||
if (which)
|
||||
return which->read_index;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Return the index list which belongs to NAME. */
|
||||
INDEX_ELT *
|
||||
index_list (name)
|
||||
char *name;
|
||||
{
|
||||
int which = translate_index (name);
|
||||
if (which < 0)
|
||||
return (INDEX_ELT *) -1;
|
||||
else
|
||||
return the_indices[which];
|
||||
}
|
||||
|
||||
/* Define a new index command. Arg is name of index. */
|
||||
static void
|
||||
gen_defindex (code)
|
||||
int code;
|
||||
{
|
||||
char *name;
|
||||
get_rest_of_line (0, &name);
|
||||
|
||||
if (find_index (name))
|
||||
{
|
||||
line_error (_("Index `%s' already exists"), name);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *temp = xmalloc (strlen (name) + sizeof ("index"));
|
||||
sprintf (temp, "%sindex", name);
|
||||
define_user_command (temp, gen_index, 0);
|
||||
defindex (name, code);
|
||||
free (temp);
|
||||
}
|
||||
|
||||
free (name);
|
||||
}
|
||||
|
||||
void
|
||||
cm_defindex ()
|
||||
{
|
||||
gen_defindex (0);
|
||||
}
|
||||
|
||||
void
|
||||
cm_defcodeindex ()
|
||||
{
|
||||
gen_defindex (1);
|
||||
}
|
||||
|
||||
/* Expects 2 args, on the same line. Both are index abbreviations.
|
||||
Make the first one be a synonym for the second one, i.e. make the
|
||||
first one have the same index as the second one. */
|
||||
void
|
||||
cm_synindex ()
|
||||
{
|
||||
int source, target;
|
||||
char *abbrev1, *abbrev2;
|
||||
|
||||
skip_whitespace ();
|
||||
get_until_in_line (0, " ", &abbrev1);
|
||||
target = find_index_offset (abbrev1);
|
||||
skip_whitespace ();
|
||||
get_until_in_line (0, " ", &abbrev2);
|
||||
source = find_index_offset (abbrev2);
|
||||
if (source < 0 || target < 0)
|
||||
{
|
||||
line_error (_("Unknown index `%s' and/or `%s' in @synindex"),
|
||||
abbrev1, abbrev2);
|
||||
}
|
||||
else
|
||||
{
|
||||
name_index_alist[target]->write_index
|
||||
= name_index_alist[source]->write_index;
|
||||
}
|
||||
|
||||
free (abbrev1);
|
||||
free (abbrev2);
|
||||
}
|
||||
|
||||
void
|
||||
cm_pindex () /* Pinhead index. */
|
||||
{
|
||||
index_add_arg ("pg");
|
||||
}
|
||||
|
||||
void
|
||||
cm_vindex () /* Variable index. */
|
||||
{
|
||||
index_add_arg ("vr");
|
||||
}
|
||||
|
||||
void
|
||||
cm_kindex () /* Key index. */
|
||||
{
|
||||
index_add_arg ("ky");
|
||||
}
|
||||
|
||||
void
|
||||
cm_cindex () /* Concept index. */
|
||||
{
|
||||
index_add_arg ("cp");
|
||||
}
|
||||
|
||||
void
|
||||
cm_findex () /* Function index. */
|
||||
{
|
||||
index_add_arg ("fn");
|
||||
}
|
||||
|
||||
void
|
||||
cm_tindex () /* Data Type index. */
|
||||
{
|
||||
index_add_arg ("tp");
|
||||
}
|
||||
|
||||
int
|
||||
index_element_compare (element1, element2)
|
||||
INDEX_ELT **element1, **element2;
|
||||
{
|
||||
return index_compare_fn ((*element1)->entry, (*element2)->entry);
|
||||
}
|
||||
|
||||
/* Force all index entries to be unique. */
|
||||
void
|
||||
make_index_entries_unique (array, count)
|
||||
INDEX_ELT **array;
|
||||
int count;
|
||||
{
|
||||
int i, j;
|
||||
INDEX_ELT **copy;
|
||||
int counter = 1;
|
||||
|
||||
copy = xmalloc ((1 + count) * sizeof (INDEX_ELT *));
|
||||
|
||||
for (i = 0, j = 0; i < count; i++)
|
||||
{
|
||||
if (i == (count - 1)
|
||||
|| array[i]->node != array[i + 1]->node
|
||||
|| !STREQ (array[i]->entry, array[i + 1]->entry))
|
||||
copy[j++] = array[i];
|
||||
else
|
||||
{
|
||||
free (array[i]->entry);
|
||||
free (array[i]->entry_text);
|
||||
free (array[i]);
|
||||
}
|
||||
}
|
||||
copy[j] = NULL;
|
||||
|
||||
/* Now COPY contains only unique entries. Duplicated entries in the
|
||||
original array have been freed. Replace the current array with
|
||||
the copy, fixing the NEXT pointers. */
|
||||
for (i = 0; copy[i]; i++)
|
||||
{
|
||||
copy[i]->next = copy[i + 1];
|
||||
|
||||
/* Fix entry names which are the same. They point to different nodes,
|
||||
so we make the entry name unique. */
|
||||
if (copy[i+1]
|
||||
&& STREQ (copy[i]->entry, copy[i + 1]->entry)
|
||||
&& !html)
|
||||
{
|
||||
char *new_entry_name;
|
||||
|
||||
new_entry_name = xmalloc (10 + strlen (copy[i]->entry));
|
||||
sprintf (new_entry_name, "%s <%d>", copy[i]->entry, counter);
|
||||
free (copy[i]->entry);
|
||||
copy[i]->entry = new_entry_name;
|
||||
counter++;
|
||||
}
|
||||
else
|
||||
counter = 1;
|
||||
|
||||
array[i] = copy[i];
|
||||
}
|
||||
array[i] = NULL;
|
||||
|
||||
/* Free the storage used only by COPY. */
|
||||
free (copy);
|
||||
}
|
||||
|
||||
/* Sort the index passed in INDEX, returning an array of
|
||||
pointers to elements. The array is terminated with a NULL
|
||||
pointer. We call qsort because it's supposed to be fast.
|
||||
I think this looks bad. */
|
||||
INDEX_ELT **
|
||||
sort_index (index)
|
||||
INDEX_ELT *index;
|
||||
{
|
||||
INDEX_ELT **array;
|
||||
INDEX_ELT *temp = index;
|
||||
int count = 0;
|
||||
int save_line_number = line_number;
|
||||
char *save_input_filename = input_filename;
|
||||
int save_html = html;
|
||||
|
||||
/* Pretend we are in non-HTML mode, for the purpose of getting the
|
||||
expanded index entry that lacks any markup and other HTML escape
|
||||
characters which could produce a wrong sort order. */
|
||||
/* fixme: html: this still causes some markup, such as non-ASCII
|
||||
characters @AE{} etc., to sort incorrectly. */
|
||||
html = 0;
|
||||
|
||||
while (temp)
|
||||
{
|
||||
count++;
|
||||
temp = temp->next;
|
||||
}
|
||||
|
||||
/* We have the length. Make an array. */
|
||||
|
||||
array = xmalloc ((count + 1) * sizeof (INDEX_ELT *));
|
||||
count = 0;
|
||||
temp = index;
|
||||
|
||||
while (temp)
|
||||
{
|
||||
array[count++] = temp;
|
||||
|
||||
/* Set line number and input filename to the source line for this
|
||||
index entry, as this expansion finds any errors. */
|
||||
line_number = array[count - 1]->defining_line;
|
||||
input_filename = array[count - 1]->defining_file;
|
||||
|
||||
/* If this particular entry should be printed as a "code" index,
|
||||
then expand it as @code{entry}, i.e. as in fixed-width font. */
|
||||
array[count-1]->entry = expansion (temp->entry_text,
|
||||
array[count-1]->code);
|
||||
|
||||
temp = temp->next;
|
||||
}
|
||||
array[count] = NULL; /* terminate the array. */
|
||||
line_number = save_line_number;
|
||||
input_filename = save_input_filename;
|
||||
html = save_html;
|
||||
|
||||
#ifdef HAVE_STRCOLL
|
||||
/* This is not perfect. We should set (then restore) the locale to the
|
||||
documentlanguage, so strcoll operates according to the document's
|
||||
locale, not the user's. For now, I'm just going to assume that
|
||||
those few new documents which use @documentlanguage will be
|
||||
processed in the appropriate locale. In any case, don't use
|
||||
strcoll in the C (aka POSIX) locale, that is the ASCII ordering. */
|
||||
if (language_code != en)
|
||||
{
|
||||
char *lang_env = getenv ("LANG");
|
||||
if (lang_env && !STREQ (lang_env, "C") && !STREQ (lang_env, "POSIX"))
|
||||
index_compare_fn = strcoll;
|
||||
}
|
||||
#endif /* HAVE_STRCOLL */
|
||||
|
||||
/* Sort the array. */
|
||||
qsort (array, count, sizeof (INDEX_ELT *), index_element_compare);
|
||||
make_index_entries_unique (array, count);
|
||||
return array;
|
||||
}
|
||||
|
||||
/* Nonzero means that we are in the middle of printing an index. */
|
||||
int printing_index = 0;
|
||||
|
||||
/* Takes one arg, a short name of an index to print.
|
||||
Outputs a menu of the sorted elements of the index. */
|
||||
void
|
||||
cm_printindex ()
|
||||
{
|
||||
int item;
|
||||
INDEX_ELT *index;
|
||||
INDEX_ELT *last_index = 0;
|
||||
INDEX_ELT **array;
|
||||
char *index_name;
|
||||
unsigned line_length;
|
||||
char *line;
|
||||
int saved_inhibit_paragraph_indentation = inhibit_paragraph_indentation;
|
||||
int saved_filling_enabled = filling_enabled;
|
||||
int saved_line_number = line_number;
|
||||
char *saved_input_filename = input_filename;
|
||||
|
||||
close_paragraph ();
|
||||
get_rest_of_line (0, &index_name);
|
||||
|
||||
index = index_list (index_name);
|
||||
if (index == (INDEX_ELT *)-1)
|
||||
{
|
||||
line_error (_("Unknown index `%s' in @printindex"), index_name);
|
||||
free (index_name);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Do this before sorting, so execute_string in index_element_compare
|
||||
will give the same results as when we actually print. */
|
||||
printing_index = 1;
|
||||
filling_enabled = 0;
|
||||
inhibit_paragraph_indentation = 1;
|
||||
array = sort_index (index);
|
||||
|
||||
close_paragraph ();
|
||||
if (html)
|
||||
add_word ("<ul compact>");
|
||||
else if (!no_headers)
|
||||
add_word ("* Menu:\n\n");
|
||||
|
||||
me_inhibit_expansion++;
|
||||
|
||||
/* This will probably be enough. */
|
||||
line_length = 100;
|
||||
line = xmalloc (line_length);
|
||||
|
||||
for (item = 0; (index = array[item]); item++)
|
||||
{
|
||||
/* A pathological document might have an index entry outside of any
|
||||
node. Don't crash; try using the section name instead. */
|
||||
char *index_node = index->node;
|
||||
|
||||
line_number = index->defining_line;
|
||||
input_filename = index->defining_file;
|
||||
|
||||
if ((!index_node || !*index_node) && html)
|
||||
index_node = toc_find_section_of_node (index_node);
|
||||
|
||||
if (!index_node || !*index_node)
|
||||
{
|
||||
line_error (_("Entry for index `%s' outside of any node"),
|
||||
index_name);
|
||||
if (html || !no_headers)
|
||||
index_node = _("(outside of any node)");
|
||||
}
|
||||
|
||||
if (html)
|
||||
/* fixme: html: we should use specific index anchors pointing
|
||||
to the actual location of the indexed position (but then we
|
||||
have to find something to wrap the anchor around). */
|
||||
{
|
||||
if (last_index
|
||||
&& STREQ (last_index->entry_text, index->entry_text))
|
||||
add_word (", "); /* Don't repeat the previous entry. */
|
||||
else
|
||||
{
|
||||
/* In the HTML case, the expanded index entry is not
|
||||
good for us, since it was expanded for non-HTML mode
|
||||
inside sort_index. So we need to HTML-escape and
|
||||
expand the original entry text here. */
|
||||
char *escaped_entry = xstrdup (index->entry_text);
|
||||
char *expanded_entry;
|
||||
|
||||
/* expansion() doesn't HTML-escape the argument, so need
|
||||
to do it separately. */
|
||||
escaped_entry = escape_string (escaped_entry);
|
||||
expanded_entry = expansion (escaped_entry, index->code);
|
||||
add_word_args ("\n<li>%s: ", expanded_entry);
|
||||
free (escaped_entry);
|
||||
free (expanded_entry);
|
||||
}
|
||||
add_word ("<a href=\"");
|
||||
if (index->node && *index->node)
|
||||
{
|
||||
/* Make sure any non-macros in the node name are expanded. */
|
||||
in_fixed_width_font++;
|
||||
index_node = expansion (index_node, 0);
|
||||
in_fixed_width_font--;
|
||||
add_anchor_name (index_node, 1);
|
||||
add_word_args ("\">%s</a>", index_node);
|
||||
free (index_node);
|
||||
}
|
||||
else if (STREQ (index_node, _("(outside of any node)")))
|
||||
{
|
||||
add_anchor_name (index_node, 1);
|
||||
add_word_args ("\">%s</a>", index_node);
|
||||
}
|
||||
else
|
||||
/* If we use the section instead of the (missing) node, then
|
||||
index_node already includes all we need except the #. */
|
||||
add_word_args ("#%s</a>", index_node);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned new_length = strlen (index->entry);
|
||||
|
||||
if (new_length < 50) /* minimum length used below */
|
||||
new_length = 50;
|
||||
new_length += strlen (index_node) + 7; /* * : .\n\0 */
|
||||
|
||||
if (new_length > line_length)
|
||||
{
|
||||
line_length = new_length;
|
||||
line = xrealloc (line, line_length);
|
||||
}
|
||||
/* Print the entry, nicely formatted. We've already
|
||||
expanded any commands in index->entry, including any
|
||||
implicit @code. Thus, can't call execute_string, since
|
||||
@@ has turned into @. */
|
||||
if (!no_headers)
|
||||
{
|
||||
sprintf (line, "* %-37s ", index->entry);
|
||||
line[2 + strlen (index->entry)] = ':';
|
||||
insert_string (line);
|
||||
/* Make sure any non-macros in the node name are expanded. */
|
||||
in_fixed_width_font++;
|
||||
execute_string ("%s.\n", index_node);
|
||||
in_fixed_width_font--;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* With --no-headers, the @node lines are gone, so
|
||||
there's little sense in referring to them in the
|
||||
index. Instead, output the number or name of the
|
||||
section that corresponds to that node. */
|
||||
char *section_name = toc_find_section_of_node (index_node);
|
||||
|
||||
sprintf (line, "%-*s ", number_sections ? 50 : 1, index->entry);
|
||||
line[strlen (index->entry)] = ':';
|
||||
insert_string (line);
|
||||
if (section_name)
|
||||
{
|
||||
int idx = 0;
|
||||
unsigned ref_len = strlen (section_name) + 30;
|
||||
|
||||
if (ref_len > line_length)
|
||||
{
|
||||
line_length = ref_len;
|
||||
line = xrealloc (line, line_length);
|
||||
}
|
||||
|
||||
if (number_sections)
|
||||
{
|
||||
while (section_name[idx]
|
||||
&& (isdigit (section_name[idx])
|
||||
|| (idx && section_name[idx] == '.')))
|
||||
idx++;
|
||||
}
|
||||
if (idx)
|
||||
sprintf (line, " See %.*s.\n", idx, section_name);
|
||||
else
|
||||
sprintf (line, "\n See ``%s''.\n", section_name);
|
||||
insert_string (line);
|
||||
}
|
||||
else
|
||||
{
|
||||
insert_string (" "); /* force a blank */
|
||||
execute_string ("See node %s.\n", index_node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Prevent `output_paragraph' from growing to the size of the
|
||||
whole index. */
|
||||
flush_output ();
|
||||
last_index = index;
|
||||
}
|
||||
|
||||
free (line);
|
||||
free (index_name);
|
||||
|
||||
me_inhibit_expansion--;
|
||||
|
||||
printing_index = 0;
|
||||
free (array);
|
||||
close_single_paragraph ();
|
||||
filling_enabled = saved_filling_enabled;
|
||||
inhibit_paragraph_indentation = saved_inhibit_paragraph_indentation;
|
||||
input_filename = saved_input_filename;
|
||||
line_number = saved_line_number;
|
||||
|
||||
if (html)
|
||||
add_word ("</ul>");
|
||||
}
|
36
contrib/texinfo/makeinfo/index.h
Normal file
36
contrib/texinfo/makeinfo/index.h
Normal file
@ -0,0 +1,36 @@
|
||||
/* index.h -- declarations for index.c.
|
||||
$Id: index.h,v 1.4 1999/04/19 18:12:17 karl Exp $
|
||||
|
||||
Copyright (C) 1998, 99 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 INDEX_H
|
||||
#define INDEX_H
|
||||
|
||||
#include "makeinfo.h"
|
||||
#include "cmds.h"
|
||||
|
||||
/* User commands are only new indices. (Macros are handled separately.) */
|
||||
extern COMMAND **user_command_array;
|
||||
extern int user_command_array_len;
|
||||
|
||||
/* Initialize all indices. */
|
||||
extern void init_indices ();
|
||||
|
||||
/* Function to compare index entries for sorting. */
|
||||
extern int (*index_compare_fn) ();
|
||||
|
||||
#endif /* !INDEX_H */
|
1368
contrib/texinfo/makeinfo/insertion.c
Normal file
1368
contrib/texinfo/makeinfo/insertion.c
Normal file
File diff suppressed because it is too large
Load Diff
61
contrib/texinfo/makeinfo/insertion.h
Normal file
61
contrib/texinfo/makeinfo/insertion.h
Normal file
@ -0,0 +1,61 @@
|
||||
/* insertion.h -- declarations for insertion.c.
|
||||
$Id: insertion.h,v 1.6 1999/07/06 23:12:58 karl Exp $
|
||||
|
||||
Copyright (C) 1998, 99 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 INSERTION_H
|
||||
#define INSERTION_H
|
||||
|
||||
/* Must match list in insertion.c. */
|
||||
enum insertion_type
|
||||
{
|
||||
cartouche, defcv, deffn, defivar, defmac, defmethod, defop, defopt,
|
||||
defspec, deftp, deftypefn, deftypefun, deftypeivar, deftypemethod,
|
||||
deftypeop, deftypevar, deftypevr, defun, defvar, defvr, detailmenu,
|
||||
direntry, display, enumerate, example, flushleft, flushright, format,
|
||||
ftable, group, ifclear, ifhtml, ifinfo, ifnothtml, ifnotinfo,
|
||||
ifnottex, ifset, iftex, itemize, lisp, menu, multitable, quotation,
|
||||
rawhtml, rawtex, smalldisplay, smallexample, smallformat, smalllisp,
|
||||
table, tex, vtable, bad_type
|
||||
};
|
||||
|
||||
typedef struct istack_elt
|
||||
{
|
||||
struct istack_elt *next;
|
||||
char *item_function;
|
||||
char *filename;
|
||||
int line_number;
|
||||
int filling_enabled;
|
||||
int indented_fill;
|
||||
enum insertion_type insertion;
|
||||
int inhibited;
|
||||
int in_fixed_width_font;
|
||||
} INSERTION_ELT;
|
||||
|
||||
|
||||
extern int insertion_level;
|
||||
extern INSERTION_ELT *insertion_stack;
|
||||
extern int in_menu;
|
||||
extern int in_detailmenu;
|
||||
extern int had_menu_commentary;
|
||||
extern int in_paragraph;
|
||||
|
||||
extern void command_name_condition ();
|
||||
extern void cm_ifnothtml (), cm_ifhtml(), cm_html ();
|
||||
extern void cm_ifinfo (), cm_ifnotinfo ();
|
||||
extern void cm_ifnottex (), cm_iftex (), cm_tex ();
|
||||
#endif /* !INSERTION_H */
|
415
contrib/texinfo/makeinfo/lang.c
Normal file
415
contrib/texinfo/makeinfo/lang.c
Normal file
@ -0,0 +1,415 @@
|
||||
/* lang.c -- language depend behaviour (startpoint)
|
||||
$Id: lang.c,v 1.11 1999/07/13 21:16:29 karl Exp $
|
||||
|
||||
Copyright (C) 1999 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 Karl Heinz Marbaise <kama@hippo.fido.de>. */
|
||||
|
||||
#include "system.h"
|
||||
#include "cmds.h"
|
||||
#include "lang.h"
|
||||
#include "makeinfo.h"
|
||||
|
||||
/* Current document encoding. */
|
||||
char *document_encoding = NULL;
|
||||
|
||||
/* Current language code; default is English. */
|
||||
language_code_type language_code = en;
|
||||
|
||||
language_struct language_table[] = {
|
||||
{ aa, "aa", "Afar" },
|
||||
{ ab, "ab", "Abkhazian" },
|
||||
{ af, "af", "Afrikaans" },
|
||||
{ am, "am", "Amharic" },
|
||||
{ ar, "ar", "Arabic" },
|
||||
{ as, "as", "Assamese" },
|
||||
{ ay, "ay", "Aymara" },
|
||||
{ az, "az", "Azerbaijani" },
|
||||
{ ba, "ba", "Bashkir" },
|
||||
{ be, "be", "Byelorussian" },
|
||||
{ bg, "bg", "Bulgarian" },
|
||||
{ bh, "bh", "Bihari" },
|
||||
{ bi, "bi", "Bislama" },
|
||||
{ bn, "bn", "Bengali; Bangla" },
|
||||
{ bo, "bo", "Tibetan" },
|
||||
{ br, "br", "Breton" },
|
||||
{ ca, "ca", "Catalan" },
|
||||
{ co, "co", "Corsican" },
|
||||
{ cs, "cs", "Czech" },
|
||||
{ cy, "cy", "Welsh" },
|
||||
{ da, "da", "Danish" },
|
||||
{ de, "de", "German" },
|
||||
{ dz, "dz", "Bhutani" },
|
||||
{ el, "el", "Greek" },
|
||||
{ en, "en", "English" },
|
||||
{ eo, "eo", "Esperanto" },
|
||||
{ es, "es", "Spanish" },
|
||||
{ et, "et", "Estonian" },
|
||||
{ eu, "eu", "Basque" },
|
||||
{ fa, "fa", "Persian" },
|
||||
{ fi, "fi", "Finnish" },
|
||||
{ fj, "fj", "Fiji" },
|
||||
{ fo, "fo", "Faroese" },
|
||||
{ fr, "fr", "French" },
|
||||
{ fy, "fy", "Frisian" },
|
||||
{ ga, "ga", "Irish" },
|
||||
{ gd, "gd", "Scots Gaelic" },
|
||||
{ gl, "gl", "Galician" },
|
||||
{ gn, "gn", "Guarani" },
|
||||
{ gu, "gu", "Gujarati" },
|
||||
{ ha, "ha", "Hausa" },
|
||||
{ he, "he", "Hebrew" } /* (formerly iw) */,
|
||||
{ hi, "hi", "Hindi" },
|
||||
{ hr, "hr", "Croatian" },
|
||||
{ hu, "hu", "Hungarian" },
|
||||
{ hy, "hy", "Armenian" },
|
||||
{ ia, "ia", "Interlingua" },
|
||||
{ id, "id", "Indonesian" } /* (formerly in) */,
|
||||
{ ie, "ie", "Interlingue" },
|
||||
{ ik, "ik", "Inupiak" },
|
||||
{ is, "is", "Icelandic" },
|
||||
{ it, "it", "Italian" },
|
||||
{ iu, "iu", "Inuktitut" },
|
||||
{ ja, "ja", "Japanese" },
|
||||
{ jw, "jw", "Javanese" },
|
||||
{ ka, "ka", "Georgian" },
|
||||
{ kk, "kk", "Kazakh" },
|
||||
{ kl, "kl", "Greenlandic" },
|
||||
{ km, "km", "Cambodian" },
|
||||
{ kn, "kn", "Kannada" },
|
||||
{ ko, "ko", "Korean" },
|
||||
{ ks, "ks", "Kashmiri" },
|
||||
{ ku, "ku", "Kurdish" },
|
||||
{ ky, "ky", "Kirghiz" },
|
||||
{ la, "la", "Latin" },
|
||||
{ ln, "ln", "Lingala" },
|
||||
{ lo, "lo", "Laothian" },
|
||||
{ lt, "lt", "Lithuanian" },
|
||||
{ lv, "lv", "Latvian, Lettish" },
|
||||
{ mg, "mg", "Malagasy" },
|
||||
{ mi, "mi", "Maori" },
|
||||
{ mk, "mk", "Macedonian" },
|
||||
{ ml, "ml", "Malayalam" },
|
||||
{ mn, "mn", "Mongolian" },
|
||||
{ mo, "mo", "Moldavian" },
|
||||
{ mr, "mr", "Marathi" },
|
||||
{ ms, "ms", "Malay" },
|
||||
{ mt, "mt", "Maltese" },
|
||||
{ my, "my", "Burmese" },
|
||||
{ na, "na", "Nauru" },
|
||||
{ ne, "ne", "Nepali" },
|
||||
{ nl, "nl", "Dutch" },
|
||||
{ no, "no", "Norwegian" },
|
||||
{ oc, "oc", "Occitan" },
|
||||
{ om, "om", "(Afan) Oromo" },
|
||||
{ or, "or", "Oriya" },
|
||||
{ pa, "pa", "Punjabi" },
|
||||
{ pl, "pl", "Polish" },
|
||||
{ ps, "ps", "Pashto, Pushto" },
|
||||
{ pt, "pt", "Portuguese" },
|
||||
{ qu, "qu", "Quechua" },
|
||||
{ rm, "rm", "Rhaeto-Romance" },
|
||||
{ rn, "rn", "Kirundi" },
|
||||
{ ro, "ro", "Romanian" },
|
||||
{ ru, "ru", "Russian" },
|
||||
{ rw, "rw", "Kinyarwanda" },
|
||||
{ sa, "sa", "Sanskrit" },
|
||||
{ sd, "sd", "Sindhi" },
|
||||
{ sg, "sg", "Sangro" },
|
||||
{ sh, "sh", "Serbo-Croatian" },
|
||||
{ si, "si", "Sinhalese" },
|
||||
{ sk, "sk", "Slovak" },
|
||||
{ sl, "sl", "Slovenian" },
|
||||
{ sm, "sm", "Samoan" },
|
||||
{ sn, "sn", "Shona" },
|
||||
{ so, "so", "Somali" },
|
||||
{ sq, "sq", "Albanian" },
|
||||
{ sr, "sr", "Serbian" },
|
||||
{ ss, "ss", "Siswati" },
|
||||
{ st, "st", "Sesotho" },
|
||||
{ su, "su", "Sundanese" },
|
||||
{ sv, "sv", "Swedish" },
|
||||
{ sw, "sw", "Swahili" },
|
||||
{ ta, "ta", "Tamil" },
|
||||
{ te, "te", "Telugu" },
|
||||
{ tg, "tg", "Tajik" },
|
||||
{ th, "th", "Thai" },
|
||||
{ ti, "ti", "Tigrinya" },
|
||||
{ tk, "tk", "Turkmen" },
|
||||
{ tl, "tl", "Tagalog" },
|
||||
{ tn, "tn", "Setswana" },
|
||||
{ to, "to", "Tonga" },
|
||||
{ tr, "tr", "Turkish" },
|
||||
{ ts, "ts", "Tsonga" },
|
||||
{ tt, "tt", "Tatar" },
|
||||
{ tw, "tw", "Twi" },
|
||||
{ ug, "ug", "Uighur" },
|
||||
{ uk, "uk", "Ukrainian" },
|
||||
{ ur, "ur", "Urdu" },
|
||||
{ uz, "uz", "Uzbek" },
|
||||
{ vi, "vi", "Vietnamese" },
|
||||
{ vo, "vo", "Volapuk" },
|
||||
{ wo, "wo", "Wolof" },
|
||||
{ xh, "xh", "Xhosa" },
|
||||
{ yi, "yi", "Yiddish" } /* (formerly ji) */,
|
||||
{ yo, "yo", "Yoruba" },
|
||||
{ za, "za", "Zhuang" },
|
||||
{ zh, "zh", "Chinese" },
|
||||
{ zu, "zu", "Zulu" },
|
||||
{ last_language_code, NULL, NULL }
|
||||
};
|
||||
|
||||
/* @documentlanguage. Maybe we'll do something useful with this in the
|
||||
future. For now, we just recognize it. */
|
||||
void
|
||||
cm_documentlanguage ()
|
||||
{
|
||||
language_code_type c;
|
||||
char *lang_arg;
|
||||
|
||||
/* Read the line with the language code on it. */
|
||||
get_rest_of_line (1, &lang_arg);
|
||||
|
||||
/* Linear search is fine these days. */
|
||||
for (c = aa; c != last_language_code; c++)
|
||||
{
|
||||
if (strcmp (lang_arg, language_table[c].abbrev) == 0)
|
||||
{ /* Set current language code. */
|
||||
language_code = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we didn't find this code, complain. */
|
||||
if (c == last_language_code)
|
||||
warning (_("%s is not a valid ISO 639 language code"), lang_arg);
|
||||
|
||||
free (lang_arg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* @documentencoding. Set global. */
|
||||
void
|
||||
cm_documentencoding ()
|
||||
{
|
||||
get_rest_of_line (1, &document_encoding);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Accent commands that take explicit arguments and don't have any
|
||||
special HTML support. */
|
||||
|
||||
void
|
||||
cm_accent (arg)
|
||||
int arg;
|
||||
{
|
||||
if (arg == START)
|
||||
{
|
||||
/* Must come first to avoid ambiguity with overdot. */
|
||||
if (strcmp (command, "udotaccent") == 0) /* underdot */
|
||||
add_char ('.');
|
||||
}
|
||||
else if (arg == END)
|
||||
{
|
||||
if (strcmp (command, "=") == 0) /* macron */
|
||||
add_word (html ? "¯" : "=");
|
||||
else if (strcmp (command, "H") == 0) /* Hungarian umlaut */
|
||||
add_word ("''");
|
||||
else if (strcmp (command, "dotaccent") == 0) /* overdot */
|
||||
add_meta_char ('.');
|
||||
else if (strcmp (command, "ringaccent") == 0) /* ring */
|
||||
add_char ('*');
|
||||
else if (strcmp (command, "tieaccent") == 0) /* long tie */
|
||||
add_char ('[');
|
||||
else if (strcmp (command, "u") == 0) /* breve */
|
||||
add_char ('(');
|
||||
else if (strcmp (command, "ubaraccent") == 0) /* underbar */
|
||||
add_char ('_');
|
||||
else if (strcmp (command, "v") == 0) /* hacek/check */
|
||||
add_word (html ? "<" : "<");
|
||||
}
|
||||
}
|
||||
|
||||
/* Common routine for the accent characters that have support in HTML.
|
||||
If the character being accented is in the HTML_SUPPORTED set, then
|
||||
produce &CHTML_SOLO;, for example, Ä for an A-umlaut. If not in
|
||||
HTML_SUPPORTED, just produce &HTML_SOLO;X for the best we can do with
|
||||
at an X-umlaut. Finally, if not producing HTML, just use SINGLE, a
|
||||
character such as " which is the best plain text representation we
|
||||
can manage. If HTML_SOLO_STANDALONE is zero the given HTML_SOLO
|
||||
does not exist as valid standalone character in HTML. */
|
||||
|
||||
static void
|
||||
cm_accent_generic (arg, start, end, html_supported, single,
|
||||
html_solo_standalone, html_solo)
|
||||
int arg, start, end;
|
||||
char *html_supported;
|
||||
int single;
|
||||
int html_solo_standalone;
|
||||
char *html_solo;
|
||||
{
|
||||
if (html)
|
||||
{
|
||||
static int valid_html_accent;
|
||||
|
||||
if (arg == START)
|
||||
{ /* If HTML has good support for this character, use it. */
|
||||
if (strchr (html_supported, curchar ()))
|
||||
{ /* Yes; start with an ampersand. The character itself
|
||||
will be added later in read_command (makeinfo.c). */
|
||||
add_char ('&');
|
||||
valid_html_accent = 1;
|
||||
}
|
||||
else
|
||||
{ /* No special HTML support, so produce standalone char. */
|
||||
valid_html_accent = 0;
|
||||
if (html_solo_standalone)
|
||||
{
|
||||
add_char ('&');
|
||||
add_word (html_solo);
|
||||
add_char (';');
|
||||
}
|
||||
else
|
||||
/* If the html_solo does not exist as standalone character
|
||||
(namely ˆ ` ˜), then we use
|
||||
the single character version instead. */
|
||||
add_char (single);
|
||||
}
|
||||
}
|
||||
else if (arg == END)
|
||||
{ /* Only if we saw a valid_html_accent can we use the full
|
||||
HTML accent (umlaut, grave ...). */
|
||||
if (valid_html_accent)
|
||||
{
|
||||
add_word (html_solo);
|
||||
add_char (';');
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (arg == END)
|
||||
{ /* Not producing HTML, so just use the normal character. */
|
||||
add_char (single);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
cm_accent_umlaut (arg, start, end)
|
||||
int arg, start, end;
|
||||
{
|
||||
cm_accent_generic (arg, start, end, "aouAOUEeIiy", '"', 1, "uml");
|
||||
}
|
||||
|
||||
void
|
||||
cm_accent_acute (arg, start, end)
|
||||
int arg, start, end;
|
||||
{
|
||||
cm_accent_generic (arg, start, end, "AEIOUYaeiouy", '\'', 1, "acute");
|
||||
}
|
||||
|
||||
void
|
||||
cm_accent_cedilla (arg, start, end)
|
||||
int arg, start, end;
|
||||
{
|
||||
cm_accent_generic (arg, start, end, "Cc", ',', 1, "cedil");
|
||||
}
|
||||
|
||||
void
|
||||
cm_accent_hat (arg, start, end)
|
||||
int arg, start, end;
|
||||
{
|
||||
cm_accent_generic (arg, start, end, "AEIOUaeiou", '^', 0, "circ");
|
||||
}
|
||||
|
||||
void
|
||||
cm_accent_grave (arg, start, end)
|
||||
int arg, start, end;
|
||||
{
|
||||
cm_accent_generic (arg, start, end, "AEIOUaeiou", '`', 0, "grave");
|
||||
}
|
||||
|
||||
void
|
||||
cm_accent_tilde (arg, start, end)
|
||||
int arg, start, end;
|
||||
{
|
||||
cm_accent_generic (arg, start, end, "AOano", '~', 0, "tilde");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Non-English letters/characters that don't insert themselves. */
|
||||
void
|
||||
cm_special_char (arg)
|
||||
{
|
||||
if (arg == START)
|
||||
{
|
||||
if ((*command == 'L' || *command == 'l'
|
||||
|| *command == 'O' || *command == 'o')
|
||||
&& command[1] == 0)
|
||||
{ /* Lslash lslash Oslash oslash.
|
||||
Lslash and lslash aren't supported in HTML. */
|
||||
if (html && (command[0] == 'O' || command[0] == 'o'))
|
||||
add_word_args ("&%cslash;", command[0]);
|
||||
else
|
||||
add_word_args ("/%c", command[0]);
|
||||
}
|
||||
else if (strcmp (command, "exclamdown") == 0)
|
||||
add_word (html ? "¡" : "!");
|
||||
else if (strcmp (command, "pounds") == 0)
|
||||
add_word (html ? "£" : "#");
|
||||
else if (strcmp (command, "questiondown") == 0)
|
||||
add_word (html ? "¿" : "?");
|
||||
else if (strcmp (command, "AE") == 0)
|
||||
add_word (html ? "Æ" : command);
|
||||
else if (strcmp (command, "ae") == 0)
|
||||
add_word (html ? "æ" : command);
|
||||
else if (strcmp (command, "OE") == 0)
|
||||
add_word (html ? "Œ" : command);
|
||||
else if (strcmp (command, "oe") == 0)
|
||||
add_word (html ? "œ" : command);
|
||||
else if (strcmp (command, "AA") == 0)
|
||||
add_word (html ? "Å" : command);
|
||||
else if (strcmp (command, "aa") == 0)
|
||||
add_word (html ? "å" : command);
|
||||
else if (strcmp (command, "ss") == 0)
|
||||
add_word (html ? "ß" : command);
|
||||
else
|
||||
line_error ("cm_special_char internal error: command=@%s", command);
|
||||
}
|
||||
}
|
||||
|
||||
/* Dotless i or j. */
|
||||
void
|
||||
cm_dotless (arg, start, end)
|
||||
int arg, start, end;
|
||||
{
|
||||
if (arg == END)
|
||||
{
|
||||
if (output_paragraph[start] != 'i' && output_paragraph[start] != 'j')
|
||||
/* This error message isn't perfect if the argument is multiple
|
||||
characters, but it doesn't seem worth getting right. */
|
||||
line_error (_("%c%s expects `i' or `j' as argument, not `%c'"),
|
||||
COMMAND_PREFIX, command, output_paragraph[start]);
|
||||
|
||||
else if (end - start != 1)
|
||||
line_error (_("%c%s expects a single character `i' or `j' as argument"),
|
||||
COMMAND_PREFIX, command);
|
||||
|
||||
/* We've already inserted the `i' or `j', so nothing to do. */
|
||||
}
|
||||
}
|
86
contrib/texinfo/makeinfo/lang.h
Normal file
86
contrib/texinfo/makeinfo/lang.h
Normal file
@ -0,0 +1,86 @@
|
||||
/* lang.h -- declarations for language codes etc.
|
||||
$Id: lang.h,v 1.6 1999/03/22 20:07:34 karl Exp $
|
||||
|
||||
Copyright (C) 1999 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 Karl Heinz Marbaise <kama@hippo.fido.de>. */
|
||||
|
||||
#ifndef LANG_H
|
||||
#define LANG_H
|
||||
|
||||
/* The langauge code which can be changed through @documentlanguage
|
||||
* Actualy Info does not support this (may be in the future) ;-)
|
||||
* Default for language code is en (english!) kama
|
||||
* These code should ISO 639 two letter codes.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
aa, ab, af, am, ar, as, ay, az,
|
||||
ba, be, bg, bh, bi, bn, bo, br,
|
||||
ca, co, cs, cy,
|
||||
da, de, dz,
|
||||
el, en, eo, es, et, eu,
|
||||
fa, fi, fj, fo, fr, fy,
|
||||
ga, gd, gl, gn, gu,
|
||||
ha, he, hi, hr, hu, hy,
|
||||
ia, id, ie, ik, is, it, iu,
|
||||
ja, jw,
|
||||
ka, kk, kl, km, kn, ko, ks, ku, ky,
|
||||
la, ln, lo, lt, lv,
|
||||
mg, mi, mk, ml, mn, mo, mr, ms, mt, my,
|
||||
na, ne, nl, no,
|
||||
oc, om, or,
|
||||
pa, pl, ps, pt,
|
||||
qu,
|
||||
rm, rn, ro, ru, rw,
|
||||
sa, sd, sg, sh, si, sk, sl, sm, sn, so, sq, sr, ss, st, su, sv, sw,
|
||||
ta, te, tg, th, ti, tk, tl, tn, to, tr, ts, tt, tw,
|
||||
ug, uk, ur, uz,
|
||||
vi, vo,
|
||||
wo,
|
||||
xh,
|
||||
yi, yo,
|
||||
za, zh, zu,
|
||||
last_language_code
|
||||
} language_code_type;
|
||||
|
||||
/* The current language code. */
|
||||
extern language_code_type language_code;
|
||||
|
||||
/* Information about all valid languages. */
|
||||
typedef struct
|
||||
{
|
||||
language_code_type lc; /* language code as enum type */
|
||||
char *abbrev; /* two letter language code */
|
||||
char *desc; /* full name for language code */
|
||||
} language_struct;
|
||||
extern language_struct language_table[];
|
||||
|
||||
/* The encoding, or null if not set. */
|
||||
extern char *document_encoding;
|
||||
|
||||
|
||||
/* The commands. */
|
||||
extern void cm_documentlanguage (), cm_documentencoding ();
|
||||
|
||||
/* Accents, other non-English characters. */
|
||||
void cm_accent (), cm_special_char (), cm_dotless ();
|
||||
|
||||
extern void cm_accent_umlaut (), cm_accent_acute (), cm_accent_cedilla (),
|
||||
cm_accent_hat (), cm_accent_grave (), cm_accent_tilde ();
|
||||
|
||||
#endif /* not LANG_H */
|
1114
contrib/texinfo/makeinfo/macro.c
Normal file
1114
contrib/texinfo/makeinfo/macro.c
Normal file
File diff suppressed because it is too large
Load Diff
71
contrib/texinfo/makeinfo/macro.h
Normal file
71
contrib/texinfo/makeinfo/macro.h
Normal file
@ -0,0 +1,71 @@
|
||||
/* macro.h -- declarations for macro.c.
|
||||
$Id: macro.h,v 1.5 1999/07/15 00:00:46 karl Exp $
|
||||
|
||||
Copyright (C) 1998, 99 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 MACRO_H
|
||||
#define MACRO_H
|
||||
|
||||
extern FILE *macro_expansion_output_stream;
|
||||
extern char *macro_expansion_filename;
|
||||
extern int me_executing_string;
|
||||
extern int only_macro_expansion;
|
||||
|
||||
/* Here is a structure used to remember input text strings and offsets
|
||||
within them. */
|
||||
typedef struct {
|
||||
char *pointer; /* Pointer to the input text. */
|
||||
int offset; /* Offset of the last character output. */
|
||||
} ITEXT;
|
||||
|
||||
/* Macro definitions for user-defined commands. */
|
||||
typedef struct {
|
||||
char *name; /* Name of the macro. */
|
||||
char **arglist; /* Args to replace when executing. */
|
||||
char *body; /* Macro body. */
|
||||
char *source_file; /* File where this macro is defined. */
|
||||
int source_lineno; /* Line number within FILENAME. */
|
||||
int inhibited; /* Nonzero means make find_macro () fail. */
|
||||
int flags; /* ME_RECURSE, ME_QUOTE_ARG, etc. */
|
||||
} MACRO_DEF;
|
||||
|
||||
/* flags for MACRO_DEF */
|
||||
#define ME_RECURSE 0x01
|
||||
#define ME_QUOTE_ARG 0x02
|
||||
|
||||
extern void execute_macro ();
|
||||
extern MACRO_DEF *find_macro ();
|
||||
extern char *expand_macro ();
|
||||
|
||||
extern ITEXT *remember_itext ();
|
||||
extern void forget_itext ();
|
||||
extern void maybe_write_itext ();
|
||||
extern void write_region_to_macro_output ();
|
||||
extern void append_to_expansion_output ();
|
||||
extern void me_append_before_this_command ();
|
||||
extern void me_execute_string ();
|
||||
|
||||
extern char *alias_expand ();
|
||||
extern int enclosure_command ();
|
||||
extern void enclosure_expand ();
|
||||
|
||||
/* The @commands. */
|
||||
extern void cm_macro (), cm_rmacro (), cm_unmacro ();
|
||||
extern void cm_alias (), cm_definfoenclose ();
|
||||
|
||||
#endif /* not MACRO_H */
|
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
||||
/* makeinfo.h -- Declarations for Makeinfo.
|
||||
$Id: makeinfo.h,v 1.3 1997/07/15 18:28:38 karl Exp $
|
||||
/* makeinfo.h -- declarations for Makeinfo.
|
||||
$Id: makeinfo.h,v 1.25 1999/09/18 18:09:22 karl Exp $
|
||||
|
||||
Copyright (C) 1996, 97 Free Software Foundation, Inc.
|
||||
Copyright (C) 1996, 97, 98, 99 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
|
||||
@ -19,68 +19,44 @@
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
/* Why, oh why, did I ever listen to rms when he said:
|
||||
"Don't make lots of small files, just make one big one!" I've
|
||||
regretted it ever since with this program, and with readline.
|
||||
bfox@ai.mit.edu Thu Jul 11 07:54:32 1996 */
|
||||
|
||||
#if !defined (MAKEINFO_H)
|
||||
#ifndef MAKEINFO_H
|
||||
#define MAKEINFO_H
|
||||
|
||||
#if defined (COMPILING_MAKEINFO)
|
||||
# define DECLARE(type, var, init) type var = init
|
||||
#ifdef COMPILING_MAKEINFO
|
||||
# define DECLARE(type,var,init) type var = init
|
||||
#else
|
||||
# define DECLARE(type, var, init) extern type var
|
||||
# define DECLARE(type,var,init) extern type var
|
||||
#endif
|
||||
|
||||
enum insertion_type
|
||||
/* Hardcoded per GNU standards, not dependent on argv[0]. */
|
||||
DECLARE (char *, progname, "makeinfo");
|
||||
|
||||
enum reftype
|
||||
{
|
||||
cartouche, defcv, deffn, defivar, defmac, defmethod,
|
||||
defop, defopt, defspec, deftp, deftypefn, deftypefun,
|
||||
deftypemethod, deftypevar, deftypevr, defun, defvar,
|
||||
defvr, detailmenu, direntry, display, enumerate, example,
|
||||
flushleft, flushright, format, ftable, group, ifclear,
|
||||
ifinfo, ifnothtml, ifnottex, ifset, itemize, lisp, menu,
|
||||
multitable, quotation, smallexample, smalllisp, table, vtable,
|
||||
bad_type
|
||||
menu_reference, followed_reference
|
||||
};
|
||||
|
||||
DECLARE (int, insertion_level, 0);
|
||||
extern char *get_xref_token ();
|
||||
|
||||
/* Nonzero means a string is in execution, as opposed to a file. */
|
||||
DECLARE (int, executing_string, 0);
|
||||
|
||||
#if defined (COMPILING_MAKEINFO)
|
||||
char *insertion_type_names[] =
|
||||
{
|
||||
"cartouche", "defcv", "deffn", "defivar", "defmac", "defmethod",
|
||||
"defop", "defopt", "defspec", "deftp", "deftypefn", "deftypefun",
|
||||
"deftypemethod", "deftypevar", "deftypevr", "defun", "defvar",
|
||||
"defvr", "detailmenu", "direntry", "display", "enumerate", "example",
|
||||
"flushleft", "flushright", "format", "ftable", "group", "ifclear",
|
||||
"ifinfo", "ifnothtml", "ifnottex", "ifset", "itemize", "lisp", "menu",
|
||||
"multitable", "quotation", "smallexample", "smalllisp", "table", "vtable",
|
||||
"bad_type"
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef struct istack_elt
|
||||
{
|
||||
struct istack_elt *next;
|
||||
char *item_function;
|
||||
char *filename;
|
||||
int line_number;
|
||||
int filling_enabled;
|
||||
int indented_fill;
|
||||
enum insertion_type insertion;
|
||||
int inhibited;
|
||||
int in_fixed_width_font;
|
||||
} INSERTION_ELT;
|
||||
|
||||
DECLARE (INSERTION_ELT *, insertion_stack, (INSERTION_ELT *)NULL);
|
||||
/* Nonzero means to inhibit writing macro expansions to the output
|
||||
stream, because it has already been written. */
|
||||
DECLARE (int, me_inhibit_expansion, 0);
|
||||
|
||||
extern char *expansion (), *text_expansion ();
|
||||
|
||||
/* Current output stream. */
|
||||
DECLARE (FILE *, output_stream, (FILE *)NULL);
|
||||
DECLARE (FILE *, output_stream, NULL);
|
||||
|
||||
DECLARE (char *, pretty_output_filename, NULL);
|
||||
|
||||
/* Current output file name. */
|
||||
DECLARE (char *, current_output_filename, NULL);
|
||||
|
||||
/* Output paragraph buffer. */
|
||||
DECLARE (unsigned char *, output_paragraph, (unsigned char *)NULL);
|
||||
DECLARE (unsigned char *, output_paragraph, NULL);
|
||||
|
||||
/* Offset into OUTPUT_PARAGRAPH. */
|
||||
DECLARE (int, output_paragraph_offset, 0);
|
||||
@ -88,46 +64,132 @@ DECLARE (int, output_paragraph_offset, 0);
|
||||
/* The output paragraph "cursor" horizontal position. */
|
||||
DECLARE (int, output_column, 0);
|
||||
|
||||
/* Non-zero means output_paragraph contains text. */
|
||||
/* Position in the output file. */
|
||||
DECLARE (int, output_position, 0);
|
||||
|
||||
/* The offset into OUTPUT_PARAGRAPH where we have a meta character
|
||||
produced by a markup such as @code or @dfn. */
|
||||
DECLARE (int, meta_char_pos, -1);
|
||||
|
||||
/* Nonzero means output_paragraph contains text. */
|
||||
DECLARE (int, paragraph_is_open, 0);
|
||||
|
||||
/* Nonzero means that `start_paragraph' MUST be called before we pay
|
||||
any attention to `close_paragraph' calls. */
|
||||
DECLARE (int, must_start_paragraph, 0);
|
||||
|
||||
/* Nonzero means that we have seen "@top" once already. */
|
||||
DECLARE (int, top_node_seen, 0);
|
||||
|
||||
/* Nonzero means that we have seen a non-"@top" node already. */
|
||||
DECLARE (int, non_top_node_seen, 0);
|
||||
|
||||
/* Nonzero indicates that indentation is temporarily turned off. */
|
||||
DECLARE (int, no_indent, 1);
|
||||
|
||||
/* Nonzero indicates that filling a line also indents the new line. */
|
||||
DECLARE (int, indented_fill, 0);
|
||||
|
||||
/* Nonzero means forcing output text to be flushright. */
|
||||
DECLARE (int, force_flush_right, 0);
|
||||
|
||||
/* The amount of indentation to apply at the start of each line. */
|
||||
DECLARE (int, current_indent, 0);
|
||||
|
||||
/* nonzero if we are currently processing a multitable command */
|
||||
DECLARE (int, multitable_active, 0);
|
||||
|
||||
/* The column at which long lines are broken. */
|
||||
DECLARE (int, fill_column, 72);
|
||||
|
||||
/* Nonzero means that words are not to be split, even in long lines. This
|
||||
gets changed for cm_w (). */
|
||||
DECLARE (int, non_splitting_words, 0);
|
||||
|
||||
/* Amount by which @example indentation increases/decreases. */
|
||||
DECLARE (int, default_indentation_increment, 5);
|
||||
|
||||
/* Nonzero means that we are currently hacking the insides of an
|
||||
insertion which would use a fixed width font. */
|
||||
DECLARE (int, in_fixed_width_font, 0);
|
||||
|
||||
/* Nonzero if we are currently processing a multitable command */
|
||||
DECLARE (int, multitable_active, 0);
|
||||
|
||||
/* Nonzero means that we're generating HTML. */
|
||||
DECLARE (int, html, 0);
|
||||
|
||||
/* Nonzero means escape characters in HTML output. */
|
||||
DECLARE (int, escape_html, 1);
|
||||
extern char *escape_string (); /* do HTML escapes */
|
||||
|
||||
/* Nonzero means that the use of paragraph_start_indent is inhibited.
|
||||
@example uses this to line up the left columns of the example text.
|
||||
A negative value for this variable is incremented each time it is used.
|
||||
@noindent uses this to inhibit indentation for a single paragraph. */
|
||||
DECLARE (int, inhibit_paragraph_indentation, 0);
|
||||
|
||||
/* Nonzero indicates that filling will take place on long lines. */
|
||||
DECLARE (int, filling_enabled, 1);
|
||||
|
||||
/* The current node's node name. */
|
||||
DECLARE (char *, current_node, NULL);
|
||||
|
||||
/* Command name in the process of being hacked. */
|
||||
DECLARE (char *, command, NULL);
|
||||
|
||||
/* Nonzero if the last character inserted has the syntax class of NEWLINE. */
|
||||
DECLARE (int, last_char_was_newline, 1);
|
||||
|
||||
/* The current input file state. */
|
||||
DECLARE (char *, input_filename, (char *)NULL);
|
||||
DECLARE (char *, input_text, (char *)NULL);
|
||||
DECLARE (int, size_of_input_text, 0);
|
||||
DECLARE (int, input_text_length, 0);
|
||||
DECLARE (int, input_text_offset, 0);
|
||||
DECLARE (int, line_number, 0);
|
||||
|
||||
#define curchar() input_text[input_text_offset]
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Global Defines */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* A colon separated list of directories to search for files included
|
||||
with @include. This can be controlled with the `-I' option to makeinfo. */
|
||||
DECLARE (char *, include_files_path, NULL);
|
||||
|
||||
/* Error levels */
|
||||
#define NO_ERROR 0
|
||||
#define SYNTAX 2
|
||||
#define FATAL 4
|
||||
/* The filename of the current input file. This is never freed. */
|
||||
DECLARE (char *, node_filename, NULL);
|
||||
|
||||
/* Nonzero means do not output "Node: Foo" for node separations, that
|
||||
is, generate plain text. (--no-headers) */
|
||||
DECLARE (int, no_headers, 0);
|
||||
|
||||
/* Nonzero means that we process @html and @rawhtml even when not
|
||||
generating HTML. (--ifhtml) */
|
||||
DECLARE (int, process_html, 0);
|
||||
|
||||
/* Nonzero means that we process @ifinfo even when generating HTML.
|
||||
(--ifinfo) */
|
||||
DECLARE (int, process_info, 1);
|
||||
|
||||
/* Nonzero means that we process @tex and @iftex. (--iftex) */
|
||||
DECLARE (int, process_tex, 0);
|
||||
|
||||
/* Maximum number of references to a single node before complaining.
|
||||
(--reference-limit) */
|
||||
DECLARE (int, reference_warning_limit, 1000);
|
||||
|
||||
/* Default is to check node references. (--no-validate) */
|
||||
DECLARE (int, validating, 1);
|
||||
|
||||
/* Nonzero means print information about what is going on. (--verbose) */
|
||||
DECLARE (int, verbose_mode, 0);
|
||||
|
||||
/* Nonzero means prefix each @chapter, ... with a number like 1. (--number-sections) */
|
||||
DECLARE (int, number_sections, 0);
|
||||
|
||||
/* Nonzero means expand node names and references while validating.
|
||||
This will avoid errors when the Texinfo document uses features
|
||||
like @@ and @value inconsistently in node names, but will slow
|
||||
the program by about 80%. You HAVE been warned. */
|
||||
DECLARE (int, expensive_validation, 0);
|
||||
|
||||
/* C's standard macros don't check to make sure that the characters being
|
||||
changed are within range. So I have to check explicitly. */
|
||||
|
||||
/* GNU Library doesn't have toupper(). Until GNU gets this fixed, I will
|
||||
have to do it. */
|
||||
#ifndef toupper
|
||||
#define toupper(c) ((c) - 32)
|
||||
#endif
|
||||
|
||||
#define coerce_to_upper(c) ((islower(c) ? toupper(c) : (c)))
|
||||
#define coerce_to_lower(c) ((isupper(c) ? tolower(c) : (c)))
|
||||
|
||||
@ -138,9 +200,9 @@ DECLARE (int, line_number, 0);
|
||||
#define META(c) ((c) | (meta_character_bit))
|
||||
#define UNMETA(c) ((c) & (~meta_character_bit))
|
||||
|
||||
#define whitespace(c) (((c) == '\t') || ((c) == ' '))
|
||||
#define sentence_ender(c) ((c) == '.' || (c) == '?' || (c) == '!')
|
||||
#define cr_or_whitespace(c) (((c) == '\t') || ((c) == ' ') || ((c) == '\n'))
|
||||
#define whitespace(c) ((c) == '\t' || (c) == ' ')
|
||||
#define sentence_ender(c) ((c) == '.' || (c) == '?' || (c) == '!')
|
||||
#define cr_or_whitespace(c) (whitespace(c) || (c) == '\r' || (c) == '\n')
|
||||
|
||||
#ifndef isletter
|
||||
#define isletter(c) (((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z'))
|
||||
@ -158,33 +220,30 @@ DECLARE (int, line_number, 0);
|
||||
#define digit_value(c) ((c) - '0')
|
||||
#endif
|
||||
|
||||
#define member(c, s) (strchr (s, c) != NULL)
|
||||
#define HTML_SAFE "$-_.+!*'()"
|
||||
#define URL_SAFE_CHAR(ch) (isalnum (ch) || strchr (HTML_SAFE, ch))
|
||||
|
||||
#define COMMAND_PREFIX '@'
|
||||
|
||||
/* Stuff for splitting large files. */
|
||||
#define SPLIT_SIZE_THRESHOLD 70000 /* What's good enough for Stallman... */
|
||||
#define DEFAULT_SPLIT_SIZE 50000 /* Is probably good enough for me. */
|
||||
|
||||
DECLARE (int, splitting, 1); /* Defaults to true for now. */
|
||||
|
||||
typedef void COMMAND_FUNCTION (); /* So I can say COMMAND_FUNCTION *foo; */
|
||||
|
||||
#define command_char(c) ((!whitespace(c)) && \
|
||||
((c) != '\n') && \
|
||||
((c) != '{') && \
|
||||
((c) != '}') && \
|
||||
((c) != '='))
|
||||
#define command_char(c) (!cr_or_whitespace(c) \
|
||||
&& (c) != '{' \
|
||||
&& (c) != '}' \
|
||||
&& (c) != '=')
|
||||
|
||||
#define skip_whitespace() \
|
||||
while ((input_text_offset != size_of_input_text) && \
|
||||
while ((input_text_offset != input_text_length) && \
|
||||
whitespace (curchar())) \
|
||||
input_text_offset++
|
||||
|
||||
#define skip_whitespace_and_newlines() \
|
||||
do { \
|
||||
while ((input_text_offset != size_of_input_text) && \
|
||||
(whitespace (curchar ()) || (curchar () == '\n'))) \
|
||||
while (input_text_offset != input_text_length \
|
||||
&& cr_or_whitespace (curchar ())) \
|
||||
{ \
|
||||
if (curchar () == '\n') \
|
||||
line_number++; \
|
||||
@ -192,4 +251,10 @@ typedef void COMMAND_FUNCTION (); /* So I can say COMMAND_FUNCTION *foo; */
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif /* !MAKEINFO_H */
|
||||
/* Return nonzero if STRING is the text at input_text + input_text_offset,
|
||||
else zero. */
|
||||
#define looking_at(string) \
|
||||
(strncmp (input_text + input_text_offset, string, strlen (string)) == 0)
|
||||
|
||||
|
||||
#endif /* not MAKEINFO_H */
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* multi.c -- multitable stuff for makeinfo.
|
||||
$Id: multi.c,v 1.9 1997/07/24 22:01:00 karl Exp $
|
||||
$Id: multi.c,v 1.18 1999/08/17 21:06:56 karl Exp $
|
||||
|
||||
Copyright (C) 1996, 97 Free Software Foundation, Inc.
|
||||
Copyright (C) 1996, 97, 98, 99 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
|
||||
@ -18,6 +18,7 @@
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "system.h"
|
||||
#include "insertion.h"
|
||||
#include "makeinfo.h"
|
||||
|
||||
#define MAXCOLS 100 /* remove this limit later @@ */
|
||||
@ -51,6 +52,7 @@ struct env
|
||||
{
|
||||
unsigned char *output_paragraph;
|
||||
int output_paragraph_offset;
|
||||
int meta_char_pos;
|
||||
int output_column;
|
||||
int paragraph_is_open;
|
||||
int current_indent;
|
||||
@ -66,20 +68,33 @@ static int last_column;
|
||||
/* flags indicating whether horizontal and vertical separators need
|
||||
to be drawn, separating rows and columns in the current multitable. */
|
||||
static int hsep, vsep;
|
||||
|
||||
/* whether this is the first row. */
|
||||
static int first_row;
|
||||
|
||||
static void output_multitable_row ();
|
||||
|
||||
/* Output a row. Have to keep `output_position' up-to-date for each
|
||||
character we output, or the tags table will be off, leading to
|
||||
chopped-off output files and undefined nodes (because they're in the
|
||||
wrong file, etc.). Perhaps it would be better to accumulate this
|
||||
value somewhere and add it once at the end of the table, or return it
|
||||
as the value, but this seems simplest. */
|
||||
/* Output a row. Calls insert, but also flushes the buffered output
|
||||
when we see a newline, since in multitable every line is a separate
|
||||
paragraph. */
|
||||
static void
|
||||
out_char (ch)
|
||||
int ch;
|
||||
{
|
||||
extern int output_position;
|
||||
putc (ch, output_stream);
|
||||
output_position++;
|
||||
if (html)
|
||||
add_char (ch);
|
||||
else
|
||||
{
|
||||
int env = select_output_environment (0);
|
||||
insert (ch);
|
||||
if (ch == '\n')
|
||||
{
|
||||
uninhibit_output_flushing ();
|
||||
flush_output ();
|
||||
inhibit_output_flushing ();
|
||||
}
|
||||
select_output_environment (env);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -88,6 +103,12 @@ draw_horizontal_separator ()
|
||||
{
|
||||
int i, j, s;
|
||||
|
||||
if (html)
|
||||
{
|
||||
add_word ("<hr>");
|
||||
return;
|
||||
}
|
||||
|
||||
for (s = 0; s < envs[0].current_indent; s++)
|
||||
out_char (' ');
|
||||
if (vsep)
|
||||
@ -101,34 +122,48 @@ draw_horizontal_separator ()
|
||||
out_char ('\n');
|
||||
}
|
||||
|
||||
|
||||
/* multitable strategy:
|
||||
for each item {
|
||||
for each column in an item {
|
||||
initialize a new paragraph
|
||||
do ordinary formatting into the new paragraph
|
||||
save the paragraph away
|
||||
repeat if there are more paragraphs in the column
|
||||
}
|
||||
dump out the saved paragraphs and free the storage
|
||||
}
|
||||
|
||||
For HTML we construct a simple HTML 3.2 table with <br>s inserted
|
||||
to help non-tables browsers. `@item' inserts a <tr> and `@tab'
|
||||
inserts <td>; we also try to close <tr>. The only real
|
||||
alternative is to rely on the info formatting engine and present
|
||||
preformatted text. */
|
||||
|
||||
void
|
||||
do_multitable ()
|
||||
{
|
||||
int ncolumns;
|
||||
|
||||
/*
|
||||
* multitable strategy:
|
||||
* for each item {
|
||||
* for each column in an item {
|
||||
* initialize a new paragraph
|
||||
* do ordinary formatting into the new paragraph
|
||||
* save the paragraph away
|
||||
* repeat if there are more paragraphs in the column
|
||||
* }
|
||||
* dump out the saved paragraphs and free the storage
|
||||
* }
|
||||
*/
|
||||
|
||||
if (multitable_active)
|
||||
{
|
||||
line_error ("Multitables cannot be nested");
|
||||
return;
|
||||
}
|
||||
|
||||
close_single_paragraph ();
|
||||
|
||||
/* scan the current item function to get the field widths
|
||||
and number of columns, and set up the output environment list
|
||||
accordingly. */
|
||||
ncolumns = setup_multitable_parameters ();
|
||||
first_row = 1;
|
||||
|
||||
/* <p> for non-tables browsers. @multitable implicitly ends the
|
||||
current paragraph, so this is ok. */
|
||||
if (html)
|
||||
add_word ("<p><table>");
|
||||
|
||||
if (hsep)
|
||||
draw_horizontal_separator ();
|
||||
|
||||
@ -141,6 +176,53 @@ do_multitable ()
|
||||
++multitable_active;
|
||||
}
|
||||
|
||||
/* Called to handle a {...} template on the @multitable line.
|
||||
We're at the { and our first job is to find the matching }; as a side
|
||||
effect, we change *PARAMS to point to after it. Our other job is to
|
||||
expand the template text and return the width of that string. */
|
||||
static unsigned
|
||||
find_template_width (params)
|
||||
char **params;
|
||||
{
|
||||
char *template, *xtemplate;
|
||||
unsigned len;
|
||||
char *start = *params;
|
||||
int brace_level = 0;
|
||||
|
||||
/* The first character should be a {. */
|
||||
if (!params || !*params || **params != '{')
|
||||
{
|
||||
line_error ("find_template width internal error: passed %s",
|
||||
params ? *params : "null");
|
||||
return 0;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
if (**params == '{' && (*params)[-1] != '@')
|
||||
brace_level++;
|
||||
else if (**params == '}' && (*params)[-1] != '@')
|
||||
brace_level--;
|
||||
else if (**params == 0)
|
||||
{
|
||||
line_error (_("Missing } in @multitable template"));
|
||||
return 0;
|
||||
}
|
||||
(*params)++;
|
||||
}
|
||||
while (brace_level > 0);
|
||||
|
||||
template = substring (start + 1, *params - 1); /* omit braces */
|
||||
xtemplate = expansion (template, 0);
|
||||
len = strlen (xtemplate);
|
||||
|
||||
free (template);
|
||||
free (xtemplate);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
/* Read the parameters for a multitable from the current command
|
||||
line, save the parameters away, and return the
|
||||
number of columns. */
|
||||
@ -150,7 +232,7 @@ setup_multitable_parameters ()
|
||||
char *params = insertion_stack->item_function;
|
||||
int nchars;
|
||||
float columnfrac;
|
||||
char command[200]; /* naughty, should be no fixed limits */
|
||||
char command[200]; /* xx no fixed limits */
|
||||
int i = 1;
|
||||
|
||||
/* We implement @hsep and @vsep even though TeX doesn't.
|
||||
@ -176,12 +258,12 @@ setup_multitable_parameters ()
|
||||
for ( ; i <= MAXCOLS; i++) {
|
||||
if (sscanf (params, "%f", &columnfrac) < 1)
|
||||
goto done;
|
||||
/* Unfortunately, can't use %n since some m68k-hp-bsd libc
|
||||
/* Unfortunately, can't use %n since m68k-hp-bsd libc (at least)
|
||||
doesn't support it. So skip whitespace (preceding the
|
||||
number) and then non-whitespace (the number). */
|
||||
while (*params && (*params == ' ' || *params == '\t'))
|
||||
params++;
|
||||
/* Hmm, but what what @columnfractions 3foo. Well, I suppose
|
||||
/* Hmm, but what about @columnfractions 3foo. Well, I suppose
|
||||
it's invalid input anyway. */
|
||||
while (*params && *params != ' ' && *params != '\t'
|
||||
&& *params != '\n' && *params != '@')
|
||||
@ -192,15 +274,11 @@ setup_multitable_parameters ()
|
||||
}
|
||||
|
||||
} else if (*params == '{') {
|
||||
char *start = params;
|
||||
while ((*params != '}' || params[-1] == '@') && *params) {
|
||||
params++;
|
||||
}
|
||||
unsigned template_width = find_template_width (¶ms);
|
||||
|
||||
/* This gives us two spaces between columns. Seems reasonable.
|
||||
Really should expand the text, though, so a template of
|
||||
`@code{foo}' has a width of five, not ten. Also have to match
|
||||
braces, then. How to take into account current_indent here? */
|
||||
setup_output_environment (i++, params++ - start);
|
||||
How to take into account current_indent here? */
|
||||
setup_output_environment (i++, template_width + 2);
|
||||
|
||||
} else {
|
||||
warning (_("ignoring stray text `%s' after @multitable"), params);
|
||||
@ -252,6 +330,7 @@ select_output_environment (n)
|
||||
/* stash current env info from global vars into the old environment */
|
||||
e->output_paragraph = output_paragraph;
|
||||
e->output_paragraph_offset = output_paragraph_offset;
|
||||
e->meta_char_pos = meta_char_pos;
|
||||
e->output_column = output_column;
|
||||
e->paragraph_is_open = paragraph_is_open;
|
||||
e->current_indent = current_indent;
|
||||
@ -262,6 +341,7 @@ select_output_environment (n)
|
||||
e = &envs[current_env_no];
|
||||
output_paragraph = e->output_paragraph;
|
||||
output_paragraph_offset = e->output_paragraph_offset;
|
||||
meta_char_pos = e->meta_char_pos;
|
||||
output_column = e->output_column;
|
||||
paragraph_is_open = e->paragraph_is_open;
|
||||
current_indent = e->current_indent;
|
||||
@ -281,8 +361,6 @@ nselect_next_environment ()
|
||||
}
|
||||
|
||||
|
||||
static void output_multitable_row ();
|
||||
|
||||
/* do anything needed at the beginning of processing a
|
||||
multitable column. */
|
||||
void
|
||||
@ -300,10 +378,20 @@ int
|
||||
multitable_item ()
|
||||
{
|
||||
if (!multitable_active) {
|
||||
/* impossible, I think. */
|
||||
error (_("multitable item not in active multitable"));
|
||||
exit (1);
|
||||
line_error ("multitable_item internal error: no active multitable");
|
||||
xexit (1);
|
||||
}
|
||||
|
||||
if (html)
|
||||
{
|
||||
if (!first_row)
|
||||
add_word ("<br></tr>"); /* <br> for non-tables browsers. */
|
||||
add_word ("<tr align=\"left\"><td>");
|
||||
first_row = 0;
|
||||
return;
|
||||
}
|
||||
first_row = 0;
|
||||
|
||||
if (current_env_no > 0) {
|
||||
output_multitable_row ();
|
||||
}
|
||||
@ -311,7 +399,7 @@ multitable_item ()
|
||||
select_output_environment (1);
|
||||
if (!output_paragraph) {
|
||||
line_error (_("Cannot select column #%d in multitable"), current_env_no);
|
||||
exit (FATAL);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
init_column ();
|
||||
@ -322,11 +410,11 @@ multitable_item ()
|
||||
static void
|
||||
output_multitable_row ()
|
||||
{
|
||||
int i, j, s, remaining;
|
||||
|
||||
/* offset in the output paragraph of the next char needing
|
||||
to be output for that column. */
|
||||
int offset[MAXCOLS];
|
||||
int i, j, s, remaining;
|
||||
int had_newline = 0;
|
||||
|
||||
for (i = 0; i <= last_column; i++)
|
||||
offset[i] = 0;
|
||||
@ -340,9 +428,12 @@ output_multitable_row ()
|
||||
|
||||
/* remove trailing whitespace from each column */
|
||||
for (i = 1; i <= last_column; i++) {
|
||||
while (cr_or_whitespace (CHAR_AT (envs[i].output_paragraph_offset - 1))) {
|
||||
envs[i].output_paragraph_offset--;
|
||||
}
|
||||
if (envs[i].output_paragraph_offset)
|
||||
while (cr_or_whitespace (CHAR_AT (envs[i].output_paragraph_offset - 1)))
|
||||
envs[i].output_paragraph_offset--;
|
||||
|
||||
if (i == current_env_no)
|
||||
output_paragraph_offset = envs[i].output_paragraph_offset;
|
||||
}
|
||||
|
||||
/* read the current line from each column, outputting them all
|
||||
@ -367,7 +458,7 @@ output_multitable_row ()
|
||||
out_char ('|');
|
||||
|
||||
for (i = 1; i <= last_column; i++) {
|
||||
for (s = 0; i < envs[i].current_indent; s++)
|
||||
for (s = 0; s < envs[i].current_indent; s++)
|
||||
out_char (' ');
|
||||
for (j = 0; CHAR_ADDR (j) < envs[i].output_paragraph_offset; j++) {
|
||||
if (CHAR_AT (j) == '\n')
|
||||
@ -375,13 +466,22 @@ output_multitable_row ()
|
||||
out_char (CHAR_AT (j));
|
||||
}
|
||||
offset[i] += j + 1; /* skip last text plus skip the newline */
|
||||
for (; j <= envs[i].fill_column; j++)
|
||||
out_char (' ');
|
||||
|
||||
/* Do not output trailing blanks if we're in the last column and
|
||||
there will be no trailing |. */
|
||||
if (i < last_column && !vsep)
|
||||
for (; j <= envs[i].fill_column; j++)
|
||||
out_char (' ');
|
||||
if (vsep)
|
||||
out_char ('|'); /* draw column separator */
|
||||
}
|
||||
out_char ('\n'); /* end of line */
|
||||
had_newline = 1;
|
||||
}
|
||||
|
||||
/* If completely blank item, get blank line despite no other output. */
|
||||
if (!had_newline)
|
||||
out_char ('\n'); /* end of line */
|
||||
|
||||
if (hsep)
|
||||
draw_horizontal_separator ();
|
||||
@ -403,7 +503,11 @@ cm_tab ()
|
||||
if (!multitable_active)
|
||||
error (_("ignoring @tab outside of multitable"));
|
||||
|
||||
nselect_next_environment ();
|
||||
if (html)
|
||||
add_word ("<td>");
|
||||
else
|
||||
nselect_next_environment ();
|
||||
|
||||
init_column ();
|
||||
}
|
||||
|
||||
@ -412,17 +516,19 @@ cm_tab ()
|
||||
void
|
||||
end_multitable ()
|
||||
{
|
||||
output_multitable_row ();
|
||||
if (!html)
|
||||
output_multitable_row ();
|
||||
|
||||
/* Multitables cannot be nested. Otherwise, we'd have to save the
|
||||
previous output environment number on a stack somewhere, and then
|
||||
restore to that environment. */
|
||||
select_output_environment (0);
|
||||
close_paragraph ();
|
||||
insert ('\n'); /* we swallow newlines, so insert one of our own */
|
||||
|
||||
multitable_active = 0;
|
||||
uninhibit_output_flushing ();
|
||||
close_insertion_paragraph ();
|
||||
|
||||
if (html)
|
||||
add_word ("<br></tr></table>\n");
|
||||
|
||||
#if 0
|
||||
printf (_("** Multicolumn output from last row:\n"));
|
||||
|
1568
contrib/texinfo/makeinfo/node.c
Normal file
1568
contrib/texinfo/makeinfo/node.c
Normal file
File diff suppressed because it is too large
Load Diff
111
contrib/texinfo/makeinfo/node.h
Normal file
111
contrib/texinfo/makeinfo/node.h
Normal file
@ -0,0 +1,111 @@
|
||||
/* node.h -- declarations for Node.
|
||||
$Id: node.h,v 1.5 1999/07/11 16:50:19 karl Exp $
|
||||
|
||||
Copyright (C) 1996, 97, 98, 99 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 NODE_H
|
||||
#define NODE_H
|
||||
|
||||
/* The various references that we know about. */
|
||||
/* What we remember for each node. */
|
||||
typedef struct tentry
|
||||
{
|
||||
struct tentry *next_ent;
|
||||
char *node; /* Name of this node. */
|
||||
char *prev; /* Name of "Prev:" for this node. */
|
||||
char *next; /* Name of "Next:" for this node. */
|
||||
char *up; /* Name of "Up:" for this node. */
|
||||
int position; /* Output file position of this node. */
|
||||
int line_no; /* Defining line in source file. */
|
||||
char *filename; /* The file that this node was found in. */
|
||||
int touched; /* Nonzero means this node has been referenced. */
|
||||
int flags;
|
||||
int number; /* Number for this node, relevant for HTML
|
||||
splitting -- from use+define order, not just
|
||||
define. */
|
||||
} TAG_ENTRY;
|
||||
|
||||
/* If node-a has a "Next" for node-b, but node-b has no "Prev" for node-a,
|
||||
we turn on this flag bit in node-b's tag entry. This means that when
|
||||
it is time to validate node-b, we don't report an additional error
|
||||
if there was no "Prev" field. */
|
||||
#define TAG_FLAG_PREV_ERROR 1
|
||||
#define TAG_FLAG_NEXT_ERROR 2
|
||||
#define TAG_FLAG_UP_ERROR 4
|
||||
#define TAG_FLAG_NO_WARN 8
|
||||
#define TAG_FLAG_IS_TOP 16
|
||||
#define TAG_FLAG_ANCHOR 32
|
||||
|
||||
/* Menu reference, *note reference, and validation hacking. */
|
||||
|
||||
/* A structure to remember references with. A reference to a node is
|
||||
either an entry in a menu, or a cross-reference made with [px]ref. */
|
||||
typedef struct node_ref
|
||||
{
|
||||
struct node_ref *next;
|
||||
char *node; /* Name of node referred to. */
|
||||
char *containing_node; /* Name of node containing this reference. */
|
||||
int line_no; /* Line number where the reference occurs. */
|
||||
int section; /* Section level where the reference occurs. */
|
||||
char *filename; /* Name of file where the reference occurs. */
|
||||
enum reftype type; /* Type of reference, either menu or note. */
|
||||
int number; /* Number for this node, relevant for
|
||||
HTML splitting -- from use+define
|
||||
order, not just define. */
|
||||
} NODE_REF;
|
||||
|
||||
/* The linked list of such structures. */
|
||||
extern NODE_REF *node_references;
|
||||
|
||||
/* A similar list for references occuring in @node next
|
||||
and similar references, needed for HTML. */
|
||||
extern NODE_REF *node_node_references;
|
||||
|
||||
/* List of all nodes. */
|
||||
extern TAG_ENTRY *tag_table;
|
||||
|
||||
/* Counter for setting node_ref.number; zero is Top. */
|
||||
extern int node_number;
|
||||
|
||||
/* The current node's section level. */
|
||||
extern int current_section;
|
||||
|
||||
/* Nonzero when the next sectioning command should generate an anchor
|
||||
corresponding to the current node in HTML mode. */
|
||||
extern int outstanding_node;
|
||||
|
||||
extern TAG_ENTRY *find_node ();
|
||||
|
||||
/* A search string which is used to find a line defining a node. */
|
||||
DECLARE (char *, node_search_string, "\n@node ");
|
||||
|
||||
/* Extract node name from a menu item. */
|
||||
extern char *glean_node_from_menu ();
|
||||
|
||||
/* Remember a node for later validation. */
|
||||
extern void remember_node_reference ();
|
||||
|
||||
/* Remember the name of the current output file. */
|
||||
extern void set_current_output_filename ();
|
||||
|
||||
/* Expand macros and commands in the node name and canonicalize
|
||||
whitespace in the resulting expansion. */
|
||||
extern char *expand_node_name ();
|
||||
|
||||
#endif /* NODE_H */
|
691
contrib/texinfo/makeinfo/sectioning.c
Normal file
691
contrib/texinfo/makeinfo/sectioning.c
Normal file
@ -0,0 +1,691 @@
|
||||
/* sectioning.c -- all related stuff @chapter, @section... @contents
|
||||
$Id: sectioning.c,v 1.12 1999/08/17 21:06:50 karl Exp $
|
||||
|
||||
Copyright (C) 1999 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 Karl Heinz Marbaise <kama@hippo.fido.de>. */
|
||||
|
||||
#include "system.h"
|
||||
#include "cmds.h"
|
||||
#include "macro.h"
|
||||
#include "makeinfo.h"
|
||||
#include "node.h"
|
||||
#include "toc.h"
|
||||
#include "sectioning.h"
|
||||
|
||||
/* See comment in sectioning.h. */
|
||||
section_alist_type section_alist[] = {
|
||||
{ "unnumberedsubsubsec", 5, ENUM_SECT_NO, TOC_YES },
|
||||
{ "unnumberedsubsec", 4, ENUM_SECT_NO, TOC_YES },
|
||||
{ "unnumberedsec", 3, ENUM_SECT_NO, TOC_YES },
|
||||
{ "unnumbered", 2, ENUM_SECT_NO, TOC_YES },
|
||||
|
||||
{ "appendixsubsubsec", 5, ENUM_SECT_APP, TOC_YES }, /* numbered like A.X.X.X */
|
||||
{ "appendixsubsec", 4, ENUM_SECT_APP, TOC_YES },
|
||||
{ "appendixsec", 3, ENUM_SECT_APP, TOC_YES },
|
||||
{ "appendixsection", 3, ENUM_SECT_APP, TOC_YES },
|
||||
{ "appendix", 2, ENUM_SECT_APP, TOC_YES },
|
||||
|
||||
{ "subsubsec", 5, ENUM_SECT_YES, TOC_YES },
|
||||
{ "subsubsection", 5, ENUM_SECT_YES, TOC_YES },
|
||||
{ "subsection", 4, ENUM_SECT_YES, TOC_YES },
|
||||
{ "section", 3, ENUM_SECT_YES, TOC_YES },
|
||||
{ "chapter", 2, ENUM_SECT_YES, TOC_YES },
|
||||
|
||||
{ "subsubheading", 5, ENUM_SECT_NO, TOC_NO },
|
||||
{ "subheading", 4, ENUM_SECT_NO, TOC_NO },
|
||||
{ "heading", 3, ENUM_SECT_NO, TOC_NO },
|
||||
{ "chapheading", 2, ENUM_SECT_NO, TOC_NO },
|
||||
{ "majorheading", 2, ENUM_SECT_NO, TOC_NO },
|
||||
|
||||
{ "top", 1, ENUM_SECT_NO, TOC_YES },
|
||||
{ NULL, 0, 0, 0 }
|
||||
};
|
||||
|
||||
/* The argument of @settitle, used for HTML. */
|
||||
char *title = NULL;
|
||||
|
||||
|
||||
#define APPENDIX_MAGIC 1024
|
||||
#define UNNUMBERED_MAGIC 2048
|
||||
|
||||
/* Number memory for every level @chapter, @section,
|
||||
@subsection, @subsubsection. */
|
||||
static int numbers [] = { 0, 0, 0, 0 };
|
||||
|
||||
/* enum_marker == APPENDIX_MAGIC then we are counting appendencies
|
||||
enum_marker == UNNUMBERED_MAGIC then we are within unnumbered area.
|
||||
Handling situations like this:
|
||||
@unnumbered ..
|
||||
@section ... */
|
||||
static int enum_marker = 0;
|
||||
|
||||
/* Organized by level commands. That is, "*" == chapter, "=" == section. */
|
||||
static char *scoring_characters = "*=-.";
|
||||
|
||||
/* Amount to offset the name of sectioning commands to levels by. */
|
||||
static int section_alist_offset = 0;
|
||||
|
||||
|
||||
/* num == ENUM_SECT_NO means unnumbered (should never call this)
|
||||
num == ENUM_SECT_YES means numbered
|
||||
num == ENUM_SECT_APP means numbered like A.1 and so on */
|
||||
char *
|
||||
get_sectioning_number (level, num)
|
||||
int level;
|
||||
int num;
|
||||
{
|
||||
static char s[100]; /* should ever be enough for 99.99.99.99
|
||||
Appendix A.1 */
|
||||
|
||||
char *p;
|
||||
int i;
|
||||
|
||||
s[0] = 0;
|
||||
|
||||
/* create enumeration in front of chapter, section, subsection and so on. */
|
||||
for (i = 0; i < level; i++)
|
||||
{
|
||||
p = s + strlen (s);
|
||||
if ((i == 0) && (enum_marker == APPENDIX_MAGIC))
|
||||
sprintf (p, "%c.", numbers[i] + 64); /* Should be changed to
|
||||
be more portable */
|
||||
else
|
||||
sprintf (p, "%d.", numbers[i]);
|
||||
}
|
||||
|
||||
/* the last number is never followed by a dot */
|
||||
p = s + strlen (s);
|
||||
if ((num == ENUM_SECT_APP)
|
||||
&& (i == 0)
|
||||
&& (enum_marker == APPENDIX_MAGIC))
|
||||
sprintf (p, _("Appendix %c "), numbers[i] + 64);
|
||||
else
|
||||
sprintf (p, "%d ", numbers[i]);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
/* Set the level of @top to LEVEL. Return the old level of @top. */
|
||||
int
|
||||
set_top_section_level (level)
|
||||
int level;
|
||||
{
|
||||
int i, result = -1;
|
||||
|
||||
for (i = 0; section_alist[i].name; i++)
|
||||
if (strcmp (section_alist[i].name, "top") == 0)
|
||||
{
|
||||
result = section_alist[i].level;
|
||||
section_alist[i].level = level;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* return the index of the given sectioning command in section_alist */
|
||||
int
|
||||
search_sectioning (text)
|
||||
char *text;
|
||||
{
|
||||
int i;
|
||||
char *t;
|
||||
|
||||
/* ignore the optional command prefix */
|
||||
if (text[0] == COMMAND_PREFIX)
|
||||
text++;
|
||||
|
||||
for (i = 0; (t = section_alist[i].name); i++)
|
||||
{
|
||||
if (strcmp (t, text) == 0)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Return an integer which identifies the type section present in TEXT. */
|
||||
int
|
||||
what_section (text)
|
||||
char *text;
|
||||
{
|
||||
int index, j;
|
||||
char *temp;
|
||||
int return_val;
|
||||
|
||||
find_section_command:
|
||||
for (j = 0; text[j] && cr_or_whitespace (text[j]); j++);
|
||||
if (text[j] != COMMAND_PREFIX)
|
||||
return -1;
|
||||
|
||||
text = text + j + 1;
|
||||
|
||||
/* We skip @c, @comment, and @?index commands. */
|
||||
if ((strncmp (text, "comment", strlen ("comment")) == 0) ||
|
||||
(text[0] == 'c' && cr_or_whitespace (text[1])) ||
|
||||
(strcmp (text + 1, "index") == 0))
|
||||
{
|
||||
while (*text++ != '\n');
|
||||
goto find_section_command;
|
||||
}
|
||||
|
||||
/* Handle italicized sectioning commands. */
|
||||
if (*text == 'i')
|
||||
text++;
|
||||
|
||||
for (j = 0; text[j] && !cr_or_whitespace (text[j]); j++);
|
||||
|
||||
temp = xmalloc (1 + j);
|
||||
strncpy (temp, text, j);
|
||||
temp[j] = 0;
|
||||
|
||||
index = search_sectioning (temp);
|
||||
free (temp);
|
||||
if (index >= 0)
|
||||
{
|
||||
return_val = section_alist[index].level + section_alist_offset;
|
||||
if (return_val < 0)
|
||||
return_val = 0;
|
||||
else if (return_val > 5)
|
||||
return_val = 5;
|
||||
return return_val;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sectioning_underscore (cmd)
|
||||
char *cmd;
|
||||
{
|
||||
char character;
|
||||
char *temp;
|
||||
int level;
|
||||
|
||||
temp = xmalloc (2 + strlen (cmd));
|
||||
temp[0] = COMMAND_PREFIX;
|
||||
strcpy (&temp[1], cmd);
|
||||
level = what_section (temp);
|
||||
free (temp);
|
||||
level -= 2;
|
||||
|
||||
if (level < 0)
|
||||
level = 0;
|
||||
|
||||
if (html)
|
||||
sectioning_html (level, cmd);
|
||||
else
|
||||
{
|
||||
character = scoring_characters[level];
|
||||
insert_and_underscore (level, character, cmd);
|
||||
}
|
||||
}
|
||||
|
||||
/* insert_and_underscore and sectioning_html are the
|
||||
only functions which call this.
|
||||
I have created this, because it was exactly the same
|
||||
code in both functions. */
|
||||
static char *
|
||||
handle_enum_increment (level, index)
|
||||
int level;
|
||||
int index;
|
||||
{
|
||||
/* special for unnumbered */
|
||||
if (number_sections && section_alist[index].num == ENUM_SECT_NO)
|
||||
{
|
||||
if (level == 0
|
||||
&& enum_marker != UNNUMBERED_MAGIC)
|
||||
enum_marker = UNNUMBERED_MAGIC;
|
||||
}
|
||||
/* enumerate only things which are allowed */
|
||||
if (number_sections && section_alist[index].num)
|
||||
{
|
||||
/* reset the marker if we get into enumerated areas */
|
||||
if (section_alist[index].num == ENUM_SECT_YES
|
||||
&& level == 0
|
||||
&& enum_marker == UNNUMBERED_MAGIC)
|
||||
enum_marker = 0;
|
||||
/* This is special for appendix; if we got the first
|
||||
time an appendix command then we are entering appendix.
|
||||
Thats the point we have to start countint with A, B and so on. */
|
||||
if (section_alist[index].num == ENUM_SECT_APP
|
||||
&& level == 0
|
||||
&& enum_marker != APPENDIX_MAGIC)
|
||||
{
|
||||
enum_marker = APPENDIX_MAGIC;
|
||||
numbers [0] = 0; /* this means we start with Appendix A */
|
||||
}
|
||||
|
||||
/* only increment counters if we are not in unnumbered
|
||||
area. This handles situations like this:
|
||||
@unnumbered .... This sets enum_marker to UNNUMBERED_MAGIC
|
||||
@section .... */
|
||||
if (enum_marker != UNNUMBERED_MAGIC)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* reset all counters which are one level deeper */
|
||||
for (i = level; i < 3; i++)
|
||||
numbers [i + 1] = 0;
|
||||
|
||||
numbers[level]++;
|
||||
return xstrdup
|
||||
(get_sectioning_number (level, section_alist[index].num));
|
||||
}
|
||||
} /* if (number_sections)... */
|
||||
|
||||
return xstrdup ("");
|
||||
}
|
||||
|
||||
|
||||
/* Insert the text following input_text_offset up to the end of the line
|
||||
in a new, separate paragraph. Directly underneath it, insert a
|
||||
line of WITH_CHAR, the same length of the inserted text. */
|
||||
void
|
||||
insert_and_underscore (level, with_char, cmd)
|
||||
int level;
|
||||
int with_char;
|
||||
char *cmd;
|
||||
{
|
||||
int i, len;
|
||||
int index;
|
||||
int old_no_indent;
|
||||
unsigned char *starting_pos, *ending_pos;
|
||||
char *temp;
|
||||
|
||||
close_paragraph ();
|
||||
filling_enabled = indented_fill = 0;
|
||||
old_no_indent = no_indent;
|
||||
no_indent = 1;
|
||||
|
||||
if (macro_expansion_output_stream && !executing_string)
|
||||
append_to_expansion_output (input_text_offset + 1);
|
||||
|
||||
get_rest_of_line (0, &temp);
|
||||
starting_pos = output_paragraph + output_paragraph_offset;
|
||||
|
||||
index = search_sectioning (cmd);
|
||||
if (index < 0)
|
||||
{
|
||||
/* should never happen, but a poor guy, named Murphy ... */
|
||||
warning (_("Internal error (search_sectioning) \"%s\"!"), cmd);
|
||||
return;
|
||||
}
|
||||
|
||||
/* This is a bit tricky: we must produce "X.Y SECTION-NAME" in the
|
||||
Info output and in TOC, but only SECTION-NAME in the macro-expanded
|
||||
output. */
|
||||
|
||||
/* Step 1: produce "X.Y" and add it to Info output. */
|
||||
add_word (handle_enum_increment (level, index));
|
||||
|
||||
/* Step 2: add "SECTION-NAME" to both Info and macro-expanded output. */
|
||||
if (macro_expansion_output_stream && !executing_string)
|
||||
{
|
||||
char *temp1 = xmalloc (2 + strlen (temp));
|
||||
sprintf (temp1, "%s\n", temp);
|
||||
remember_itext (input_text, input_text_offset);
|
||||
me_execute_string (temp1);
|
||||
free (temp1);
|
||||
}
|
||||
else
|
||||
execute_string ("%s\n", temp);
|
||||
|
||||
/* Step 3: pluck "X.Y SECTION-NAME" from the output buffer and
|
||||
insert it into the TOC. */
|
||||
ending_pos = output_paragraph + output_paragraph_offset;
|
||||
if (section_alist[index].toc == TOC_YES)
|
||||
toc_add_entry (substring (starting_pos, ending_pos - 1),
|
||||
level, current_node, NULL);
|
||||
|
||||
free (temp);
|
||||
|
||||
len = (ending_pos - starting_pos) - 1;
|
||||
for (i = 0; i < len; i++)
|
||||
add_char (with_char);
|
||||
insert ('\n');
|
||||
close_paragraph ();
|
||||
filling_enabled = 1;
|
||||
no_indent = old_no_indent;
|
||||
}
|
||||
|
||||
/* Insert the text following input_text_offset up to the end of the
|
||||
line as an HTML heading element of the appropriate `level' and
|
||||
tagged as an anchor for the current node.. */
|
||||
void
|
||||
sectioning_html (level, cmd)
|
||||
int level;
|
||||
char *cmd;
|
||||
{
|
||||
static int toc_ref_count = 0;
|
||||
int index;
|
||||
int old_no_indent;
|
||||
unsigned char *starting_pos, *ending_pos;
|
||||
char *temp, *toc_anchor = NULL;
|
||||
|
||||
close_paragraph ();
|
||||
filling_enabled = indented_fill = 0;
|
||||
old_no_indent = no_indent;
|
||||
no_indent = 1;
|
||||
|
||||
add_word_args ("<h%d>", level + 1); /* level 0 is <h1> */
|
||||
|
||||
/* If we are outside of any node, produce an anchor that
|
||||
the TOC could refer to. */
|
||||
if (!current_node || !*current_node)
|
||||
{
|
||||
starting_pos = output_paragraph + output_paragraph_offset;
|
||||
add_word_args ("<a name=\"TOC%d\">", toc_ref_count++);
|
||||
toc_anchor = substring (starting_pos + 9,
|
||||
output_paragraph + output_paragraph_offset);
|
||||
}
|
||||
starting_pos = output_paragraph + output_paragraph_offset;
|
||||
|
||||
if (macro_expansion_output_stream && !executing_string)
|
||||
append_to_expansion_output (input_text_offset + 1);
|
||||
|
||||
get_rest_of_line (0, &temp);
|
||||
|
||||
index = search_sectioning (cmd);
|
||||
if (index < 0)
|
||||
{
|
||||
/* should never happen, but a poor guy, named Murphy ... */
|
||||
warning (_("Internal error (search_sectioning) \"%s\"!"), cmd);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Produce "X.Y" and add it to HTML output. */
|
||||
add_word (handle_enum_increment (level, index));
|
||||
|
||||
/* add the section name to both HTML and macro-expanded output. */
|
||||
if (macro_expansion_output_stream && !executing_string)
|
||||
{
|
||||
remember_itext (input_text, input_text_offset);
|
||||
me_execute_string (temp);
|
||||
write_region_to_macro_output ("\n", 0, 1);
|
||||
}
|
||||
else
|
||||
execute_string ("%s", temp);
|
||||
|
||||
ending_pos = output_paragraph + output_paragraph_offset;
|
||||
|
||||
/* Pluck ``X.Y SECTION-NAME'' from the output buffer and insert it
|
||||
into the TOC. */
|
||||
if (section_alist[index].toc == TOC_YES)
|
||||
toc_add_entry (substring (starting_pos, ending_pos),
|
||||
level, current_node, toc_anchor);
|
||||
|
||||
free (temp);
|
||||
|
||||
if (outstanding_node)
|
||||
outstanding_node = 0;
|
||||
|
||||
add_word_args ("</h%d>", level+1);
|
||||
close_paragraph();
|
||||
filling_enabled = 1;
|
||||
no_indent = old_no_indent;
|
||||
}
|
||||
|
||||
|
||||
/* Shift the meaning of @section to @chapter. */
|
||||
void
|
||||
cm_raisesections ()
|
||||
{
|
||||
discard_until ("\n");
|
||||
section_alist_offset--;
|
||||
}
|
||||
|
||||
/* Shift the meaning of @chapter to @section. */
|
||||
void
|
||||
cm_lowersections ()
|
||||
{
|
||||
discard_until ("\n");
|
||||
section_alist_offset++;
|
||||
}
|
||||
|
||||
/* The command still works, but prints a warning message in addition. */
|
||||
void
|
||||
cm_ideprecated (arg, start, end)
|
||||
int arg, start, end;
|
||||
{
|
||||
warning (_("%c%s is obsolete; use %c%s instead"),
|
||||
COMMAND_PREFIX, command, COMMAND_PREFIX, command + 1);
|
||||
sectioning_underscore (command + 1);
|
||||
}
|
||||
|
||||
|
||||
/* Treat this just like @unnumbered. The only difference is
|
||||
in node defaulting. */
|
||||
void
|
||||
cm_top ()
|
||||
{
|
||||
/* It is an error to have more than one @top. */
|
||||
if (top_node_seen && strcmp (current_node, "Top") != 0)
|
||||
{
|
||||
TAG_ENTRY *tag = tag_table;
|
||||
|
||||
line_error (_("Node with %ctop as a section already exists"),
|
||||
COMMAND_PREFIX);
|
||||
|
||||
while (tag)
|
||||
{
|
||||
if (tag->flags & TAG_FLAG_IS_TOP)
|
||||
{
|
||||
int old_line_number = line_number;
|
||||
char *old_input_filename = input_filename;
|
||||
|
||||
line_number = tag->line_no;
|
||||
input_filename = tag->filename;
|
||||
line_error (_("Here is the %ctop node"), COMMAND_PREFIX);
|
||||
input_filename = old_input_filename;
|
||||
line_number = old_line_number;
|
||||
return;
|
||||
}
|
||||
tag = tag->next_ent;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TAG_ENTRY *top_node = find_node ("Top");
|
||||
top_node_seen = 1;
|
||||
|
||||
/* It is an error to use @top before you have used @node. */
|
||||
if (!tag_table)
|
||||
{
|
||||
char *top_name;
|
||||
|
||||
get_rest_of_line (0, &top_name);
|
||||
line_error (_("%ctop used before %cnode, defaulting to %s"),
|
||||
COMMAND_PREFIX, COMMAND_PREFIX, top_name);
|
||||
execute_string ("@node Top, , (dir), (dir)\n@top %s\n", top_name);
|
||||
free (top_name);
|
||||
return;
|
||||
}
|
||||
else if (html && splitting)
|
||||
{
|
||||
char *next = top_node ? top_node->next : NULL;
|
||||
|
||||
add_word ("<p>");
|
||||
if (next)
|
||||
{
|
||||
add_word (_("Next:"));
|
||||
add_word ("<a rel=next href=\"");
|
||||
add_anchor_name (next, 1);
|
||||
add_word ("\">");
|
||||
execute_string (next);
|
||||
add_word ("</a>\n");
|
||||
}
|
||||
}
|
||||
|
||||
cm_unnumbered ();
|
||||
|
||||
/* The most recently defined node is the top node. */
|
||||
tag_table->flags |= TAG_FLAG_IS_TOP;
|
||||
|
||||
/* Now set the logical hierarchical level of the Top node. */
|
||||
{
|
||||
int orig_offset = input_text_offset;
|
||||
|
||||
input_text_offset = search_forward (node_search_string, orig_offset);
|
||||
|
||||
if (input_text_offset > 0)
|
||||
{
|
||||
int this_section;
|
||||
|
||||
/* We have encountered a non-top node, so mark that one exists. */
|
||||
non_top_node_seen = 1;
|
||||
|
||||
/* Move to the end of this line, and find out what the
|
||||
sectioning command is here. */
|
||||
while (input_text[input_text_offset] != '\n')
|
||||
input_text_offset++;
|
||||
|
||||
if (input_text_offset < input_text_length)
|
||||
input_text_offset++;
|
||||
|
||||
this_section = what_section (input_text + input_text_offset);
|
||||
|
||||
/* If we found a sectioning command, then give the top section
|
||||
a level of this section - 1. */
|
||||
if (this_section != -1)
|
||||
set_top_section_level (this_section - 1);
|
||||
}
|
||||
input_text_offset = orig_offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* The remainder of the text on this line is a chapter heading. */
|
||||
void
|
||||
cm_chapter ()
|
||||
{
|
||||
sectioning_underscore ("chapter");
|
||||
}
|
||||
|
||||
/* The remainder of the text on this line is a section heading. */
|
||||
void
|
||||
cm_section ()
|
||||
{
|
||||
sectioning_underscore ("section");
|
||||
}
|
||||
|
||||
/* The remainder of the text on this line is a subsection heading. */
|
||||
void
|
||||
cm_subsection ()
|
||||
{
|
||||
sectioning_underscore ("subsection");
|
||||
}
|
||||
|
||||
/* The remainder of the text on this line is a subsubsection heading. */
|
||||
void
|
||||
cm_subsubsection ()
|
||||
{
|
||||
sectioning_underscore ("subsubsection");
|
||||
}
|
||||
|
||||
/* The remainder of the text on this line is an unnumbered heading. */
|
||||
void
|
||||
cm_unnumbered ()
|
||||
{
|
||||
sectioning_underscore ("unnumbered");
|
||||
}
|
||||
|
||||
/* The remainder of the text on this line is an unnumbered section heading. */
|
||||
void
|
||||
cm_unnumberedsec ()
|
||||
{
|
||||
sectioning_underscore ("unnumberedsec");
|
||||
}
|
||||
|
||||
/* The remainder of the text on this line is an unnumbered
|
||||
subsection heading. */
|
||||
void
|
||||
cm_unnumberedsubsec ()
|
||||
{
|
||||
sectioning_underscore ("unnumberedsubsec");
|
||||
}
|
||||
|
||||
/* The remainder of the text on this line is an unnumbered
|
||||
subsubsection heading. */
|
||||
void
|
||||
cm_unnumberedsubsubsec ()
|
||||
{
|
||||
sectioning_underscore ("unnumberedsubsubsec");
|
||||
}
|
||||
|
||||
/* The remainder of the text on this line is an appendix heading. */
|
||||
void
|
||||
cm_appendix ()
|
||||
{
|
||||
sectioning_underscore ("appendix");
|
||||
}
|
||||
|
||||
/* The remainder of the text on this line is an appendix section heading. */
|
||||
void
|
||||
cm_appendixsec ()
|
||||
{
|
||||
sectioning_underscore ("appendixsec");
|
||||
}
|
||||
|
||||
/* The remainder of the text on this line is an appendix subsection heading. */
|
||||
void
|
||||
cm_appendixsubsec ()
|
||||
{
|
||||
sectioning_underscore ("appendixsubsec");
|
||||
}
|
||||
|
||||
/* The remainder of the text on this line is an appendix
|
||||
subsubsection heading. */
|
||||
void
|
||||
cm_appendixsubsubsec ()
|
||||
{
|
||||
sectioning_underscore ("appendixsubsubsec");
|
||||
}
|
||||
|
||||
/* Compatibility functions substitute for chapter, section, etc. */
|
||||
void
|
||||
cm_majorheading ()
|
||||
{
|
||||
sectioning_underscore ("majorheading");
|
||||
}
|
||||
|
||||
void
|
||||
cm_chapheading ()
|
||||
{
|
||||
sectioning_underscore ("chapheading");
|
||||
}
|
||||
|
||||
void
|
||||
cm_heading ()
|
||||
{
|
||||
sectioning_underscore ("heading");
|
||||
}
|
||||
|
||||
void
|
||||
cm_subheading ()
|
||||
{
|
||||
sectioning_underscore ("subheading");
|
||||
}
|
||||
|
||||
void
|
||||
cm_subsubheading ()
|
||||
{
|
||||
sectioning_underscore ("subsubheading");
|
||||
}
|
80
contrib/texinfo/makeinfo/sectioning.h
Normal file
80
contrib/texinfo/makeinfo/sectioning.h
Normal file
@ -0,0 +1,80 @@
|
||||
/* sectioning.h -- all related stuff @chapter, @section... @contents
|
||||
$Id: sectioning.h,v 1.2 1999/03/09 22:48:15 karl Exp $
|
||||
|
||||
Copyright (C) 1999 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 Karl Heinz Marbaise <kama@hippo.fido.de>. */
|
||||
|
||||
#ifndef SECTIONING_H
|
||||
#define SECTIONING_H
|
||||
|
||||
/* Sectioning. */
|
||||
extern void
|
||||
cm_chapter (), cm_unnumbered (), cm_appendix (), cm_top (),
|
||||
cm_section (), cm_unnumberedsec (), cm_appendixsec (),
|
||||
cm_subsection (), cm_unnumberedsubsec (), cm_appendixsubsec (),
|
||||
cm_subsubsection (), cm_unnumberedsubsubsec (), cm_appendixsubsubsec (),
|
||||
cm_heading (), cm_chapheading (), cm_subheading (), cm_subsubheading (),
|
||||
cm_majorheading (), cm_raisesections (), cm_lowersections (),
|
||||
|
||||
cm_ideprecated ();
|
||||
|
||||
extern void
|
||||
sectioning_underscore (), insert_and_underscore ();
|
||||
|
||||
extern int what_section ();
|
||||
|
||||
|
||||
|
||||
/* is needed in node.c */
|
||||
extern int set_top_section_level ();
|
||||
|
||||
extern void sectioning_html ();
|
||||
extern int what_section ();
|
||||
|
||||
/* The argument of @settitle, used for HTML. */
|
||||
extern char *title;
|
||||
|
||||
|
||||
/* Here is a structure which associates sectioning commands with
|
||||
an integer that reflects the depth of the current section. */
|
||||
typedef struct
|
||||
{
|
||||
char *name;
|
||||
int level; /* I can't replace the levels with defines
|
||||
because it is changed during run */
|
||||
int num; /* ENUM_SECT_NO means no enumeration...
|
||||
ENUM_SECT_YES means enumerated version
|
||||
ENUM_SECT_APP appendix (Character enumerated
|
||||
at first position */
|
||||
int toc; /* TOC_NO means do not enter in toc;
|
||||
TOC_YES means enter it in toc */
|
||||
} section_alist_type;
|
||||
|
||||
extern section_alist_type section_alist[];
|
||||
|
||||
/* enumerate sections */
|
||||
#define ENUM_SECT_NO 0
|
||||
#define ENUM_SECT_YES 1
|
||||
#define ENUM_SECT_APP 2
|
||||
|
||||
/* make entries into toc no/yes */
|
||||
#define TOC_NO 0
|
||||
#define TOC_YES 1
|
||||
|
||||
|
||||
#endif /* not SECTIONING_H */
|
476
contrib/texinfo/makeinfo/toc.c
Normal file
476
contrib/texinfo/makeinfo/toc.c
Normal file
@ -0,0 +1,476 @@
|
||||
/* toc.c -- table of contents handling.
|
||||
$Id: toc.c,v 1.14 1999/08/09 20:28:18 karl Exp $
|
||||
|
||||
Copyright (C) 1999 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 Karl Heinz Marbaise <kama@hippo.fido.de>. */
|
||||
|
||||
#include "system.h"
|
||||
#include "makeinfo.h"
|
||||
#include "cmds.h"
|
||||
#include "files.h"
|
||||
#include "macro.h"
|
||||
#include "node.h"
|
||||
#include "lang.h"
|
||||
#include "makeinfo.h"
|
||||
#include "sectioning.h"
|
||||
#include "toc.h"
|
||||
|
||||
|
||||
|
||||
|
||||
/* array of toc entries */
|
||||
static TOC_ENTRY_ELT **toc_entry_alist = NULL;
|
||||
|
||||
/* toc_counter start from 0 ... n for every @chapter, @section ... */
|
||||
static int toc_counter = 0;
|
||||
|
||||
/* the file where we found the @contents directive */
|
||||
char *contents_filename;
|
||||
|
||||
/* the file where we found the @shortcontents directive */
|
||||
char *shortcontents_filename;
|
||||
|
||||
static const char contents_placebo[] = "\n...Table of Contents...\n";
|
||||
static const char shortcontents_placebo[] = "\n...Short Contents...\n";
|
||||
static const char lots_of_stars[] =
|
||||
"***************************************************************************";
|
||||
|
||||
|
||||
/* Routine to add an entry to the table of contents */
|
||||
int
|
||||
toc_add_entry (tocname, level, node_name, anchor)
|
||||
char *tocname;
|
||||
int level;
|
||||
char *node_name;
|
||||
char *anchor;
|
||||
{
|
||||
char *tocname_and_node, *expanded_node, *s, *d;
|
||||
|
||||
if (!node_name)
|
||||
node_name = "";
|
||||
|
||||
/* I assume that xrealloc behaves like xmalloc if toc_entry_alist is
|
||||
NULL */
|
||||
toc_entry_alist = xrealloc (toc_entry_alist,
|
||||
(toc_counter + 1) * sizeof (TOC_ENTRY_ELT *));
|
||||
|
||||
toc_entry_alist[toc_counter] = xmalloc (sizeof (TOC_ENTRY_ELT));
|
||||
|
||||
if (html)
|
||||
{
|
||||
/* We need to insert the expanded node name into the TOC, so
|
||||
that when we eventually output the TOC, its <A REF= link will
|
||||
point to the <A NAME= tag created by cm_node in the navigation
|
||||
bar. We cannot expand the containing_node member, for the
|
||||
reasons explained in the WARNING below. We also cannot wait
|
||||
with the node name expansion until the TOC is actually output,
|
||||
since by that time the macro definitions may have been changed.
|
||||
So instead we store in the tocname member the expanded node
|
||||
name and the TOC name concatenated together (with the necessary
|
||||
HTML markup), since that's how they are output. */
|
||||
if (!anchor)
|
||||
s = expanded_node = expand_node_name (node_name);
|
||||
else
|
||||
expanded_node = anchor;
|
||||
/* Sigh... Need to HTML-escape the expanded node name like
|
||||
add_anchor_name does, except that we are not writing this to
|
||||
the output, so can't use add_anchor_name... */
|
||||
/* The factor 5 in the next allocation is because the maximum
|
||||
expansion of HTML-escaping is for the & character, which is
|
||||
output as "&". 2 is for "> that separates node from tocname. */
|
||||
d = tocname_and_node = (char *)xmalloc (2 + 5 * strlen (expanded_node)
|
||||
+ strlen (tocname) + 1);
|
||||
if (!anchor)
|
||||
{
|
||||
for (; *s; s++)
|
||||
{
|
||||
if (*s == '&')
|
||||
{
|
||||
strcpy (d, "&");
|
||||
d += 5;
|
||||
}
|
||||
else if (! URL_SAFE_CHAR (*s))
|
||||
{
|
||||
sprintf (d, "%%%x", (unsigned char) *s);
|
||||
/* do this manually since sprintf returns char * on
|
||||
SunOS 4 and other old systems. */
|
||||
while (*d)
|
||||
d++;
|
||||
}
|
||||
else
|
||||
*d++ = *s;
|
||||
}
|
||||
strcpy (d, "\">");
|
||||
}
|
||||
else
|
||||
/* Section outside any node, they provided explicit anchor. */
|
||||
strcpy (d, anchor);
|
||||
strcat (d, tocname);
|
||||
free (tocname); /* it was malloc'ed by substring() */
|
||||
free (expanded_node);
|
||||
toc_entry_alist[toc_counter]->name = tocname_and_node;
|
||||
}
|
||||
else
|
||||
toc_entry_alist[toc_counter]->name = tocname;
|
||||
/* WARNING! The node name saved in containing_node member must
|
||||
be the node name with _only_ macros expanded (the macros in
|
||||
the node name are expanded by cm_node when it grabs the name
|
||||
from the @node directive). Non-macros, like @value, @@ and
|
||||
other @-commands must NOT be expanded in containing_node,
|
||||
because toc_find_section_of_node looks up the node name where
|
||||
they are also unexpanded. You *have* been warned! */
|
||||
toc_entry_alist[toc_counter]->containing_node = xstrdup (node_name);
|
||||
toc_entry_alist[toc_counter]->level = level;
|
||||
toc_entry_alist[toc_counter]->number = toc_counter;
|
||||
|
||||
/* have to be done at least */
|
||||
return toc_counter++;
|
||||
}
|
||||
|
||||
/* Return the name of a chapter/section/subsection etc. that
|
||||
corresponds to the node NODE. If the node isn't found,
|
||||
return NULL.
|
||||
|
||||
WARNING! This function relies on NODE being unexpanded
|
||||
except for macros (i.e., @value, @@, and other non-macros
|
||||
should NOT be expanded), because the containing_node member
|
||||
stores unexpanded node names.
|
||||
|
||||
Note that this function returns the first section whose
|
||||
containing node is NODE. Thus, they will lose if they use
|
||||
more than a single chapter structioning command in a node,
|
||||
or if they have a node without any structuring commands. */
|
||||
char *
|
||||
toc_find_section_of_node (node)
|
||||
char *node;
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!node)
|
||||
node = "";
|
||||
for (i = 0; i < toc_counter; i++)
|
||||
if (STREQ (node, toc_entry_alist[i]->containing_node))
|
||||
return toc_entry_alist[i]->name;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* free up memory used by toc entries */
|
||||
void
|
||||
toc_free ()
|
||||
{
|
||||
int i;
|
||||
|
||||
if (toc_counter)
|
||||
{
|
||||
for (i = 0; i < toc_counter; i++)
|
||||
{
|
||||
free (toc_entry_alist[i]->name);
|
||||
free (toc_entry_alist[i]->containing_node);
|
||||
free (toc_entry_alist[i]);
|
||||
}
|
||||
|
||||
free (toc_entry_alist);
|
||||
toc_entry_alist = NULL; /* to be sure ;-) */
|
||||
toc_counter = 0; /* to be absolutley sure ;-) */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* print table of contents in HTML, may be we can produce a standalone
|
||||
HTML file? */
|
||||
static void
|
||||
contents_update_html (fp)
|
||||
FILE *fp;
|
||||
{
|
||||
int i;
|
||||
int k;
|
||||
int last_level;
|
||||
|
||||
/* does exist any toc? */
|
||||
if (!toc_counter)
|
||||
/* no, so return to sender ;-) */
|
||||
return;
|
||||
|
||||
flush_output (); /* in case we are writing stdout */
|
||||
|
||||
fprintf (fp, "\n<h1>%s</h1>\n<ul>\n", _("Table of Contents"));
|
||||
|
||||
last_level = toc_entry_alist[0]->level;
|
||||
|
||||
for (i = 0; i < toc_counter; i++)
|
||||
{
|
||||
if (toc_entry_alist[i]->level > last_level)
|
||||
{
|
||||
/* unusual, but it is possible
|
||||
@chapter ...
|
||||
@subsubsection ... ? */
|
||||
for (k = 0; k < (toc_entry_alist[i]->level-last_level); k++)
|
||||
fputs ("<ul>\n", fp);
|
||||
}
|
||||
else if (toc_entry_alist[i]->level < last_level)
|
||||
{
|
||||
/* @subsubsection ...
|
||||
@chapter ... this IS usual.*/
|
||||
for (k = 0; k < (last_level-toc_entry_alist[i]->level); k++)
|
||||
fputs ("</ul>\n", fp);
|
||||
}
|
||||
|
||||
fprintf (fp, "<li><a href=\"#%s</a>\n", toc_entry_alist[i]->name);
|
||||
|
||||
last_level = toc_entry_alist[i]->level;
|
||||
}
|
||||
|
||||
/* Go back to start level. */
|
||||
if (toc_entry_alist[0]->level < last_level)
|
||||
for (k = 0; k < (last_level-toc_entry_alist[0]->level); k++)
|
||||
fputs ("</ul>\n", fp);
|
||||
|
||||
fputs ("</ul>\n\n", fp);
|
||||
}
|
||||
|
||||
/* print table of contents in ASCII (--no-headers)
|
||||
May be we should create a new command line switch --ascii ? */
|
||||
static void
|
||||
contents_update_info (fp)
|
||||
FILE *fp;
|
||||
{
|
||||
int i;
|
||||
int k;
|
||||
|
||||
if (!toc_counter)
|
||||
return;
|
||||
|
||||
flush_output (); /* in case we are writing stdout */
|
||||
|
||||
fprintf (fp, "%s\n%.*s\n\n", _("Table of Contents"),
|
||||
(int) strlen (_("Table of Contents")), lots_of_stars);
|
||||
|
||||
for (i = 0; i < toc_counter; i++)
|
||||
{
|
||||
if (toc_entry_alist[i]->level == 0)
|
||||
fputs ("\n", fp);
|
||||
|
||||
/* indention with two spaces per level, should this
|
||||
changed? */
|
||||
for (k = 0; k < toc_entry_alist[i]->level; k++)
|
||||
fputs (" ", fp);
|
||||
|
||||
fprintf (fp, "%s\n", toc_entry_alist[i]->name);
|
||||
}
|
||||
fputs ("\n\n", fp);
|
||||
}
|
||||
|
||||
/* shortcontents in HTML; Should this produce a standalone file? */
|
||||
static void
|
||||
shortcontents_update_html (fp)
|
||||
FILE *fp;
|
||||
{
|
||||
int i;
|
||||
|
||||
/* does exist any toc? */
|
||||
if (!toc_counter)
|
||||
return;
|
||||
|
||||
flush_output (); /* in case we are writing stdout */
|
||||
|
||||
fprintf (fp, "\n<h1>%s</h1>\n<ul>\n", _("Short Contents"));
|
||||
|
||||
for (i = 0; i < toc_counter; i++)
|
||||
{
|
||||
if ((toc_entry_alist[i])->level == 0)
|
||||
{
|
||||
fputs ("<li>", fp);
|
||||
fprintf (fp, "<a href=\"#%s\n", toc_entry_alist[i]->name);
|
||||
}
|
||||
}
|
||||
|
||||
fputs ("</ul>\n\n", fp);
|
||||
}
|
||||
|
||||
/* short contents in ASCII (--no-headers).
|
||||
May be we should create a new command line switch --ascii ? */
|
||||
static void
|
||||
shortcontents_update_info (fp)
|
||||
FILE *fp;
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!toc_counter)
|
||||
return;
|
||||
|
||||
flush_output (); /* in case we are writing stdout */
|
||||
|
||||
fprintf (fp, "%s\n%.*s\n\n", _("Short Contents"),
|
||||
(int) strlen (_("Short Contents")), lots_of_stars);
|
||||
|
||||
for (i = 0; i < toc_counter; i++)
|
||||
{
|
||||
if ((toc_entry_alist[i])->level == 0)
|
||||
fprintf (fp, "%s\n", toc_entry_alist[i]->name);
|
||||
}
|
||||
fputs ("\n\n", fp);
|
||||
}
|
||||
|
||||
|
||||
static FILE *toc_fp;
|
||||
static char *toc_buf;
|
||||
|
||||
static int
|
||||
rewrite_top (fname, placebo)
|
||||
const char *fname, *placebo;
|
||||
{
|
||||
int idx;
|
||||
|
||||
toc_buf = find_and_load (fname);
|
||||
|
||||
if (!toc_buf)
|
||||
{
|
||||
/* Can't rewrite standard output. No point in complaining. */
|
||||
if (!STREQ (fname, "-"))
|
||||
fs_error (fname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
idx = search_forward (placebo, 0);
|
||||
|
||||
if (idx < 0)
|
||||
{
|
||||
error (_("%s: TOC should be here, but it was not found"), fname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
toc_fp = fopen (fname, "w");
|
||||
if (!toc_fp)
|
||||
{
|
||||
fs_error (fname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fwrite (toc_buf, 1, idx, toc_fp) != idx)
|
||||
{
|
||||
fs_error (fname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return idx + strlen (placebo);
|
||||
}
|
||||
|
||||
static void
|
||||
contents_update ()
|
||||
{
|
||||
int cont_idx = rewrite_top (contents_filename, contents_placebo);
|
||||
|
||||
if (cont_idx < 0)
|
||||
return;
|
||||
|
||||
if (html)
|
||||
contents_update_html (toc_fp);
|
||||
else
|
||||
contents_update_info (toc_fp);
|
||||
|
||||
if (fwrite (toc_buf + cont_idx, 1, input_text_length - cont_idx, toc_fp)
|
||||
!= input_text_length - cont_idx
|
||||
|| fclose (toc_fp) != 0)
|
||||
fs_error (contents_filename);
|
||||
}
|
||||
|
||||
static void
|
||||
shortcontents_update ()
|
||||
{
|
||||
int cont_idx = rewrite_top (shortcontents_filename, shortcontents_placebo);
|
||||
|
||||
if (cont_idx < 0)
|
||||
return;
|
||||
|
||||
if (html)
|
||||
shortcontents_update_html (toc_fp);
|
||||
else
|
||||
shortcontents_update_info (toc_fp);
|
||||
|
||||
if (fwrite (toc_buf + cont_idx, 1, input_text_length - cont_idx - 1, toc_fp)
|
||||
!= input_text_length - cont_idx - 1
|
||||
|| fclose (toc_fp) != 0)
|
||||
fs_error (shortcontents_filename);
|
||||
}
|
||||
|
||||
void
|
||||
toc_update ()
|
||||
{
|
||||
if (!html && !no_headers)
|
||||
return;
|
||||
|
||||
if (contents_filename)
|
||||
contents_update ();
|
||||
if (shortcontents_filename)
|
||||
shortcontents_update ();
|
||||
}
|
||||
|
||||
void
|
||||
cm_contents (arg)
|
||||
int arg;
|
||||
{
|
||||
if ((html || no_headers) && arg == START)
|
||||
{
|
||||
if (contents_filename)
|
||||
{
|
||||
free (contents_filename);
|
||||
contents_filename = NULL;
|
||||
}
|
||||
|
||||
if (contents_filename && STREQ (contents_filename, "-"))
|
||||
{
|
||||
if (html)
|
||||
contents_update_html (stdout);
|
||||
else
|
||||
contents_update_info (stdout);
|
||||
}
|
||||
else
|
||||
{
|
||||
contents_filename = xstrdup (current_output_filename);
|
||||
insert_string (contents_placebo); /* just mark it, for now */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
cm_shortcontents (arg)
|
||||
int arg;
|
||||
{
|
||||
if ((html || no_headers) && arg == START)
|
||||
{
|
||||
if (shortcontents_filename)
|
||||
{
|
||||
free (shortcontents_filename);
|
||||
shortcontents_filename = NULL;
|
||||
}
|
||||
|
||||
if (shortcontents_filename && STREQ (shortcontents_filename, "-"))
|
||||
{
|
||||
if (html)
|
||||
shortcontents_update_html (stdout);
|
||||
else
|
||||
shortcontents_update_info (stdout);
|
||||
}
|
||||
else
|
||||
{
|
||||
shortcontents_filename = xstrdup (current_output_filename);
|
||||
insert_string (shortcontents_placebo); /* just mark it, for now */
|
||||
}
|
||||
}
|
||||
}
|
49
contrib/texinfo/makeinfo/toc.h
Normal file
49
contrib/texinfo/makeinfo/toc.h
Normal file
@ -0,0 +1,49 @@
|
||||
/* toc.h -- table of contents handling.
|
||||
$Id: toc.h,v 1.4 1999/04/25 19:49:22 karl Exp $
|
||||
|
||||
Copyright (C) 1999 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 Karl Heinz Marbaise <kama@hippo.fido.de>. */
|
||||
|
||||
#ifndef TOC_H
|
||||
#define TOC_H
|
||||
|
||||
/* the file where we found the @contents directive */
|
||||
extern char *contents_filename;
|
||||
|
||||
/* the file where we found the @shortcontents directive */
|
||||
extern char *shortcontents_filename;
|
||||
|
||||
/* Structure to hold one entry for the toc. */
|
||||
typedef struct toc_entry_elt {
|
||||
char *name;
|
||||
char *containing_node; /* Name of node containing this section. */
|
||||
int number; /* counting number from 0...n independent from
|
||||
chapter/section can be used for anchors or
|
||||
references to it. */
|
||||
int level; /* level: chapter, section, subsection... */
|
||||
} TOC_ENTRY_ELT;
|
||||
|
||||
/* all routines which have relationship with TOC should start with
|
||||
toc_ (this is a kind of name-space) */
|
||||
extern int toc_add_entry (); /* return the number for the toc-entry */
|
||||
extern void toc_free ();
|
||||
extern char *toc_find_section_of_node ();
|
||||
|
||||
extern void cm_contents (), cm_shortcontents ();
|
||||
|
||||
#endif /* not TOC_H */
|
@ -2,3 +2,9 @@ Assorted Texinfo-related programs and scripts.
|
||||
|
||||
texindex, texi2dvi, and install-info get installed.
|
||||
The other items here are for your amusement and/or hacking pleasure.
|
||||
|
||||
You may also be interested in a2ps, an ASCII->PostScript program which
|
||||
has a Texinfo style option. Available from
|
||||
http://www.inf.enst.fr/~demaille/a2ps/ and
|
||||
ftp://ftp.enst.fr/pub/unix/a2ps/.
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
||||
/* Prepare TeX index dribble output into an actual index.
|
||||
$Id: texindex.c,v 1.22 1998/02/22 23:00:09 karl Exp $
|
||||
/* Process TeX index dribble output into an actual index.
|
||||
$Id: texindex.c,v 1.34 1999/08/06 17:03:14 karl Exp $
|
||||
|
||||
Copyright (C) 1987, 91, 92, 96, 97, 98 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987, 91, 92, 96, 97, 98, 99 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
|
||||
@ -20,6 +20,8 @@
|
||||
#include "system.h"
|
||||
#include <getopt.h>
|
||||
|
||||
static char *program_name = "texindex";
|
||||
|
||||
#if defined (emacs)
|
||||
# include "../src/config.h"
|
||||
/* Some s/os.h files redefine these. */
|
||||
@ -34,19 +36,8 @@
|
||||
#define memset(ptr, ignore, count) bzero (ptr, count)
|
||||
#endif
|
||||
|
||||
|
||||
char *mktemp ();
|
||||
|
||||
#if defined (VMS)
|
||||
# include <file.h>
|
||||
# define TI_NO_ERROR ((1 << 28) | 1)
|
||||
# define TI_FATAL_ERROR ((1 << 28) | 4)
|
||||
# define unlink delete
|
||||
#else /* !VMS */
|
||||
# define TI_NO_ERROR 0
|
||||
# define TI_FATAL_ERROR 1
|
||||
#endif /* !VMS */
|
||||
|
||||
#if !defined (SEEK_SET)
|
||||
# define SEEK_SET 0
|
||||
# define SEEK_CUR 1
|
||||
@ -124,11 +115,7 @@ char *text_base;
|
||||
/* Nonzero means do not delete tempfiles -- for debugging. */
|
||||
int keep_tempfiles;
|
||||
|
||||
/* The name this program was run with. */
|
||||
char *program_name;
|
||||
|
||||
/* Forward declarations of functions in this file. */
|
||||
|
||||
void decode_command ();
|
||||
void sort_in_core ();
|
||||
void sort_offline ();
|
||||
@ -149,9 +136,7 @@ void fatal ();
|
||||
void error ();
|
||||
void *xmalloc (), *xrealloc ();
|
||||
char *concat ();
|
||||
char *maketempname ();
|
||||
void flush_tempfiles ();
|
||||
char *tempcopy ();
|
||||
|
||||
#define MAX_IN_CORE_SORT 500000
|
||||
|
||||
@ -165,12 +150,6 @@ main (argc, argv)
|
||||
tempcount = 0;
|
||||
last_deleted_tempcount = 0;
|
||||
|
||||
program_name = strrchr (argv[0], '/');
|
||||
if (program_name != (char *)NULL)
|
||||
program_name++;
|
||||
else
|
||||
program_name = argv[0];
|
||||
|
||||
#ifdef HAVE_SETLOCALE
|
||||
/* Set locale via LC_ALL. */
|
||||
setlocale (LC_ALL, "");
|
||||
@ -208,14 +187,26 @@ main (argc, argv)
|
||||
for (i = 0; i < num_infiles; i++)
|
||||
{
|
||||
int desc;
|
||||
long ptr;
|
||||
off_t ptr;
|
||||
char *outfile;
|
||||
struct stat instat;
|
||||
|
||||
desc = open (infiles[i], O_RDONLY, 0);
|
||||
if (desc < 0)
|
||||
pfatal_with_name (infiles[i]);
|
||||
|
||||
if (stat (infiles[i], &instat))
|
||||
pfatal_with_name (infiles[i]);
|
||||
if (S_ISDIR (instat.st_mode))
|
||||
{
|
||||
#ifdef EISDIR
|
||||
errno = EISDIR;
|
||||
#endif
|
||||
pfatal_with_name (infiles[i]);
|
||||
}
|
||||
|
||||
lseek (desc, (off_t) 0, SEEK_END);
|
||||
ptr = (long) lseek (desc, (off_t) 0, SEEK_CUR);
|
||||
ptr = (off_t) lseek (desc, (off_t) 0, SEEK_CUR);
|
||||
|
||||
close (desc);
|
||||
|
||||
@ -233,8 +224,8 @@ main (argc, argv)
|
||||
}
|
||||
|
||||
flush_tempfiles (tempcount);
|
||||
exit (TI_NO_ERROR);
|
||||
|
||||
xexit (0);
|
||||
|
||||
return 0; /* Avoid bogus warnings. */
|
||||
}
|
||||
|
||||
@ -249,6 +240,8 @@ typedef struct
|
||||
} TEXINDEX_OPTION;
|
||||
|
||||
TEXINDEX_OPTION texindex_options[] = {
|
||||
{ "--help", "-h", (int *)NULL, 0, (char *)NULL,
|
||||
N_("display this help and exit") },
|
||||
{ "--keep", "-k", &keep_tempfiles, 1, (char *)NULL,
|
||||
N_("keep temporary files around after processing") },
|
||||
{ "--no-keep", 0, &keep_tempfiles, 0, (char *)NULL,
|
||||
@ -257,8 +250,6 @@ TEXINDEX_OPTION texindex_options[] = {
|
||||
N_("send output to FILE") },
|
||||
{ "--version", (char *)NULL, (int *)NULL, 0, (char *)NULL,
|
||||
N_("display version information and exit") },
|
||||
{ "--help", "-h", (int *)NULL, 0, (char *)NULL,
|
||||
N_("display this help and exit") },
|
||||
{ (char *)NULL, (char *)NULL, (int *)NULL, 0, (char *)NULL }
|
||||
};
|
||||
|
||||
@ -272,11 +263,15 @@ usage (result_value)
|
||||
fprintf (f, _("Usage: %s [OPTION]... FILE...\n"), program_name);
|
||||
fprintf (f, _("Generate a sorted index for each TeX output FILE.\n"));
|
||||
/* Avoid trigraph nonsense. */
|
||||
fprintf (f, _("Usually FILE... is `foo.??\' for a document `foo.texi'.\n"));
|
||||
fprintf (f,
|
||||
_("Usually FILE... is specified as `foo.%c%c\' for a document `foo.texi'.\n"),
|
||||
'?', '?'); /* avoid trigraph in cat-id-tbl.c */
|
||||
fprintf (f, _("\nOptions:\n"));
|
||||
|
||||
for (i = 0; texindex_options[i].long_name; i++)
|
||||
{
|
||||
putc (' ', f);
|
||||
|
||||
if (texindex_options[i].short_name)
|
||||
fprintf (f, "%s, ", texindex_options[i].short_name);
|
||||
|
||||
@ -287,9 +282,12 @@ usage (result_value)
|
||||
|
||||
fprintf (f, "\t%s\n", _(texindex_options[i].doc_string));
|
||||
}
|
||||
puts (_("\nEmail bug reports to bug-texinfo@gnu.org."));
|
||||
fputs (_("\n\
|
||||
Email bug reports to bug-texinfo@gnu.org,\n\
|
||||
general questions and discussion to help-texinfo@gnu.org.\n\
|
||||
"), f);
|
||||
|
||||
exit (result_value);
|
||||
xexit (result_value);
|
||||
}
|
||||
|
||||
/* Decode the command line arguments to set the parameter variables
|
||||
@ -307,15 +305,14 @@ decode_command (argc, argv)
|
||||
/* Store default values into parameter variables. */
|
||||
|
||||
tempdir = getenv ("TMPDIR");
|
||||
#ifdef VMS
|
||||
if (tempdir == NULL)
|
||||
tempdir = "sys$scratch:";
|
||||
#else
|
||||
tempdir = getenv ("TEMP");
|
||||
if (tempdir == NULL)
|
||||
tempdir = "/tmp/";
|
||||
tempdir = getenv ("TMP");
|
||||
if (tempdir == NULL)
|
||||
tempdir = DEFAULT_TMPDIR;
|
||||
else
|
||||
tempdir = concat (tempdir, "/", "");
|
||||
#endif
|
||||
|
||||
keep_tempfiles = 0;
|
||||
|
||||
@ -335,12 +332,13 @@ decode_command (argc, argv)
|
||||
if (strcmp (arg, "--version") == 0)
|
||||
{
|
||||
printf ("texindex (GNU %s) %s\n", PACKAGE, VERSION);
|
||||
printf (_("Copyright (C) %s Free Software Foundation, Inc.\n\
|
||||
puts ("");
|
||||
printf (_("Copyright (C) %s Free Software Foundation, Inc.\n\
|
||||
There is NO warranty. You may redistribute this software\n\
|
||||
under the terms of the GNU General Public License.\n\
|
||||
For more information about these matters, see the files named COPYING.\n"),
|
||||
"1998");
|
||||
exit (0);
|
||||
"1999");
|
||||
xexit (0);
|
||||
}
|
||||
else if ((strcmp (arg, "--keep") == 0) ||
|
||||
(strcmp (arg, "-k") == 0))
|
||||
@ -383,12 +381,12 @@ For more information about these matters, see the files named COPYING.\n"),
|
||||
|
||||
/* Return a name for a temporary file. */
|
||||
|
||||
char *
|
||||
static char *
|
||||
maketempname (count)
|
||||
int count;
|
||||
{
|
||||
char tempsuffix[10];
|
||||
sprintf (tempsuffix, "%d", count);
|
||||
sprintf (tempsuffix, ".%d", count);
|
||||
return concat (tempdir, tempbase, tempsuffix);
|
||||
}
|
||||
|
||||
@ -404,36 +402,6 @@ flush_tempfiles (to_count)
|
||||
unlink (maketempname (++last_deleted_tempcount));
|
||||
}
|
||||
|
||||
/* Copy the input file open on IDESC into a temporary file
|
||||
and return the temporary file name. */
|
||||
|
||||
#define BUFSIZE 1024
|
||||
|
||||
char *
|
||||
tempcopy (idesc)
|
||||
int idesc;
|
||||
{
|
||||
char *outfile = maketempname (++tempcount);
|
||||
int odesc;
|
||||
char buffer[BUFSIZE];
|
||||
|
||||
odesc = open (outfile, O_WRONLY | O_CREAT, 0666);
|
||||
|
||||
if (odesc < 0)
|
||||
pfatal_with_name (outfile);
|
||||
|
||||
while (1)
|
||||
{
|
||||
int nread = read (idesc, buffer, BUFSIZE);
|
||||
write (odesc, buffer, nread);
|
||||
if (!nread)
|
||||
break;
|
||||
}
|
||||
|
||||
close (odesc);
|
||||
|
||||
return outfile;
|
||||
}
|
||||
|
||||
/* Compare LINE1 and LINE2 according to the specified set of keyfields. */
|
||||
|
||||
@ -894,7 +862,7 @@ void
|
||||
sort_offline (infile, nfiles, total, outfile)
|
||||
char *infile;
|
||||
int nfiles;
|
||||
long total;
|
||||
off_t total;
|
||||
char *outfile;
|
||||
{
|
||||
/* More than enough. */
|
||||
@ -993,7 +961,7 @@ sort_offline (infile, nfiles, total, outfile)
|
||||
void
|
||||
sort_in_core (infile, total, outfile)
|
||||
char *infile;
|
||||
long total;
|
||||
off_t total;
|
||||
char *outfile;
|
||||
{
|
||||
char **nextline;
|
||||
@ -1251,7 +1219,7 @@ indexify (line, ostream)
|
||||
pagenumber = find_braced_pos (line, 1, 0, 0);
|
||||
pagelength = find_braced_end (pagenumber) - pagenumber;
|
||||
if (pagelength == 0)
|
||||
abort ();
|
||||
fatal (_("No page number in %s"), line);
|
||||
|
||||
primary = find_braced_pos (line, 2, 0, 0);
|
||||
primarylength = find_braced_end (primary) - primary;
|
||||
@ -1627,7 +1595,7 @@ fatal (format, arg)
|
||||
char *format, *arg;
|
||||
{
|
||||
error (format, arg);
|
||||
exit (TI_FATAL_ERROR);
|
||||
xexit (1);
|
||||
}
|
||||
|
||||
/* Print error message. FORMAT is printf control string, ARG is arg for it. */
|
||||
@ -1661,7 +1629,7 @@ pfatal_with_name (name)
|
||||
s = strerror (errno);
|
||||
printf ("%s: ", program_name);
|
||||
printf (_("%s; for file `%s'.\n"), s, name);
|
||||
exit (TI_FATAL_ERROR);
|
||||
xexit (1);
|
||||
}
|
||||
|
||||
/* Return a newly-allocated string whose contents concatenate those of
|
||||
@ -1682,21 +1650,6 @@ concat (s1, s2, s3)
|
||||
return result;
|
||||
}
|
||||
|
||||
#if !defined (HAVE_STRERROR)
|
||||
extern char *sys_errlist[];
|
||||
extern int sys_nerr;
|
||||
|
||||
char *
|
||||
strerror (num)
|
||||
int num;
|
||||
{
|
||||
if (num >= sys_nerr)
|
||||
return ("");
|
||||
else
|
||||
return (sys_errlist[num]);
|
||||
}
|
||||
#endif /* !HAVE_STRERROR */
|
||||
|
||||
#if !defined (HAVE_STRCHR)
|
||||
char *
|
||||
strrchr (string, character)
|
||||
@ -1712,50 +1665,3 @@ strrchr (string, character)
|
||||
return ((char *)NULL);
|
||||
}
|
||||
#endif /* HAVE_STRCHR */
|
||||
|
||||
void
|
||||
memory_error (callers_name, bytes_wanted)
|
||||
char *callers_name;
|
||||
int bytes_wanted;
|
||||
{
|
||||
char printable_string[80];
|
||||
|
||||
sprintf (printable_string,
|
||||
_("Virtual memory exhausted in %s ()! Needed %d bytes."),
|
||||
callers_name, bytes_wanted);
|
||||
|
||||
error (printable_string);
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* Just like malloc, but kills the program in case of fatal error. */
|
||||
void *
|
||||
xmalloc (nbytes)
|
||||
int nbytes;
|
||||
{
|
||||
void *temp = (void *) malloc (nbytes);
|
||||
|
||||
if (nbytes && temp == (void *)NULL)
|
||||
memory_error ("xmalloc", nbytes);
|
||||
|
||||
return (temp);
|
||||
}
|
||||
|
||||
/* Like realloc (), but barfs if there isn't enough memory. */
|
||||
void *
|
||||
xrealloc (pointer, nbytes)
|
||||
void *pointer;
|
||||
int nbytes;
|
||||
{
|
||||
void *temp;
|
||||
|
||||
if (!pointer)
|
||||
temp = (void *)xmalloc (nbytes);
|
||||
else
|
||||
temp = (void *)realloc (pointer, nbytes);
|
||||
|
||||
if (nbytes && !temp)
|
||||
memory_error ("xrealloc", nbytes);
|
||||
|
||||
return (temp);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user