This commit was generated by cvs2svn to compensate for changes in r2726,
which included commits to RCS files with non-trunk default branches.
This commit is contained in:
commit
52038e4d67
8
gnu/usr.bin/texinfo/Makefile
Normal file
8
gnu/usr.bin/texinfo/Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
#
|
||||
# Bmake file for texinfo
|
||||
#
|
||||
|
||||
SUBDIR= info info-files makedoc makeinfo texindex
|
||||
|
||||
.include <bsd.subdir.mk>
|
||||
|
7
gnu/usr.bin/texinfo/Makefile.inc
Normal file
7
gnu/usr.bin/texinfo/Makefile.inc
Normal file
@ -0,0 +1,7 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
|
||||
|
||||
INFODIR= /usr/share/info
|
||||
|
18
gnu/usr.bin/texinfo/info-files/Makefile
Normal file
18
gnu/usr.bin/texinfo/info-files/Makefile
Normal file
@ -0,0 +1,18 @@
|
||||
#
|
||||
# Makefile for INFO files
|
||||
#
|
||||
|
||||
INFOFILES+= dir info.info makeinfo.info texi.info texi.info-1 texi.inf-2
|
||||
INFOFILES+= texi.info-3 texi.info-4 texi.info-5 texi.info-6 texi.info-7
|
||||
INFOFILES+= texi.info-8 texi.info-9 texi.info-10 texi.info-11
|
||||
|
||||
install:
|
||||
mkdir -p ${INFODIR}
|
||||
install -g ${BINGRP} -o ${BINOWN} -m 444 ${INFOFILES} ${INFODIR}
|
||||
|
||||
clean:
|
||||
cleandir:
|
||||
obj:
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
18
gnu/usr.bin/texinfo/info-files/dir
Normal file
18
gnu/usr.bin/texinfo/info-files/dir
Normal file
@ -0,0 +1,18 @@
|
||||
-*- Text -*-
|
||||
This is the file .../info/dir, which contains the topmost node of the
|
||||
Info hierarchy. The first time you invoke Info you start off
|
||||
looking at that node, which is (dir)Top.
|
||||
|
||||
File: dir Node: Top This is the top of the INFO tree
|
||||
This (the Directory node) gives a menu of major topics.
|
||||
Typing "d" returns here, "q" exits, "?" lists all INFO commands, "h"
|
||||
gives a primer for first-timers, "mTexinfo<Return>" visits Texinfo topic,
|
||||
etc.
|
||||
--- PLEASE ADD DOCUMENTATION TO THIS TREE. (See INFO topic first.) ---
|
||||
|
||||
* Menu: The list of major topics begins on the next line.
|
||||
|
||||
* Info: (info). Documentation browsing system.
|
||||
* Texi: (texi). TexInfo guide.
|
||||
* Makeinfo: (makeinfo). Makeinfo guide.
|
||||
|
1259
gnu/usr.bin/texinfo/info-files/info-stnd.info
Normal file
1259
gnu/usr.bin/texinfo/info-files/info-stnd.info
Normal file
File diff suppressed because it is too large
Load Diff
777
gnu/usr.bin/texinfo/info-files/info.info
Normal file
777
gnu/usr.bin/texinfo/info-files/info.info
Normal file
@ -0,0 +1,777 @@
|
||||
This is Info file info.info, produced by Makeinfo-1.55 from the input
|
||||
file info.texi.
|
||||
|
||||
This file describes how to use Info, the on-line, menu-driven GNU
|
||||
documentation system.
|
||||
|
||||
Copyright (C) 1989, 1992 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 Free Software Foundation.
|
||||
|
||||
|
||||
File: info.info, Node: Top, Next: Getting Started, Prev: (dir), Up: (dir)
|
||||
|
||||
Info: An Introduction
|
||||
*********************
|
||||
|
||||
Info is a program for reading documentation, which you are using now.
|
||||
|
||||
To learn how to use Info, type the command `h'. It brings you to a
|
||||
programmed instruction sequence.
|
||||
|
||||
To learn advanced Info commands, type `n' twice. This brings you to
|
||||
`Info for Experts', skipping over the . `Getting Started' chapter.
|
||||
|
||||
* Menu:
|
||||
|
||||
* Getting Started::
|
||||
* Advanced Info::
|
||||
* Create an Info File::
|
||||
|
||||
|
||||
File: info.info, Node: Getting Started, Next: Advanced Info, Prev: Top, Up: Top
|
||||
|
||||
Getting Started
|
||||
***************
|
||||
|
||||
This first part of the Info manual describes how to get around inside
|
||||
of Info. The second part of the manual describes various advanced Info
|
||||
commands, and how to write an Info as distinct from a Texinfo file.
|
||||
The third part is about how to generate Info files from Texinfo files.
|
||||
|
||||
* Menu:
|
||||
|
||||
* Help-Small-Screen:: Starting Info on a Small Screen
|
||||
* Help:: How to use Info
|
||||
* Help-P:: Returning to the Previous node
|
||||
* Help-^L:: The Space, Rubout, B and ^L commands.
|
||||
* Help-M:: Menus
|
||||
* Help-Adv:: Some advanced Info commands
|
||||
* Help-Q:: Quitting Info
|
||||
|
||||
|
||||
File: info.info, Node: Help-Small-Screen, Next: Help, Up: Getting Started
|
||||
|
||||
Starting Info on a Small Screen
|
||||
===============================
|
||||
|
||||
Since your terminal has an unusually small number of lines on its
|
||||
screen, it is necessary to give you special advice at the beginning.
|
||||
|
||||
If you see the text `--All----' at near the bottom right corner of
|
||||
the screen, it means the entire text you are looking at fits on the
|
||||
screen. If you see `--Top----' instead, it means that there is more
|
||||
text below that does not fit. To move forward through the text and see
|
||||
another screen full, press the Space bar, SPC. To move back up, press
|
||||
the key labeled `Rubout' or `Delete' or DEL.
|
||||
|
||||
Here are 40 lines of junk, so you can try SPC and DEL and see what
|
||||
they do. At the end are instructions of what you should do next.
|
||||
|
||||
This is line 17
|
||||
This is line 18
|
||||
This is line 19
|
||||
This is line 20
|
||||
This is line 21
|
||||
This is line 22
|
||||
This is line 23
|
||||
This is line 24
|
||||
This is line 25
|
||||
This is line 26
|
||||
This is line 27
|
||||
This is line 28
|
||||
This is line 29
|
||||
This is line 30
|
||||
This is line 31
|
||||
This is line 32
|
||||
This is line 33
|
||||
This is line 34
|
||||
This is line 35
|
||||
This is line 36
|
||||
This is line 37
|
||||
This is line 38
|
||||
This is line 39
|
||||
This is line 40
|
||||
This is line 41
|
||||
This is line 42
|
||||
This is line 43
|
||||
This is line 44
|
||||
This is line 45
|
||||
This is line 46
|
||||
This is line 47
|
||||
This is line 48
|
||||
This is line 49
|
||||
This is line 50
|
||||
This is line 51
|
||||
This is line 52
|
||||
This is line 53
|
||||
This is line 54
|
||||
This is line 55
|
||||
This is line 56
|
||||
If you have managed to get here, go back to the beginning with DEL, and
|
||||
come back here again, then you understand SPC and DEL. So now type an
|
||||
`n'--just one character; do not type the quotes and do not type the
|
||||
Return key, RET, afterward--to get to the normal start of the course.
|
||||
|
||||
|
||||
File: info.info, Node: Help, Next: Help-P, Prev: Help-Small-Screen, Up: Getting Started
|
||||
|
||||
How to use Info
|
||||
===============
|
||||
|
||||
You are talking to the program Info, for reading documentation.
|
||||
|
||||
Right now you are looking at one "Node" of Information. A node
|
||||
contains text describing a specific topic at a specific level of
|
||||
detail. This node's topic is "how to use Info".
|
||||
|
||||
The top line of a node is its "header". This node's header (look at
|
||||
it now) says that it is the node named `Help' in the file `info'. It
|
||||
says that the `Next' node after this one is the node called `Help-P'.
|
||||
An advanced Info command lets you go to any node whose name you know.
|
||||
|
||||
Besides a `Next', a node can have a `Previous' or an `Up'. This
|
||||
node has a `Previous' but no `Up', as you can see.
|
||||
|
||||
Now it is time to move on to the `Next' node, named `Help-P'.
|
||||
|
||||
>> Type `n' to move there. Type just one character; do not type
|
||||
the quotes and do not type a RET afterward.
|
||||
|
||||
`>>' in the margin means it is really time to try a command.
|
||||
|
||||
|
||||
File: info.info, Node: Help-P, Next: Help-^L, Prev: Help, Up: Getting Started
|
||||
|
||||
Returning to the Previous node
|
||||
==============================
|
||||
|
||||
This node is called `Help-P'. The `Previous' node, as you see, is
|
||||
`Help', which is the one you just came from using the `n' command.
|
||||
Another `n' command now would take you to the next node, `Help-^L'.
|
||||
|
||||
>> But do not do that yet. First, try the `p' command, which takes
|
||||
you to the `Previous' node. When you get there, you can do an `n'
|
||||
again to return here.
|
||||
|
||||
This all probably seems insultingly simple so far, but *do not* be
|
||||
led into skimming. Things will get more complicated soon. Also, do
|
||||
not try a new command until you are told it is time to. Otherwise, you
|
||||
may make Info skip past an important warning that was coming up.
|
||||
|
||||
>> Now do an `n' to get to the node `Help-^L' and learn more.
|
||||
|
||||
|
||||
File: info.info, Node: Help-^L, Next: Help-M, Prev: Help-P, Up: Getting Started
|
||||
|
||||
The Space, Rubout, B and ^L commands.
|
||||
=====================================
|
||||
|
||||
This node's header tells you that you are now at node `Help-^L', and
|
||||
that `p' would get you back to `Help-P'. The node's title is
|
||||
underlined; it says what the node is about (most nodes have titles).
|
||||
|
||||
This is a big node and it does not all fit on your display screen.
|
||||
You can tell that there is more that is not visible because you can see
|
||||
the string `--Top-----' rather than `--All----' near the bottom right
|
||||
corner of the screen.
|
||||
|
||||
The SPC, DEL and `b' commands exist to allow you to "move around" in
|
||||
a node that does not all fit on the screen at once. SPC moves forward,
|
||||
to show what was below the bottom of the screen. DEL moves backward,
|
||||
to show what was above the top of the screen (there is not anything
|
||||
above the top until you have typed some spaces).
|
||||
|
||||
>> Now try typing a SPC (afterward, type a DEL to return here).
|
||||
|
||||
When you type the SPC, the two lines that were at the bottom of the
|
||||
screen appear at the top, followed by more lines. DEL takes the two
|
||||
lines from the top and moves them to the bottom, *usually*, but if
|
||||
there are not a full screen's worth of lines above them they may not
|
||||
make it all the way to the bottom.
|
||||
|
||||
If you type a SPC when there is no more to see, it rings the bell
|
||||
and otherwise does nothing. The same goes for a DEL when the header of
|
||||
the node is visible.
|
||||
|
||||
If your screen is ever garbaged, you can tell Info to print it out
|
||||
again by typing `C-l' (`Control-L', that is--hold down "Control" and
|
||||
type an L or `l').
|
||||
|
||||
>> Type `C-l' now.
|
||||
|
||||
To move back to the beginning of the node you are on, you can type a
|
||||
lot of DELs. You can also type simply `b' for beginning.
|
||||
|
||||
>> Try that now. (I have put in enough verbiage to make sure you are
|
||||
not on the first screenful now). Then come back, typing SPC
|
||||
several times.
|
||||
|
||||
You have just learned a considerable number of commands. If you
|
||||
want to use one but have trouble remembering which, you should type a ?
|
||||
which prints out a brief list of commands. When you are finished
|
||||
looking at the list, make it go away by typing a SPC.
|
||||
|
||||
>> Type a ? now. After it finishes, type a SPC.
|
||||
|
||||
(If you are using the standalone Info reader, type `l' to return
|
||||
here.)
|
||||
|
||||
From now on, you will encounter large nodes without warning, and
|
||||
will be expected to know how to use SPC and DEL to move around in them
|
||||
without being told. Since not all terminals have the same size screen,
|
||||
it would be impossible to warn you anyway.
|
||||
|
||||
>> Now type `n' to see the description of the `m' command.
|
||||
|
||||
|
||||
File: info.info, Node: Help-M, Next: Help-Adv, Prev: Help-^L, Up: Getting Started
|
||||
|
||||
Menus
|
||||
=====
|
||||
|
||||
Menus and the `m' command
|
||||
|
||||
With only the `n' and `p' commands for moving between nodes, nodes
|
||||
are restricted to a linear sequence. Menus allow a branching
|
||||
structure. A menu is a list of other nodes you can move to. It is
|
||||
actually just part of the text of the node formatted specially so that
|
||||
Info can interpret it. The beginning of a menu is always identified by
|
||||
a line which starts with `* Menu:'. A node contains a menu if and only
|
||||
if it has a line in it which starts that way. The only menu you can
|
||||
use at any moment is the one in the node you are in. To use a menu in
|
||||
any other node, you must move to that node first.
|
||||
|
||||
After the start of the menu, each line that starts with a `*'
|
||||
identifies one subtopic. The line usually contains a brief name for
|
||||
the subtopic (followed by a `:'), the name of the node that talks about
|
||||
that subtopic, and optionally some further description of the subtopic.
|
||||
Lines in the menu that do not start with a `*' have no special
|
||||
meaning--they are only for the human reader's benefit and do not define
|
||||
additional subtopics. Here is an example:
|
||||
|
||||
* Foo: FOO's Node This tells about FOO
|
||||
|
||||
The subtopic name is Foo, and the node describing it is `FOO's Node'.
|
||||
The rest of the line is just for the reader's Information. [[ But this
|
||||
line is not a real menu item, simply because there is no line above it
|
||||
which starts with `* Menu:'.]]
|
||||
|
||||
When you use a menu to go to another node (in a way that will be
|
||||
described soon), what you specify is the subtopic name, the first thing
|
||||
in the menu line. Info uses it to find the menu line, extracts the
|
||||
node name from it, and goes to that node. The reason that there is
|
||||
both a subtopic name and a node name is that the node name must be
|
||||
meaningful to the computer and may therefore have to be ugly looking.
|
||||
The subtopic name can be chosen just to be convenient for the user to
|
||||
specify. Often the node name is convenient for the user to specify and
|
||||
so both it and the subtopic name are the same. There is an
|
||||
abbreviation for this:
|
||||
|
||||
* Foo:: This tells about FOO
|
||||
|
||||
This means that the subtopic name and node name are the same; they are
|
||||
both `Foo'.
|
||||
|
||||
>> Now use SPCs to find the menu in this node, then come back to
|
||||
the front with a `b'. As you see, a menu is actually visible in its
|
||||
node. If you cannot find a menu in a node by looking at it, then
|
||||
the node does not have a menu and the `m' command is not available.
|
||||
|
||||
The command to go to one of the subnodes is `m'--but *do not do it
|
||||
yet!* Before you use `m', you must understand the difference between
|
||||
commands and arguments. So far, you have learned several commands that
|
||||
do not need arguments. When you type one, Info processes it and is
|
||||
instantly ready for another command. The `m' command is different: it
|
||||
is incomplete without the "name of the subtopic". Once you have typed
|
||||
`m', Info tries to read the subtopic name.
|
||||
|
||||
Now look for the line containing many dashes near the bottom of the
|
||||
screen. There is one more line beneath that one, but usually it is
|
||||
blank If it is empty, Info is ready for a command, such as `n' or `b'
|
||||
or SPC or `m'. If that line contains text ending in a colon, it mean
|
||||
Info is trying to read the "argument" to a command. At such times,
|
||||
commands do not work, because Info tries to use them as the argument.
|
||||
You must either type the argument and finish the command you started,
|
||||
or type `Control-g' to cancel the command. When you have done one of
|
||||
those things, the line becomes blank again.
|
||||
|
||||
The command to go to a subnode via a menu is `m'. After you type
|
||||
the `m', the line at the bottom of the screen says `Menu item: '. You
|
||||
must then type the name of the subtopic you want, and end it with a RET.
|
||||
|
||||
You can abbreviate the subtopic name. If the abbreviation is not
|
||||
unique, the first matching subtopic is chosen. Some menus put the
|
||||
shortest possible abbreviation for each subtopic name in capital
|
||||
letters, so you can see how much you need to type. It does not matter
|
||||
whether you use upper case or lower case when you type the subtopic.
|
||||
You should not put any spaces at the end, or inside of the item name,
|
||||
except for one space where a space appears in the item in the menu.
|
||||
|
||||
Here is a menu to give you a chance to practice.
|
||||
|
||||
* Menu: The menu starts here.
|
||||
|
||||
This menu givs you three ways of going to one place, Help-FOO.
|
||||
|
||||
* Foo: Help-FOO. A node you can visit for fun.
|
||||
* Bar: Help-FOO. Strange! two ways to get to the same place.
|
||||
* Help-FOO:: And yet another!
|
||||
>> Now type just an `m' and see what happens:
|
||||
|
||||
Now you are "inside" an `m' command. Commands cannot be used now;
|
||||
the next thing you will type must be the name of a subtopic.
|
||||
|
||||
You can change your mind about doing the `m' by typing Control-g.
|
||||
|
||||
>> Try that now; notice the bottom line clear.
|
||||
|
||||
>> Then type another `m'.
|
||||
|
||||
>> Now type `BAR' item name. Do not type RET yet.
|
||||
|
||||
While you are typing the item name, you can use the DEL character to
|
||||
cancel one character at a time if you make a mistake.
|
||||
|
||||
>> Type one to cancel the `R'. You could type another `R' to
|
||||
replace it. You do not have to, since `BA' is a valid abbreviation.
|
||||
|
||||
>> Now you are ready to go. Type a RET.
|
||||
|
||||
After visiting Help-FOO, you should return here.
|
||||
|
||||
>> Type `n' to see more commands.
|
||||
|
||||
Here is another way to get to Help-FOO, a menu. You can ignore this
|
||||
if you want, or else try it (but then please come back to here).
|
||||
|
||||
* Menu:
|
||||
|
||||
* Help-FOO::
|
||||
|
||||
|
||||
File: info.info, Node: Help-FOO, Up: Help-M
|
||||
|
||||
The `u' command
|
||||
---------------
|
||||
|
||||
Congratulations! This is the node `Help-FOO'. Unlike the other
|
||||
nodes you have seen, this one has an `Up': `Help-M', the node you just
|
||||
came from via the `m' command. This is the usual convention--the nodes
|
||||
you reach from a menu have `Up' nodes that lead back to the menu.
|
||||
Menus move Down in the tree, and `Up' moves Up. `Previous', on the
|
||||
other hand, is usually used to "stay on the same level but go backwards"
|
||||
|
||||
You can go back to the node `Help-M' by typing the command `u' for
|
||||
"Up". That puts you at the *front* of the node--to get back to where
|
||||
you were reading you have to type some SPCs.
|
||||
|
||||
>> Now type `u' to move back up to `Help-M'.
|
||||
|
||||
|
||||
File: info.info, Node: Help-Adv, Next: Help-Q, Prev: Help-M, Up: Getting Started
|
||||
|
||||
Some advanced Info commands
|
||||
===========================
|
||||
|
||||
The course is almost over, so please stick with it to the end.
|
||||
|
||||
If you have been moving around to different nodes and wish to
|
||||
retrace your steps, the `l' command (`l' for "last") will do that, one
|
||||
node at a time. If you have been following directions, an `l' command
|
||||
now will get you back to `Help-M'. Another `l' command would undo the
|
||||
`u' and get you back to `Help-FOO'. Another `l' would undo the `m' and
|
||||
get you back to `Help-M'.
|
||||
|
||||
>> Try typing three `l''s, pausing in between to see what each
|
||||
`l' does.
|
||||
|
||||
Then follow directions again and you will end up back here.
|
||||
|
||||
Note the difference between `l' and `p': `l' moves to where *you*
|
||||
last were, whereas `p' always moves to the node which the header says
|
||||
is the `Previous' node (from this node, to `Help-M').
|
||||
|
||||
The `d' command gets you instantly to the Directory node. This
|
||||
node, which is the first one you saw when you entered Info, has a menu
|
||||
which leads (directly, or indirectly through other menus), to all the
|
||||
nodes that exist.
|
||||
|
||||
>> Try doing a `d', then do an `l' to return here (yes, *do*
|
||||
return).
|
||||
|
||||
Sometimes, in Info documentation, you will see a cross reference.
|
||||
Cross references look like this: *Note Cross: Help-Cross. That is a
|
||||
real, live cross reference which is named `Cross' and points at the
|
||||
node named `Help-Cross'.
|
||||
|
||||
If you wish to follow a cross reference, you must use the `f'
|
||||
command. The `f' must be followed by the cross reference name (in this
|
||||
case, `Cross'). You can use DEL to edit the name, and if you change
|
||||
your mind about following any reference you can use `Control-g' to
|
||||
cancel the command.
|
||||
|
||||
Completion is available in the `f' command; you can complete among
|
||||
all the cross reference names in the current node.
|
||||
|
||||
>> Type `f', followed by `Cross', and a RET.
|
||||
|
||||
To get a list of all the cross references in the current node, you
|
||||
can type `?' after an `f'. The `f' continues to await a cross
|
||||
reference name even after printing the list, so if you do not actually
|
||||
want to follow a reference you should type a `Control-g' to cancel the
|
||||
`f'.
|
||||
|
||||
>> Type "f?" to get a list of the footnotes in this node. Then type
|
||||
a `Control-g' and see how the `f' gives up.
|
||||
|
||||
>> Now type `n' to see the last node of the course.
|
||||
|
||||
|
||||
File: info.info, Node: Help-Cross, Up: Help-Adv
|
||||
|
||||
The node reached by the cross reference in Info
|
||||
-----------------------------------------------
|
||||
|
||||
This is the node reached by the cross reference named `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 `Next', `Previous' or `Up' pointing back to where
|
||||
you came from. In general, the `l' (el) command is the only way to get
|
||||
back there.
|
||||
|
||||
>> Type `l' to return to the node where the cross reference was.
|
||||
|
||||
|
||||
File: info.info, Node: Help-Q, Prev: Help-Adv, Up: Getting Started
|
||||
|
||||
Quitting Info
|
||||
=============
|
||||
|
||||
To get out of Info, back to what you were doing before, type `q' for
|
||||
"Quit".
|
||||
|
||||
This is the end of the course on using Info. There are some other
|
||||
commands that are not essential or are meant for experienced users;
|
||||
they are useful, and you can find them by looking in the directory for
|
||||
documentation on Info. Finding them will be a good exercise in using
|
||||
Info in the usual manner.
|
||||
|
||||
>> Type `d' to go to the Info directory node; then type `mInfo'
|
||||
and RET, to get to the node about Info and see what other help is
|
||||
available.
|
||||
|
||||
|
||||
File: info.info, Node: Advanced Info, Next: Create an Info File, Prev: Getting Started, Up: Top
|
||||
|
||||
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 *both* to
|
||||
generate an Info file and to make a printed manual. *Note Overview of
|
||||
Texinfo: (texinfo)Top.)
|
||||
|
||||
* Menu:
|
||||
|
||||
* Expert:: Advanced Info commands: g, s, e, and 1 - 5.
|
||||
* Add:: Describes how to add new nodes to the hierarchy.
|
||||
Also tells what nodes look like.
|
||||
* Menus:: How to add to or create menus in Info nodes.
|
||||
* Cross-refs:: How to add cross-references to Info nodes.
|
||||
* Tags:: How to make tag tables for Info files.
|
||||
* Checking:: Checking an Info File
|
||||
|
||||
|
||||
File: info.info, Node: Expert, Next: Add, Up: Advanced Info
|
||||
|
||||
Advanced Info Commands
|
||||
======================
|
||||
|
||||
`g', `s', `1', - `5', and `e'
|
||||
|
||||
If you know a node's name, you can go there by typing `g', the name,
|
||||
and RET. Thus, `gTopRET' would go to the node called `Top' in this
|
||||
file (its directory node). `gExpertRET' would come back here.
|
||||
|
||||
Unlike `m', `g' does not allow the use of abbreviations.
|
||||
|
||||
To go to a node in another file, you can include the filename in the
|
||||
node name by putting it at the front, in parentheses. Thus,
|
||||
`g(dir)TopRET' would go to the Info Directory node, which is node `Top'
|
||||
in the file `dir'.
|
||||
|
||||
The node name `*' specifies the whole file. So you can look at all
|
||||
of the current file by typing `g*RET' or all of any other file with
|
||||
`g(FILENAME)RET'.
|
||||
|
||||
The `s' command allows you to search a whole file for a string. It
|
||||
switches to the next node if and when that is necessary. You type `s'
|
||||
followed by the string to search for, terminated by RET. To search for
|
||||
the same string again, just `s' followed by 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 `next' pointers. But normally the two orders
|
||||
are not very different. In any case, you can always do a `b' to find
|
||||
out what node you have reached, if the header is not visible (this can
|
||||
happen, because `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 `1', `2', `3', `4', and `5'. They are
|
||||
short for the `m' command together with an argument. "1", "2", "3",
|
||||
"4", and "5". `1' goes through the first item in the current node's
|
||||
menu; `2' goes through the second item, etc. Note that numbers larger
|
||||
than 5 are not allowed. If the item you want is that far down, you are
|
||||
better off using an abbreviation for its name than counting.
|
||||
|
||||
The Info command `e' changes from Info mode to an ordinary Emacs
|
||||
editing mode, so that you can edit the text of the current node. Type
|
||||
`C-c C-c' to switch back to Info. The `e' command is allowed only if
|
||||
the variable `Info-enable-edit' is non-`nil'.
|
||||
|
||||
|
||||
File: info.info, Node: Add, Next: Menus, Prev: Expert, Up: Advanced Info
|
||||
|
||||
Adding a new node to Info
|
||||
=========================
|
||||
|
||||
To add a new topic to the list in the directory, you must:
|
||||
|
||||
1. Create a node, in some file, to document that topic.
|
||||
|
||||
2. Put that topic in the menu in the directory. *Note Menu: Menus.
|
||||
|
||||
The new node can live in an existing documentation file, or in a new
|
||||
one. It must have a ^_ character before it (invisible to the user;
|
||||
this node has one but you cannot see it), and it ends with either a ^_,
|
||||
a ^L, or the end of file. Note: If you put in a ^L to end a new node,
|
||||
be sure that there is a ^_ after it to start the next one, since ^L
|
||||
cannot *start* a node. Also, a nicer way to make a node boundary be a
|
||||
page boundary as well is to put a ^L *right after* the ^_.
|
||||
|
||||
The ^_ starting a node must be followed by a newline or a ^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 `Next', `Previous', and `Up' nodes (if there are any). As you
|
||||
can see, this node's `Up' node is the node `Top', which points at all
|
||||
the documentation for Info. The `Next' node is `Menus'.
|
||||
|
||||
The keywords "Node", "Previous", "Up" and "Next", may appear in any
|
||||
order, anywhere in the header line, but the recommended order is the
|
||||
one in this sentence. Each keyword must be followed by a colon, spaces
|
||||
and tabs, and then the appropriate name. The name may be terminated
|
||||
with a tab, a comma, or a newline. A space does not end it; node names
|
||||
may contain spaces. The case of letters in the names is insignificant.
|
||||
|
||||
A node name has two forms. A node in the current file is named by
|
||||
what appears after the `Node: ' in that node's first line. For
|
||||
example, this node's name is `Add'. A node in another file is named by
|
||||
`(FILENAME)NODE-WITHIN-FILE', as in `(info)Add' for this node. If the
|
||||
file name is relative, it is taken starting from the standard Info file
|
||||
directory of your site. The name `(FILENAME)Top' can be abbreviated to
|
||||
just `(FILENAME)'. By convention, the name `Top' is used for the
|
||||
"highest" node in any single file--the node whose `Up' points out of
|
||||
the file. The Directory node is `(dir)'. The `Top' node of a document
|
||||
file listed in the Directory should have an `Up: (dir)' in it.
|
||||
|
||||
The node name `*' is special: it refers to the entire file. Thus,
|
||||
`g*' shows you the whole current file. The use of the node `*' is to
|
||||
make it possible to make old-fashioned, unstructured files into nodes
|
||||
of the tree.
|
||||
|
||||
The `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 `Next', `Previous' and `Up' names may
|
||||
contain them. In this node, since the `Up' node is in the same file,
|
||||
it was not necessary to use one.
|
||||
|
||||
Note that the nodes in this file have a file name in the header
|
||||
line. The file names are ignored by Info, but they serve as comments
|
||||
to help identify the node for the user.
|
||||
|
||||
|
||||
File: info.info, Node: Menus, Next: Cross-refs, Prev: Add, Up: Advanced Info
|
||||
|
||||
How to Create Menus
|
||||
===================
|
||||
|
||||
Any node in the Info hierarchy may have a "menu"--a list of subnodes.
|
||||
The `m' command searches the current node's menu for the topic which it
|
||||
reads from the terminal.
|
||||
|
||||
A menu begins with a line starting with `* Menu:'. The rest of the
|
||||
line is a comment. After the starting line, every line that begins
|
||||
with a `* ' lists a single topic. The name of the topic-the argument
|
||||
that the user must give to the `m' command to select this topic--comes
|
||||
right after the star and space, and is followed by a colon, spaces and
|
||||
tabs, and the name of the node which discusses that topic. The node
|
||||
name, like node names following `Next', `Previous' and `Up', may be
|
||||
terminated with a tab, comma, or newline; it may also be terminated
|
||||
with a period.
|
||||
|
||||
If the node name and topic name are the same, than rather than
|
||||
giving the name twice, the abbreviation `* NAME::' may be used (and
|
||||
should be used, whenever possible, as it reduces the visual clutter in
|
||||
the menu).
|
||||
|
||||
It is considerate to choose the topic names so that they differ from
|
||||
each other very near the beginning--this allows the user to type short
|
||||
abbreviations. In a long menu, it is a good idea to capitalize the
|
||||
beginning of each item name which is the minimum acceptable
|
||||
abbreviation for it (a long menu is more than 5 or so entries).
|
||||
|
||||
The nodes listed in a node's menu are called its "subnodes", and it
|
||||
is their "superior". They should each have an `Up:' pointing at the
|
||||
superior. It is often useful to arrange all or most of the subnodes in
|
||||
a sequence of `Next' and `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 `(dir)Top'--that
|
||||
is, node `Top' in file `.../info/dir'. You can put new entries in that
|
||||
menu just like any other menu. The Info Directory is *not* the same as
|
||||
the file directory called `info'. It happens that many of Info's files
|
||||
live on that file directory, but they do not have to; and files on that
|
||||
directory are not automatically listed in the Info Directory node.
|
||||
|
||||
Also, although the Info node graph is claimed to be a "hierarchy",
|
||||
in fact it can be *any* directed graph. Shared structures and pointer
|
||||
cycles are perfectly possible, and can be used if they are appropriate
|
||||
to the meaning to be expressed. There is no need for all the nodes in
|
||||
a file to form a connected structure. In fact, this file has two
|
||||
connected components. You are in one of them, which is under the node
|
||||
`Top'; the other contains the node `Help' which the `h' command goes
|
||||
to. In fact, since there is no garbage collector, nothing terrible
|
||||
happens if a substructure is not pointed to, but such a substructure is
|
||||
rather useless since nobody can ever find out that it exists.
|
||||
|
||||
|
||||
File: info.info, Node: Cross-refs, Next: Tags, Prev: Menus, Up: Advanced Info
|
||||
|
||||
Creating Cross References
|
||||
=========================
|
||||
|
||||
A cross reference can be placed anywhere in the text, unlike a menu
|
||||
item which must go at the front of a line. A cross reference looks
|
||||
like a menu item except that it has `*note' instead of `*'. It
|
||||
*cannot* be terminated by a `)', because `)''s are so often part of
|
||||
node names. If you wish to enclose a cross reference in parentheses,
|
||||
terminate it with a period first. Here are two examples of cross
|
||||
references pointers:
|
||||
|
||||
*Note details: commands. (See *note 3: Full Proof.)
|
||||
|
||||
They are just examples. The places they "lead to" do not really
|
||||
exist!
|
||||
|
||||
|
||||
File: info.info, Node: Tags, Next: Checking, Prev: Cross-refs, Up: Advanced Info
|
||||
|
||||
Tag Tables for Info Files
|
||||
=========================
|
||||
|
||||
You can speed up the access to nodes of a large Info file by giving
|
||||
it a tag table. Unlike the tag table for a program, the tag table for
|
||||
an Info file lives inside the file itself and is used automatically
|
||||
whenever Info reads in the file.
|
||||
|
||||
To make a tag table, go to a node in the file using Emacs Info mode
|
||||
and type `M-x Info-tagify'. Then you must use `C-x C-s' to save the
|
||||
file.
|
||||
|
||||
Once the Info file has a tag table, you must make certain it is up
|
||||
to date. If, as a result of deletion of text, any node moves back more
|
||||
than a thousand characters in the file from the position recorded in
|
||||
the tag table, Info will no longer be able to find that node. To
|
||||
update the tag table, use the `Info-tagify' command again.
|
||||
|
||||
An Info file tag table appears at the end of the file and looks like
|
||||
this:
|
||||
|
||||
^_
|
||||
Tag Table:
|
||||
File: info, Node: Cross-refs^?21419
|
||||
File: info, Node: Tags^?22145
|
||||
^_
|
||||
End Tag Table
|
||||
|
||||
Note that it contains one line per node, and this line contains the
|
||||
beginning of the node's header (ending just after the node name), a DEL
|
||||
character, and the character position in the file of the beginning of
|
||||
the node.
|
||||
|
||||
|
||||
File: info.info, Node: Checking, Prev: Tags, Up: Advanced Info
|
||||
|
||||
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 `Next', `Previous', and `Up' is
|
||||
checked, as is every menu item and every cross reference. In addition,
|
||||
any `Next' which does not have a `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 `M-x Info-validate' while looking at any
|
||||
node of the file with Emacs Info mode.
|
||||
|
||||
|
||||
File: info.info, Node: Create an Info File, Prev: Advanced Info, Up: Top
|
||||
|
||||
Creating an Info File from a Makeinfo file
|
||||
******************************************
|
||||
|
||||
`makeinfo' is a utility that converts a Texinfo file into an Info
|
||||
file; `texinfo-format-region' and `texinfo-format-buffer' are GNU Emacs
|
||||
functions that do the same.
|
||||
|
||||
*Note Creating an Info File: (texinfo)Create an Info File, to learn
|
||||
how to create an Info file from a Texinfo file.
|
||||
|
||||
*Note Overview of Texinfo: (texinfo)Top, to learn how to write a
|
||||
Texinfo file.
|
||||
|
||||
|
||||
|
||||
Tag Table:
|
||||
Node: Top913
|
||||
Node: Getting Started1431
|
||||
Node: Help-Small-Screen2179
|
||||
Node: Help3921
|
||||
Node: Help-P4949
|
||||
Node: Help-^L5811
|
||||
Node: Help-M8462
|
||||
Node: Help-FOO14030
|
||||
Node: Help-Adv14766
|
||||
Node: Help-Cross17148
|
||||
Node: Help-Q17794
|
||||
Node: Advanced Info18434
|
||||
Node: Expert19330
|
||||
Node: Add21601
|
||||
Node: Menus24635
|
||||
Node: Cross-refs27509
|
||||
Node: Tags28211
|
||||
Node: Checking29510
|
||||
Node: Create an Info File30434
|
||||
|
||||
End Tag Table
|
224
gnu/usr.bin/texinfo/info-files/makeinfo.info
Normal file
224
gnu/usr.bin/texinfo/info-files/makeinfo.info
Normal file
@ -0,0 +1,224 @@
|
||||
This is Info file makeinfo.info, produced by Makeinfo-1.55 from the
|
||||
input file makeinfo.texi.
|
||||
|
||||
This file is an extract from the `Texinfo' manual.
|
||||
It documents `makeinfo', a program that converts Texinfo files into
|
||||
Info files.
|
||||
|
||||
Copyright (C) 1992, 1993 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 Free Software Foundation.
|
||||
|
||||
|
||||
File: makeinfo.info, Node: Top, Next: What is makeinfo, Prev: (dir), Up: (dir)
|
||||
|
||||
`makeinfo'
|
||||
**********
|
||||
|
||||
This file documents the use of the `makeinfo' program, versions 1.51
|
||||
and later. It is an extract from the `Texinfo' manual.
|
||||
|
||||
* Menu:
|
||||
|
||||
* What is makeinfo::
|
||||
|
||||
|
||||
File: makeinfo.info, Node: What is makeinfo, Prev: Top, Up: Top
|
||||
|
||||
What is `makeinfo'?
|
||||
*******************
|
||||
|
||||
`makeinfo' is a program for converting "Texinfo" files into "Info"
|
||||
files. Texinfo is a documentation system that uses a single source
|
||||
file to produce both on-line information and printed output.
|
||||
|
||||
You can read the on-line information using Info; type `info' to learn
|
||||
about Info. *Note Texinfo: (texinfo.texi)Top, to learn about the
|
||||
Texinfo documentation system.
|
||||
|
||||
* Menu:
|
||||
|
||||
* Formatting Control::
|
||||
* Options::
|
||||
* Pointer Validation::
|
||||
|
||||
|
||||
File: makeinfo.info, Node: Formatting Control, Next: Options, Up: What is makeinfo
|
||||
|
||||
Controlling Paragraph Formats
|
||||
=============================
|
||||
|
||||
In general, `makeinfo' "fills" the paragraphs that it outputs to an
|
||||
Info file. Filling is the process of breaking and connecting lines so
|
||||
that lines are the same length as or shorter than the number specified
|
||||
as the fill column. Lines are broken between words. With `makeinfo',
|
||||
you can control:
|
||||
|
||||
* The width of each paragraph (the "fill-column").
|
||||
|
||||
* The amount of indentation that the first line of each paragraph
|
||||
receives (the "paragraph-indentation").
|
||||
|
||||
|
||||
File: makeinfo.info, Node: Options, Next: Pointer Validation, Prev: Formatting Control, Up: What is makeinfo
|
||||
|
||||
Command Line Options
|
||||
====================
|
||||
|
||||
The following command line options are available for `makeinfo'.
|
||||
|
||||
`-D VAR'
|
||||
Cause VAR to be defined. This is equivalent to `@set VAR' in the
|
||||
Texinfo file.
|
||||
|
||||
`--error-limit LIMIT'
|
||||
Set the maximum number of errors that `makeinfo' will report
|
||||
before exiting (on the assumption that continuing would be
|
||||
useless). The default number of errors that can be reported before
|
||||
`makeinfo' gives up is 100.
|
||||
|
||||
`--fill-column WIDTH'
|
||||
Specify the maximum number of columns in a line; this is the
|
||||
right-hand edge of a line. Paragraphs that are filled will be
|
||||
filled to this width. The default value for `fill-column' is 72.
|
||||
|
||||
`--footnote-style STYLE'
|
||||
Set the footnote style to STYLE, either `end' for the end node
|
||||
style or `separate' for the separate node style. The value set by
|
||||
this option overrides the value set in a Texinfo file by an
|
||||
`@footnotestyle' command. When the footnote style is `separate',
|
||||
`makeinfo' makes a new node containing the footnotes found in the
|
||||
current node. When the footnote style is `end', `makeinfo' places
|
||||
the footnote references at the end of the current node.
|
||||
|
||||
`-I DIR'
|
||||
Add `dir' to the directory search list for finding files that are
|
||||
included using the `@include' command. By default, `makeinfo'
|
||||
searches only the current directory.
|
||||
|
||||
`--no-headers'
|
||||
Do not include menus or node lines in the output. This results in
|
||||
an ASCII file that you cannot read in Info since it does not
|
||||
contain the requisite nodes or menus; but you can print such a
|
||||
file in a single, typewriter-like font and produce acceptable
|
||||
output.
|
||||
|
||||
`--no-split'
|
||||
Suppress the splitting stage of `makeinfo'. Normally, large
|
||||
output files (where the size is greater than 70k bytes) are split
|
||||
into smaller subfiles, each one approximately 50k bytes. If you
|
||||
specify `--no-split', `makeinfo' will not split up the output file.
|
||||
|
||||
`--no-pointer-validate'
|
||||
`--no-validate'
|
||||
Suppress the pointer-validation phase of `makeinfo'. Normally,
|
||||
after a Texinfo file is processed, some consistency checks are
|
||||
made to ensure that cross references can be resolved, etc. *Note
|
||||
Pointer Validation::.
|
||||
|
||||
`--no-warn'
|
||||
Suppress the output of warning messages. This does *not* suppress
|
||||
the output of error messages, only warnings. You might want this
|
||||
if the file you are creating has examples of Texinfo cross
|
||||
references within it, and the nodes that are referenced do not
|
||||
actually exist.
|
||||
|
||||
`--no-number-footnotes'
|
||||
Supress automatic footnote numbering. By default, `makeinfo'
|
||||
numbers each footnote sequentially in a single node, resetting the
|
||||
current footnote number to 1 at the start of each node.
|
||||
|
||||
`--output FILE'
|
||||
`-o FILE'
|
||||
Specify that the output should be directed to FILE and not to the
|
||||
file name specified in the `@setfilename' command found in the
|
||||
Texinfo source. FILE can be the special token `-', which specifies
|
||||
standard output.
|
||||
|
||||
`--paragraph-indent INDENT'
|
||||
Set the paragraph indentation style to INDENT. The value set by
|
||||
this option overrides the value set in a Texinfo file by an
|
||||
`@paragraphindent' command. The value of INDENT is interpreted as
|
||||
follows:
|
||||
|
||||
* If the value of INDENT is `asis', do not change the existing
|
||||
indentation at the starts of paragraphs.
|
||||
|
||||
* If the value of INDENT is zero, delete any existing
|
||||
indentation.
|
||||
|
||||
* If the value of INDENT is greater than zero, indent each
|
||||
paragraph by that number of spaces.
|
||||
|
||||
`--reference-limit LIMIT'
|
||||
Set the value of the number of references to a node that
|
||||
`makeinfo' will make without reporting a warning. If a node has
|
||||
more than this number of references in it, `makeinfo' will make the
|
||||
references but also report a warning.
|
||||
|
||||
`-U VAR'
|
||||
Cause VAR to be undefined. This is equivalent to `@clear VAR' in
|
||||
the Texinfo file.
|
||||
|
||||
`--verbose'
|
||||
Cause `makeinfo' to display messages saying what it is doing.
|
||||
Normally, `makeinfo' only outputs messages if there are errors or
|
||||
warnings.
|
||||
|
||||
`--version'
|
||||
Report the version number of this copy of `makeinfo'.
|
||||
|
||||
|
||||
File: makeinfo.info, Node: Pointer Validation, Prev: Options, Up: What is makeinfo
|
||||
|
||||
Pointer Validation
|
||||
==================
|
||||
|
||||
If you do not suppress pointer-validation (by using the
|
||||
`--no-pointer-validation' option), `makeinfo' will check the validity
|
||||
of the final Info file. Mostly, this means ensuring that nodes you
|
||||
have referenced really exist. Here is a complete list of what is
|
||||
checked:
|
||||
|
||||
1. If a `Next', `Previous', or `Up' node reference is a reference to a
|
||||
node in the current file and is not an external reference such as
|
||||
to `(dir)', then the referenced node must exist.
|
||||
|
||||
2. In every node, if the `Previous' node is different from the `Up'
|
||||
node, then the `Previous' node must also be pointed to by a `Next'
|
||||
node.
|
||||
|
||||
3. Every node except the `Top' node must have an `Up' pointer.
|
||||
|
||||
4. The node referenced by an `Up' pointer must contain a reference to
|
||||
the current node in some manner other than through a `Next'
|
||||
reference. This includes menu entries and cross references.
|
||||
|
||||
5. If the `Next' reference of a node is not the same as the `Next'
|
||||
reference of the `Up' reference, then the node referenced by the
|
||||
`Next' pointer must have a `Previous' pointer that points back to
|
||||
the current node. This rule allows the last node in a section to
|
||||
point to the first node of the next chapter.
|
||||
|
||||
|
||||
|
||||
Tag Table:
|
||||
Node: Top949
|
||||
Node: What is makeinfo1215
|
||||
Node: Formatting Control1758
|
||||
Node: Options2377
|
||||
Node: Pointer Validation6743
|
||||
|
||||
End Tag Table
|
1359
gnu/usr.bin/texinfo/info-files/texi-files/info-stnd.texi
Normal file
1359
gnu/usr.bin/texinfo/info-files/texi-files/info-stnd.texi
Normal file
File diff suppressed because it is too large
Load Diff
861
gnu/usr.bin/texinfo/info-files/texi-files/info.texi
Normal file
861
gnu/usr.bin/texinfo/info-files/texi-files/info.texi
Normal file
@ -0,0 +1,861 @@
|
||||
\input texinfo @c -*-texinfo-*-
|
||||
@comment %**start of header
|
||||
@setfilename info.info
|
||||
@settitle Info 1.0
|
||||
@comment %**end of header
|
||||
|
||||
@iftex
|
||||
@finalout
|
||||
@end iftex
|
||||
|
||||
@ifinfo
|
||||
This file describes how to use Info,
|
||||
the on-line, menu-driven GNU documentation system.
|
||||
|
||||
Copyright (C) 1989, 1992 Free Software Foundation, Inc.
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this manual provided the copyright notice and this permission notice
|
||||
are preserved on all copies.
|
||||
|
||||
@ignore
|
||||
Permission is granted to process this file through TeX and print the
|
||||
results, provided the printed document carries copying permission
|
||||
notice identical to this one except for the removal of this paragraph
|
||||
(this paragraph not being relevant to the printed manual).
|
||||
|
||||
@end ignore
|
||||
Permission is granted to copy and distribute modified versions of this
|
||||
manual under the conditions for verbatim copying, provided that the entire
|
||||
resulting derived work is distributed under the terms of a permission
|
||||
notice identical to this one.
|
||||
|
||||
Permission is granted to copy and distribute translations of this manual
|
||||
into another language, under the above conditions for modified versions,
|
||||
except that this permission notice may be stated in a translation approved
|
||||
by the Free Software Foundation.
|
||||
@end ifinfo
|
||||
|
||||
@setchapternewpage odd
|
||||
@titlepage
|
||||
@sp 11
|
||||
@center @titlefont{Info}
|
||||
@sp 2
|
||||
@center The
|
||||
@sp 2
|
||||
@center On-line, Menu-driven
|
||||
@sp 2
|
||||
@center GNU Documentation System
|
||||
|
||||
@page
|
||||
@vskip 0pt plus 1filll
|
||||
Copyright @copyright{} 1989, 1992, 1993 Free Software Foundation, Inc.
|
||||
@sp 2
|
||||
|
||||
Published by the Free Software Foundation @*
|
||||
675 Massachusetts Avenue, @*
|
||||
Cambridge, MA 02139 USA @*
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this manual provided the copyright notice and this permission notice
|
||||
are preserved on all copies.
|
||||
|
||||
Permission is granted to copy and distribute modified versions of this
|
||||
manual under the conditions for verbatim copying, provided that the entire
|
||||
resulting derived work is distributed under the terms of a permission
|
||||
notice identical to this one.
|
||||
|
||||
Permission is granted to copy and distribute translations of this manual
|
||||
into another language, under the above conditions for modified versions,
|
||||
except that this permission notice may be stated in a translation approved
|
||||
by the Free Software Foundation.
|
||||
@end titlepage
|
||||
|
||||
@ifinfo
|
||||
@node Top, Getting Started, (dir), (dir)
|
||||
@top Info: An Introduction
|
||||
|
||||
Info is a program for reading documentation, which you are using now.
|
||||
|
||||
To learn how to use Info, type the command @kbd{h}. It brings you
|
||||
to a programmed instruction sequence.
|
||||
|
||||
@c Need to make sure that `Info-help' goes to the right node,
|
||||
@c which is the first node of the first chapter. (It should.)
|
||||
@c (Info-find-node "info"
|
||||
@c (if (< (window-height) 23)
|
||||
@c "Help-Small-Screen"
|
||||
@c "Help")))
|
||||
|
||||
To learn advanced Info commands, type @kbd{n} twice. This
|
||||
brings you to @cite{Info for Experts}, skipping over the .
|
||||
`Getting Started' chapter.
|
||||
@end ifinfo
|
||||
|
||||
@menu
|
||||
* Getting Started::
|
||||
* Advanced Info::
|
||||
* Create an Info File::
|
||||
@end menu
|
||||
|
||||
@node Getting Started, Advanced Info, Top, Top
|
||||
@comment node-name, next, previous, up
|
||||
@chapter Getting Started
|
||||
|
||||
This first part of the Info manual describes how to get around inside
|
||||
of Info. The second part of the manual describes various advanced
|
||||
Info commands, and how to write an Info as distinct from a Texinfo
|
||||
file. The third part is about how to generate Info files from
|
||||
Texinfo files.
|
||||
|
||||
@iftex
|
||||
This manual is primarily designed for use on a computer, so that you can
|
||||
try Info commands while reading about them. Reading it on paper is less
|
||||
effective, since you must take it on faith that the commands described
|
||||
really do what the manual says. By all means go through this manual now
|
||||
that you have it; but please try going through the on-line version as
|
||||
well.
|
||||
|
||||
There are two ways of looking at the online version of this manual:
|
||||
|
||||
@enumerate
|
||||
@item
|
||||
Type @code{info} at your shell's command line. This approach uses a
|
||||
small stand-alone program designed just to read Info files.
|
||||
|
||||
@item
|
||||
Type @code{emacs} at the command line; then type @kbd{C-h i} (Control
|
||||
@kbd{h}, followed by @kbd{i}). This approach uses
|
||||
the Info mode of the Emacs program, an editor with many other
|
||||
capabilities.
|
||||
@end enumerate
|
||||
|
||||
In either case, then type @kbd{mInfo} (just the letters), followed by
|
||||
@key{RET}---the ``Return'' or ``Enter'' key. At this point, you should
|
||||
be ready to follow the instructions in this manual as you read them on
|
||||
the screen.
|
||||
@c FIXME! (pesch@cygnus.com, 14 dec 1992)
|
||||
@c Is it worth worrying about what-if the beginner goes to somebody
|
||||
@c else's Emacs session, which already has an Info running in the middle
|
||||
@c of something---in which case these simple instructions won't work?
|
||||
@end iftex
|
||||
|
||||
@menu
|
||||
* Help-Small-Screen:: Starting Info on a Small Screen
|
||||
* Help:: How to use Info
|
||||
* Help-P:: Returning to the Previous node
|
||||
* Help-^L:: The Space, Rubout, B and ^L commands.
|
||||
* Help-M:: Menus
|
||||
* Help-Adv:: Some advanced Info commands
|
||||
* Help-Q:: Quitting Info
|
||||
@end menu
|
||||
|
||||
@node Help-Small-Screen, Help, , Getting Started
|
||||
@comment node-name, next, previous, up
|
||||
@section Starting Info on a Small Screen
|
||||
|
||||
@iftex
|
||||
(In Info, you only see this section if your terminal has a small
|
||||
number of lines; most readers pass by it without seeing it.)
|
||||
@end iftex
|
||||
|
||||
Since your terminal has an unusually small number of lines on its
|
||||
screen, it is necessary to give you special advice at the beginning.
|
||||
|
||||
If you see the text @samp{--All----} at near the bottom right corner
|
||||
of the screen, it means the entire text you are looking at fits on the
|
||||
screen. If you see @samp{--Top----} instead, it means that there is
|
||||
more text below that does not fit. To move forward through the text
|
||||
and see another screen full, press the Space bar, @key{SPC}. To move
|
||||
back up, press the key labeled @samp{Rubout} or @samp{Delete} or
|
||||
@key{DEL}.
|
||||
|
||||
@ifinfo
|
||||
Here are 40 lines of junk, so you can try @key{SPC} and @key{DEL} and
|
||||
see what they do. At the end are instructions of what you should do
|
||||
next.
|
||||
|
||||
This is line 17 @*
|
||||
This is line 18 @*
|
||||
This is line 19 @*
|
||||
This is line 20 @*
|
||||
This is line 21 @*
|
||||
This is line 22 @*
|
||||
This is line 23 @*
|
||||
This is line 24 @*
|
||||
This is line 25 @*
|
||||
This is line 26 @*
|
||||
This is line 27 @*
|
||||
This is line 28 @*
|
||||
This is line 29 @*
|
||||
This is line 30 @*
|
||||
This is line 31 @*
|
||||
This is line 32 @*
|
||||
This is line 33 @*
|
||||
This is line 34 @*
|
||||
This is line 35 @*
|
||||
This is line 36 @*
|
||||
This is line 37 @*
|
||||
This is line 38 @*
|
||||
This is line 39 @*
|
||||
This is line 40 @*
|
||||
This is line 41 @*
|
||||
This is line 42 @*
|
||||
This is line 43 @*
|
||||
This is line 44 @*
|
||||
This is line 45 @*
|
||||
This is line 46 @*
|
||||
This is line 47 @*
|
||||
This is line 48 @*
|
||||
This is line 49 @*
|
||||
This is line 50 @*
|
||||
This is line 51 @*
|
||||
This is line 52 @*
|
||||
This is line 53 @*
|
||||
This is line 54 @*
|
||||
This is line 55 @*
|
||||
This is line 56 @*
|
||||
|
||||
If you have managed to get here, go back to the beginning with
|
||||
@key{DEL}, and come back here again, then you understand @key{SPC} and
|
||||
@key{DEL}. So now type an @kbd{n}---just one character; do not type
|
||||
the quotes and do not type the Return key, @key{RET}, afterward---to
|
||||
get to the normal start of the course.
|
||||
@end ifinfo
|
||||
|
||||
@node Help, Help-P, Help-Small-Screen, Getting Started
|
||||
@comment node-name, next, previous, up
|
||||
@section How to use Info
|
||||
|
||||
You are talking to the program Info, for reading documentation.
|
||||
|
||||
Right now you are looking at one @dfn{Node} of Information.
|
||||
A node contains text describing a specific topic at a specific
|
||||
level of detail. This node's topic is ``how to use Info''.
|
||||
|
||||
The top line of a node is its @dfn{header}. This node's header (look at
|
||||
it now) says that it is the node named @samp{Help} in the file
|
||||
@file{info}. It says that the @samp{Next} node after this one is the node
|
||||
called @samp{Help-P}. An advanced Info command lets you go to any node
|
||||
whose name you know.
|
||||
|
||||
Besides a @samp{Next}, a node can have a @samp{Previous} or an @samp{Up}.
|
||||
This node has a @samp{Previous} but no @samp{Up}, as you can see.
|
||||
|
||||
Now it is time to move on to the @samp{Next} node, named @samp{Help-P}.
|
||||
|
||||
>> Type @samp{n} to move there. Type just one character;
|
||||
do not type the quotes and do not type a @key{RET} afterward.
|
||||
|
||||
@samp{>>} in the margin means it is really time to try a command.
|
||||
|
||||
@node Help-P, Help-^L, Help, Getting Started
|
||||
@comment node-name, next, previous, up
|
||||
@section Returning to the Previous node
|
||||
|
||||
This node is called @samp{Help-P}. The @samp{Previous} node, as you see,
|
||||
is @samp{Help}, which is the one you just came from using the @kbd{n}
|
||||
command. Another @kbd{n} command now would take you to the next
|
||||
node, @samp{Help-^L}.
|
||||
|
||||
>> But do not do that yet. First, try the @kbd{p} command, which takes
|
||||
you to the @samp{Previous} node. When you get there, you can do an
|
||||
@kbd{n} again to return here.
|
||||
|
||||
This all probably seems insultingly simple so far, but @emph{do not} be
|
||||
led into skimming. Things will get more complicated soon. Also,
|
||||
do not try a new command until you are told it is time to. Otherwise,
|
||||
you may make Info skip past an important warning that was coming up.
|
||||
|
||||
>> Now do an @kbd{n} to get to the node @samp{Help-^L} and learn more.
|
||||
|
||||
@node Help-^L, Help-M, Help-P, Getting Started
|
||||
@comment node-name, next, previous, up
|
||||
@section The Space, Rubout, B and ^L commands.
|
||||
|
||||
This node's header tells you that you are now at node @samp{Help-^L}, and
|
||||
that @kbd{p} would get you back to @samp{Help-P}. The node's title is
|
||||
underlined; it says what the node is about (most nodes have titles).
|
||||
|
||||
This is a big node and it does not all fit on your display screen.
|
||||
You can tell that there is more that is not visible because you
|
||||
can see the string @samp{--Top-----} rather than @samp{--All----} near
|
||||
the bottom right corner of the screen.
|
||||
|
||||
The @key{SPC}, @key{DEL} and @kbd{b} commands exist to allow you to ``move
|
||||
around'' in a node that does not all fit on the screen at once.
|
||||
@key{SPC} moves forward, to show what was below the bottom of the screen.
|
||||
@key{DEL} moves backward, to show what was above the top of the screen
|
||||
(there is not anything above the top until you have typed some spaces).
|
||||
|
||||
>> Now try typing a @key{SPC} (afterward, type a @key{DEL} to return here).
|
||||
|
||||
When you type the @key{SPC}, the two lines that were at the bottom
|
||||
of the screen appear at the top, followed by more lines. @key{DEL}
|
||||
takes the two lines from the top and moves them to the bottom,
|
||||
@emph{usually}, but if there are not a full screen's worth of lines above
|
||||
them they may not make it all the way to the bottom.
|
||||
|
||||
If you type a @key{SPC} when there is no more to see, it rings the
|
||||
bell and otherwise does nothing. The same goes for a @key{DEL} when
|
||||
the header of the node is visible.
|
||||
|
||||
If your screen is ever garbaged, you can tell Info to print it out
|
||||
again by typing @kbd{C-l} (@kbd{Control-L}, that is---hold down ``Control'' and
|
||||
type an @key{L} or @kbd{l}).
|
||||
|
||||
>> Type @kbd{C-l} now.
|
||||
|
||||
To move back to the beginning of the node you are on, you can type
|
||||
a lot of @key{DEL}s. You can also type simply @kbd{b} for beginning.
|
||||
|
||||
>> Try that now. (I have put in enough verbiage to make sure you are
|
||||
not on the first screenful now). Then come back, typing @key{SPC}
|
||||
several times.
|
||||
|
||||
You have just learned a considerable number of commands. If you
|
||||
want to use one but have trouble remembering which, you should type
|
||||
a @key{?} which prints out a brief list of commands. When you are
|
||||
finished looking at the list, make it go away by typing a @key{SPC}.
|
||||
|
||||
>> Type a @key{?} now. After it finishes, type a @key{SPC}.
|
||||
|
||||
(If you are using the standalone Info reader, type `l' to return here.)
|
||||
|
||||
From now on, you will encounter large nodes without warning, and
|
||||
will be expected to know how to use @key{SPC} and @key{DEL} to move
|
||||
around in them without being told. Since not all terminals have
|
||||
the same size screen, it would be impossible to warn you anyway.
|
||||
|
||||
>> Now type @kbd{n} to see the description of the @kbd{m} command.
|
||||
|
||||
@node Help-M, Help-Adv, Help-^L, Getting Started
|
||||
@comment node-name, next, previous, up
|
||||
@section Menus
|
||||
|
||||
Menus and the @kbd{m} command
|
||||
|
||||
With only the @kbd{n} and @kbd{p} commands for moving between nodes, nodes
|
||||
are restricted to a linear sequence. Menus allow a branching
|
||||
structure. A menu is a list of other nodes you can move to. It is
|
||||
actually just part of the text of the node formatted specially so that
|
||||
Info can interpret it. The beginning of a menu is always identified
|
||||
by a line which starts with @samp{* Menu:}. A node contains a menu if and
|
||||
only if it has a line in it which starts that way. The only menu you
|
||||
can use at any moment is the one in the node you are in. To use a
|
||||
menu in any other node, you must move to that node first.
|
||||
|
||||
After the start of the menu, each line that starts with a @samp{*}
|
||||
identifies one subtopic. The line usually contains a brief name
|
||||
for the subtopic (followed by a @samp{:}), the name of the node that talks
|
||||
about that subtopic, and optionally some further description of the
|
||||
subtopic. Lines in the menu that do not start with a @samp{*} have no
|
||||
special meaning---they are only for the human reader's benefit and do
|
||||
not define additional subtopics. Here is an example:
|
||||
|
||||
@example
|
||||
* Foo: FOO's Node This tells about FOO
|
||||
@end example
|
||||
|
||||
The subtopic name is Foo, and the node describing it is @samp{FOO's Node}.
|
||||
The rest of the line is just for the reader's Information.
|
||||
[[ But this line is not a real menu item, simply because there is
|
||||
no line above it which starts with @samp{* Menu:}.]]
|
||||
|
||||
When you use a menu to go to another node (in a way that will be
|
||||
described soon), what you specify is the subtopic name, the first
|
||||
thing in the menu line. Info uses it to find the menu line, extracts
|
||||
the node name from it, and goes to that node. The reason that there
|
||||
is both a subtopic name and a node name is that the node name must be
|
||||
meaningful to the computer and may therefore have to be ugly looking.
|
||||
The subtopic name can be chosen just to be convenient for the user to
|
||||
specify. Often the node name is convenient for the user to specify
|
||||
and so both it and the subtopic name are the same. There is an
|
||||
abbreviation for this:
|
||||
|
||||
@example
|
||||
* Foo:: This tells about FOO
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
This means that the subtopic name and node name are the same; they are
|
||||
both @samp{Foo}.
|
||||
|
||||
>> Now use @key{SPC}s to find the menu in this node, then come back to
|
||||
the front with a @kbd{b}. As you see, a menu is actually visible in
|
||||
its node. If you cannot find a menu in a node by looking at it,
|
||||
then the node does not have a menu and the @kbd{m} command is not
|
||||
available.
|
||||
|
||||
The command to go to one of the subnodes is @kbd{m}---but @emph{do not do it
|
||||
yet!} Before you use @kbd{m}, you must understand the difference between
|
||||
commands and arguments. So far, you have learned several commands
|
||||
that do not need arguments. When you type one, Info processes it and
|
||||
is instantly ready for another command. The @kbd{m} command is different:
|
||||
it is incomplete without the @dfn{name of the subtopic}. Once you have
|
||||
typed @kbd{m}, Info tries to read the subtopic name.
|
||||
|
||||
Now look for the line containing many dashes near the bottom of the
|
||||
screen. There is one more line beneath that one, but usually it is
|
||||
blank If it is empty, Info is ready for a command, such as @kbd{n} or @kbd{b}
|
||||
or @key{SPC} or @kbd{m}. If that line contains text ending in a colon, it
|
||||
mean Info is trying to read the @dfn{argument} to a command. At such
|
||||
times, commands do not work, because Info tries to use them as the
|
||||
argument. You must either type the argument and finish the command
|
||||
you started, or type @kbd{Control-g} to cancel the command. When you have
|
||||
done one of those things, the line becomes blank again.
|
||||
|
||||
The command to go to a subnode via a menu is @kbd{m}. After you type
|
||||
the @kbd{m}, the line at the bottom of the screen says @samp{Menu item: }.
|
||||
You must then type the name of the subtopic you want, and end it with
|
||||
a @key{RET}.
|
||||
|
||||
You can abbreviate the subtopic name. If the abbreviation is not
|
||||
unique, the first matching subtopic is chosen. Some menus put
|
||||
the shortest possible abbreviation for each subtopic name in capital
|
||||
letters, so you can see how much you need to type. It does not
|
||||
matter whether you use upper case or lower case when you type the
|
||||
subtopic. You should not put any spaces at the end, or inside of the
|
||||
item name, except for one space where a space appears in the item in
|
||||
the menu.
|
||||
|
||||
Here is a menu to give you a chance to practice.
|
||||
|
||||
* Menu: The menu starts here.
|
||||
|
||||
This menu givs you three ways of going to one place, Help-FOO.
|
||||
|
||||
* Foo: Help-FOO. A node you can visit for fun.@*
|
||||
* Bar: Help-FOO. Strange! two ways to get to the same place.@*
|
||||
* Help-FOO:: And yet another!@*
|
||||
|
||||
|
||||
>> Now type just an @kbd{m} and see what happens:
|
||||
|
||||
Now you are ``inside'' an @kbd{m} command. Commands cannot be used
|
||||
now; the next thing you will type must be the name of a subtopic.
|
||||
|
||||
You can change your mind about doing the @kbd{m} by typing Control-g.
|
||||
|
||||
>> Try that now; notice the bottom line clear.
|
||||
|
||||
>> Then type another @kbd{m}.
|
||||
|
||||
>> Now type @samp{BAR} item name. Do not type @key{RET} yet.
|
||||
|
||||
While you are typing the item name, you can use the @key{DEL}
|
||||
character to cancel one character at a time if you make a mistake.
|
||||
|
||||
>> Type one to cancel the @samp{R}. You could type another @samp{R} to
|
||||
replace it. You do not have to, since @samp{BA} is a valid abbreviation.
|
||||
|
||||
>> Now you are ready to go. Type a @key{RET}.
|
||||
|
||||
After visiting Help-FOO, you should return here.
|
||||
|
||||
>> Type @kbd{n} to see more commands.
|
||||
|
||||
@c If a menu appears at the end of this node, remove it.
|
||||
@c It is an accident of the menu updating command.
|
||||
|
||||
Here is another way to get to Help-FOO, a menu. You can ignore this
|
||||
if you want, or else try it (but then please come back to here).
|
||||
|
||||
@menu
|
||||
* Help-FOO::
|
||||
@end menu
|
||||
|
||||
@node Help-FOO, , , Help-M
|
||||
@comment node-name, next, previous, up
|
||||
@subsection The @kbd{u} command
|
||||
|
||||
Congratulations! This is the node @samp{Help-FOO}. Unlike the other
|
||||
nodes you have seen, this one has an @samp{Up}: @samp{Help-M}, the node you
|
||||
just came from via the @kbd{m} command. This is the usual
|
||||
convention---the nodes you reach from a menu have @samp{Up} nodes that lead
|
||||
back to the menu. Menus move Down in the tree, and @samp{Up} moves Up.
|
||||
@samp{Previous}, on the other hand, is usually used to ``stay on the same
|
||||
level but go backwards''
|
||||
|
||||
You can go back to the node @samp{Help-M} by typing the command
|
||||
@kbd{u} for ``Up''. That puts you at the @emph{front} of the
|
||||
node---to get back to where you were reading you have to type
|
||||
some @key{SPC}s.
|
||||
|
||||
>> Now type @kbd{u} to move back up to @samp{Help-M}.
|
||||
|
||||
@node Help-Adv, Help-Q, Help-M, Getting Started
|
||||
@comment node-name, next, previous, up
|
||||
@section Some advanced Info commands
|
||||
|
||||
The course is almost over, so please stick with it to the end.
|
||||
|
||||
If you have been moving around to different nodes and wish to
|
||||
retrace your steps, the @kbd{l} command (@kbd{l} for @dfn{last}) will
|
||||
do that, one node at a time. If you have been following directions,
|
||||
an @kbd{l} command now will get you back to @samp{Help-M}. Another
|
||||
@kbd{l} command would undo the @kbd{u} and get you back to
|
||||
@samp{Help-FOO}. Another @kbd{l} would undo the @kbd{m} and get you
|
||||
back to @samp{Help-M}.
|
||||
|
||||
>> Try typing three @kbd{l}'s, pausing in between to see what each
|
||||
@kbd{l} does.
|
||||
|
||||
Then follow directions again and you will end up back here.
|
||||
|
||||
Note the difference between @kbd{l} and @kbd{p}: @kbd{l} moves to
|
||||
where @emph{you} last were, whereas @kbd{p} always moves to the node
|
||||
which the header says is the @samp{Previous} node (from this node, to
|
||||
@samp{Help-M}).
|
||||
|
||||
The @samp{d} command gets you instantly to the Directory node.
|
||||
This node, which is the first one you saw when you entered Info,
|
||||
has a menu which leads (directly, or indirectly through other menus),
|
||||
to all the nodes that exist.
|
||||
|
||||
>> Try doing a @samp{d}, then do an @kbd{l} to return here (yes,
|
||||
@emph{do} return).
|
||||
|
||||
Sometimes, in Info documentation, you will see a cross reference.
|
||||
Cross references look like this: @xref{Help-Cross, Cross}. That is a
|
||||
real, live cross reference which is named @samp{Cross} and points at
|
||||
the node named @samp{Help-Cross}.
|
||||
|
||||
If you wish to follow a cross reference, you must use the @samp{f}
|
||||
command. The @samp{f} must be followed by the cross reference name
|
||||
(in this case, @samp{Cross}). You can use @key{DEL} to edit the name,
|
||||
and if you change your mind about following any reference you can use
|
||||
@kbd{Control-g} to cancel the command.
|
||||
|
||||
Completion is available in the @samp{f} command; you can complete among
|
||||
all the cross reference names in the current node.
|
||||
|
||||
>> Type @samp{f}, followed by @samp{Cross}, and a @key{RET}.
|
||||
|
||||
To get a list of all the cross references in the current node, you can
|
||||
type @kbd{?} after an @samp{f}. The @samp{f} continues to await a
|
||||
cross reference name even after printing the list, so if you do not
|
||||
actually want to follow a reference you should type a @kbd{Control-g}
|
||||
to cancel the @samp{f}.
|
||||
|
||||
>> Type "f?" to get a list of the footnotes in this node. Then type a
|
||||
@kbd{Control-g} and see how the @samp{f} gives up.
|
||||
|
||||
>> Now type @kbd{n} to see the last node of the course.
|
||||
|
||||
@c If a menu appears at the end of this node, remove it.
|
||||
@c It is an accident of the menu updating command.
|
||||
|
||||
@node Help-Cross, , , Help-Adv
|
||||
@comment node-name, next, previous, up
|
||||
@unnumberedsubsec The node reached by the cross reference in Info
|
||||
|
||||
This is the node reached by the cross reference named @samp{Cross}.
|
||||
|
||||
While this node is specifically intended to be reached by a cross
|
||||
reference, most cross references lead to nodes that ``belong''
|
||||
someplace else far away in the structure of Info. So you cannot expect
|
||||
the footnote to have a @samp{Next}, @samp{Previous} or @samp{Up} pointing back to
|
||||
where you came from. In general, the @kbd{l} (el) command is the only
|
||||
way to get back there.
|
||||
|
||||
>> Type @kbd{l} to return to the node where the cross reference was.
|
||||
|
||||
@node Help-Q, , Help-Adv, Getting Started
|
||||
@comment node-name, next, previous, up
|
||||
@section Quitting Info
|
||||
|
||||
To get out of Info, back to what you were doing before, type @kbd{q}
|
||||
for @dfn{Quit}.
|
||||
|
||||
This is the end of the course on using Info. There are some other
|
||||
commands that are not essential or are meant for experienced users;
|
||||
they are useful, and you can find them by looking in the directory for
|
||||
documentation on Info. Finding them will be a good exercise in using
|
||||
Info in the usual manner.
|
||||
|
||||
>> Type @samp{d} to go to the Info directory node; then type
|
||||
@samp{mInfo} and @key{RET}, to get to the node about Info
|
||||
and see what other help is available.
|
||||
|
||||
@node Advanced Info, Create an Info File, Getting Started, Top
|
||||
@comment node-name, next, previous, up
|
||||
@chapter Info for Experts
|
||||
|
||||
This chapter describes various advanced Info commands, and how to write
|
||||
an Info as distinct from a Texinfo file. (However, in most cases, writing a
|
||||
Texinfo file is better, since you can use it @emph{both} to generate an
|
||||
Info file and to make a printed manual. @xref{Top,, Overview of
|
||||
Texinfo, texinfo, Texinfo: The GNU Documentation Format}.)
|
||||
|
||||
@menu
|
||||
* Expert:: Advanced Info commands: g, s, e, and 1 - 5.
|
||||
* Add:: Describes how to add new nodes to the hierarchy.
|
||||
Also tells what nodes look like.
|
||||
* Menus:: How to add to or create menus in Info nodes.
|
||||
* Cross-refs:: How to add cross-references to Info nodes.
|
||||
* Tags:: How to make tag tables for Info files.
|
||||
* Checking:: Checking an Info File
|
||||
@end menu
|
||||
|
||||
@node Expert, Add, , Advanced Info
|
||||
@comment node-name, next, previous, up
|
||||
@section Advanced Info Commands
|
||||
|
||||
@kbd{g}, @kbd{s}, @kbd{1}, -- @kbd{5}, and @kbd{e}
|
||||
|
||||
If you know a node's name, you can go there by typing @kbd{g}, the
|
||||
name, and @key{RET}. Thus, @kbd{gTop@key{RET}} would go to the node
|
||||
called @samp{Top} in this file (its directory node).
|
||||
@kbd{gExpert@key{RET}} would come back here.
|
||||
|
||||
Unlike @kbd{m}, @kbd{g} does not allow the use of abbreviations.
|
||||
|
||||
To go to a node in another file, you can include the filename in the
|
||||
node name by putting it at the front, in parentheses. Thus,
|
||||
@kbd{g(dir)Top@key{RET}} would go to the Info Directory node, which is
|
||||
node @samp{Top} in the file @file{dir}.
|
||||
|
||||
The node name @samp{*} specifies the whole file. So you can look at
|
||||
all of the current file by typing @kbd{g*@key{RET}} or all of any
|
||||
other file with @kbd{g(FILENAME)@key{RET}}.
|
||||
|
||||
The @kbd{s} command allows you to search a whole file for a string.
|
||||
It switches to the next node if and when that is necessary. You
|
||||
type @kbd{s} followed by the string to search for, terminated by
|
||||
@key{RET}. To search for the same string again, just @kbd{s} followed
|
||||
by @key{RET} will do. The file's nodes are scanned in the order
|
||||
they are in in the file, which has no necessary relationship to the
|
||||
order that they may be in in the tree structure of menus and @samp{next} pointers.
|
||||
But normally the two orders are not very different. In any case,
|
||||
you can always do a @kbd{b} to find out what node you have reached, if
|
||||
the header is not visible (this can happen, because @kbd{s} puts your
|
||||
cursor at the occurrence of the string, not at the beginning of the
|
||||
node).
|
||||
|
||||
If you grudge the system each character of type-in it requires, you
|
||||
might like to use the commands @kbd{1}, @kbd{2}, @kbd{3}, @kbd{4}, and
|
||||
@kbd{5}. They are short for the @kbd{m} command together with an
|
||||
argument. "1", "2", "3", "4", and "5". @kbd{1} goes through the
|
||||
first item in the current node's menu; @kbd{2} goes through the second
|
||||
item, etc. Note that numbers larger than 5 are not allowed. If the
|
||||
item you want is that far down, you are better off using an
|
||||
abbreviation for its name than counting.
|
||||
|
||||
The Info command @kbd{e} changes from Info mode to an ordinary
|
||||
Emacs editing mode, so that you can edit the text of the current node.
|
||||
Type @kbd{C-c C-c} to switch back to Info. The @kbd{e} command is allowed
|
||||
only if the variable @code{Info-enable-edit} is non-@code{nil}.
|
||||
|
||||
@node Add, Menus, Expert, Advanced Info
|
||||
@comment node-name, next, previous, up
|
||||
@section Adding a new node to Info
|
||||
|
||||
To add a new topic to the list in the directory, you must:
|
||||
|
||||
@enumerate
|
||||
@item
|
||||
Create a node, in some file, to document that topic.
|
||||
|
||||
@item
|
||||
Put that topic in the menu in the directory. @xref{Menus, Menu}.
|
||||
@end enumerate
|
||||
|
||||
The new node can live in an existing documentation file, or in a new
|
||||
one. It must have a @key{^_} character before it (invisible to the
|
||||
user; this node has one but you cannot see it), and it ends with either
|
||||
a @key{^_}, a @key{^L}, or the end of file. Note: If you put in a
|
||||
@key{^L} to end a new node, be sure that there is a @key{^_} after it
|
||||
to start the next one, since @key{^L} cannot @emph{start} a node.
|
||||
Also, a nicer way to make a node boundary be a page boundary as well
|
||||
is to put a @key{^L} @emph{right after} the @key{^_}.
|
||||
|
||||
The @key{^_} starting a node must be followed by a newline or a
|
||||
@key{^L} newline, after which comes the node's header line. The
|
||||
header line must give the node's name (by which Info finds it),
|
||||
and state the names of the @samp{Next}, @samp{Previous}, and @samp{Up} nodes (if
|
||||
there are any). As you can see, this node's @samp{Up} node is the node
|
||||
@samp{Top}, which points at all the documentation for Info. The @samp{Next}
|
||||
node is @samp{Menus}.
|
||||
|
||||
The keywords @dfn{Node}, @dfn{Previous}, @dfn{Up} and @dfn{Next},
|
||||
may appear in any order, anywhere in the header line, but the
|
||||
recommended order is the one in this sentence. Each keyword must be
|
||||
followed by a colon, spaces and tabs, and then the appropriate name.
|
||||
The name may be terminated with a tab, a comma, or a newline. A space
|
||||
does not end it; node names may contain spaces. The case of letters
|
||||
in the names is insignificant.
|
||||
|
||||
A node name has two forms. A node in the current file is named by
|
||||
what appears after the @samp{Node: } in that node's first line. For
|
||||
example, this node's name is @samp{Add}. A node in another file is
|
||||
named by @samp{(@var{filename})@var{node-within-file}}, as in
|
||||
@samp{(info)Add} for this node. If the file name is relative, it is
|
||||
taken starting from the standard Info file directory of your site.
|
||||
The name @samp{(@var{filename})Top} can be abbreviated to just
|
||||
@samp{(@var{filename})}. By convention, the name @samp{Top} is used for
|
||||
the ``highest'' node in any single file---the node whose @samp{Up} points
|
||||
out of the file. The Directory node is @file{(dir)}. The @samp{Top} node
|
||||
of a document file listed in the Directory should have an @samp{Up:
|
||||
(dir)} in it.
|
||||
|
||||
The node name @kbd{*} is special: it refers to the entire file.
|
||||
Thus, @kbd{g*} shows you the whole current file. The use of the
|
||||
node @kbd{*} is to make it possible to make old-fashioned,
|
||||
unstructured files into nodes of the tree.
|
||||
|
||||
The @samp{Node:} name, in which a node states its own name, must not
|
||||
contain a filename, since Info when searching for a node does not
|
||||
expect one to be there. The @samp{Next}, @samp{Previous} and @samp{Up} names may
|
||||
contain them. In this node, since the @samp{Up} node is in the same file,
|
||||
it was not necessary to use one.
|
||||
|
||||
Note that the nodes in this file have a file name in the header
|
||||
line. The file names are ignored by Info, but they serve as comments
|
||||
to help identify the node for the user.
|
||||
|
||||
@node Menus, Cross-refs, Add, Advanced Info
|
||||
@comment node-name, next, previous, up
|
||||
@section How to Create Menus
|
||||
|
||||
Any node in the Info hierarchy may have a @dfn{menu}---a list of subnodes.
|
||||
The @kbd{m} command searches the current node's menu for the topic which it
|
||||
reads from the terminal.
|
||||
|
||||
A menu begins with a line starting with @samp{* Menu:}. The rest of the
|
||||
line is a comment. After the starting line, every line that begins
|
||||
with a @samp{* } lists a single topic. The name of the topic--the
|
||||
argument that the user must give to the @kbd{m} command to select this
|
||||
topic---comes right after the star and space, and is followed by a
|
||||
colon, spaces and tabs, and the name of the node which discusses that
|
||||
topic. The node name, like node names following @samp{Next}, @samp{Previous}
|
||||
and @samp{Up}, may be terminated with a tab, comma, or newline; it may also
|
||||
be terminated with a period.
|
||||
|
||||
If the node name and topic name are the same, than rather than
|
||||
giving the name twice, the abbreviation @samp{* NAME::} may be used
|
||||
(and should be used, whenever possible, as it reduces the visual
|
||||
clutter in the menu).
|
||||
|
||||
It is considerate to choose the topic names so that they differ
|
||||
from each other very near the beginning---this allows the user to type
|
||||
short abbreviations. In a long menu, it is a good idea to capitalize
|
||||
the beginning of each item name which is the minimum acceptable
|
||||
abbreviation for it (a long menu is more than 5 or so entries).
|
||||
|
||||
The nodes listed in a node's menu are called its ``subnodes'', and
|
||||
it is their ``superior''. They should each have an @samp{Up:} pointing at
|
||||
the superior. It is often useful to arrange all or most of the
|
||||
subnodes in a sequence of @samp{Next} and @samp{Previous} pointers so that someone who
|
||||
wants to see them all need not keep revisiting the Menu.
|
||||
|
||||
The Info Directory is simply the menu of the node @samp{(dir)Top}---that
|
||||
is, node @samp{Top} in file @file{.../info/dir}. You can put new entries
|
||||
in that menu just like any other menu. The Info Directory is @emph{not} the
|
||||
same as the file directory called @file{info}. It happens that many of
|
||||
Info's files live on that file directory, but they do not have to; and
|
||||
files on that directory are not automatically listed in the Info
|
||||
Directory node.
|
||||
|
||||
Also, although the Info node graph is claimed to be a ``hierarchy'',
|
||||
in fact it can be @emph{any} directed graph. Shared structures and
|
||||
pointer cycles are perfectly possible, and can be used if they are
|
||||
appropriate to the meaning to be expressed. There is no need for all
|
||||
the nodes in a file to form a connected structure. In fact, this file
|
||||
has two connected components. You are in one of them, which is under
|
||||
the node @samp{Top}; the other contains the node @samp{Help} which the
|
||||
@kbd{h} command goes to. In fact, since there is no garbage
|
||||
collector, nothing terrible happens if a substructure is not pointed
|
||||
to, but such a substructure is rather useless since nobody can
|
||||
ever find out that it exists.
|
||||
|
||||
@node Cross-refs, Tags, Menus, Advanced Info
|
||||
@comment node-name, next, previous, up
|
||||
@section Creating Cross References
|
||||
|
||||
A cross reference can be placed anywhere in the text, unlike a menu
|
||||
item which must go at the front of a line. A cross reference looks
|
||||
like a menu item except that it has @samp{*note} instead of @kbd{*}.
|
||||
It @emph{cannot} be terminated by a @samp{)}, because @samp{)}'s are
|
||||
so often part of node names. If you wish to enclose a cross reference
|
||||
in parentheses, terminate it with a period first. Here are two
|
||||
examples of cross references pointers:
|
||||
|
||||
@example
|
||||
*Note details: commands. (See *note 3: Full Proof.)
|
||||
@end example
|
||||
|
||||
They are just examples. The places they ``lead to'' do not really exist!
|
||||
|
||||
@node Tags, Checking, Cross-refs, Advanced Info
|
||||
@comment node-name, next, previous, up
|
||||
@section Tag Tables for Info Files
|
||||
|
||||
You can speed up the access to nodes of a large Info file by giving
|
||||
it a tag table. Unlike the tag table for a program, the tag table for
|
||||
an Info file lives inside the file itself and is used
|
||||
automatically whenever Info reads in the file.
|
||||
|
||||
To make a tag table, go to a node in the file using Emacs Info mode and type
|
||||
@kbd{M-x Info-tagify}. Then you must use @kbd{C-x C-s} to save the
|
||||
file.
|
||||
|
||||
Once the Info file has a tag table, you must make certain it is up
|
||||
to date. If, as a result of deletion of text, any node moves back
|
||||
more than a thousand characters in the file from the position
|
||||
recorded in the tag table, Info will no longer be able to find that
|
||||
node. To update the tag table, use the @code{Info-tagify} command again.
|
||||
|
||||
An Info file tag table appears at the end of the file and looks like
|
||||
this:
|
||||
|
||||
@example
|
||||
^_
|
||||
Tag Table:
|
||||
File: info, Node: Cross-refs^?21419
|
||||
File: info, Node: Tags^?22145
|
||||
^_
|
||||
End Tag Table
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
Note that it contains one line per node, and this line contains
|
||||
the beginning of the node's header (ending just after the node name),
|
||||
a @key{DEL} character, and the character position in the file of the
|
||||
beginning of the node.
|
||||
|
||||
@node Checking, , Tags, Advanced Info
|
||||
@comment node-name, next, previous, up
|
||||
@section Checking an Info File
|
||||
|
||||
When creating an Info file, it is easy to forget the name of a node
|
||||
when you are making a pointer to it from another node. If you put in
|
||||
the wrong name for a node, this is not detected until someone
|
||||
tries to go through the pointer using Info. Verification of the Info
|
||||
file is an automatic process which checks all pointers to nodes and
|
||||
reports any pointers which are invalid. Every @samp{Next}, @samp{Previous}, and
|
||||
@samp{Up} is checked, as is every menu item and every cross reference. In
|
||||
addition, any @samp{Next} which does not have a @samp{Previous} pointing back is
|
||||
reported. Only pointers within the file are checked, because checking
|
||||
pointers to other files would be terribly slow. But those are usually
|
||||
few.
|
||||
|
||||
To check an Info file, do @kbd{M-x Info-validate} while looking at
|
||||
any node of the file with Emacs Info mode.
|
||||
|
||||
@node Create an Info File, , Advanced Info, Top
|
||||
@comment node-name, next, previous, up
|
||||
@chapter Creating an Info File from a Makeinfo file
|
||||
|
||||
@code{makeinfo} is a utility that converts a Texinfo file into an Info
|
||||
file; @code{texinfo-format-region} and @code{texinfo-format-buffer} are
|
||||
GNU Emacs functions that do the same.
|
||||
|
||||
@xref{Create an Info File, , Creating an Info File, texinfo, the Texinfo
|
||||
Manual}, to learn how to create an Info file from a Texinfo file.
|
||||
|
||||
@xref{Top,, Overview of Texinfo, texinfo, Texinfo: The GNU Documentation
|
||||
Format}, to learn how to write a Texinfo file.
|
||||
|
||||
@bye
|
||||
|
285
gnu/usr.bin/texinfo/info-files/texi-files/makeinfo.texi
Normal file
285
gnu/usr.bin/texinfo/info-files/texi-files/makeinfo.texi
Normal file
@ -0,0 +1,285 @@
|
||||
\input texinfo @c -*-texinfo-*-
|
||||
@comment %**start of header
|
||||
@setfilename makeinfo.info
|
||||
@set VERSION 1.51
|
||||
@paragraphindent none
|
||||
@comment %**start of header
|
||||
|
||||
@ifinfo
|
||||
This file is an extract from the @cite{Texinfo} manual.@*
|
||||
It documents @code{makeinfo}, a program that converts Texinfo
|
||||
files into Info files.
|
||||
|
||||
Copyright (C) 1992, 1993 Free Software Foundation, Inc.
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this manual provided the copyright notice and this permission notice
|
||||
are preserved on all copies.
|
||||
|
||||
@ignore
|
||||
Permission is granted to process this file through TeX and print the
|
||||
results, provided the printed document carries copying permission
|
||||
notice identical to this one except for the removal of this paragraph
|
||||
(this paragraph not being relevant to the printed manual).
|
||||
|
||||
@end ignore
|
||||
Permission is granted to copy and distribute modified versions of this
|
||||
manual under the conditions for verbatim copying, provided that the entire
|
||||
resulting derived work is distributed under the terms of a permission
|
||||
notice identical to this one.
|
||||
|
||||
Permission is granted to copy and distribute translations of this manual
|
||||
into another language, under the above conditions for modified versions,
|
||||
except that this permission notice may be stated in a translation approved
|
||||
by the Free Software Foundation.
|
||||
@end ifinfo
|
||||
|
||||
@titlepage
|
||||
@title Makeinfo
|
||||
@author Brian J. Fox and Robert J. Chassell
|
||||
|
||||
@page
|
||||
@vskip 0pt plus 1filll
|
||||
Copyright @copyright{} 1992, 1993 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 Free Software Foundation.
|
||||
@end titlepage
|
||||
|
||||
@ifinfo
|
||||
@node Top, What is makeinfo, (dir), (dir)
|
||||
@unnumbered @code{makeinfo}
|
||||
|
||||
This file documents the use of the @code{makeinfo} program, versions
|
||||
@value{VERSION} and later. It is an extract from the @cite{Texinfo} manual.
|
||||
@end ifinfo
|
||||
|
||||
@menu
|
||||
* What is makeinfo::
|
||||
@end menu
|
||||
|
||||
@node What is makeinfo, , Top, Top
|
||||
@chapter What is @code{makeinfo}?
|
||||
|
||||
@iftex
|
||||
This file documents the use of the @code{makeinfo} program, versions
|
||||
@value{VERSION} and later. It is an extract from the @cite{Texinfo} manual.
|
||||
@end iftex
|
||||
|
||||
@code{makeinfo} is a program for converting @dfn{Texinfo} files into @dfn{Info}
|
||||
files. Texinfo is a documentation system that uses a single source file to
|
||||
produce both on-line information and printed output.
|
||||
|
||||
You can read the on-line information using Info; type @code{info} to
|
||||
learn about Info.
|
||||
@ifinfo
|
||||
@xref{Top, Texinfo, Overview of Texinfo, texinfo.texi, Texinfo},
|
||||
@end ifinfo
|
||||
@iftex
|
||||
See the @cite{Texinfo} manual,
|
||||
@end iftex
|
||||
to learn about the Texinfo documentation system.
|
||||
|
||||
@menu
|
||||
* Formatting Control::
|
||||
* Options::
|
||||
* Pointer Validation::
|
||||
@end menu
|
||||
|
||||
@node Formatting Control, Options, , What is makeinfo
|
||||
@section Controlling Paragraph Formats
|
||||
|
||||
In general, @code{makeinfo} @dfn{fills} the paragraphs that it outputs
|
||||
to an Info file. Filling is the process of breaking and connecting
|
||||
lines so that lines are the same length as or shorter than the number
|
||||
specified as the fill column. Lines are broken between words. With
|
||||
@code{makeinfo}, you can control:
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
The width of each paragraph (the @dfn{fill-column}).
|
||||
@item
|
||||
The amount of indentation that the first line of
|
||||
each paragraph receives (the @dfn{paragraph-indentation}).
|
||||
@end itemize
|
||||
|
||||
@node Options, Pointer Validation, Formatting Control, What is makeinfo
|
||||
@section Command Line Options
|
||||
|
||||
The following command line options are available for @code{makeinfo}.
|
||||
|
||||
@need 100
|
||||
@table @code
|
||||
@item -D @var{var}
|
||||
Cause @var{var} to be defined. This is equivalent to
|
||||
@code{@@set @var{var}} in the Texinfo file.
|
||||
|
||||
@need 150
|
||||
@item --error-limit @var{limit}
|
||||
Set the maximum number of errors that @code{makeinfo} will report
|
||||
before exiting (on the assumption that continuing would be useless).
|
||||
The default number of errors that can be reported before
|
||||
@code{makeinfo} gives up is 100.@refill
|
||||
|
||||
@need 150
|
||||
@item --fill-column @var{width}
|
||||
Specify the maximum number of columns in a line; this is the right-hand
|
||||
edge of a line. Paragraphs that are filled will be filled to this
|
||||
width. The default value for @code{fill-column} is 72.
|
||||
@refill
|
||||
|
||||
@item --footnote-style @var{style}
|
||||
Set the footnote style to @var{style}, either @samp{end} for the end
|
||||
node style or @samp{separate} for the separate node style. The value
|
||||
set by this option overrides the value set in a Texinfo file by an
|
||||
@code{@@footnotestyle} command. When the footnote style is
|
||||
@samp{separate}, @code{makeinfo} makes a new node containing the
|
||||
footnotes found in the current node. When the footnote style is
|
||||
@samp{end}, @code{makeinfo} places the footnote references at the end
|
||||
of the current node.@refill
|
||||
|
||||
@need 150
|
||||
@item -I @var{dir}
|
||||
Add @code{dir} to the directory search list for finding files that are
|
||||
included using the @code{@@include} command. By default,
|
||||
@code{makeinfo} searches only the current directory.
|
||||
|
||||
@need 150
|
||||
@item --no-headers
|
||||
Do not include menus or node lines in the output. This results in an
|
||||
@sc{ascii} file that you cannot read in Info since it does not contain
|
||||
the requisite nodes or menus; but you can print such a file in a
|
||||
single, typewriter-like font and produce acceptable output.
|
||||
|
||||
@need 150
|
||||
@item --no-split
|
||||
Suppress the splitting stage of @code{makeinfo}. Normally, large
|
||||
output files (where the size is greater than 70k bytes) are split into
|
||||
smaller subfiles, each one approximately 50k bytes. If you specify
|
||||
@samp{--no-split}, @code{makeinfo} will not split up the output
|
||||
file.@refill
|
||||
|
||||
@need 100
|
||||
@item --no-pointer-validate
|
||||
@item --no-validate
|
||||
Suppress the pointer-validation phase of @code{makeinfo}. Normally,
|
||||
after a Texinfo file is processed, some consistency checks are made to
|
||||
ensure that cross references can be resolved, etc.
|
||||
@xref{Pointer Validation}.@refill
|
||||
|
||||
@need 150
|
||||
@item --no-warn
|
||||
Suppress the output of warning messages. This does @emph{not}
|
||||
suppress the output of error messages, only warnings. You might
|
||||
want this if the file you are creating has examples of Texinfo cross
|
||||
references within it, and the nodes that are referenced do not actually
|
||||
exist.@refill
|
||||
|
||||
@item --no-number-footnotes
|
||||
Supress automatic footnote numbering. By default, @code{makeinfo}
|
||||
numbers each footnote sequentially in a single node, resetting the
|
||||
current footnote number to 1 at the start of each node.
|
||||
|
||||
@need 150
|
||||
@item --output @var{file}
|
||||
@itemx -o @var{file}
|
||||
Specify that the output should be directed to @var{file} and not to the
|
||||
file name specified in the @code{@@setfilename} command found in the Texinfo
|
||||
source. @var{file} can be the special token @samp{-}, which specifies
|
||||
standard output.
|
||||
|
||||
@need 150
|
||||
@item --paragraph-indent @var{indent}
|
||||
Set the paragraph indentation style to @var{indent}. The value set by
|
||||
this option overrides the value set in a Texinfo file by an
|
||||
@code{@@paragraphindent} command. The value of @var{indent} is
|
||||
interpreted as follows:@refill
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
If the value of @var{indent} is @samp{asis}, do not change the
|
||||
existing indentation at the starts of paragraphs.@refill
|
||||
|
||||
@item
|
||||
If the value of @var{indent} is zero, delete any existing
|
||||
indentation.@refill
|
||||
|
||||
@item
|
||||
If the value of @var{indent} is greater than zero, indent each
|
||||
paragraph by that number of spaces.@refill
|
||||
@end itemize
|
||||
|
||||
@need 100
|
||||
@item --reference-limit @var{limit}
|
||||
Set the value of the number of references to a node that
|
||||
@code{makeinfo} will make without reporting a warning. If a node has more
|
||||
than this number of references in it, @code{makeinfo} will make the
|
||||
references but also report a warning.@refill
|
||||
|
||||
@need 150
|
||||
@item -U @var{var}
|
||||
Cause @var{var} to be undefined. This is equivalent to
|
||||
@code{@@clear @var{var}} in the Texinfo file.
|
||||
|
||||
@need 100
|
||||
@item --verbose
|
||||
Cause @code{makeinfo} to display messages saying what it is doing.
|
||||
Normally, @code{makeinfo} only outputs messages if there are errors or
|
||||
warnings.@refill
|
||||
|
||||
@need 100
|
||||
@item --version
|
||||
Report the version number of this copy of @code{makeinfo}.@refill
|
||||
@end table
|
||||
|
||||
@node Pointer Validation, , Options, What is makeinfo
|
||||
@section Pointer Validation
|
||||
@cindex Pointer validation with @code{makeinfo}
|
||||
@cindex Validation of pointers
|
||||
|
||||
If you do not suppress pointer-validation (by using the
|
||||
@samp{--no-pointer-validation} option), @code{makeinfo}
|
||||
will check the validity of the final Info file. Mostly,
|
||||
this means ensuring that nodes you have referenced
|
||||
really exist. Here is a complete list of what is
|
||||
checked:@refill
|
||||
|
||||
@enumerate
|
||||
@item
|
||||
If a `Next', `Previous', or `Up' node reference is a reference to a
|
||||
node in the current file and is not an external reference such as to
|
||||
@file{(dir)}, then the referenced node must exist.@refill
|
||||
|
||||
@item
|
||||
In every node, if the `Previous' node is different from the `Up' node,
|
||||
then the `Previous' node must also be pointed to by a `Next' node.@refill
|
||||
|
||||
@item
|
||||
Every node except the `Top' node must have an `Up' pointer.@refill
|
||||
|
||||
@item
|
||||
The node referenced by an `Up' pointer must contain a reference to the
|
||||
current node in some manner other than through a `Next' reference.
|
||||
This includes menu entries and cross references.@refill
|
||||
|
||||
@item
|
||||
If the `Next' reference of a node is not the same as the `Next' reference
|
||||
of the `Up' reference, then the node referenced by the `Next' pointer
|
||||
must have a `Previous' pointer that points back to the current node.
|
||||
This rule allows the last node in a section to point to the first node
|
||||
of the next chapter.@refill
|
||||
@end enumerate
|
||||
|
||||
@bye
|
15626
gnu/usr.bin/texinfo/info-files/texi-files/texi.texi
Normal file
15626
gnu/usr.bin/texinfo/info-files/texi-files/texi.texi
Normal file
File diff suppressed because it is too large
Load Diff
1263
gnu/usr.bin/texinfo/info-files/texi-files/userdoc.texi
Normal file
1263
gnu/usr.bin/texinfo/info-files/texi-files/userdoc.texi
Normal file
File diff suppressed because it is too large
Load Diff
297
gnu/usr.bin/texinfo/info-files/texi.info
Normal file
297
gnu/usr.bin/texinfo/info-files/texi.info
Normal file
@ -0,0 +1,297 @@
|
||||
This is Info file texi.info, produced by Makeinfo-1.55 from the input
|
||||
file texi.texi.
|
||||
|
||||
This file documents Texinfo, a documentation system that uses a
|
||||
single source file to produce both on-line information and a printed
|
||||
manual.
|
||||
|
||||
Copyright (C) 1988, 1990, 1991, 1992, 1993 Free Software Foundation,
|
||||
Inc.
|
||||
|
||||
This is the second edition of the Texinfo documentation,
|
||||
and is consistent with version 2 of `texinfo.tex'.
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of this
|
||||
manual provided the copyright notice and this permission notice are
|
||||
preserved on all copies.
|
||||
|
||||
Permission is granted to copy and distribute modified versions of
|
||||
this manual under the conditions for verbatim copying, provided that
|
||||
the entire resulting derived work is distributed under the terms of a
|
||||
permission notice identical to this one.
|
||||
|
||||
Permission is granted to copy and distribute translations of this
|
||||
manual into another language, under the above conditions for modified
|
||||
versions, except that this permission notice may be stated in a
|
||||
translation approved by the Free Software Foundation.
|
||||
|
||||
|
||||
Indirect:
|
||||
texi.info-1: 1096
|
||||
texi.info-2: 50585
|
||||
texi.info-3: 100344
|
||||
texi.info-4: 149083
|
||||
texi.info-5: 197497
|
||||
texi.info-6: 247275
|
||||
texi.info-7: 296490
|
||||
texi.info-8: 346023
|
||||
texi.info-9: 387598
|
||||
texi.info-10: 433598
|
||||
texi.info-11: 476101
|
||||
|
||||
Tag Table:
|
||||
(Indirect)
|
||||
Node: Top1096
|
||||
Node: Copying21758
|
||||
Node: Overview23766
|
||||
Node: Using Texinfo25673
|
||||
Node: Info Files28165
|
||||
Node: Printed Books32225
|
||||
Node: Formatting Commands35110
|
||||
Node: Conventions38551
|
||||
Node: Comments40811
|
||||
Node: Minimum42233
|
||||
Node: Six Parts44386
|
||||
Node: Short Sample45896
|
||||
Node: Acknowledgements50027
|
||||
Node: Texinfo Mode50585
|
||||
Node: Texinfo Mode Overview51956
|
||||
Node: Emacs Editing52709
|
||||
Node: Inserting54839
|
||||
Node: Showing the Structure59115
|
||||
Node: Updating Nodes and Menus61634
|
||||
Node: Updating Commands62706
|
||||
Node: Updating Requirements68741
|
||||
Node: Other Updating Commands71042
|
||||
Node: Info Formatting74311
|
||||
Node: Printing75635
|
||||
Node: Texinfo Mode Summary77399
|
||||
Node: Beginning a File82167
|
||||
Node: Four Parts83056
|
||||
Node: Sample Beginning84502
|
||||
Node: Header86125
|
||||
Node: First Line87476
|
||||
Node: Start of Header88448
|
||||
Node: setfilename89163
|
||||
Node: settitle90763
|
||||
Node: setchapternewpage92646
|
||||
Node: paragraphindent95412
|
||||
Node: End of Header96877
|
||||
Node: Info Summary and Permissions97717
|
||||
Node: Titlepage & Copyright Page98738
|
||||
Node: titlepage100344
|
||||
Node: titlefont center sp102665
|
||||
Node: title subtitle author103895
|
||||
Node: Copyright & Permissions106171
|
||||
Node: end titlepage108176
|
||||
Node: headings on off109881
|
||||
Node: The Top Node111707
|
||||
Node: Title of Top Node112862
|
||||
Node: Master Menu Parts114099
|
||||
Node: Software Copying Permissions116150
|
||||
Node: Ending a File117318
|
||||
Node: Printing Indices & Menus118165
|
||||
Node: Contents120448
|
||||
Node: File End122790
|
||||
Node: Structuring123462
|
||||
Node: Tree Structuring125043
|
||||
Node: Structuring Command Types126467
|
||||
Node: makeinfo top128792
|
||||
Node: chapter129323
|
||||
Node: unnumbered & appendix130147
|
||||
Node: majorheading & chapheading130986
|
||||
Node: section131808
|
||||
Node: unnumberedsec appendixsec heading132573
|
||||
Node: subsection133560
|
||||
Node: unnumberedsubsec appendixsubsec subheading134131
|
||||
Node: subsubsection135083
|
||||
Node: Nodes136603
|
||||
Node: Two Paths137538
|
||||
Node: Node Menu Illustration138810
|
||||
Node: node142510
|
||||
Node: Node Names145206
|
||||
Node: Writing a Node146271
|
||||
Node: Node Line Tips148291
|
||||
Node: Node Line Requirements149083
|
||||
Node: First Node150691
|
||||
Node: makeinfo top command151811
|
||||
Node: Top Node Summary153591
|
||||
Node: makeinfo Pointer Creation154728
|
||||
Node: Menus155977
|
||||
Node: Menu Location157220
|
||||
Node: Writing a Menu158884
|
||||
Node: Menu Parts159850
|
||||
Node: Less Cluttered Menu Entry160848
|
||||
Node: Menu Example161473
|
||||
Node: Other Info Files162995
|
||||
Node: Cross References164855
|
||||
Node: References165734
|
||||
Node: Cross Reference Commands167458
|
||||
Node: Cross Reference Parts168509
|
||||
Node: xref171238
|
||||
Node: Reference Syntax172035
|
||||
Node: One Argument173679
|
||||
Node: Two Arguments174690
|
||||
Node: Three Arguments175804
|
||||
Node: Four and Five Arguments178189
|
||||
Node: Top Node Naming180602
|
||||
Node: ref181610
|
||||
Node: pxref182998
|
||||
Node: inforef185382
|
||||
Node: Marking Text186662
|
||||
Node: Indicating187283
|
||||
Node: Useful Highlighting189014
|
||||
Node: code190199
|
||||
Node: kbd193243
|
||||
Node: key194431
|
||||
Node: samp195985
|
||||
Node: var197497
|
||||
Node: file199287
|
||||
Node: dfn199893
|
||||
Node: cite200802
|
||||
Node: Emphasis201243
|
||||
Node: emph & strong202071
|
||||
Node: Smallcaps203041
|
||||
Node: Fonts204371
|
||||
Node: Quotations and Examples205427
|
||||
Node: Block Enclosing Commands207048
|
||||
Node: quotation209043
|
||||
Node: example210132
|
||||
Node: noindent212190
|
||||
Node: Lisp Example213657
|
||||
Node: smallexample & smalllisp214488
|
||||
Node: display216516
|
||||
Node: format217146
|
||||
Node: exdent217605
|
||||
Node: flushleft & flushright218684
|
||||
Node: cartouche219946
|
||||
Node: Lists and Tables220716
|
||||
Node: Introducing Lists221311
|
||||
Node: itemize222953
|
||||
Node: enumerate225104
|
||||
Node: Two-column Tables227594
|
||||
Node: table228287
|
||||
Node: ftable vtable230601
|
||||
Node: itemx231644
|
||||
Node: Indices232604
|
||||
Node: Index Entries233753
|
||||
Node: Predefined Indices234870
|
||||
Node: Indexing Commands235865
|
||||
Node: Combining Indices239873
|
||||
Node: syncodeindex241235
|
||||
Node: synindex242874
|
||||
Node: New Indices243398
|
||||
Node: Insertions245227
|
||||
Node: Braces Atsigns Periods245985
|
||||
Node: Inserting An Atsign247275
|
||||
Node: Inserting Braces247533
|
||||
Node: Controlling Spacing247932
|
||||
Node: dmn249490
|
||||
Node: Dots Bullets250719
|
||||
Node: dots251525
|
||||
Node: bullet251920
|
||||
Node: TeX and copyright252297
|
||||
Node: tex252861
|
||||
Node: copyright symbol253233
|
||||
Node: minus253479
|
||||
Node: Glyphs254350
|
||||
Node: Glyphs Summary255461
|
||||
Node: result255973
|
||||
Node: expansion256430
|
||||
Node: Print Glyph257352
|
||||
Node: Error Glyph258203
|
||||
Node: Equivalence259021
|
||||
Node: Point Glyph259683
|
||||
Node: Breaks261206
|
||||
Node: Break Commands262558
|
||||
Node: Line Breaks263246
|
||||
Node: w264248
|
||||
Node: sp265066
|
||||
Node: page265474
|
||||
Node: group265851
|
||||
Node: need267596
|
||||
Node: Definition Commands268326
|
||||
Node: Def Cmd Template269897
|
||||
Node: Optional Arguments272807
|
||||
Node: deffnx274396
|
||||
Node: Def Cmds in Detail275352
|
||||
Node: Functions Commands276462
|
||||
Node: Variables Commands279391
|
||||
Node: Typed Functions281340
|
||||
Node: Typed Variables284875
|
||||
Node: Abstract Objects286856
|
||||
Node: Data Types291752
|
||||
Node: Def Cmd Conventions293005
|
||||
Node: Sample Function Definition293566
|
||||
Node: Footnotes296490
|
||||
Node: Conditionals300343
|
||||
Node: Conditional Commands301099
|
||||
Node: Using Ordinary TeX Commands302508
|
||||
Node: set clear value303956
|
||||
Node: ifset ifclear304761
|
||||
Node: value307921
|
||||
Node: value Example309339
|
||||
Node: Format/Print Hardcopy310917
|
||||
Node: Use TeX312719
|
||||
Node: Shell Format & Print313310
|
||||
Node: Within Emacs317908
|
||||
Node: Texinfo Mode Printing318896
|
||||
Node: Compile-Command322646
|
||||
Node: Requirements Summary323554
|
||||
Node: Preparing for TeX324974
|
||||
Node: Overfull hboxes326989
|
||||
Node: smallbook328549
|
||||
Node: A4 Paper329782
|
||||
Node: Cropmarks and Magnification330484
|
||||
Node: Create an Info File332460
|
||||
Node: makeinfo advantages333764
|
||||
Node: Invoking makeinfo334651
|
||||
Node: makeinfo options335363
|
||||
Node: Pointer Validation340823
|
||||
Node: makeinfo in Emacs342207
|
||||
Node: texinfo-format commands344752
|
||||
Node: Batch Formatting346023
|
||||
Node: Tag and Split Files347269
|
||||
Node: Install an Info File350626
|
||||
Node: Directory file351276
|
||||
Node: New Info File352956
|
||||
Node: Other Info Directories354095
|
||||
Node: Command List355961
|
||||
Node: Tips387598
|
||||
Node: Sample Texinfo File399031
|
||||
Node: Sample Permissions401147
|
||||
Node: Inserting Permissions402188
|
||||
Node: ifinfo Permissions404469
|
||||
Node: Titlepage Permissions406088
|
||||
Node: Include Files407348
|
||||
Node: Using Include Files408434
|
||||
Node: texinfo-multiple-files-update410368
|
||||
Node: Include File Requirements412759
|
||||
Node: Sample Include File414004
|
||||
Node: Include Files Evolution415532
|
||||
Node: Headings417509
|
||||
Node: Headings Introduced418144
|
||||
Node: Heading Format420033
|
||||
Node: Heading Choice422489
|
||||
Node: Custom Headings423860
|
||||
Node: Catching Mistakes428069
|
||||
Node: makeinfo preferred429359
|
||||
Node: Debugging with Info430260
|
||||
Node: Debugging with TeX433598
|
||||
Node: Using texinfo-show-structure437940
|
||||
Node: Using occur441040
|
||||
Node: Running Info-Validate442579
|
||||
Node: Using Info-validate443639
|
||||
Node: Unsplit445454
|
||||
Node: Tagifying446502
|
||||
Node: Splitting447361
|
||||
Node: Refilling Paragraphs448981
|
||||
Node: Command Syntax450800
|
||||
Node: Obtaining TeX453731
|
||||
Node: New Features454842
|
||||
Node: New Texinfo Mode Commands455424
|
||||
Node: New Commands458894
|
||||
Node: Command and Variable Index463543
|
||||
Node: Concept Index476101
|
||||
|
||||
End Tag Table
|
1131
gnu/usr.bin/texinfo/info-files/texi.info-1
Normal file
1131
gnu/usr.bin/texinfo/info-files/texi.info-1
Normal file
File diff suppressed because it is too large
Load Diff
1165
gnu/usr.bin/texinfo/info-files/texi.info-10
Normal file
1165
gnu/usr.bin/texinfo/info-files/texi.info-10
Normal file
File diff suppressed because it is too large
Load Diff
451
gnu/usr.bin/texinfo/info-files/texi.info-11
Normal file
451
gnu/usr.bin/texinfo/info-files/texi.info-11
Normal file
@ -0,0 +1,451 @@
|
||||
This is Info file texi.info, produced by Makeinfo-1.55 from the input
|
||||
file texi.texi.
|
||||
|
||||
This file documents Texinfo, a documentation system that uses a
|
||||
single source file to produce both on-line information and a printed
|
||||
manual.
|
||||
|
||||
Copyright (C) 1988, 1990, 1991, 1992, 1993 Free Software Foundation,
|
||||
Inc.
|
||||
|
||||
This is the second edition of the Texinfo documentation,
|
||||
and is consistent with version 2 of `texinfo.tex'.
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of this
|
||||
manual provided the copyright notice and this permission notice are
|
||||
preserved on all copies.
|
||||
|
||||
Permission is granted to copy and distribute modified versions of
|
||||
this manual under the conditions for verbatim copying, provided that
|
||||
the entire resulting derived work is distributed under the terms of a
|
||||
permission notice identical to this one.
|
||||
|
||||
Permission is granted to copy and distribute translations of this
|
||||
manual into another language, under the above conditions for modified
|
||||
versions, except that this permission notice may be stated in a
|
||||
translation approved by the Free Software Foundation.
|
||||
|
||||
|
||||
File: texi.info, Node: Concept Index, Prev: Command and Variable Index, Up: Top
|
||||
|
||||
Concept Index
|
||||
*************
|
||||
|
||||
* Menu:
|
||||
|
||||
* @-command in nodename: Node Line Requirements.
|
||||
* @-command list: Command List.
|
||||
* @-command syntax: Command Syntax.
|
||||
* @-commands: Formatting Commands.
|
||||
* .cshrc initialization file: Preparing for TeX.
|
||||
* .profile initialization file: Preparing for TeX.
|
||||
* @include file sample: Sample Include File.
|
||||
* @menu parts: Menu Parts.
|
||||
* @node line writing: Writing a Node.
|
||||
* makeinfo inside Emacs: makeinfo in Emacs.
|
||||
* makeinfo options: makeinfo options.
|
||||
* TEXINPUTS environment variable: Preparing for TeX.
|
||||
* dir directory for Info installation: Install an Info File.
|
||||
* dir file listing: New Info File.
|
||||
* End node footnote style: Footnotes.
|
||||
* Separate footnote style: Footnotes.
|
||||
* Top node: The Top Node.
|
||||
* Top node is first: First Node.
|
||||
* Top node naming for references: Top Node Naming.
|
||||
* Top node summary: Top Node Summary.
|
||||
* hboxes, overfull: Overfull hboxes.
|
||||
* ifinfo permissions: ifinfo Permissions.
|
||||
* TeX commands, using ordinary: Using Ordinary TeX Commands.
|
||||
* TeX index sorting: Format/Print Hardcopy.
|
||||
* TeX input initialization: Preparing for TeX.
|
||||
* TeX, how to obtain: Obtaining TeX.
|
||||
* A4 paper, printing on: A4 Paper.
|
||||
* Abbreviations for keys: key.
|
||||
* Adding a new info file: New Info File.
|
||||
* Alphabetical @-command list: Command List.
|
||||
* Another Info directory: Other Info Directories.
|
||||
* Apostrophe in nodename: Node Line Requirements.
|
||||
* Arguments, repeated and optional: Optional Arguments.
|
||||
* Automatic pointer creation with makeinfo: makeinfo Pointer Creation.
|
||||
* Automatically insert nodes, menus: Updating Nodes and Menus.
|
||||
* Badly referenced nodes: Running Info-Validate.
|
||||
* Batch formatting for Info: Batch Formatting.
|
||||
* Beginning a Texinfo file: Beginning a File.
|
||||
* Beginning line of a Texinfo file: First Line.
|
||||
* Black rectangle in hardcopy: Overfull hboxes.
|
||||
* Blank lines: sp.
|
||||
* Book characteristics, printed: Printed Books.
|
||||
* Book, printing small: smallbook.
|
||||
* Box with rounded corners: cartouche.
|
||||
* Braces and argument syntax: Command Syntax.
|
||||
* Braces, inserting: Braces Atsigns Periods.
|
||||
* Braces, when to use: Formatting Commands.
|
||||
* Breaks in a line: Line Breaks.
|
||||
* Buffer formatting and printing: Printing.
|
||||
* Bullets, inserting: Dots Bullets.
|
||||
* Capitalizing index entries: Indexing Commands.
|
||||
* Case in nodename: Node Line Requirements.
|
||||
* Catching errors with TeX formatting: Debugging with TeX.
|
||||
* Catching errors with Info formatting: Debugging with Info.
|
||||
* Catching mistakes: Catching Mistakes.
|
||||
* Chapter structuring: Structuring.
|
||||
* Characteristics, printed books or manuals: Printed Books.
|
||||
* Checking for badly referenced nodes: Running Info-Validate.
|
||||
* Colon in nodename: Node Line Requirements.
|
||||
* Combining indices: Combining Indices.
|
||||
* Comma in nodename: Node Line Requirements.
|
||||
* Command definitions: Sample Function Definition.
|
||||
* Commands to insert single characters: Braces Atsigns Periods.
|
||||
* Commands using ordinary TeX: Using Ordinary TeX Commands.
|
||||
* Commands, inserting them: Inserting.
|
||||
* Comments: Comments.
|
||||
* Compile command for formatting: Compile-Command.
|
||||
* Conditionally visible text: Conditionals.
|
||||
* Conditions for copying Texinfo: Copying.
|
||||
* Contents, Table of: Contents.
|
||||
* Contents-like outline of file structure: Showing the Structure.
|
||||
* Conventions for writing definitions: Def Cmd Conventions.
|
||||
* Conventions, syntactic: Conventions.
|
||||
* Copying conditions: Copying.
|
||||
* Copying permissions: Sample Permissions.
|
||||
* Copying software: Software Copying Permissions.
|
||||
* Copyright page: Copyright & Permissions.
|
||||
* Correcting mistakes: Catching Mistakes.
|
||||
* Create nodes, menus automatically: Updating Nodes and Menus.
|
||||
* Creating an Info file: Create an Info File.
|
||||
* Creating an unsplit file: Unsplit.
|
||||
* Creating index entries: Indexing Commands.
|
||||
* Creating indices: Indices.
|
||||
* Creating pointers with makeinfo: makeinfo Pointer Creation.
|
||||
* Cropmarks for printing: Cropmarks and Magnification.
|
||||
* Cross reference parts: Cross Reference Parts.
|
||||
* Cross references: Cross References.
|
||||
* Cross references using @inforef: inforef.
|
||||
* Cross references using @pxref: pxref.
|
||||
* Cross references using @ref: ref.
|
||||
* Cross references using @xref: xref.
|
||||
* Debugging the Texinfo structure: Catching Mistakes.
|
||||
* Debugging with TeX formatting: Debugging with TeX.
|
||||
* Debugging with Info formatting: Debugging with Info.
|
||||
* Defining indexing entries: Indexing Commands.
|
||||
* Defining new indices: New Indices.
|
||||
* Definition commands: Definition Commands.
|
||||
* Definition conventions: Def Cmd Conventions.
|
||||
* Definition template: Def Cmd Template.
|
||||
* Definitions grouped together: deffnx.
|
||||
* Description for menu, start: Inserting.
|
||||
* Different cross reference commands: Cross Reference Commands.
|
||||
* Dimension formatting: dmn.
|
||||
* Display formatting: display.
|
||||
* Distribution: Software Copying Permissions.
|
||||
* Dots, inserting: dots.
|
||||
* Dots, inserting: Dots Bullets.
|
||||
* Double-colon menu entries: Less Cluttered Menu Entry.
|
||||
* DVI file: Shell Format & Print.
|
||||
* Ellipsis, inserting: Dots Bullets.
|
||||
* Emacs: Texinfo Mode.
|
||||
* Emacs shell, format, print from: Within Emacs.
|
||||
* Emphasizing text: Emphasis.
|
||||
* Emphasizing text, font for: emph & strong.
|
||||
* End of header line: End of Header.
|
||||
* End titlepage starts headings: end titlepage.
|
||||
* Ending a Texinfo file: Ending a File.
|
||||
* Entries for an index: Indexing Commands.
|
||||
* Entries, making index: Index Entries.
|
||||
* Enumeration: enumerate.
|
||||
* Equivalence, indicating it: Equivalence.
|
||||
* Error message, indicating it: Error Glyph.
|
||||
* Errors, parsing: makeinfo in Emacs.
|
||||
* European A4 paper: A4 Paper.
|
||||
* Evaluation glyph: result.
|
||||
* Example for a small book: smallexample & smalllisp.
|
||||
* Example menu: Menu Example.
|
||||
* Examples, formatting them: example.
|
||||
* Expansion, indicating it: expansion.
|
||||
* File beginning: Beginning a File.
|
||||
* File ending: Ending a File.
|
||||
* File section structure, showing it: Showing the Structure.
|
||||
* Filling paragraphs: Refilling Paragraphs.
|
||||
* Final output: Overfull hboxes.
|
||||
* Finding badly referenced nodes: Running Info-Validate.
|
||||
* First line of a Texinfo file: First Line.
|
||||
* First node: First Node.
|
||||
* Fonts for indices: syncodeindex.
|
||||
* Fonts for printing, not for Info: Fonts.
|
||||
* Footings: Headings.
|
||||
* Footnotes: Footnotes.
|
||||
* Format a dimension: dmn.
|
||||
* Format and print hardcopy: Format/Print Hardcopy.
|
||||
* Format and print in Texinfo mode: Texinfo Mode Printing.
|
||||
* Format with the compile command: Compile-Command.
|
||||
* Format, print from Emacs shell: Within Emacs.
|
||||
* Formatting a file for Info: Create an Info File.
|
||||
* Formatting commands: Formatting Commands.
|
||||
* Formatting examples: example.
|
||||
* Formatting for Info: Info Formatting.
|
||||
* Formatting for printing: Printing.
|
||||
* Formatting headings and footings: Headings.
|
||||
* Formatting requirements: Requirements Summary.
|
||||
* Frequently used commands, inserting: Inserting.
|
||||
* Function definitions: Sample Function Definition.
|
||||
* General syntactic conventions: Conventions.
|
||||
* Generating menus with indices: Printing Indices & Menus.
|
||||
* Glyphs: Glyphs.
|
||||
* GNU Emacs: Texinfo Mode.
|
||||
* GNU Emacs shell, format, print from: Within Emacs.
|
||||
* Going to other Info files' nodes: Other Info Files.
|
||||
* Group (hold text together vertically): group.
|
||||
* Grouping two definitions together: deffnx.
|
||||
* Hardcopy, printing it: Format/Print Hardcopy.
|
||||
* Header for Texinfo files: Header.
|
||||
* Header of a Texinfo file: First Line.
|
||||
* Headings: Headings.
|
||||
* Headings, page, begin to appear: end titlepage.
|
||||
* Highlighting text: Indicating.
|
||||
* Hints: Tips.
|
||||
* Holding text together vertically: group.
|
||||
* If text conditionally visible: Conditionals.
|
||||
* Ignored text: Comments.
|
||||
* Include file requirements: Include File Requirements.
|
||||
* Include file sample: Sample Include File.
|
||||
* Include files: Include Files.
|
||||
* Indentation undoing: exdent.
|
||||
* Indenting paragraphs: paragraphindent.
|
||||
* Index entries: Indexing Commands.
|
||||
* Index entries, making: Index Entries.
|
||||
* Index entry capitalization: Indexing Commands.
|
||||
* Index font types: Indexing Commands.
|
||||
* Indexing commands, predefined: Indexing Commands.
|
||||
* Indexing table entries automatically: ftable vtable.
|
||||
* Indicating commands, definitions, etc.: Indicating.
|
||||
* Indicating evaluation: result.
|
||||
* Indices: Indices.
|
||||
* Indices, combining them: Combining Indices.
|
||||
* Indices, defining new: New Indices.
|
||||
* Indices, printing and menus: Printing Indices & Menus.
|
||||
* Indices, sorting: Format/Print Hardcopy.
|
||||
* Indices, two letter names: syncodeindex.
|
||||
* Indirect subfiles: Tag and Split Files.
|
||||
* Info batch formatting: Batch Formatting.
|
||||
* Info file installation: Install an Info File.
|
||||
* Info file requires @setfilename: setfilename.
|
||||
* Info file, listing new one: New Info File.
|
||||
* Info file, splitting manually: Splitting.
|
||||
* Info files: Info Files.
|
||||
* Info formatting: Info Formatting.
|
||||
* Info installed in another directory: Other Info Directories.
|
||||
* Info validating a large file: Using Info-validate.
|
||||
* Info, creating an on-line file: Create an Info File.
|
||||
* Info; other files' nodes: Other Info Files.
|
||||
* Initialization file for TeX input: Preparing for TeX.
|
||||
* Insert nodes, menus automatically: Updating Nodes and Menus.
|
||||
* Inserting @, braces, and periods: Braces Atsigns Periods.
|
||||
* Inserting dots: Dots Bullets.
|
||||
* Inserting dots: dots.
|
||||
* Inserting ellipsis: Dots Bullets.
|
||||
* Inserting frequently used commands: Inserting.
|
||||
* Inserting special characters and symbols: Insertions.
|
||||
* Installing an Info file: Install an Info File.
|
||||
* Installing Info in another directory: Other Info Directories.
|
||||
* Introduction, as part of file: Software Copying Permissions.
|
||||
* Itemization: itemize.
|
||||
* Keys, recommended names: key.
|
||||
* Larger or smaller pages: Cropmarks and Magnification.
|
||||
* Less cluttered menu entry: Less Cluttered Menu Entry.
|
||||
* License agreement: Software Copying Permissions.
|
||||
* Line breaks: Line Breaks.
|
||||
* Line breaks, preventing: w.
|
||||
* Line spacing: sp.
|
||||
* Lisp example: Lisp Example.
|
||||
* Lisp example for a small book: smallexample & smalllisp.
|
||||
* List of @-commands: Command List.
|
||||
* Listing a new info file: New Info File.
|
||||
* Lists and tables, making them: Lists and Tables.
|
||||
* Local variables: Compile-Command.
|
||||
* Location of menus: Menu Location.
|
||||
* Looking for badly referenced nodes: Running Info-Validate.
|
||||
* Macro definitions: Sample Function Definition.
|
||||
* Magnified printing: Cropmarks and Magnification.
|
||||
* Making a printed manual: Format/Print Hardcopy.
|
||||
* Making a tag table automatically: Tag and Split Files.
|
||||
* Making a tag table manually: Unsplit.
|
||||
* Making cross references: Cross References.
|
||||
* Making line and page breaks: Breaks.
|
||||
* Making lists and tables: Lists and Tables.
|
||||
* Manual characteristics, printed: Printed Books.
|
||||
* Marking text within a paragraph: Marking Text.
|
||||
* Marking words and phrases: Marking Text.
|
||||
* Master menu: The Top Node.
|
||||
* Master menu parts: Master Menu Parts.
|
||||
* Mathematical expressions: Using Ordinary TeX Commands.
|
||||
* Menu description, start: Inserting.
|
||||
* Menu entries with two colons: Less Cluttered Menu Entry.
|
||||
* Menu example: Menu Example.
|
||||
* Menu location: Menu Location.
|
||||
* Menu parts: Menu Parts.
|
||||
* Menu writing: Writing a Menu.
|
||||
* Menus: Menus.
|
||||
* Menus generated with indices: Printing Indices & Menus.
|
||||
* META key: key.
|
||||
* Meta-syntactic chars for arguments: Optional Arguments.
|
||||
* Minimal Texinfo file (requirements): Minimum.
|
||||
* Mistakes, catching: Catching Mistakes.
|
||||
* Mode, using Texinfo: Texinfo Mode.
|
||||
* Must have in Texinfo file: Minimum.
|
||||
* Names for indices: syncodeindex.
|
||||
* Names recommended for keys: key.
|
||||
* Naming a `Top' Node in references: Top Node Naming.
|
||||
* Need space at page bottom: need.
|
||||
* New index defining: New Indices.
|
||||
* New info file, listing it in dir file: New Info File.
|
||||
* Node line requirements: Node Line Requirements.
|
||||
* Node line writing: Writing a Node.
|
||||
* Node, defined: node.
|
||||
* Node, `Top': The Top Node.
|
||||
* Nodename must be unique: Node Line Requirements.
|
||||
* Nodename, cannot contain: Node Line Requirements.
|
||||
* Nodes for menus are short: Menu Location.
|
||||
* Nodes in other Info files: Other Info Files.
|
||||
* Nodes, catching mistakes: Catching Mistakes.
|
||||
* Nodes, checking for badly referenced: Running Info-Validate.
|
||||
* Obtaining TeX: Obtaining TeX.
|
||||
* Occurrences, listing with @occur: Using occur.
|
||||
* Optional and repeated arguments: Optional Arguments.
|
||||
* Options for makeinfo: makeinfo options.
|
||||
* Ordinary TeX commands, using: Using Ordinary TeX Commands.
|
||||
* Other Info files' nodes: Other Info Files.
|
||||
* Outline of file structure, showing it: Showing the Structure.
|
||||
* Overfull hboxes: Overfull hboxes.
|
||||
* Overview of Texinfo: Overview.
|
||||
* Page breaks: page.
|
||||
* Page delimiter in Texinfo mode: Showing the Structure.
|
||||
* Page headings: Headings.
|
||||
* Page numbering: Headings.
|
||||
* Page sizes for books: smallbook.
|
||||
* Pages, starting odd: setchapternewpage.
|
||||
* Paper size, European A4: A4 Paper.
|
||||
* Paragraph indentation: paragraphindent.
|
||||
* Paragraph, marking text within: Marking Text.
|
||||
* Parsing errors: makeinfo in Emacs.
|
||||
* Part of file formatting and printing: Printing.
|
||||
* Parts of a cross reference: Cross Reference Parts.
|
||||
* Parts of a master menu: Master Menu Parts.
|
||||
* Parts of a menu: Menu Parts.
|
||||
* Periods, inserting: Braces Atsigns Periods.
|
||||
* Permissions: Sample Permissions.
|
||||
* Permissions, printed: Copyright & Permissions.
|
||||
* PlainTeX: Using Ordinary TeX Commands.
|
||||
* Point, indicating it in a buffer: Point Glyph.
|
||||
* Pointer creation with makeinfo: makeinfo Pointer Creation.
|
||||
* Pointer validation with makeinfo: Pointer Validation.
|
||||
* Predefined indexing commands: Indexing Commands.
|
||||
* Predefined names for indices: syncodeindex.
|
||||
* Preparing to use TeX: Preparing for TeX.
|
||||
* Preventing line and page breaks: Breaks.
|
||||
* Print and format in Texinfo mode: Texinfo Mode Printing.
|
||||
* Print, format from Emacs shell: Within Emacs.
|
||||
* Printed book and manual characteristics: Printed Books.
|
||||
* Printed output, indicating it: Print Glyph.
|
||||
* Printed permissions: Copyright & Permissions.
|
||||
* Printing a region or buffer: Printing.
|
||||
* Printing an index: Printing Indices & Menus.
|
||||
* Printing cropmarks: Cropmarks and Magnification.
|
||||
* Problems, catching: Catching Mistakes.
|
||||
* Quotations: quotation.
|
||||
* Recommended names for keys: key.
|
||||
* Rectangle, ugly, black in hardcopy: Overfull hboxes.
|
||||
* References: Cross References.
|
||||
* References using @inforef: inforef.
|
||||
* References using @pxref: pxref.
|
||||
* References using @ref: ref.
|
||||
* References using @xref: xref.
|
||||
* Referring to other Info files: Other Info Files.
|
||||
* Refilling paragraphs: Refilling Paragraphs.
|
||||
* Region formatting and printing: Printing.
|
||||
* Region printing in Texinfo mode: Texinfo Mode Printing.
|
||||
* Repeated and optional arguments: Optional Arguments.
|
||||
* Required in Texinfo file: Minimum.
|
||||
* Requirements for formatting: Requirements Summary.
|
||||
* Requirements for include files: Include File Requirements.
|
||||
* Requirements for updating commands: Updating Requirements.
|
||||
* Result of an expression: result.
|
||||
* Running Info-validate: Using Info-validate.
|
||||
* Running makeinfo in Emacs: makeinfo in Emacs.
|
||||
* Running an Info formatter: Info Formatting.
|
||||
* Sample @include file: Sample Include File.
|
||||
* Sample function definition: Sample Function Definition.
|
||||
* Sample Texinfo file: Short Sample.
|
||||
* Sample Texinfo file, no comments: Sample Texinfo File.
|
||||
* Section structure of a file, showing it: Showing the Structure.
|
||||
* Shell, format, print from: Within Emacs.
|
||||
* Shell, running makeinfo in: makeinfo in Emacs.
|
||||
* Short nodes for menus: Menu Location.
|
||||
* Showing the section structure of a file: Showing the Structure.
|
||||
* Showing the structure of a file: Using texinfo-show-structure.
|
||||
* Single characters, commands to insert: Braces Atsigns Periods.
|
||||
* Size of printed book: smallbook.
|
||||
* Small book example: smallexample & smalllisp.
|
||||
* Small book size: smallbook.
|
||||
* Small caps font: Smallcaps.
|
||||
* Software copying permissions: Software Copying Permissions.
|
||||
* Sorting indices: Format/Print Hardcopy.
|
||||
* Spaces (blank lines): sp.
|
||||
* Special insertions: Insertions.
|
||||
* Special typesetting commands: Dots Bullets.
|
||||
* Specifying index entries: Indexing Commands.
|
||||
* Splitting an Info file manually: Splitting.
|
||||
* Start of header line: Start of Header.
|
||||
* Starting chapters: setchapternewpage.
|
||||
* Structure of a file, showing it: Showing the Structure.
|
||||
* Structure, catching mistakes in: Catching Mistakes.
|
||||
* Structuring of chapters: Structuring.
|
||||
* Subsection-like commands: unnumberedsubsec appendixsubsec subheading.
|
||||
* Subsub commands: subsubsection.
|
||||
* Syntactic conventions: Conventions.
|
||||
* Syntax, optional & repeated arguments: Optional Arguments.
|
||||
* Table of contents: Contents.
|
||||
* Tables and lists, making them: Lists and Tables.
|
||||
* Tables with indexes: ftable vtable.
|
||||
* Tables, making two-column: Two-column Tables.
|
||||
* Tabs; don't use!: Conventions.
|
||||
* Tag table, making automatically: Tag and Split Files.
|
||||
* Tag table, making manually: Unsplit.
|
||||
* Template for a definition: Def Cmd Template.
|
||||
* Texinfo file beginning: Beginning a File.
|
||||
* Texinfo file ending: Ending a File.
|
||||
* Texinfo file header: Header.
|
||||
* Texinfo file minimum: Minimum.
|
||||
* Texinfo file section structure, showing it: Showing the Structure.
|
||||
* Texinfo mode: Texinfo Mode.
|
||||
* Texinfo overview: Overview.
|
||||
* Texinfo printed book characteristics: Printed Books.
|
||||
* Text, conditionally visible: Conditionals.
|
||||
* Thin space between number, dimension: dmn.
|
||||
* Tips: Tips.
|
||||
* Title page: titlepage.
|
||||
* Titlepage end starts headings: end titlepage.
|
||||
* Titlepage permissions: Titlepage Permissions.
|
||||
* Tree structuring: Tree Structuring.
|
||||
* Two letter names for indices: syncodeindex.
|
||||
* Two named items for @table: itemx.
|
||||
* Two part menu entry: Less Cluttered Menu Entry.
|
||||
* Two `First' Lines for @deffn: deffnx.
|
||||
* Typesetting commands for dots, etc.: Dots Bullets.
|
||||
* Uncluttered menu entry: Less Cluttered Menu Entry.
|
||||
* Unique nodename requirement: Node Line Requirements.
|
||||
* Unprocessed text: Comments.
|
||||
* Unsplit file creation: Unsplit.
|
||||
* Updating nodes and menus: Updating Nodes and Menus.
|
||||
* Updating requirements: Updating Requirements.
|
||||
* Usage tips: Tips.
|
||||
* Validating a large file: Using Info-validate.
|
||||
* Validation of pointers: Pointer Validation.
|
||||
* Value of an expression, indicating: result.
|
||||
* Vertical whitespace (vskip): Copyright & Permissions.
|
||||
* Vertically holding text together: group.
|
||||
* Visibility of conditional text: Conditionals.
|
||||
* Words and phrases, marking them: Marking Text.
|
||||
* Writing a menu: Writing a Menu.
|
||||
* Writing an @node line: Writing a Node.
|
||||
|
||||
|
1289
gnu/usr.bin/texinfo/info-files/texi.info-2
Normal file
1289
gnu/usr.bin/texinfo/info-files/texi.info-2
Normal file
File diff suppressed because it is too large
Load Diff
1262
gnu/usr.bin/texinfo/info-files/texi.info-3
Normal file
1262
gnu/usr.bin/texinfo/info-files/texi.info-3
Normal file
File diff suppressed because it is too large
Load Diff
1412
gnu/usr.bin/texinfo/info-files/texi.info-4
Normal file
1412
gnu/usr.bin/texinfo/info-files/texi.info-4
Normal file
File diff suppressed because it is too large
Load Diff
1433
gnu/usr.bin/texinfo/info-files/texi.info-5
Normal file
1433
gnu/usr.bin/texinfo/info-files/texi.info-5
Normal file
File diff suppressed because it is too large
Load Diff
1461
gnu/usr.bin/texinfo/info-files/texi.info-6
Normal file
1461
gnu/usr.bin/texinfo/info-files/texi.info-6
Normal file
File diff suppressed because it is too large
Load Diff
1307
gnu/usr.bin/texinfo/info-files/texi.info-7
Normal file
1307
gnu/usr.bin/texinfo/info-files/texi.info-7
Normal file
File diff suppressed because it is too large
Load Diff
1056
gnu/usr.bin/texinfo/info-files/texi.info-8
Normal file
1056
gnu/usr.bin/texinfo/info-files/texi.info-8
Normal file
File diff suppressed because it is too large
Load Diff
1210
gnu/usr.bin/texinfo/info-files/texi.info-9
Normal file
1210
gnu/usr.bin/texinfo/info-files/texi.info-9
Normal file
File diff suppressed because it is too large
Load Diff
28
gnu/usr.bin/texinfo/info/Makefile
Normal file
28
gnu/usr.bin/texinfo/info/Makefile
Normal file
@ -0,0 +1,28 @@
|
||||
#
|
||||
# Bmakefile for GNU info
|
||||
#
|
||||
# $id$
|
||||
#
|
||||
|
||||
PROG= info
|
||||
|
||||
SRCS+= dir.c display.c dribble.c echo_area.c filesys.c info-utils.c info.c
|
||||
SRCS+= infodoc.c infomap.c m-x.c nodes.c search.c session.c signals.c
|
||||
SRCS+= terminal.c tilde.c window.c indices.c doc.c nodemenu.c
|
||||
SRCS+= footnotes.c variables.c gc.c xmalloc.c getopt1.c getopt.c
|
||||
|
||||
CFLAGS=
|
||||
|
||||
CFLAGS+= -I${.CURDIR}
|
||||
CFLAGS+= -DNAMED_FUNCTIONS=1 -DSTDC_HEADERS=1
|
||||
CFLAGS+= -DHAVE_UNISTD_H=1 -DHAVE_STRING_H=1 -DHAVE_VARARGS_H=1
|
||||
CFLAGS+= -DHAVE_SYS_FCNTL_H=1 -DHAVE_SETVBUF=1 -DHAVE_GETCWD=1 -DHAVE_BZERO=1
|
||||
CFLAGS+= -DHAVE_RINDEX=1 -DHAVE_VFPRINTF=1 -DHAVE_VSPRINTF=1
|
||||
CFLAGS+= -DHAVE_SYS_TIME_H=1 -DDEFAULT_INFOPATH='"${INFODIR}"'
|
||||
|
||||
LDADD+= -ltermcap
|
||||
DPADD+= ${LIBTERMCAP}
|
||||
|
||||
.include "../../Makefile.inc"
|
||||
.include <bsd.prog.mk>
|
||||
|
224
gnu/usr.bin/texinfo/info/dir.c
Normal file
224
gnu/usr.bin/texinfo/info/dir.c
Normal file
@ -0,0 +1,224 @@
|
||||
/* dir.c -- How to build a special "dir" node from "localdir" files. */
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/errno.h>
|
||||
#include "info-utils.h"
|
||||
#include "filesys.h"
|
||||
#include "tilde.h"
|
||||
|
||||
/* The "dir" node can be built from the contents of a file called "dir",
|
||||
with the addition of the menus of every file called "localdir" found in
|
||||
INFOPATH. */
|
||||
|
||||
static void add_menu_to_file_buffer (), insert_text_into_fb_at_binding ();
|
||||
|
||||
void
|
||||
maybe_build_dir_node (dirname, from_files_named)
|
||||
char *dirname;
|
||||
char *from_files_named;
|
||||
{
|
||||
FILE_BUFFER *dir_buffer;
|
||||
|
||||
/* See if the file has already been loaded and exists. */
|
||||
dir_buffer = info_find_file (dirname);
|
||||
|
||||
/* If there is no "dir" in the current info path, we cannot build one
|
||||
from nothing. */
|
||||
if (!dir_buffer)
|
||||
return;
|
||||
|
||||
/* If this directory has already been built, return now. */
|
||||
if (dir_buffer->flags & N_CannotGC)
|
||||
return;
|
||||
|
||||
dir_buffer->flags |= N_CannotGC;
|
||||
|
||||
/* For every file named FROM_FILES_NAMED in the search path, add the
|
||||
contents of that file's menu to our "dir" node. */
|
||||
{
|
||||
struct stat finfo;
|
||||
char *this_dir;
|
||||
int namelen, path_index;
|
||||
int update_tags = 0;
|
||||
|
||||
namelen = strlen (from_files_named);
|
||||
path_index = 0;
|
||||
|
||||
/* Using each element of the path, check for "localdir". Do not check
|
||||
for "localdir.info.Z" or anything else. Only files explictly named
|
||||
"localdir" are eligible. This is a design decision. There can be
|
||||
an info file name "localdir.info" which contains information on the
|
||||
setting up of "localdir" files. */
|
||||
while (this_dir = extract_colon_unit (infopath, &path_index))
|
||||
{
|
||||
char *fullpath;
|
||||
int statable;
|
||||
|
||||
/* Expand a leading tilde if one is present. */
|
||||
if (*this_dir == '~')
|
||||
{
|
||||
char *tilde_expanded_dirname;
|
||||
|
||||
tilde_expanded_dirname = tilde_expand_word (this_dir);
|
||||
free (this_dir);
|
||||
this_dir = tilde_expanded_dirname;
|
||||
}
|
||||
|
||||
fullpath = (char *)xmalloc (3 + strlen (this_dir) + namelen);
|
||||
strcpy (fullpath, this_dir);
|
||||
if (fullpath[strlen (fullpath) - 1] != '/')
|
||||
strcat (fullpath, "/");
|
||||
strcat (fullpath, from_files_named);
|
||||
|
||||
statable = (stat (fullpath, &finfo) == 0);
|
||||
|
||||
if (statable && S_ISREG (finfo.st_mode))
|
||||
{
|
||||
long filesize;
|
||||
char *contents;
|
||||
|
||||
contents = filesys_read_info_file (fullpath, &filesize, &finfo);
|
||||
|
||||
if (contents)
|
||||
{
|
||||
update_tags++;
|
||||
add_menu_to_file_buffer (contents, filesize, dir_buffer);
|
||||
free (contents);
|
||||
}
|
||||
}
|
||||
|
||||
free (fullpath);
|
||||
free (this_dir);
|
||||
}
|
||||
if (update_tags)
|
||||
build_tags_and_nodes (dir_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
/* Given CONTENTS and FB (a file buffer), add the menu found in CONTENTS
|
||||
to the menu found in FB->contents. Second argument SIZE is the total
|
||||
size of CONTENTS. */
|
||||
static void
|
||||
add_menu_to_file_buffer (contents, size, fb)
|
||||
char *contents;
|
||||
long size;
|
||||
FILE_BUFFER *fb;
|
||||
{
|
||||
SEARCH_BINDING contents_binding, fb_binding;
|
||||
long contents_offset, fb_offset;
|
||||
|
||||
contents_binding.buffer = contents;
|
||||
contents_binding.start = 0;
|
||||
contents_binding.end = size;
|
||||
contents_binding.flags = S_FoldCase | S_SkipDest;
|
||||
|
||||
fb_binding.buffer = fb->contents;
|
||||
fb_binding.start = 0;
|
||||
fb_binding.end = fb->filesize;
|
||||
fb_binding.flags = S_FoldCase | S_SkipDest;
|
||||
|
||||
/* Move to the start of the menus in CONTENTS and FB. */
|
||||
contents_offset = search_forward (INFO_MENU_LABEL, &contents_binding);
|
||||
fb_offset = search_forward (INFO_MENU_LABEL, &fb_binding);
|
||||
|
||||
/* If there is no menu in CONTENTS, quit now. */
|
||||
if (contents_offset == -1)
|
||||
return;
|
||||
|
||||
/* If there is no menu in FB, make one. */
|
||||
if (fb_offset == -1)
|
||||
{
|
||||
/* Find the start of the second node in this file buffer. If there
|
||||
is only one node, we will be adding the contents to the end of
|
||||
this node. */
|
||||
fb_offset = find_node_separator (&fb_binding);
|
||||
|
||||
/* If not even a single node separator, give up. */
|
||||
if (fb_offset == -1)
|
||||
return;
|
||||
|
||||
fb_binding.start = fb_offset;
|
||||
fb_binding.start +=
|
||||
skip_node_separator (fb_binding.buffer + fb_binding.start);
|
||||
|
||||
/* Try to find the next node separator. */
|
||||
fb_offset = find_node_separator (&fb_binding);
|
||||
|
||||
/* If found one, consider that the start of the menu. Otherwise, the
|
||||
start of this menu is the end of the file buffer (i.e., fb->size). */
|
||||
if (fb_offset != -1)
|
||||
fb_binding.start = fb_offset;
|
||||
else
|
||||
fb_binding.start = fb_binding.end;
|
||||
|
||||
insert_text_into_fb_at_binding
|
||||
(fb, &fb_binding, INFO_MENU_LABEL, strlen (INFO_MENU_LABEL));
|
||||
|
||||
fb_binding.buffer = fb->contents;
|
||||
fb_binding.start = 0;
|
||||
fb_binding.end = fb->filesize;
|
||||
fb_offset = search_forward (INFO_MENU_LABEL, &fb_binding);
|
||||
if (fb_offset == -1)
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* CONTENTS_OFFSET and FB_OFFSET point to the starts of the menus that
|
||||
appear in their respective buffers. Add the remainder of CONTENTS
|
||||
to the end of FB's menu. */
|
||||
fb_binding.start = fb_offset;
|
||||
fb_offset = find_node_separator (&fb_binding);
|
||||
if (fb_offset != -1)
|
||||
fb_binding.start = fb_offset;
|
||||
else
|
||||
fb_binding.start = fb_binding.end;
|
||||
|
||||
insert_text_into_fb_at_binding
|
||||
(fb, &fb_binding, contents + contents_offset, size - contents_offset);
|
||||
}
|
||||
|
||||
static void
|
||||
insert_text_into_fb_at_binding (fb, binding, text, textlen)
|
||||
FILE_BUFFER *fb;
|
||||
SEARCH_BINDING *binding;
|
||||
char *text;
|
||||
int textlen;
|
||||
{
|
||||
char *contents;
|
||||
long start, end;
|
||||
|
||||
start = binding->start;
|
||||
end = fb->filesize;
|
||||
|
||||
contents = (char *)xmalloc (fb->filesize + textlen + 1);
|
||||
memcpy (contents, fb->contents, start);
|
||||
memcpy (contents + start, text, textlen);
|
||||
memcpy (contents + start + textlen, fb->contents + start, end - start);
|
||||
free (fb->contents);
|
||||
fb->contents = contents;
|
||||
fb->filesize += textlen;
|
||||
fb->finfo.st_size = fb->filesize;
|
||||
}
|
561
gnu/usr.bin/texinfo/info/display.c
Normal file
561
gnu/usr.bin/texinfo/info/display.c
Normal file
@ -0,0 +1,561 @@
|
||||
/* display.c -- How to display Info windows. */
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include "display.h"
|
||||
|
||||
extern int info_any_buffered_input_p (); /* Found in session.c. */
|
||||
|
||||
static void free_display ();
|
||||
static DISPLAY_LINE **make_display ();
|
||||
|
||||
/* An array of display lines which tell us what is currently visible on
|
||||
the display. */
|
||||
DISPLAY_LINE **the_display = (DISPLAY_LINE **)NULL;
|
||||
|
||||
/* Non-zero means do no output. */
|
||||
int display_inhibited = 0;
|
||||
|
||||
/* Initialize THE_DISPLAY to WIDTH and HEIGHT, with nothing in it. */
|
||||
void
|
||||
display_initialize_display (width, height)
|
||||
int width, height;
|
||||
{
|
||||
free_display (the_display);
|
||||
the_display = make_display (width, height);
|
||||
display_clear_display (the_display);
|
||||
}
|
||||
|
||||
/* Clear all of the lines in DISPLAY making the screen blank. */
|
||||
void
|
||||
display_clear_display (display)
|
||||
DISPLAY_LINE **display;
|
||||
{
|
||||
register int i;
|
||||
register DISPLAY_LINE *display_line;
|
||||
|
||||
for (i = 0; display_line = display[i]; i++)
|
||||
{
|
||||
display[i]->text[0] = '\0';
|
||||
display[i]->textlen = 0;
|
||||
display[i]->inverse = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Non-zero if we didn't completely redisplay a window. */
|
||||
int display_was_interrupted_p = 0;
|
||||
|
||||
/* Update the windows pointed to by WINDOW in the_display. This actually
|
||||
writes the text on the screen. */
|
||||
void
|
||||
display_update_display (window)
|
||||
WINDOW *window;
|
||||
{
|
||||
register WINDOW *win;
|
||||
|
||||
display_was_interrupted_p = 0;
|
||||
|
||||
/* For every window in the list, check contents against the display. */
|
||||
for (win = window; win; win = win->next)
|
||||
{
|
||||
/* Only re-display visible windows which need updating. */
|
||||
if (((win->flags & W_WindowVisible) == 0) ||
|
||||
((win->flags & W_UpdateWindow) == 0) ||
|
||||
(win->height == 0))
|
||||
continue;
|
||||
|
||||
display_update_one_window (win);
|
||||
if (display_was_interrupted_p)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Always update the echo area. */
|
||||
display_update_one_window (the_echo_area);
|
||||
}
|
||||
|
||||
/* Display WIN on the_display. Unlike display_update_display (), this
|
||||
function only does one window. */
|
||||
void
|
||||
display_update_one_window (win)
|
||||
WINDOW *win;
|
||||
{
|
||||
register char *nodetext; /* Current character to display. */
|
||||
register char *last_node_char; /* Position of the last character in node. */
|
||||
register int i; /* General use index. */
|
||||
char *printed_line; /* Buffer for a printed line. */
|
||||
int pl_index = 0; /* Index into PRINTED_LINE. */
|
||||
int line_index = 0; /* Number of lines done so far. */
|
||||
DISPLAY_LINE **display = the_display;
|
||||
|
||||
/* If display is inhibited, that counts as an interrupted display. */
|
||||
if (display_inhibited)
|
||||
display_was_interrupted_p = 1;
|
||||
|
||||
/* If the window has no height, or display is inhibited, quit now. */
|
||||
if (!win->height || display_inhibited)
|
||||
return;
|
||||
|
||||
/* If the window's first row doesn't appear in the_screen, then it
|
||||
cannot be displayed. This can happen when the_echo_area is the
|
||||
window to be displayed, and the screen has shrunk to less than one
|
||||
line. */
|
||||
if ((win->first_row < 0) || (win->first_row > the_screen->height))
|
||||
return;
|
||||
|
||||
/* Print each line in the window into our local buffer, and then
|
||||
check the contents of that buffer against the display. If they
|
||||
differ, update the display. */
|
||||
printed_line = (char *)xmalloc (1 + win->width);
|
||||
|
||||
if (!win->node || !win->line_starts)
|
||||
goto done_with_node_display;
|
||||
|
||||
nodetext = win->line_starts[win->pagetop];
|
||||
last_node_char = win->node->contents + win->node->nodelen;
|
||||
|
||||
for (; nodetext < last_node_char; nodetext++)
|
||||
{
|
||||
char *rep, *rep_carried_over, rep_temp[2];
|
||||
int replen;
|
||||
|
||||
if (isprint (*nodetext))
|
||||
{
|
||||
rep_temp[0] = *nodetext;
|
||||
replen = 1;
|
||||
rep_temp[1] = '\0';
|
||||
rep = rep_temp;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*nodetext == '\r' || *nodetext == '\n')
|
||||
{
|
||||
replen = win->width - pl_index;
|
||||
}
|
||||
else
|
||||
{
|
||||
rep = printed_representation (*nodetext, pl_index);
|
||||
replen = strlen (rep);
|
||||
}
|
||||
}
|
||||
|
||||
/* If this character can be printed without passing the width of
|
||||
the line, then stuff it into the line. */
|
||||
if (replen + pl_index < win->width)
|
||||
{
|
||||
/* Optimize if possible. */
|
||||
if (replen == 1)
|
||||
{
|
||||
printed_line[pl_index++] = *rep;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < replen; i++)
|
||||
printed_line[pl_index++] = rep[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DISPLAY_LINE *entry;
|
||||
|
||||
/* If this character cannot be printed in this line, we have
|
||||
found the end of this line as it would appear on the screen.
|
||||
Carefully print the end of the line, and then compare. */
|
||||
if (*nodetext == '\n' || *nodetext == '\r' || *nodetext == '\t')
|
||||
{
|
||||
printed_line[pl_index] = '\0';
|
||||
rep_carried_over = (char *)NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The printed representation of this character extends into
|
||||
the next line. Remember the offset of the last character
|
||||
printed out of REP so that we can carry the character over
|
||||
to the next line. */
|
||||
for (i = 0; pl_index < (win->width - 1);)
|
||||
printed_line[pl_index++] = rep[i++];
|
||||
|
||||
rep_carried_over = rep + i;
|
||||
|
||||
/* If printing the last character in this window couldn't
|
||||
possibly cause the screen to scroll, place a backslash
|
||||
in the rightmost column. */
|
||||
if (1 + line_index + win->first_row < the_screen->height)
|
||||
{
|
||||
if (win->flags & W_NoWrap)
|
||||
printed_line[pl_index++] = '$';
|
||||
else
|
||||
printed_line[pl_index++] = '\\';
|
||||
}
|
||||
printed_line[pl_index] = '\0';
|
||||
}
|
||||
|
||||
/* We have the exact line as it should appear on the screen.
|
||||
Check to see if this line matches the one already appearing
|
||||
on the screen. */
|
||||
entry = display[line_index + win->first_row];
|
||||
|
||||
/* If the screen line is inversed, then we have to clear
|
||||
the line from the screen first. Why, I don't know. */
|
||||
if (entry->inverse)
|
||||
{
|
||||
terminal_goto_xy (0, line_index + win->first_row);
|
||||
terminal_clear_to_eol ();
|
||||
entry->inverse = 0;
|
||||
entry->text[0] = '\0';
|
||||
entry->textlen = 0;
|
||||
}
|
||||
|
||||
/* Find the offset where these lines differ. */
|
||||
for (i = 0; i < pl_index; i++)
|
||||
if (printed_line[i] != entry->text[i])
|
||||
break;
|
||||
|
||||
/* If the lines are not the same length, or if they differed
|
||||
at all, we must do some redrawing. */
|
||||
if ((i != pl_index) || (pl_index != entry->textlen))
|
||||
{
|
||||
/* Move to the proper point on the terminal. */
|
||||
terminal_goto_xy (i, line_index + win->first_row);
|
||||
|
||||
/* If there is any text to print, print it. */
|
||||
if (i != pl_index)
|
||||
terminal_put_text (printed_line + i);
|
||||
|
||||
/* If the printed text didn't extend all the way to the edge
|
||||
of the window, and text was appearing between here and the
|
||||
edge of the window, clear from here to the end of the line. */
|
||||
if ((pl_index < win->width && pl_index < entry->textlen) ||
|
||||
(entry->inverse))
|
||||
terminal_clear_to_eol ();
|
||||
|
||||
fflush (stdout);
|
||||
|
||||
/* Update the display text buffer. */
|
||||
strcpy (entry->text + i, printed_line + i);
|
||||
entry->textlen = pl_index;
|
||||
|
||||
/* Lines showing node text are not in inverse. Only modelines
|
||||
have that distinction. */
|
||||
entry->inverse = 0;
|
||||
}
|
||||
|
||||
/* We have done at least one line. Increment our screen line
|
||||
index, and check against the bottom of the window. */
|
||||
if (++line_index == win->height)
|
||||
break;
|
||||
|
||||
/* A line has been displayed, and the screen reflects that state.
|
||||
If there is typeahead pending, then let that typeahead be read
|
||||
now, instead of continuing with the display. */
|
||||
if (info_any_buffered_input_p ())
|
||||
{
|
||||
free (printed_line);
|
||||
display_was_interrupted_p = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Reset PL_INDEX to the start of the line. */
|
||||
pl_index = 0;
|
||||
|
||||
/* If there are characters from REP left to print, stuff them
|
||||
into the buffer now. */
|
||||
if (rep_carried_over)
|
||||
for (; rep[pl_index]; pl_index++)
|
||||
printed_line[pl_index] = rep[pl_index];
|
||||
|
||||
/* If this window has chosen not to wrap lines, skip to the end
|
||||
of the physical line in the buffer, and start a new line here. */
|
||||
if (pl_index && (win->flags & W_NoWrap))
|
||||
{
|
||||
char *begin;
|
||||
|
||||
pl_index = 0;
|
||||
printed_line[0] = '\0';
|
||||
|
||||
begin = nodetext;
|
||||
|
||||
while ((nodetext < last_node_char) && (*nodetext != '\n'))
|
||||
nodetext++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
done_with_node_display:
|
||||
/* We have reached the end of the node or the end of the window. If it
|
||||
is the end of the node, then clear the lines of the window from here
|
||||
to the end of the window. */
|
||||
for (; line_index < win->height; line_index++)
|
||||
{
|
||||
DISPLAY_LINE *entry = display[line_index + win->first_row];
|
||||
|
||||
/* If this line has text on it then make it go away. */
|
||||
if (entry && entry->textlen)
|
||||
{
|
||||
entry->textlen = 0;
|
||||
entry->text[0] = '\0';
|
||||
|
||||
terminal_goto_xy (0, line_index + win->first_row);
|
||||
terminal_clear_to_eol ();
|
||||
}
|
||||
}
|
||||
|
||||
/* Finally, if this window has a modeline it might need to be redisplayed.
|
||||
Check the window's modeline against the one in the display, and update
|
||||
if necessary. */
|
||||
if ((win->flags & W_InhibitMode) == 0)
|
||||
{
|
||||
window_make_modeline (win);
|
||||
line_index = win->first_row + win->height;
|
||||
|
||||
/* This display line must both be in inverse, and have the same
|
||||
contents. */
|
||||
if ((!display[line_index]->inverse) ||
|
||||
(strcmp (display[line_index]->text, win->modeline) != 0))
|
||||
{
|
||||
terminal_goto_xy (0, line_index);
|
||||
terminal_begin_inverse ();
|
||||
terminal_put_text (win->modeline);
|
||||
terminal_end_inverse ();
|
||||
strcpy (display[line_index]->text, win->modeline);
|
||||
display[line_index]->inverse = 1;
|
||||
display[line_index]->textlen = strlen (win->modeline);
|
||||
fflush (stdout);
|
||||
}
|
||||
}
|
||||
|
||||
/* Okay, this window doesn't need updating anymore. */
|
||||
win->flags &= ~W_UpdateWindow;
|
||||
free (printed_line);
|
||||
fflush (stdout);
|
||||
}
|
||||
|
||||
/* Scroll the region of the_display starting at START, ending at END, and
|
||||
moving the lines AMOUNT lines. If AMOUNT is less than zero, the lines
|
||||
are moved up in the screen, otherwise down. Actually, it is possible
|
||||
for no scrolling to take place in the case that the terminal doesn't
|
||||
support it. This doesn't matter to us. */
|
||||
void
|
||||
display_scroll_display (start, end, amount)
|
||||
int start, end, amount;
|
||||
{
|
||||
register int i, last;
|
||||
DISPLAY_LINE *temp;
|
||||
|
||||
/* If this terminal cannot do scrolling, give up now. */
|
||||
if (!terminal_can_scroll)
|
||||
return;
|
||||
|
||||
/* If there isn't anything displayed on the screen because it is too
|
||||
small, quit now. */
|
||||
if (!the_display[0])
|
||||
return;
|
||||
|
||||
/* If there is typeahead pending, then don't actually do any scrolling. */
|
||||
if (info_any_buffered_input_p ())
|
||||
return;
|
||||
|
||||
/* Do it on the screen. */
|
||||
terminal_scroll_terminal (start, end, amount);
|
||||
|
||||
/* Now do it in the display buffer so our contents match the screen. */
|
||||
if (amount > 0)
|
||||
{
|
||||
last = end + amount;
|
||||
|
||||
/* Shift the lines to scroll right into place. */
|
||||
for (i = 0; i < (end - start); i++)
|
||||
{
|
||||
temp = the_display[last - i];
|
||||
the_display[last - i] = the_display[end - i];
|
||||
the_display[end - i] = temp;
|
||||
}
|
||||
|
||||
/* The lines have been shifted down in the buffer. Clear all of the
|
||||
lines that were vacated. */
|
||||
for (i = start; i != (start + amount); i++)
|
||||
{
|
||||
the_display[i]->text[0] = '\0';
|
||||
the_display[i]->textlen = 0;
|
||||
the_display[i]->inverse = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (amount < 0)
|
||||
{
|
||||
last = start + amount;
|
||||
for (i = 0; i < (end - start); i++)
|
||||
{
|
||||
temp = the_display[last + i];
|
||||
the_display[last + i] = the_display[start + i];
|
||||
the_display[start + i] = temp;
|
||||
}
|
||||
|
||||
/* The lines have been shifted up in the buffer. Clear all of the
|
||||
lines that are left over. */
|
||||
for (i = end + amount; i != end; i++)
|
||||
{
|
||||
the_display[i]->text[0] = '\0';
|
||||
the_display[i]->textlen = 0;
|
||||
the_display[i]->inverse = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Try to scroll lines in WINDOW. OLD_PAGETOP is the pagetop of WINDOW before
|
||||
having had its line starts recalculated. OLD_STARTS is the list of line
|
||||
starts that used to appear in this window. OLD_COUNT is the number of lines
|
||||
that appear in the OLD_STARTS array. */
|
||||
void
|
||||
display_scroll_line_starts (window, old_pagetop, old_starts, old_count)
|
||||
WINDOW *window;
|
||||
int old_pagetop, old_count;
|
||||
char **old_starts;
|
||||
{
|
||||
register int i, old, new; /* Indices into the line starts arrays. */
|
||||
int last_new, last_old; /* Index of the last visible line. */
|
||||
int old_first, new_first; /* Index of the first changed line. */
|
||||
int unchanged_at_top = 0;
|
||||
int already_scrolled = 0;
|
||||
|
||||
/* Locate the first line which was displayed on the old window. */
|
||||
old_first = old_pagetop;
|
||||
new_first = window->pagetop;
|
||||
|
||||
/* Find the last line currently visible in this window. */
|
||||
last_new = window->pagetop + (window->height - 1);
|
||||
if (last_new > window->line_count)
|
||||
last_new = window->line_count - 1;
|
||||
|
||||
/* Find the last line which used to be currently visible in this window. */
|
||||
last_old = old_pagetop + (window->height - 1);
|
||||
if (last_old > old_count)
|
||||
last_old = old_count - 1;
|
||||
|
||||
for (old = old_first, new = new_first;
|
||||
old < last_old && new < last_new;
|
||||
old++, new++)
|
||||
if (old_starts[old] != window->line_starts[new])
|
||||
break;
|
||||
else
|
||||
unchanged_at_top++;
|
||||
|
||||
/* Loop through the old lines looking for a match in the new lines. */
|
||||
for (old = old_first + unchanged_at_top; old < last_old; old++)
|
||||
{
|
||||
for (new = new_first; new < last_new; new++)
|
||||
if (old_starts[old] == window->line_starts[new])
|
||||
{
|
||||
/* Find the extent of the matching lines. */
|
||||
for (i = 0; (old + i) < last_old; i++)
|
||||
if (old_starts[old + i] != window->line_starts[new + i])
|
||||
break;
|
||||
|
||||
/* Scroll these lines if there are enough of them. */
|
||||
{
|
||||
int start, end, amount;
|
||||
|
||||
start = (window->first_row
|
||||
+ ((old + already_scrolled) - old_pagetop));
|
||||
amount = new - (old + already_scrolled);
|
||||
end = window->first_row + window->height;
|
||||
|
||||
/* If we are shifting the block of lines down, then the last
|
||||
AMOUNT lines will become invisible. Thus, don't bother
|
||||
scrolling them. */
|
||||
if (amount > 0)
|
||||
end -= amount;
|
||||
|
||||
if ((end - start) > 0)
|
||||
{
|
||||
display_scroll_display (start, end, amount);
|
||||
|
||||
/* Some lines have been scrolled. Simulate the scrolling
|
||||
by offsetting the value of the old index. */
|
||||
old += i;
|
||||
already_scrolled += amount;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Move the screen cursor to directly over the current character in WINDOW. */
|
||||
void
|
||||
display_cursor_at_point (window)
|
||||
WINDOW *window;
|
||||
{
|
||||
int vpos, hpos;
|
||||
|
||||
vpos = window_line_of_point (window) - window->pagetop + window->first_row;
|
||||
hpos = window_get_cursor_column (window);
|
||||
terminal_goto_xy (hpos, vpos);
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Functions Static to this File */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Make a DISPLAY_LINE ** with width and height. */
|
||||
static DISPLAY_LINE **
|
||||
make_display (width, height)
|
||||
int width, height;
|
||||
{
|
||||
register int i;
|
||||
DISPLAY_LINE **display;
|
||||
|
||||
display = (DISPLAY_LINE **)xmalloc ((1 + height) * sizeof (DISPLAY_LINE *));
|
||||
|
||||
for (i = 0; i < height; i++)
|
||||
{
|
||||
display[i] = (DISPLAY_LINE *)xmalloc (sizeof (DISPLAY_LINE));
|
||||
display[i]->text = (char *)xmalloc (1 + width);
|
||||
display[i]->textlen = 0;
|
||||
display[i]->inverse = 0;
|
||||
}
|
||||
display[i] = (DISPLAY_LINE *)NULL;
|
||||
return (display);
|
||||
}
|
||||
|
||||
/* Free the storage allocated to DISPLAY. */
|
||||
static void
|
||||
free_display (display)
|
||||
DISPLAY_LINE **display;
|
||||
{
|
||||
register int i;
|
||||
register DISPLAY_LINE *display_line;
|
||||
|
||||
if (!display)
|
||||
return;
|
||||
|
||||
for (i = 0; display_line = display[i]; i++)
|
||||
{
|
||||
free (display_line->text);
|
||||
free (display_line);
|
||||
}
|
||||
free (display);
|
||||
}
|
76
gnu/usr.bin/texinfo/info/display.h
Normal file
76
gnu/usr.bin/texinfo/info/display.h
Normal file
@ -0,0 +1,76 @@
|
||||
/* display.h -- How the display in Info is done. */
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#ifndef _DISPLAY_H_
|
||||
#define _DISPLAY_H_
|
||||
|
||||
#include "info-utils.h"
|
||||
#include "terminal.h"
|
||||
|
||||
typedef struct {
|
||||
char *text; /* Text of the line as it appears. */
|
||||
int textlen; /* Printable Length of TEXT. */
|
||||
int inverse; /* Non-zero means this line is inverse. */
|
||||
} DISPLAY_LINE;
|
||||
|
||||
/* An array of display lines which tell us what is currently visible on
|
||||
the display. */
|
||||
extern DISPLAY_LINE **the_display;
|
||||
|
||||
/* Non-zero means do no output. */
|
||||
extern int display_inhibited;
|
||||
|
||||
/* Non-zero if we didn't completely redisplay a window. */
|
||||
extern int display_was_interrupted_p;
|
||||
|
||||
/* Initialize THE_DISPLAY to WIDTH and HEIGHT, with nothing in it. */
|
||||
extern void display_initialize_display ();
|
||||
|
||||
/* Clear all of the lines in DISPLAY making the screen blank. */
|
||||
extern void display_clear_display ();
|
||||
|
||||
/* Update the windows pointed to by WINDOWS in THE_DISPLAY. This actually
|
||||
writes the text on the screen. */
|
||||
extern void display_update_display ();
|
||||
|
||||
/* Display WIN on THE_DISPLAY. Unlike display_update_display (), this
|
||||
function only does one window. */
|
||||
extern void display_update_one_window ();
|
||||
|
||||
/* Move the screen cursor to directly over the current character in WINDOW. */
|
||||
extern void display_cursor_at_point ();
|
||||
|
||||
/* Scroll the region of the_display starting at START, ending at END, and
|
||||
moving the lines AMOUNT lines. If AMOUNT is less than zero, the lines
|
||||
are moved up in the screen, otherwise down. Actually, it is possible
|
||||
for no scrolling to take place in the case that the terminal doesn't
|
||||
support it. This doesn't matter to us. */
|
||||
extern void display_scroll_display ();
|
||||
|
||||
/* Try to scroll lines in WINDOW. OLD_PAGETOP is the pagetop of WINDOW before
|
||||
having had its line starts recalculated. OLD_STARTS is the list of line
|
||||
starts that used to appear in this window. OLD_COUNT is the number of lines
|
||||
that appear in the OLD_STARTS array. */
|
||||
extern void display_scroll_line_starts ();
|
||||
|
||||
#endif /* !_DISPLAY_H_ */
|
128
gnu/usr.bin/texinfo/info/doc.c
Normal file
128
gnu/usr.bin/texinfo/info/doc.c
Normal file
@ -0,0 +1,128 @@
|
||||
/* doc.c -- Generated structure containing function names and doc strings.
|
||||
|
||||
This file was automatically made from various source files with the
|
||||
command "./makedoc". DO NOT EDIT THIS FILE, only "./makedoc.c".
|
||||
Source files groveled to make this file include:
|
||||
|
||||
./session.c
|
||||
./echo_area.c
|
||||
./infodoc.c
|
||||
./m-x.c
|
||||
./indices.c
|
||||
./nodemenu.c
|
||||
./footnotes.c
|
||||
./variables.c
|
||||
|
||||
An entry in the array FUNCTION_DOC_ARRAY is made for each command
|
||||
found in the above files; each entry consists of a function pointer,
|
||||
a string which is the user-visible name of the function,
|
||||
and a string which documents its purpose. */
|
||||
|
||||
#include "doc.h"
|
||||
#include "funs.h"
|
||||
|
||||
FUNCTION_DOC function_doc_array[] = {
|
||||
|
||||
/* Commands found in "./session.c". */
|
||||
{ info_next_line, "next-line", "Move down to the next line" },
|
||||
{ info_prev_line, "prev-line", "Move up to the previous line" },
|
||||
{ info_end_of_line, "end-of-line", "Move to the end of the line" },
|
||||
{ info_beginning_of_line, "beginning-of-line", "Move to the start of the line" },
|
||||
{ info_forward_char, "forward-char", "Move forward a character" },
|
||||
{ info_backward_char, "backward-char", "Move backward a character" },
|
||||
{ info_forward_word, "forward-word", "Move forward a word" },
|
||||
{ info_backward_word, "backward-word", "Move backward a word" },
|
||||
{ info_global_next_node, "global-next-node", "Move forwards or down through node structure" },
|
||||
{ info_global_prev_node, "global-prev-node", "Move backwards or up through node structure" },
|
||||
{ info_scroll_forward, "scroll-forward", "Scroll forward in this window" },
|
||||
{ info_scroll_backward, "scroll-backward", "Scroll backward in this window" },
|
||||
{ info_beginning_of_node, "beginning-of-node", "Move to the start of this node" },
|
||||
{ info_end_of_node, "end-of-node", "Move to the end of this node" },
|
||||
{ info_next_window, "next-window", "Select the next window" },
|
||||
{ info_prev_window, "prev-window", "Select the previous window" },
|
||||
{ info_split_window, "split-window", "Split the current window" },
|
||||
{ info_delete_window, "delete-window", "Delete the current window" },
|
||||
{ info_keep_one_window, "keep-one-window", "Delete all other windows" },
|
||||
{ info_scroll_other_window, "scroll-other-window", "Scroll the other window" },
|
||||
{ info_grow_window, "grow-window", "Grow (or shrink) this window" },
|
||||
{ info_tile_windows, "tile-windows", "Divide the available screen space among the visible windows" },
|
||||
{ info_toggle_wrap, "toggle-wrap", "Toggle the state of line wrapping in the current window" },
|
||||
{ info_next_node, "next-node", "Select the `Next' node" },
|
||||
{ info_prev_node, "prev-node", "Select the `Prev' node" },
|
||||
{ info_up_node, "up-node", "Select the `Up' node" },
|
||||
{ info_last_node, "last-node", "Select the last node in this file" },
|
||||
{ info_first_node, "first-node", "Select the first node in this file" },
|
||||
{ info_history_node, "history-node", "Select the most recently selected node" },
|
||||
{ info_last_menu_item, "last-menu-item", "Select the last item in this node's menu" },
|
||||
{ info_menu_digit, "menu-digit", "Select this menu item" },
|
||||
{ info_menu_item, "menu-item", "Read a menu item and select its node" },
|
||||
{ info_xref_item, "xref-item", "Read a footnote or cross reference and select its node" },
|
||||
{ info_find_menu, "find-menu", "Move to the start of this node's menu" },
|
||||
{ info_visit_menu, "visit-menu", "Visit as many menu items at once as possible" },
|
||||
{ info_goto_node, "goto-node", "Read a node name and select it" },
|
||||
{ info_top_node, "top-node", "Select the node `Top' in this file" },
|
||||
{ info_dir_node, "dir-node", "Select the node `(dir)'" },
|
||||
{ info_kill_node, "kill-node", "Kill this node" },
|
||||
{ info_view_file, "view-file", "Read the name of a file and select it" },
|
||||
{ info_print_node, "print-node", "Pipe the contents of this node through INFO_PRINT_COMMAND" },
|
||||
{ info_search, "search", "Read a string and search for it" },
|
||||
{ isearch_forward, "isearch-forward", "Search interactively for a string as you type it" },
|
||||
{ isearch_backward, "isearch-backward", "Search interactively for a string as you type it" },
|
||||
{ info_move_to_prev_xref, "move-to-prev-xref", "Move to the previous cross reference" },
|
||||
{ info_move_to_next_xref, "move-to-next-xref", "Move to the next cross reference" },
|
||||
{ info_select_reference_this_line, "select-reference-this-line", "Select reference or menu item appearing on this line" },
|
||||
{ info_abort_key, "abort-key", "Cancel current operation" },
|
||||
{ info_move_to_window_line, "move-to-window-line", "Move to the cursor to a specific line of the window" },
|
||||
{ info_redraw_display, "redraw-display", "Redraw the display" },
|
||||
{ info_quit, "quit", "Quit using Info" },
|
||||
{ info_do_lowercase_version, "do-lowercase-version", "" },
|
||||
{ info_add_digit_to_numeric_arg, "add-digit-to-numeric-arg", "Add this digit to the current numeric argument" },
|
||||
{ info_universal_argument, "universal-argument", "Start (or multiply by 4) the current numeric argument" },
|
||||
{ info_numeric_arg_digit_loop, "numeric-arg-digit-loop", "" },
|
||||
/* Commands found in "./echo_area.c". */
|
||||
{ ea_forward, "echo-area-forward", "Move forward a character" },
|
||||
{ ea_backward, "echo-area-backward", "Move backward a character" },
|
||||
{ ea_beg_of_line, "echo-area-beg-of-line", "Move to the start of this line" },
|
||||
{ ea_end_of_line, "echo-area-end-of-line", "Move to the end of this line" },
|
||||
{ ea_forward_word, "echo-area-forward-word", "Move forward a word" },
|
||||
{ ea_backward_word, "echo-area-backward-word", "Move backward a word" },
|
||||
{ ea_delete, "echo-area-delete", "Delete the character under the cursor" },
|
||||
{ ea_rubout, "echo-area-rubout", "Delete the character behind the cursor" },
|
||||
{ ea_abort, "echo-area-abort", "Cancel or quit operation" },
|
||||
{ ea_newline, "echo-area-newline", "Accept (or force completion of) this line" },
|
||||
{ ea_quoted_insert, "echo-area-quoted-insert", "Insert next character verbatim" },
|
||||
{ ea_insert, "echo-area-insert", "Insert this character" },
|
||||
{ ea_tab_insert, "echo-area-tab-insert", "Insert a TAB character" },
|
||||
{ ea_transpose_chars, "echo-area-transpose-chars", "Transpose characters at point" },
|
||||
{ ea_yank, "echo-area-yank", "Yank back the contents of the last kill" },
|
||||
{ ea_yank_pop, "echo-area-yank-pop", "Yank back a previous kill" },
|
||||
{ ea_kill_line, "echo-area-kill-line", "Kill to the end of the line" },
|
||||
{ ea_backward_kill_line, "echo-area-backward-kill-line", "Kill to the beginning of the line" },
|
||||
{ ea_kill_word, "echo-area-kill-word", "Kill the word following the cursor" },
|
||||
{ ea_backward_kill_word, "echo-area-backward-kill-word", "Kill the word preceding the cursor" },
|
||||
{ ea_possible_completions, "echo-area-possible-completions", "List possible completions" },
|
||||
{ ea_complete, "echo-area-complete", "Insert completion" },
|
||||
{ ea_scroll_completions_window, "echo-area-scroll-completions-window", "Scroll the completions window" },
|
||||
/* Commands found in "./infodoc.c". */
|
||||
{ info_get_help_window, "get-help-window", "Display help message" },
|
||||
{ info_get_info_help_node, "get-info-help-node", "Visit Info node `(info)Help'" },
|
||||
{ describe_key, "describe-key", "Print documentation for KEY" },
|
||||
{ info_where_is, "where-is", "Show what to type to execute a given command" },
|
||||
/* Commands found in "./m-x.c". */
|
||||
{ describe_command, "describe-command", "Read the name of an Info command and describe it" },
|
||||
{ info_execute_command, "execute-command", "Read a command name in the echo area and execute it" },
|
||||
{ set_screen_height, "set-screen-height", "Set the height of the displayed window" },
|
||||
/* Commands found in "./indices.c". */
|
||||
{ info_index_search, "index-search", "Look up a string in the index for this file" },
|
||||
{ info_next_index_match, "next-index-match", "Go to the next matching index item from the last `\\[index-search]' command" },
|
||||
{ info_index_apropos, "index-apropos", "Grovel all known info file's indices for a string and build a menu" },
|
||||
/* Commands found in "./nodemenu.c". */
|
||||
{ list_visited_nodes, "list-visited-nodes", "Make a window containing a menu of all of the currently visited nodes" },
|
||||
{ select_visited_node, "select-visited-node", "Select a node which has been previously visited in a visible window" },
|
||||
/* Commands found in "./footnotes.c". */
|
||||
{ info_show_footnotes, "show-footnotes", "Show the footnotes associated with this node in another window" },
|
||||
/* Commands found in "./variables.c". */
|
||||
{ describe_variable, "describe-variable", "Explain the use of a variable" },
|
||||
{ set_variable, "set-variable", "Set the value of an Info variable" },
|
||||
{ (VFunction *)NULL, (char *)NULL, (char *)NULL }
|
||||
};
|
58
gnu/usr.bin/texinfo/info/doc.h
Normal file
58
gnu/usr.bin/texinfo/info/doc.h
Normal file
@ -0,0 +1,58 @@
|
||||
/* doc.h -- Structure associating function pointers with documentation. */
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#ifndef _DOC_H_
|
||||
#define _DOC_H_
|
||||
|
||||
#if !defined (NULL)
|
||||
# define NULL 0x0
|
||||
#endif /* !NULL */
|
||||
|
||||
#if !defined (__FUNCTION_DEF)
|
||||
# define __FUNCTION_DEF
|
||||
typedef int Function ();
|
||||
typedef void VFunction ();
|
||||
#endif /* _FUNCTION_DEF */
|
||||
|
||||
typedef struct {
|
||||
VFunction *func;
|
||||
#if defined (NAMED_FUNCTIONS)
|
||||
char *func_name;
|
||||
#endif /* NAMED_FUNCTIONS */
|
||||
char *doc;
|
||||
} FUNCTION_DOC;
|
||||
|
||||
extern FUNCTION_DOC function_doc_array[];
|
||||
|
||||
extern char *function_documentation ();
|
||||
extern char *key_documentation ();
|
||||
extern char *pretty_keyname ();
|
||||
extern char *replace_in_documentation ();
|
||||
extern void info_document_key ();
|
||||
extern void dump_map_to_message_buffer ();
|
||||
|
||||
#if defined (NAMED_FUNCTIONS)
|
||||
extern char *function_name ();
|
||||
extern VFunction *named_function ();
|
||||
#endif /* NAMED_FUNCTIONS */
|
||||
#endif /* !_DOC_H_ */
|
71
gnu/usr.bin/texinfo/info/dribble.c
Normal file
71
gnu/usr.bin/texinfo/info/dribble.c
Normal file
@ -0,0 +1,71 @@
|
||||
/* dribble.c -- Dribble files for Info. */
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "dribble.h"
|
||||
|
||||
/* When non-zero, it is a stream to write all input characters to for the
|
||||
duration of this info session. */
|
||||
FILE *info_dribble_file = (FILE *)NULL;
|
||||
|
||||
/* Open a dribble file named NAME, perhaps closing an already open one.
|
||||
This sets the global variable INFO_DRIBBLE_FILE to the open stream. */
|
||||
void
|
||||
open_dribble_file (name)
|
||||
char *name;
|
||||
{
|
||||
/* Perhaps close existing dribble file. */
|
||||
close_dribble_file ();
|
||||
|
||||
info_dribble_file = fopen (name, "w");
|
||||
|
||||
#if defined (HAVE_SETVBUF)
|
||||
if (info_dribble_file)
|
||||
# if defined (SETVBUF_REVERSED)
|
||||
setvbuf (info_dribble_file, _IONBF, (char *)NULL, 1);
|
||||
# else
|
||||
setvbuf (info_dribble_file, (char *)NULL, _IONBF, 1);
|
||||
# endif /* !SETVBUF_REVERSED */
|
||||
#endif /* HAVE_SETVBUF */
|
||||
}
|
||||
|
||||
/* If there is a dribble file already open, close it. */
|
||||
void
|
||||
close_dribble_file ()
|
||||
{
|
||||
if (info_dribble_file)
|
||||
{
|
||||
fflush (info_dribble_file);
|
||||
fclose (info_dribble_file);
|
||||
info_dribble_file = (FILE *)NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write some output to our existing dribble file. */
|
||||
void
|
||||
dribble (byte)
|
||||
unsigned char byte;
|
||||
{
|
||||
if (info_dribble_file)
|
||||
fwrite (&byte, sizeof (unsigned char), 1, info_dribble_file);
|
||||
}
|
41
gnu/usr.bin/texinfo/info/dribble.h
Normal file
41
gnu/usr.bin/texinfo/info/dribble.h
Normal file
@ -0,0 +1,41 @@
|
||||
/* dribble.h -- Functions and vars declared in dribble.c. */
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#ifndef _DRIBBLE_H_
|
||||
#define _DRIBBLE_H_
|
||||
|
||||
/* When non-zero, it is a stream to write all input characters to for the
|
||||
duration of this info session. */
|
||||
extern FILE *info_dribble_file;
|
||||
|
||||
/* Open a dribble file named NAME, perhaps closing an already open one.
|
||||
This sets the global variable INFO_DRIBBLE_FILE to the open stream. */
|
||||
extern void open_dribble_file ();
|
||||
|
||||
/* If there is a dribble file already open, close it. */
|
||||
extern void close_dribble_file ();
|
||||
|
||||
/* Write some output to our existing dribble file. */
|
||||
extern void dribble ();
|
||||
|
||||
#endif /* !_DRIBBLE_H_ */
|
1500
gnu/usr.bin/texinfo/info/echo_area.c
Normal file
1500
gnu/usr.bin/texinfo/info/echo_area.c
Normal file
File diff suppressed because it is too large
Load Diff
63
gnu/usr.bin/texinfo/info/echo_area.h
Normal file
63
gnu/usr.bin/texinfo/info/echo_area.h
Normal file
@ -0,0 +1,63 @@
|
||||
/* echo_area.h -- Functions used in reading information from the echo area. */
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#ifndef _ECHO_AREA_H_
|
||||
#define _ECHO_AREA_H_
|
||||
|
||||
#define EA_MAX_INPUT 256
|
||||
|
||||
extern int echo_area_is_active, info_aborted_echo_area;
|
||||
|
||||
/* Non-zero means that the last command executed while reading input
|
||||
killed some text. */
|
||||
extern int echo_area_last_command_was_kill;
|
||||
|
||||
extern void inform_in_echo_area (), echo_area_inform_of_deleted_window ();
|
||||
extern void echo_area_prep_read ();
|
||||
extern VFunction *ea_last_executed_command;
|
||||
|
||||
/* Read a line of text in the echo area. Return a malloc ()'ed string,
|
||||
or NULL if the user aborted out of this read. WINDOW is the currently
|
||||
active window, so that we can restore it when we need to. PROMPT, if
|
||||
non-null, is a prompt to print before reading the line. */
|
||||
extern char *info_read_in_echo_area ();
|
||||
|
||||
/* Read a line in the echo area with completion over COMPLETIONS.
|
||||
Takes arguments of WINDOW, PROMPT, and COMPLETIONS, a REFERENCE **. */
|
||||
char *info_read_completing_in_echo_area ();
|
||||
|
||||
/* Read a line in the echo area allowing completion over COMPLETIONS, but
|
||||
not requiring it. Takes arguments of WINDOW, PROMPT, and COMPLETIONS,
|
||||
a REFERENCE **. */
|
||||
extern char *info_read_maybe_completing ();
|
||||
|
||||
extern void ea_insert (), ea_quoted_insert ();
|
||||
extern void ea_beg_of_line (), ea_backward (), ea_delete (), ea_end_of_line ();
|
||||
extern void ea_forward (), ea_abort (), ea_rubout (), ea_complete ();
|
||||
extern void ea_newline (), ea_kill_line (), ea_transpose_chars ();
|
||||
extern void ea_yank (), ea_tab_insert (), ea_possible_completions ();
|
||||
extern void ea_backward_word (), ea_kill_word (), ea_forward_word ();
|
||||
extern void ea_yank_pop (), ea_backward_kill_word ();
|
||||
extern void ea_scroll_completions_window ();
|
||||
|
||||
#endif /* _ECHO_AREA_H_ */
|
624
gnu/usr.bin/texinfo/info/filesys.c
Normal file
624
gnu/usr.bin/texinfo/info/filesys.c
Normal file
@ -0,0 +1,624 @@
|
||||
/* filesys.c -- File system specific functions for hacking this system. */
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/errno.h>
|
||||
#include "general.h"
|
||||
#include "tilde.h"
|
||||
#include "filesys.h"
|
||||
|
||||
#if !defined (O_RDONLY)
|
||||
#if defined (HAVE_SYS_FCNTL_H)
|
||||
#include <sys/fcntl.h>
|
||||
#else /* !HAVE_SYS_FCNTL_H */
|
||||
#include <fcntl.h>
|
||||
#endif /* !HAVE_SYS_FCNTL_H */
|
||||
#endif /* !O_RDONLY */
|
||||
|
||||
#if !defined (errno)
|
||||
extern int errno;
|
||||
#endif /* !errno */
|
||||
|
||||
/* Found in info-utils.c. */
|
||||
extern char *filename_non_directory ();
|
||||
|
||||
#if !defined (BUILDING_LIBRARY)
|
||||
/* Found in session.c */
|
||||
extern int info_windows_initialized_p;
|
||||
|
||||
/* Found in window.c. */
|
||||
extern void message_in_echo_area (), unmessage_in_echo_area ();
|
||||
#endif /* !BUILDING_LIBRARY */
|
||||
|
||||
/* Local to this file. */
|
||||
static char *info_file_in_path (), *lookup_info_filename ();
|
||||
static void remember_info_filename (), maybe_initialize_infopath ();
|
||||
|
||||
#if !defined (NULL)
|
||||
# define NULL 0x0
|
||||
#endif /* !NULL */
|
||||
|
||||
typedef struct {
|
||||
char *suffix;
|
||||
char *decompressor;
|
||||
} COMPRESSION_ALIST;
|
||||
|
||||
static char *info_suffixes[] = {
|
||||
"",
|
||||
".info",
|
||||
"-info",
|
||||
(char *)NULL
|
||||
};
|
||||
|
||||
static COMPRESSION_ALIST compress_suffixes[] = {
|
||||
{ ".Z", "uncompress" },
|
||||
{ ".Y", "unyabba" },
|
||||
{ ".z", "gunzip" },
|
||||
{ (char *)NULL, (char *)NULL }
|
||||
};
|
||||
|
||||
/* The path on which we look for info files. You can initialize this
|
||||
from the environment variable INFOPATH if there is one, or you can
|
||||
call info_add_path () to add paths to the beginning or end of it.
|
||||
You can call zap_infopath () to make the path go away. */
|
||||
char *infopath = (char *)NULL;
|
||||
static int infopath_size = 0;
|
||||
|
||||
/* Expand the filename in PARTIAL to make a real name for this operating
|
||||
system. This looks in INFO_PATHS in order to find the correct file.
|
||||
If it can't find the file, it returns NULL. */
|
||||
static char *local_temp_filename = (char *)NULL;
|
||||
static int local_temp_filename_size = 0;
|
||||
|
||||
char *
|
||||
info_find_fullpath (partial)
|
||||
char *partial;
|
||||
{
|
||||
int initial_character;
|
||||
char *temp;
|
||||
|
||||
filesys_error_number = 0;
|
||||
|
||||
maybe_initialize_infopath ();
|
||||
|
||||
if (partial && (initial_character = *partial))
|
||||
{
|
||||
char *expansion;
|
||||
|
||||
expansion = lookup_info_filename (partial);
|
||||
|
||||
if (expansion)
|
||||
return (expansion);
|
||||
|
||||
/* If we have the full path to this file, we still may have to add
|
||||
various extensions to it. I guess we have to stat this file
|
||||
after all. */
|
||||
if (initial_character == '/')
|
||||
temp = info_file_in_path (partial + 1, "/");
|
||||
else if (initial_character == '~')
|
||||
{
|
||||
expansion = tilde_expand_word (partial);
|
||||
if (*expansion == '/')
|
||||
{
|
||||
temp = info_file_in_path (expansion + 1, "/");
|
||||
free (expansion);
|
||||
}
|
||||
else
|
||||
temp = expansion;
|
||||
}
|
||||
else if (initial_character == '.' &&
|
||||
(partial[1] == '/' || (partial[1] == '.' && partial[2] == '/')))
|
||||
{
|
||||
if (local_temp_filename_size < 1024)
|
||||
local_temp_filename = (char *)xrealloc
|
||||
(local_temp_filename, (local_temp_filename_size = 1024));
|
||||
#if defined (HAVE_GETCWD)
|
||||
if (!getcwd (local_temp_filename, local_temp_filename_size))
|
||||
#else /* !HAVE_GETCWD */
|
||||
if (!getwd (local_temp_filename))
|
||||
#endif /* !HAVE_GETCWD */
|
||||
{
|
||||
filesys_error_number = errno;
|
||||
return (partial);
|
||||
}
|
||||
|
||||
strcat (local_temp_filename, "/");
|
||||
strcat (local_temp_filename, partial);
|
||||
return (local_temp_filename);
|
||||
}
|
||||
else
|
||||
temp = info_file_in_path (partial, infopath);
|
||||
|
||||
if (temp)
|
||||
{
|
||||
remember_info_filename (partial, temp);
|
||||
if (strlen (temp) > local_temp_filename_size)
|
||||
local_temp_filename = (char *) xrealloc
|
||||
(local_temp_filename,
|
||||
(local_temp_filename_size = (50 + strlen (temp))));
|
||||
strcpy (local_temp_filename, temp);
|
||||
free (temp);
|
||||
return (local_temp_filename);
|
||||
}
|
||||
}
|
||||
return (partial);
|
||||
}
|
||||
|
||||
/* Scan the list of directories in PATH looking for FILENAME. If we find
|
||||
one that is a regular file, return it as a new string. Otherwise, return
|
||||
a NULL pointer. */
|
||||
static char *
|
||||
info_file_in_path (filename, path)
|
||||
char *filename, *path;
|
||||
{
|
||||
struct stat finfo;
|
||||
char *temp_dirname;
|
||||
int statable, dirname_index;
|
||||
|
||||
dirname_index = 0;
|
||||
|
||||
while (temp_dirname = extract_colon_unit (path, &dirname_index))
|
||||
{
|
||||
register int i, pre_suffix_length;
|
||||
char *temp;
|
||||
|
||||
/* Expand a leading tilde if one is present. */
|
||||
if (*temp_dirname == '~')
|
||||
{
|
||||
char *expanded_dirname;
|
||||
|
||||
expanded_dirname = tilde_expand_word (temp_dirname);
|
||||
free (temp_dirname);
|
||||
temp_dirname = expanded_dirname;
|
||||
}
|
||||
|
||||
temp = (char *)xmalloc (30 + strlen (temp_dirname) + strlen (filename));
|
||||
strcpy (temp, temp_dirname);
|
||||
if (temp[(strlen (temp)) - 1] != '/')
|
||||
strcat (temp, "/");
|
||||
strcat (temp, filename);
|
||||
|
||||
pre_suffix_length = strlen (temp);
|
||||
|
||||
free (temp_dirname);
|
||||
|
||||
for (i = 0; info_suffixes[i]; i++)
|
||||
{
|
||||
strcpy (temp + pre_suffix_length, info_suffixes[i]);
|
||||
|
||||
statable = (stat (temp, &finfo) == 0);
|
||||
|
||||
/* If we have found a regular file, then use that. Else, if we
|
||||
have found a directory, look in that directory for this file. */
|
||||
if (statable)
|
||||
{
|
||||
if (S_ISREG (finfo.st_mode))
|
||||
{
|
||||
return (temp);
|
||||
}
|
||||
else if (S_ISDIR (finfo.st_mode))
|
||||
{
|
||||
char *newpath, *filename_only, *newtemp;
|
||||
|
||||
newpath = savestring (temp);
|
||||
filename_only = filename_non_directory (filename);
|
||||
newtemp = info_file_in_path (filename_only, newpath);
|
||||
|
||||
free (newpath);
|
||||
if (newtemp)
|
||||
{
|
||||
free (temp);
|
||||
return (newtemp);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Add various compression suffixes to the name to see if
|
||||
the file is present in compressed format. */
|
||||
register int j, pre_compress_suffix_length;
|
||||
|
||||
pre_compress_suffix_length = strlen (temp);
|
||||
|
||||
for (j = 0; compress_suffixes[j].suffix; j++)
|
||||
{
|
||||
strcpy (temp + pre_compress_suffix_length,
|
||||
compress_suffixes[j].suffix);
|
||||
|
||||
statable = (stat (temp, &finfo) == 0);
|
||||
if (statable && (S_ISREG (finfo.st_mode)))
|
||||
return (temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
free (temp);
|
||||
}
|
||||
return ((char *)NULL);
|
||||
}
|
||||
|
||||
/* Given a string containing units of information separated by colons,
|
||||
return the next one pointed to by IDX, or NULL if there are no more.
|
||||
Advance IDX to the character after the colon. */
|
||||
char *
|
||||
extract_colon_unit (string, idx)
|
||||
char *string;
|
||||
int *idx;
|
||||
{
|
||||
register int i, start;
|
||||
|
||||
i = start = *idx;
|
||||
if ((i >= strlen (string)) || !string)
|
||||
return ((char *) NULL);
|
||||
|
||||
while (string[i] && string[i] != ':')
|
||||
i++;
|
||||
if (i == start)
|
||||
{
|
||||
return ((char *) NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *value = (char *) xmalloc (1 + (i - start));
|
||||
strncpy (value, &string[start], (i - start));
|
||||
value[i - start] = '\0';
|
||||
if (string[i])
|
||||
++i;
|
||||
*idx = i;
|
||||
return (value);
|
||||
}
|
||||
}
|
||||
|
||||
/* A structure which associates a filename with its expansion. */
|
||||
typedef struct {
|
||||
char *filename;
|
||||
char *expansion;
|
||||
} FILENAME_LIST;
|
||||
|
||||
/* An array of remembered arguments and results. */
|
||||
static FILENAME_LIST **names_and_files = (FILENAME_LIST **)NULL;
|
||||
static int names_and_files_index = 0;
|
||||
static int names_and_files_slots = 0;
|
||||
|
||||
/* Find the result for having already called info_find_fullpath () with
|
||||
FILENAME. */
|
||||
static char *
|
||||
lookup_info_filename (filename)
|
||||
char *filename;
|
||||
{
|
||||
if (filename && names_and_files)
|
||||
{
|
||||
register int i;
|
||||
for (i = 0; names_and_files[i]; i++)
|
||||
{
|
||||
if (strcmp (names_and_files[i]->filename, filename) == 0)
|
||||
return (names_and_files[i]->expansion);
|
||||
}
|
||||
}
|
||||
return (char *)NULL;;
|
||||
}
|
||||
|
||||
/* Add a filename and its expansion to our list. */
|
||||
static void
|
||||
remember_info_filename (filename, expansion)
|
||||
char *filename, *expansion;
|
||||
{
|
||||
FILENAME_LIST *new;
|
||||
|
||||
if (names_and_files_index + 2 > names_and_files_slots)
|
||||
{
|
||||
int alloc_size;
|
||||
names_and_files_slots += 10;
|
||||
|
||||
alloc_size = names_and_files_slots * sizeof (FILENAME_LIST *);
|
||||
|
||||
names_and_files =
|
||||
(FILENAME_LIST **) xrealloc (names_and_files, alloc_size);
|
||||
}
|
||||
|
||||
new = (FILENAME_LIST *)xmalloc (sizeof (FILENAME_LIST));
|
||||
new->filename = savestring (filename);
|
||||
new->expansion = expansion ? savestring (expansion) : (char *)NULL;
|
||||
|
||||
names_and_files[names_and_files_index++] = new;
|
||||
names_and_files[names_and_files_index] = (FILENAME_LIST *)NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
maybe_initialize_infopath ()
|
||||
{
|
||||
if (!infopath_size)
|
||||
{
|
||||
infopath = (char *)
|
||||
xmalloc (infopath_size = (1 + strlen (DEFAULT_INFOPATH)));
|
||||
|
||||
strcpy (infopath, DEFAULT_INFOPATH);
|
||||
}
|
||||
}
|
||||
|
||||
/* Add PATH to the list of paths found in INFOPATH. 2nd argument says
|
||||
whether to put PATH at the front or end of INFOPATH. */
|
||||
void
|
||||
info_add_path (path, where)
|
||||
char *path;
|
||||
int where;
|
||||
{
|
||||
int len;
|
||||
|
||||
if (!infopath)
|
||||
{
|
||||
infopath = (char *)xmalloc (infopath_size = 200 + strlen (path));
|
||||
infopath[0] = '\0';
|
||||
}
|
||||
|
||||
len = strlen (path) + strlen (infopath);
|
||||
|
||||
if (len + 2 >= infopath_size)
|
||||
infopath = (char *)xrealloc (infopath, (infopath_size += (2 * len) + 2));
|
||||
|
||||
if (!*infopath)
|
||||
strcpy (infopath, path);
|
||||
else if (where == INFOPATH_APPEND)
|
||||
{
|
||||
strcat (infopath, ":");
|
||||
strcat (infopath, path);
|
||||
}
|
||||
else if (where == INFOPATH_PREPEND)
|
||||
{
|
||||
char *temp = savestring (infopath);
|
||||
strcpy (infopath, path);
|
||||
strcat (infopath, ":");
|
||||
strcat (infopath, temp);
|
||||
free (temp);
|
||||
}
|
||||
}
|
||||
|
||||
/* Make INFOPATH have absolutely nothing in it. */
|
||||
void
|
||||
zap_infopath ()
|
||||
{
|
||||
if (infopath)
|
||||
free (infopath);
|
||||
|
||||
infopath = (char *)NULL;
|
||||
infopath_size = 0;
|
||||
}
|
||||
|
||||
/* Read the contents of PATHNAME, returning a buffer with the contents of
|
||||
that file in it, and returning the size of that buffer in FILESIZE.
|
||||
FINFO is a stat struct which has already been filled in by the caller.
|
||||
If the file cannot be read, return a NULL pointer. */
|
||||
char *
|
||||
filesys_read_info_file (pathname, filesize, finfo)
|
||||
char *pathname;
|
||||
long *filesize;
|
||||
struct stat *finfo;
|
||||
{
|
||||
*filesize = filesys_error_number = 0;
|
||||
|
||||
if (compressed_filename_p (pathname))
|
||||
return (filesys_read_compressed (pathname, filesize, finfo));
|
||||
else
|
||||
{
|
||||
int descriptor;
|
||||
char *contents;
|
||||
|
||||
descriptor = open (pathname, O_RDONLY, 0666);
|
||||
|
||||
/* If the file couldn't be opened, give up. */
|
||||
if (descriptor < 0)
|
||||
{
|
||||
filesys_error_number = errno;
|
||||
return ((char *)NULL);
|
||||
}
|
||||
|
||||
/* Try to read the contents of this file. */
|
||||
contents = (char *)xmalloc (1 + finfo->st_size);
|
||||
if ((read (descriptor, contents, finfo->st_size)) != finfo->st_size)
|
||||
{
|
||||
filesys_error_number = errno;
|
||||
close (descriptor);
|
||||
free (contents);
|
||||
return ((char *)NULL);
|
||||
}
|
||||
|
||||
close (descriptor);
|
||||
|
||||
*filesize = finfo->st_size;
|
||||
return (contents);
|
||||
}
|
||||
}
|
||||
|
||||
/* Typically, pipe buffers are 4k. */
|
||||
#define BASIC_PIPE_BUFFER (4 * 1024)
|
||||
|
||||
/* We use some large multiple of that. */
|
||||
#define FILESYS_PIPE_BUFFER_SIZE (16 * BASIC_PIPE_BUFFER)
|
||||
|
||||
char *
|
||||
filesys_read_compressed (pathname, filesize, finfo)
|
||||
char *pathname;
|
||||
long *filesize;
|
||||
struct stat *finfo;
|
||||
{
|
||||
FILE *stream;
|
||||
char *command, *decompressor;
|
||||
char *contents = (char *)NULL;
|
||||
|
||||
*filesize = filesys_error_number = 0;
|
||||
|
||||
decompressor = filesys_decompressor_for_file (pathname);
|
||||
|
||||
if (!decompressor)
|
||||
return ((char *)NULL);
|
||||
|
||||
command = (char *)xmalloc (10 + strlen (pathname) + strlen (decompressor));
|
||||
sprintf (command, "%s < %s", decompressor, pathname);
|
||||
|
||||
#if !defined (BUILDING_LIBRARY)
|
||||
if (info_windows_initialized_p)
|
||||
{
|
||||
char *temp;
|
||||
|
||||
temp = (char *)xmalloc (5 + strlen (command));
|
||||
sprintf (temp, "%s...", command);
|
||||
message_in_echo_area ("%s", temp);
|
||||
free (temp);
|
||||
}
|
||||
#endif /* !BUILDING_LIBRARY */
|
||||
|
||||
stream = popen (command, "r");
|
||||
free (command);
|
||||
|
||||
/* Read chunks from this file until there are none left to read. */
|
||||
if (stream)
|
||||
{
|
||||
int offset, size;
|
||||
char *chunk;
|
||||
|
||||
offset = size = 0;
|
||||
chunk = (char *)xmalloc (FILESYS_PIPE_BUFFER_SIZE);
|
||||
|
||||
while (1)
|
||||
{
|
||||
int bytes_read;
|
||||
|
||||
bytes_read = fread (chunk, 1, FILESYS_PIPE_BUFFER_SIZE, stream);
|
||||
|
||||
if (bytes_read + offset >= size)
|
||||
contents = (char *)xrealloc
|
||||
(contents, size += (2 * FILESYS_PIPE_BUFFER_SIZE));
|
||||
|
||||
memcpy (contents + offset, chunk, bytes_read);
|
||||
offset += bytes_read;
|
||||
if (bytes_read != FILESYS_PIPE_BUFFER_SIZE)
|
||||
break;
|
||||
}
|
||||
|
||||
free (chunk);
|
||||
pclose (stream);
|
||||
contents = (char *)xrealloc (contents, offset + 1);
|
||||
*filesize = offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
filesys_error_number = errno;
|
||||
}
|
||||
|
||||
#if !defined (BUILDING_LIBARARY)
|
||||
if (info_windows_initialized_p)
|
||||
unmessage_in_echo_area ();
|
||||
#endif /* !BUILDING_LIBRARY */
|
||||
return (contents);
|
||||
}
|
||||
|
||||
/* Return non-zero if FILENAME belongs to a compressed file. */
|
||||
int
|
||||
compressed_filename_p (filename)
|
||||
char *filename;
|
||||
{
|
||||
char *decompressor;
|
||||
|
||||
/* Find the final extension of this filename, and see if it matches one
|
||||
of our known ones. */
|
||||
decompressor = filesys_decompressor_for_file (filename);
|
||||
|
||||
if (decompressor)
|
||||
return (1);
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Return the command string that would be used to decompress FILENAME. */
|
||||
char *
|
||||
filesys_decompressor_for_file (filename)
|
||||
char *filename;
|
||||
{
|
||||
register int i;
|
||||
char *extension = (char *)NULL;
|
||||
|
||||
/* Find the final extension of FILENAME, and see if it appears in our
|
||||
list of known compression extensions. */
|
||||
for (i = strlen (filename) - 1; i > 0; i--)
|
||||
if (filename[i] == '.')
|
||||
{
|
||||
extension = filename + i;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!extension)
|
||||
return ((char *)NULL);
|
||||
|
||||
for (i = 0; compress_suffixes[i].suffix; i++)
|
||||
if (strcmp (extension, compress_suffixes[i].suffix) == 0)
|
||||
return (compress_suffixes[i].decompressor);
|
||||
|
||||
return ((char *)NULL);
|
||||
}
|
||||
|
||||
/* The number of the most recent file system error. */
|
||||
int filesys_error_number = 0;
|
||||
|
||||
#if !defined (HAVE_STRERROR)
|
||||
extern const char * const sys_errlist[];
|
||||
extern int sys_nerr;
|
||||
|
||||
char *
|
||||
strerror (num)
|
||||
int num;
|
||||
{
|
||||
if (num >= sys_nerr)
|
||||
return ("");
|
||||
else
|
||||
return (sys_errlist[num]);
|
||||
}
|
||||
#endif /* !HAVE_STRERROR */
|
||||
|
||||
/* A function which returns a pointer to a static buffer containing
|
||||
an error message for FILENAME and ERROR_NUM. */
|
||||
static char *errmsg_buf = (char *)NULL;
|
||||
static int errmsg_buf_size = 0;
|
||||
|
||||
char *
|
||||
filesys_error_string (filename, error_num)
|
||||
char *filename;
|
||||
int error_num;
|
||||
{
|
||||
int len;
|
||||
char *result;
|
||||
|
||||
if (error_num == 0)
|
||||
return ((char *)NULL);
|
||||
|
||||
result = strerror (error_num);
|
||||
|
||||
len = 4 + strlen (filename) + strlen (result);
|
||||
if (len >= errmsg_buf_size)
|
||||
errmsg_buf = (char *)xrealloc (errmsg_buf, (errmsg_buf_size = 2 + len));
|
||||
|
||||
sprintf (errmsg_buf, "%s: %s", filename, result);
|
||||
return (errmsg_buf);
|
||||
}
|
||||
|
84
gnu/usr.bin/texinfo/info/filesys.h
Normal file
84
gnu/usr.bin/texinfo/info/filesys.h
Normal file
@ -0,0 +1,84 @@
|
||||
/* filesys.h -- External declarations of functions and vars in filesys.c. */
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#ifndef _FILESYS_H_
|
||||
#define _FILESYS_H_
|
||||
|
||||
/* The path on which we look for info files. You can initialize this
|
||||
from the environment variable INFOPATH if there is one, or you can
|
||||
call info_add_path () to add paths to the beginning or end of it. */
|
||||
extern char *infopath;
|
||||
|
||||
/* Make INFOPATH have absolutely nothing in it. */
|
||||
extern void zap_infopath ();
|
||||
|
||||
/* Add PATH to the list of paths found in INFOPATH. 2nd argument says
|
||||
whether to put PATH at the front or end of INFOPATH. */
|
||||
extern void info_add_path ();
|
||||
|
||||
/* Defines that are passed along with the pathname to info_add_path (). */
|
||||
#define INFOPATH_PREPEND 0
|
||||
#define INFOPATH_APPEND 1
|
||||
|
||||
/* Expand the filename in PARTIAL to make a real name for this operating
|
||||
system. This looks in INFO_PATHS in order to find the correct file.
|
||||
If it can't find the file, it returns NULL. */
|
||||
extern char *info_find_fullpath ();
|
||||
|
||||
/* Read the contents of PATHNAME, returning a buffer with the contents of
|
||||
that file in it, and returning the size of that buffer in FILESIZE.
|
||||
FINFO is a stat struct which has already been filled in by the caller.
|
||||
If the file cannot be read, return a NULL pointer. */
|
||||
extern char *filesys_read_info_file ();
|
||||
extern char *filesys_read_compressed ();
|
||||
|
||||
/* Return the command string that would be used to decompress FILENAME. */
|
||||
extern char *filesys_decompressor_for_file ();
|
||||
extern int compressed_filename_p ();
|
||||
|
||||
/* A function which returns a pointer to a static buffer containing
|
||||
an error message for FILENAME and ERROR_NUM. */
|
||||
extern char *filesys_error_string ();
|
||||
|
||||
/* The number of the most recent file system error. */
|
||||
extern int filesys_error_number;
|
||||
|
||||
/* Given a string containing units of information separated by colons,
|
||||
return the next one pointed to by IDX, or NULL if there are no more.
|
||||
Advance IDX to the character after the colon. */
|
||||
extern char *extract_colon_unit ();
|
||||
|
||||
/* The default value of INFOPATH. */
|
||||
#if !defined (DEFAULT_INFOPATH)
|
||||
# define DEFAULT_INFOPATH "/usr/gnu/info:/local/gnu/info:/usr/gnu/lib/info:/usr/gnu/lib/emacs/info:/usr/local/gnu/info:/usr/local/gnu/lib/info:/usr/local/gnu/lib/emacs/info:/usr/local/lib/info:/usr/local/lib/emacs/info:/usr/local/emacs/info:."
|
||||
#endif /* !DEFAULT_INFOPATH */
|
||||
|
||||
#if !defined (S_ISREG) && defined (S_IFREG)
|
||||
# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
|
||||
#endif /* !S_ISREG && S_IFREG */
|
||||
|
||||
#if !defined (S_ISDIR) && defined (S_IFDIR)
|
||||
# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
|
||||
#endif /* !S_ISDIR && S_IFDIR */
|
||||
|
||||
#endif /* !_FILESYS_H_ */
|
264
gnu/usr.bin/texinfo/info/footnotes.c
Normal file
264
gnu/usr.bin/texinfo/info/footnotes.c
Normal file
@ -0,0 +1,264 @@
|
||||
/* footnotes.c -- Some functions for manipulating footnotes. */
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#include "info.h"
|
||||
|
||||
/* Non-zero means attempt to show footnotes when displaying a new window. */
|
||||
int auto_footnotes_p = 1;
|
||||
|
||||
static char *footnote_nodename = "*Footnotes*";
|
||||
|
||||
#define FOOTNOTE_HEADER_FORMAT \
|
||||
"*** Footnotes appearing in the node \"%s\" ***\n"
|
||||
|
||||
/* Find the window currently showing footnotes. */
|
||||
static WINDOW *
|
||||
find_footnotes_window ()
|
||||
{
|
||||
WINDOW *win;
|
||||
|
||||
/* Try to find an existing window first. */
|
||||
for (win = windows; win; win = win->next)
|
||||
if (internal_info_node_p (win->node) &&
|
||||
(strcmp (win->node->nodename, footnote_nodename) == 0))
|
||||
break;
|
||||
|
||||
return (win);
|
||||
}
|
||||
|
||||
/* Manufacture a node containing the footnotes of this node, and
|
||||
return the manufactured node. If NODE has no footnotes, return a
|
||||
NULL pointer. */
|
||||
NODE *
|
||||
make_footnotes_node (node)
|
||||
NODE *node;
|
||||
{
|
||||
NODE *fn_node, *result = (NODE *)NULL;
|
||||
long fn_start;
|
||||
|
||||
/* Make the initial assumption that the footnotes appear as simple
|
||||
text within this windows node. */
|
||||
fn_node = node;
|
||||
|
||||
/* See if this node contains the magic footnote label. */
|
||||
fn_start =
|
||||
info_search_in_node (FOOTNOTE_LABEL, node, 0, (WINDOW *)NULL, 1);
|
||||
|
||||
/* If it doesn't, check to see if it has an associated footnotes node. */
|
||||
if (fn_start == -1)
|
||||
{
|
||||
REFERENCE **refs;
|
||||
|
||||
refs = info_xrefs_of_node (node);
|
||||
|
||||
if (refs)
|
||||
{
|
||||
register int i;
|
||||
char *refname;
|
||||
|
||||
refname = (char *)xmalloc
|
||||
(1 + strlen ("-Footnotes") + strlen (node->nodename));
|
||||
|
||||
strcpy (refname, node->nodename);
|
||||
strcat (refname, "-Footnotes");
|
||||
|
||||
for (i = 0; refs[i]; i++)
|
||||
if (strcmp (refs[i]->nodename, refname) == 0)
|
||||
{
|
||||
char *filename;
|
||||
|
||||
filename = node->parent;
|
||||
if (!filename)
|
||||
filename = node->filename;
|
||||
|
||||
fn_node = info_get_node (filename, refname);
|
||||
|
||||
if (fn_node)
|
||||
fn_start = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
free (refname);
|
||||
info_free_references (refs);
|
||||
}
|
||||
}
|
||||
|
||||
/* If we never found the start of a footnotes area, quit now. */
|
||||
if (fn_start == -1)
|
||||
return ((NODE *)NULL);
|
||||
|
||||
/* Make the new node. */
|
||||
result = (NODE *)xmalloc (sizeof (NODE));
|
||||
result->flags = 0;
|
||||
|
||||
/* Get the size of the footnotes appearing within this node. */
|
||||
{
|
||||
char *header;
|
||||
long text_start = fn_start;
|
||||
|
||||
header = (char *)xmalloc
|
||||
(1 + strlen (node->nodename) + strlen (FOOTNOTE_HEADER_FORMAT));
|
||||
sprintf (header, FOOTNOTE_HEADER_FORMAT, node->nodename);
|
||||
|
||||
/* Move the start of the displayed text to right after the first line.
|
||||
This effectively skips either "---- footno...", or "File: foo...". */
|
||||
while (text_start < fn_node->nodelen)
|
||||
if (fn_node->contents[text_start++] == '\n')
|
||||
break;
|
||||
|
||||
result->nodelen = strlen (header) + fn_node->nodelen - text_start;
|
||||
|
||||
/* Set the contents of this node. */
|
||||
result->contents = (char *)xmalloc (1 + result->nodelen);
|
||||
sprintf (result->contents, "%s", header);
|
||||
memcpy (result->contents + strlen (header),
|
||||
fn_node->contents + text_start, fn_node->nodelen - text_start);
|
||||
|
||||
name_internal_node (result, footnote_nodename);
|
||||
free (header);
|
||||
}
|
||||
|
||||
#if defined (NOTDEF)
|
||||
/* If the footnotes were gleaned from the node that we were called with,
|
||||
shorten the calling node's display length. */
|
||||
if (fn_node == node)
|
||||
narrow_node (node, 0, fn_start);
|
||||
#endif /* NOTDEF */
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
/* Create or delete the footnotes window depending on whether footnotes
|
||||
exist in WINDOW's node or not. Returns FN_FOUND if footnotes were found
|
||||
and displayed. Returns FN_UNFOUND if there were no footnotes found
|
||||
in WINDOW's node. Returns FN_UNABLE if there were footnotes, but the
|
||||
window to show them couldn't be made. */
|
||||
int
|
||||
info_get_or_remove_footnotes (window)
|
||||
WINDOW *window;
|
||||
{
|
||||
WINDOW *fn_win;
|
||||
NODE *new_footnotes;
|
||||
|
||||
fn_win = find_footnotes_window ();
|
||||
|
||||
/* If we are in the footnotes window, change nothing. */
|
||||
if (fn_win == window)
|
||||
return (FN_FOUND);
|
||||
|
||||
/* Try to find footnotes for this window's node. */
|
||||
new_footnotes = make_footnotes_node (window->node);
|
||||
|
||||
/* If there was a window showing footnotes, and there are no footnotes
|
||||
for the current window, delete the old footnote window. */
|
||||
if (fn_win && !new_footnotes)
|
||||
{
|
||||
if (windows->next)
|
||||
info_delete_window_internal (fn_win);
|
||||
}
|
||||
|
||||
/* If there are footnotes for this window's node, but no window around
|
||||
showing footnotes, try to make a new window. */
|
||||
if (new_footnotes && !fn_win)
|
||||
{
|
||||
WINDOW *old_active;
|
||||
WINDOW *last, *win;
|
||||
|
||||
/* Always make this window be the last one appearing in the list. Find
|
||||
the last window in the chain. */
|
||||
for (win = windows, last = windows; win; last = win, win = win->next);
|
||||
|
||||
/* Try to split this window, and make the split window the one to
|
||||
contain the footnotes. */
|
||||
old_active = active_window;
|
||||
active_window = last;
|
||||
fn_win = window_make_window (new_footnotes);
|
||||
active_window = old_active;
|
||||
|
||||
if (!fn_win)
|
||||
{
|
||||
free (new_footnotes->contents);
|
||||
free (new_footnotes);
|
||||
|
||||
/* If we are hacking automatic footnotes, and there are footnotes
|
||||
but we couldn't display them, print a message to that effect. */
|
||||
if (auto_footnotes_p)
|
||||
inform_in_echo_area ("Footnotes could not be displayed");
|
||||
return (FN_UNABLE);
|
||||
}
|
||||
}
|
||||
|
||||
/* If there are footnotes, and there is a window to display them,
|
||||
make that window be the number of lines appearing in the footnotes. */
|
||||
if (new_footnotes && fn_win)
|
||||
{
|
||||
window_set_node_of_window (fn_win, new_footnotes);
|
||||
|
||||
window_change_window_height
|
||||
(fn_win, fn_win->line_count - fn_win->height);
|
||||
|
||||
remember_window_and_node (fn_win, new_footnotes);
|
||||
add_gcable_pointer (new_footnotes->contents);
|
||||
}
|
||||
|
||||
if (!new_footnotes)
|
||||
return (FN_UNFOUND);
|
||||
else
|
||||
return (FN_FOUND);
|
||||
}
|
||||
|
||||
/* Show the footnotes associated with this node in another window. */
|
||||
DECLARE_INFO_COMMAND (info_show_footnotes,
|
||||
"Show the footnotes associated with this node in another window")
|
||||
{
|
||||
int result;
|
||||
|
||||
/* A negative argument means just make the window go away. */
|
||||
if (count < 0)
|
||||
{
|
||||
WINDOW *fn_win = find_footnotes_window ();
|
||||
|
||||
/* If there is an old footnotes window, and it isn't the only window
|
||||
on the screen, delete it. */
|
||||
if (fn_win && windows->next)
|
||||
info_delete_window_internal (fn_win);
|
||||
}
|
||||
else
|
||||
{
|
||||
int result;
|
||||
|
||||
result = info_get_or_remove_footnotes (window);
|
||||
|
||||
switch (result)
|
||||
{
|
||||
case FN_UNFOUND:
|
||||
info_error (NO_FOOT_NODE);
|
||||
break;
|
||||
|
||||
case FN_UNABLE:
|
||||
info_error (WIN_TOO_SMALL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
46
gnu/usr.bin/texinfo/info/footnotes.h
Normal file
46
gnu/usr.bin/texinfo/info/footnotes.h
Normal file
@ -0,0 +1,46 @@
|
||||
/* footnotes.h -- Some functions for manipulating footnotes. */
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#ifndef _FOOTNOTES_H_
|
||||
#define _FOOTNOTES_H_
|
||||
|
||||
/* Magic string which indicates following text is footnotes. */
|
||||
#define FOOTNOTE_LABEL "---------- Footnotes ----------"
|
||||
|
||||
#define FN_FOUND 0
|
||||
#define FN_UNFOUND 1
|
||||
#define FN_UNABLE 2
|
||||
|
||||
|
||||
/* Create or delete the footnotes window depending on whether footnotes
|
||||
exist in WINDOW's node or not. Returns FN_FOUND if footnotes were found
|
||||
and displayed. Returns FN_UNFOUND if there were no footnotes found
|
||||
in WINDOW's node. Returns FN_UNABLE if there were footnotes, but the
|
||||
window to show them couldn't be made. */
|
||||
extern int info_get_or_remove_footnotes ();
|
||||
|
||||
/* Non-zero means attempt to show footnotes when displaying a new window. */
|
||||
extern int auto_footnotes_p;
|
||||
|
||||
#endif /* !_FOOTNOTES_H_ */
|
||||
|
110
gnu/usr.bin/texinfo/info/funs.h
Normal file
110
gnu/usr.bin/texinfo/info/funs.h
Normal file
@ -0,0 +1,110 @@
|
||||
/* funs.h -- Generated declarations for Info commands. */
|
||||
|
||||
/* Functions declared in "./session.c". */
|
||||
extern void info_next_line ();
|
||||
extern void info_prev_line ();
|
||||
extern void info_end_of_line ();
|
||||
extern void info_beginning_of_line ();
|
||||
extern void info_forward_char ();
|
||||
extern void info_backward_char ();
|
||||
extern void info_forward_word ();
|
||||
extern void info_backward_word ();
|
||||
extern void info_global_next_node ();
|
||||
extern void info_global_prev_node ();
|
||||
extern void info_scroll_forward ();
|
||||
extern void info_scroll_backward ();
|
||||
extern void info_beginning_of_node ();
|
||||
extern void info_end_of_node ();
|
||||
extern void info_next_window ();
|
||||
extern void info_prev_window ();
|
||||
extern void info_split_window ();
|
||||
extern void info_delete_window ();
|
||||
extern void info_keep_one_window ();
|
||||
extern void info_scroll_other_window ();
|
||||
extern void info_grow_window ();
|
||||
extern void info_tile_windows ();
|
||||
extern void info_toggle_wrap ();
|
||||
extern void info_next_node ();
|
||||
extern void info_prev_node ();
|
||||
extern void info_up_node ();
|
||||
extern void info_last_node ();
|
||||
extern void info_first_node ();
|
||||
extern void info_history_node ();
|
||||
extern void info_last_menu_item ();
|
||||
extern void info_menu_digit ();
|
||||
extern void info_menu_item ();
|
||||
extern void info_xref_item ();
|
||||
extern void info_find_menu ();
|
||||
extern void info_visit_menu ();
|
||||
extern void info_goto_node ();
|
||||
extern void info_top_node ();
|
||||
extern void info_dir_node ();
|
||||
extern void info_kill_node ();
|
||||
extern void info_view_file ();
|
||||
extern void info_print_node ();
|
||||
extern void info_search ();
|
||||
extern void isearch_forward ();
|
||||
extern void isearch_backward ();
|
||||
extern void info_move_to_prev_xref ();
|
||||
extern void info_move_to_next_xref ();
|
||||
extern void info_select_reference_this_line ();
|
||||
extern void info_abort_key ();
|
||||
extern void info_move_to_window_line ();
|
||||
extern void info_redraw_display ();
|
||||
extern void info_quit ();
|
||||
extern void info_do_lowercase_version ();
|
||||
extern void info_add_digit_to_numeric_arg ();
|
||||
extern void info_universal_argument ();
|
||||
extern void info_numeric_arg_digit_loop ();
|
||||
|
||||
/* Functions declared in "./echo_area.c". */
|
||||
extern void ea_forward ();
|
||||
extern void ea_backward ();
|
||||
extern void ea_beg_of_line ();
|
||||
extern void ea_end_of_line ();
|
||||
extern void ea_forward_word ();
|
||||
extern void ea_backward_word ();
|
||||
extern void ea_delete ();
|
||||
extern void ea_rubout ();
|
||||
extern void ea_abort ();
|
||||
extern void ea_newline ();
|
||||
extern void ea_quoted_insert ();
|
||||
extern void ea_insert ();
|
||||
extern void ea_tab_insert ();
|
||||
extern void ea_transpose_chars ();
|
||||
extern void ea_yank ();
|
||||
extern void ea_yank_pop ();
|
||||
extern void ea_kill_line ();
|
||||
extern void ea_backward_kill_line ();
|
||||
extern void ea_kill_word ();
|
||||
extern void ea_backward_kill_word ();
|
||||
extern void ea_possible_completions ();
|
||||
extern void ea_complete ();
|
||||
extern void ea_scroll_completions_window ();
|
||||
|
||||
/* Functions declared in "./infodoc.c". */
|
||||
extern void info_get_help_window ();
|
||||
extern void info_get_info_help_node ();
|
||||
extern void describe_key ();
|
||||
extern void info_where_is ();
|
||||
|
||||
/* Functions declared in "./m-x.c". */
|
||||
extern void describe_command ();
|
||||
extern void info_execute_command ();
|
||||
extern void set_screen_height ();
|
||||
|
||||
/* Functions declared in "./indices.c". */
|
||||
extern void info_index_search ();
|
||||
extern void info_next_index_match ();
|
||||
extern void info_index_apropos ();
|
||||
|
||||
/* Functions declared in "./nodemenu.c". */
|
||||
extern void list_visited_nodes ();
|
||||
extern void select_visited_node ();
|
||||
|
||||
/* Functions declared in "./footnotes.c". */
|
||||
extern void info_show_footnotes ();
|
||||
|
||||
/* Functions declared in "./variables.c". */
|
||||
extern void describe_variable ();
|
||||
extern void set_variable ();
|
95
gnu/usr.bin/texinfo/info/gc.c
Normal file
95
gnu/usr.bin/texinfo/info/gc.c
Normal file
@ -0,0 +1,95 @@
|
||||
/* gc.c -- Functions to remember and garbage collect unused node contents. */
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#include "info.h"
|
||||
|
||||
/* Array of pointers to the contents of gc-able nodes. A pointer on this
|
||||
list can be garbage collected when no info window contains a node whose
|
||||
contents member match the pointer. */
|
||||
static char **gcable_pointers = (char **)NULL;
|
||||
static int gcable_pointers_index = 0;
|
||||
static int gcable_pointers_slots = 0;
|
||||
|
||||
/* Add POINTER to the list of garbage collectible pointers. A pointer
|
||||
is not actually garbage collected until no info window contains a node
|
||||
whose contents member is equal to the pointer. */
|
||||
void
|
||||
add_gcable_pointer (pointer)
|
||||
char *pointer;
|
||||
{
|
||||
gc_pointers ();
|
||||
add_pointer_to_array (pointer, gcable_pointers_index, gcable_pointers,
|
||||
gcable_pointers_slots, 10, char *);
|
||||
}
|
||||
|
||||
/* Grovel the list of info windows and gc-able pointers finding those
|
||||
node->contents which are collectible, and free them. */
|
||||
void
|
||||
gc_pointers ()
|
||||
{
|
||||
register int i, j, k;
|
||||
INFO_WINDOW *iw;
|
||||
char **new = (char **)NULL;
|
||||
int new_index = 0;
|
||||
int new_slots = 0;
|
||||
|
||||
if (!info_windows || !gcable_pointers_index)
|
||||
return;
|
||||
|
||||
for (i = 0; iw = info_windows[i]; i++)
|
||||
{
|
||||
for (j = 0; j < iw->nodes_index; j++)
|
||||
{
|
||||
NODE *node = iw->nodes[j];
|
||||
|
||||
/* If this node->contents appears in our list of gcable_pointers,
|
||||
it is not gc-able, so save it. */
|
||||
for (k = 0; k < gcable_pointers_index; k++)
|
||||
if (gcable_pointers[k] == node->contents)
|
||||
{
|
||||
add_pointer_to_array
|
||||
(node->contents, new_index, new, new_slots, 10, char *);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* We have gathered all of the pointers which need to be saved. Free any
|
||||
of the original pointers which do not appear in the new list. */
|
||||
for (i = 0; i < gcable_pointers_index; i++)
|
||||
{
|
||||
for (j = 0; j < new_index; j++)
|
||||
if (gcable_pointers[i] == new[j])
|
||||
break;
|
||||
|
||||
/* If we got all the way through the new list, then the old pointer
|
||||
can be garbage collected. */
|
||||
if (new && !new[j])
|
||||
free (gcable_pointers[i]);
|
||||
}
|
||||
|
||||
free (gcable_pointers);
|
||||
gcable_pointers = new;
|
||||
gcable_pointers_slots = new_slots;
|
||||
gcable_pointers_index = new_index;
|
||||
}
|
36
gnu/usr.bin/texinfo/info/gc.h
Normal file
36
gnu/usr.bin/texinfo/info/gc.h
Normal file
@ -0,0 +1,36 @@
|
||||
/* gc.h -- Functions for garbage collecting unused node contents. */
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#ifndef _GC_H_
|
||||
#define _GC_H_
|
||||
|
||||
/* Add POINTER to the list of garbage collectible pointers. A pointer
|
||||
is not actually garbage collected until no info window contains a node
|
||||
whose contents member is equal to the pointer. */
|
||||
extern void add_gcable_pointer ();
|
||||
|
||||
/* Grovel the list of info windows and gc-able pointers finding those
|
||||
node->contents which are collectible, and free them. */
|
||||
extern void gc_pointers ();
|
||||
|
||||
#endif /* !_GC_H_ */
|
81
gnu/usr.bin/texinfo/info/general.h
Normal file
81
gnu/usr.bin/texinfo/info/general.h
Normal file
@ -0,0 +1,81 @@
|
||||
/* general.h -- Some generally useful defines. */
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#if !defined (_GENERAL_H_)
|
||||
#define _GENERAL_H_
|
||||
|
||||
extern void *xmalloc (), *xrealloc ();
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif /* HAVE_UNISTD_H */
|
||||
|
||||
#if defined (HAVE_STRING_H)
|
||||
# include <string.h>
|
||||
#else
|
||||
# include <strings.h>
|
||||
#endif /* !HAVE_STRING_H */
|
||||
|
||||
#if !defined (savestring)
|
||||
# define savestring(x) (char *)strcpy ((char *)xmalloc (1 + strlen (x)), x)
|
||||
#endif /* !savestring */
|
||||
|
||||
#define info_toupper(x) (islower (x) ? toupper (x) : x)
|
||||
#define info_tolower(x) (isupper (x) ? tolower (x) : x)
|
||||
|
||||
#if !defined (whitespace)
|
||||
# define whitespace(c) ((c == ' ') || (c == '\t'))
|
||||
#endif /* !whitespace */
|
||||
|
||||
#if !defined (whitespace_or_newline)
|
||||
# define whitespace_or_newline(c) (whitespace (c) || (c == '\n'))
|
||||
#endif /* !whitespace_or_newline */
|
||||
|
||||
#if !defined (__FUNCTION_DEF)
|
||||
# define __FUNCTION_DEF
|
||||
typedef int Function ();
|
||||
typedef void VFunction ();
|
||||
#endif /* _FUNCTION_DEF */
|
||||
|
||||
/* Add POINTER to the list of pointers found in ARRAY. SLOTS is the number
|
||||
of slots that have already been allocated. INDEX is the index into the
|
||||
array where POINTER should be added. GROW is the number of slots to grow
|
||||
ARRAY by, in the case that it needs growing. TYPE is a cast of the type
|
||||
of object stored in ARRAY (e.g., NODE_ENTRY *. */
|
||||
#define add_pointer_to_array(pointer, idx, array, slots, grow, type) \
|
||||
do { \
|
||||
if (idx + 2 >= slots) \
|
||||
array = (type *)(xrealloc (array, (slots += grow) * sizeof (type))); \
|
||||
array[idx++] = (type)pointer; \
|
||||
array[idx] = (type)NULL; \
|
||||
} while (0)
|
||||
|
||||
#define maybe_free(x) do { if (x) free (x); } while (0)
|
||||
|
||||
#if !defined (HAVE_BZERO)
|
||||
# define zero_mem(mem, length) memset (mem, 0, length)
|
||||
#else
|
||||
# define zero_mem(mem, length) bzero (mem, length)
|
||||
#endif /* !BZERO_MISSING */
|
||||
|
||||
#endif /* !_GENERAL_H_ */
|
731
gnu/usr.bin/texinfo/info/getopt.c
Normal file
731
gnu/usr.bin/texinfo/info/getopt.c
Normal file
@ -0,0 +1,731 @@
|
||||
/* Getopt for GNU.
|
||||
NOTE: getopt is now part of the C library, so if you don't know what
|
||||
"Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
|
||||
before changing it!
|
||||
|
||||
Copyright (C) 1987, 88, 89, 90, 91, 92, 1993
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* NOTE!!! AIX requires this to be the first thing in the file.
|
||||
Do not put ANYTHING before it! */
|
||||
#if !defined (__GNUC__) && defined (_AIX)
|
||||
#pragma alloca
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define alloca __builtin_alloca
|
||||
#else /* not __GNUC__ */
|
||||
#if defined (HAVE_ALLOCA_H) || (defined(sparc) && (defined(sun) || (!defined(USG) && !defined(SVR4) && !defined(__svr4__))))
|
||||
#include <alloca.h>
|
||||
#else
|
||||
#ifndef _AIX
|
||||
char *alloca ();
|
||||
#endif
|
||||
#endif /* alloca.h */
|
||||
#endif /* not __GNUC__ */
|
||||
|
||||
#if !__STDC__ && !defined(const) && IN_GCC
|
||||
#define const
|
||||
#endif
|
||||
|
||||
/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>. */
|
||||
#ifndef _NO_PROTO
|
||||
#define _NO_PROTO
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* Comment out all this code if we are using the GNU C Library, and are not
|
||||
actually compiling the library itself. This code is part of the GNU C
|
||||
Library, but also included in many other GNU distributions. Compiling
|
||||
and linking in this code is a waste when using the GNU C library
|
||||
(especially if it is a shared library). Rather than having every GNU
|
||||
program understand `configure --with-gnu-libc' and omit the object files,
|
||||
it is simpler to just do this in the source for each such file. */
|
||||
|
||||
#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
|
||||
|
||||
|
||||
/* This needs to come after some library #include
|
||||
to get __GNU_LIBRARY__ defined. */
|
||||
#ifdef __GNU_LIBRARY__
|
||||
#undef alloca
|
||||
/* Don't include stdlib.h for non-GNU C libraries because some of them
|
||||
contain conflicting prototypes for getopt. */
|
||||
#include <stdlib.h>
|
||||
#else /* Not GNU C library. */
|
||||
#define __alloca alloca
|
||||
#endif /* GNU C library. */
|
||||
|
||||
/* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a
|
||||
long-named option. Because this is not POSIX.2 compliant, it is
|
||||
being phased out. */
|
||||
/* #define GETOPT_COMPAT */
|
||||
|
||||
/* This version of `getopt' appears to the caller like standard Unix `getopt'
|
||||
but it behaves differently for the user, since it allows the user
|
||||
to intersperse the options with the other arguments.
|
||||
|
||||
As `getopt' works, it permutes the elements of ARGV so that,
|
||||
when it is done, all the options precede everything else. Thus
|
||||
all application programs are extended to handle flexible argument order.
|
||||
|
||||
Setting the environment variable POSIXLY_CORRECT disables permutation.
|
||||
Then the behavior is completely standard.
|
||||
|
||||
GNU application programs can use a third alternative mode in which
|
||||
they can distinguish the relative order of options and other arguments. */
|
||||
|
||||
#include "getopt.h"
|
||||
|
||||
/* For communication from `getopt' to the caller.
|
||||
When `getopt' finds an option that takes an argument,
|
||||
the argument value is returned here.
|
||||
Also, when `ordering' is RETURN_IN_ORDER,
|
||||
each non-option ARGV-element is returned here. */
|
||||
|
||||
char *optarg = 0;
|
||||
|
||||
/* Index in ARGV of the next element to be scanned.
|
||||
This is used for communication to and from the caller
|
||||
and for communication between successive calls to `getopt'.
|
||||
|
||||
On entry to `getopt', zero means this is the first call; initialize.
|
||||
|
||||
When `getopt' returns EOF, this is the index of the first of the
|
||||
non-option elements that the caller should itself scan.
|
||||
|
||||
Otherwise, `optind' communicates from one call to the next
|
||||
how much of ARGV has been scanned so far. */
|
||||
|
||||
/* XXX 1003.2 says this must be 1 before any call. */
|
||||
int optind = 0;
|
||||
|
||||
/* The next char to be scanned in the option-element
|
||||
in which the last option character we returned was found.
|
||||
This allows us to pick up the scan where we left off.
|
||||
|
||||
If this is zero, or a null string, it means resume the scan
|
||||
by advancing to the next ARGV-element. */
|
||||
|
||||
static char *nextchar;
|
||||
|
||||
/* Callers store zero here to inhibit the error message
|
||||
for unrecognized options. */
|
||||
|
||||
int opterr = 1;
|
||||
|
||||
/* Set to an option character which was unrecognized.
|
||||
This must be initialized on some systems to avoid linking in the
|
||||
system's own getopt implementation. */
|
||||
|
||||
int optopt = '?';
|
||||
|
||||
/* Describe how to deal with options that follow non-option ARGV-elements.
|
||||
|
||||
If the caller did not specify anything,
|
||||
the default is REQUIRE_ORDER if the environment variable
|
||||
POSIXLY_CORRECT is defined, PERMUTE otherwise.
|
||||
|
||||
REQUIRE_ORDER means don't recognize them as options;
|
||||
stop option processing when the first non-option is seen.
|
||||
This is what Unix does.
|
||||
This mode of operation is selected by either setting the environment
|
||||
variable POSIXLY_CORRECT, or using `+' as the first character
|
||||
of the list of option characters.
|
||||
|
||||
PERMUTE is the default. We permute the contents of ARGV as we scan,
|
||||
so that eventually all the non-options are at the end. This allows options
|
||||
to be given in any order, even with programs that were not written to
|
||||
expect this.
|
||||
|
||||
RETURN_IN_ORDER is an option available to programs that were written
|
||||
to expect options and other ARGV-elements in any order and that care about
|
||||
the ordering of the two. We describe each non-option ARGV-element
|
||||
as if it were the argument of an option with character code 1.
|
||||
Using `-' as the first character of the list of option characters
|
||||
selects this mode of operation.
|
||||
|
||||
The special argument `--' forces an end of option-scanning regardless
|
||||
of the value of `ordering'. In the case of RETURN_IN_ORDER, only
|
||||
`--' can cause `getopt' to return EOF with `optind' != ARGC. */
|
||||
|
||||
static enum
|
||||
{
|
||||
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
|
||||
} ordering;
|
||||
|
||||
#ifdef __GNU_LIBRARY__
|
||||
/* We want to avoid inclusion of string.h with non-GNU libraries
|
||||
because there are many ways it can cause trouble.
|
||||
On some systems, it contains special magic macros that don't work
|
||||
in GCC. */
|
||||
#include <string.h>
|
||||
#define my_index strchr
|
||||
#define my_bcopy(src, dst, n) memcpy ((dst), (src), (n))
|
||||
#else
|
||||
|
||||
/* Avoid depending on library functions or files
|
||||
whose names are inconsistent. */
|
||||
|
||||
char *getenv ();
|
||||
|
||||
static char *
|
||||
my_index (str, chr)
|
||||
const char *str;
|
||||
int chr;
|
||||
{
|
||||
while (*str)
|
||||
{
|
||||
if (*str == chr)
|
||||
return (char *) str;
|
||||
str++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
my_bcopy (from, to, size)
|
||||
const char *from;
|
||||
char *to;
|
||||
int size;
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < size; i++)
|
||||
to[i] = from[i];
|
||||
}
|
||||
#endif /* GNU C library. */
|
||||
|
||||
/* Handle permutation of arguments. */
|
||||
|
||||
/* Describe the part of ARGV that contains non-options that have
|
||||
been skipped. `first_nonopt' is the index in ARGV of the first of them;
|
||||
`last_nonopt' is the index after the last of them. */
|
||||
|
||||
static int first_nonopt;
|
||||
static int last_nonopt;
|
||||
|
||||
/* Exchange two adjacent subsequences of ARGV.
|
||||
One subsequence is elements [first_nonopt,last_nonopt)
|
||||
which contains all the non-options that have been skipped so far.
|
||||
The other is elements [last_nonopt,optind), which contains all
|
||||
the options processed since those non-options were skipped.
|
||||
|
||||
`first_nonopt' and `last_nonopt' are relocated so that they describe
|
||||
the new indices of the non-options in ARGV after they are moved. */
|
||||
|
||||
static void
|
||||
exchange (argv)
|
||||
char **argv;
|
||||
{
|
||||
int nonopts_size = (last_nonopt - first_nonopt) * sizeof (char *);
|
||||
char **temp = (char **) __alloca (nonopts_size);
|
||||
|
||||
/* Interchange the two blocks of data in ARGV. */
|
||||
|
||||
my_bcopy ((char *) &argv[first_nonopt], (char *) temp, nonopts_size);
|
||||
my_bcopy ((char *) &argv[last_nonopt], (char *) &argv[first_nonopt],
|
||||
(optind - last_nonopt) * sizeof (char *));
|
||||
my_bcopy ((char *) temp,
|
||||
(char *) &argv[first_nonopt + optind - last_nonopt],
|
||||
nonopts_size);
|
||||
|
||||
/* Update records for the slots the non-options now occupy. */
|
||||
|
||||
first_nonopt += (optind - last_nonopt);
|
||||
last_nonopt = optind;
|
||||
}
|
||||
|
||||
/* Scan elements of ARGV (whose length is ARGC) for option characters
|
||||
given in OPTSTRING.
|
||||
|
||||
If an element of ARGV starts with '-', and is not exactly "-" or "--",
|
||||
then it is an option element. The characters of this element
|
||||
(aside from the initial '-') are option characters. If `getopt'
|
||||
is called repeatedly, it returns successively each of the option characters
|
||||
from each of the option elements.
|
||||
|
||||
If `getopt' finds another option character, it returns that character,
|
||||
updating `optind' and `nextchar' so that the next call to `getopt' can
|
||||
resume the scan with the following option character or ARGV-element.
|
||||
|
||||
If there are no more option characters, `getopt' returns `EOF'.
|
||||
Then `optind' is the index in ARGV of the first ARGV-element
|
||||
that is not an option. (The ARGV-elements have been permuted
|
||||
so that those that are not options now come last.)
|
||||
|
||||
OPTSTRING is a string containing the legitimate option characters.
|
||||
If an option character is seen that is not listed in OPTSTRING,
|
||||
return '?' after printing an error message. If you set `opterr' to
|
||||
zero, the error message is suppressed but we still return '?'.
|
||||
|
||||
If a char in OPTSTRING is followed by a colon, that means it wants an arg,
|
||||
so the following text in the same ARGV-element, or the text of the following
|
||||
ARGV-element, is returned in `optarg'. Two colons mean an option that
|
||||
wants an optional arg; if there is text in the current ARGV-element,
|
||||
it is returned in `optarg', otherwise `optarg' is set to zero.
|
||||
|
||||
If OPTSTRING starts with `-' or `+', it requests different methods of
|
||||
handling the non-option ARGV-elements.
|
||||
See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
|
||||
|
||||
Long-named options begin with `--' instead of `-'.
|
||||
Their names may be abbreviated as long as the abbreviation is unique
|
||||
or is an exact match for some defined option. If they have an
|
||||
argument, it follows the option name in the same ARGV-element, separated
|
||||
from the option name by a `=', or else the in next ARGV-element.
|
||||
When `getopt' finds a long-named option, it returns 0 if that option's
|
||||
`flag' field is nonzero, the value of the option's `val' field
|
||||
if the `flag' field is zero.
|
||||
|
||||
The elements of ARGV aren't really const, because we permute them.
|
||||
But we pretend they're const in the prototype to be compatible
|
||||
with other systems.
|
||||
|
||||
LONGOPTS is a vector of `struct option' terminated by an
|
||||
element containing a name which is zero.
|
||||
|
||||
LONGIND returns the index in LONGOPT of the long-named option found.
|
||||
It is only valid when a long-named option has been found by the most
|
||||
recent call.
|
||||
|
||||
If LONG_ONLY is nonzero, '-' as well as '--' can introduce
|
||||
long-named options. */
|
||||
|
||||
int
|
||||
_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *optstring;
|
||||
const struct option *longopts;
|
||||
int *longind;
|
||||
int long_only;
|
||||
{
|
||||
int option_index;
|
||||
|
||||
optarg = 0;
|
||||
|
||||
/* Initialize the internal data when the first call is made.
|
||||
Start processing options with ARGV-element 1 (since ARGV-element 0
|
||||
is the program name); the sequence of previously skipped
|
||||
non-option ARGV-elements is empty. */
|
||||
|
||||
if (optind == 0)
|
||||
{
|
||||
first_nonopt = last_nonopt = optind = 1;
|
||||
|
||||
nextchar = NULL;
|
||||
|
||||
/* Determine how to handle the ordering of options and nonoptions. */
|
||||
|
||||
if (optstring[0] == '-')
|
||||
{
|
||||
ordering = RETURN_IN_ORDER;
|
||||
++optstring;
|
||||
}
|
||||
else if (optstring[0] == '+')
|
||||
{
|
||||
ordering = REQUIRE_ORDER;
|
||||
++optstring;
|
||||
}
|
||||
else if (getenv ("POSIXLY_CORRECT") != NULL)
|
||||
ordering = REQUIRE_ORDER;
|
||||
else
|
||||
ordering = PERMUTE;
|
||||
}
|
||||
|
||||
if (nextchar == NULL || *nextchar == '\0')
|
||||
{
|
||||
if (ordering == PERMUTE)
|
||||
{
|
||||
/* If we have just processed some options following some non-options,
|
||||
exchange them so that the options come first. */
|
||||
|
||||
if (first_nonopt != last_nonopt && last_nonopt != optind)
|
||||
exchange ((char **) argv);
|
||||
else if (last_nonopt != optind)
|
||||
first_nonopt = optind;
|
||||
|
||||
/* Now skip any additional non-options
|
||||
and extend the range of non-options previously skipped. */
|
||||
|
||||
while (optind < argc
|
||||
&& (argv[optind][0] != '-' || argv[optind][1] == '\0')
|
||||
#ifdef GETOPT_COMPAT
|
||||
&& (longopts == NULL
|
||||
|| argv[optind][0] != '+' || argv[optind][1] == '\0')
|
||||
#endif /* GETOPT_COMPAT */
|
||||
)
|
||||
optind++;
|
||||
last_nonopt = optind;
|
||||
}
|
||||
|
||||
/* Special ARGV-element `--' means premature end of options.
|
||||
Skip it like a null option,
|
||||
then exchange with previous non-options as if it were an option,
|
||||
then skip everything else like a non-option. */
|
||||
|
||||
if (optind != argc && !strcmp (argv[optind], "--"))
|
||||
{
|
||||
optind++;
|
||||
|
||||
if (first_nonopt != last_nonopt && last_nonopt != optind)
|
||||
exchange ((char **) argv);
|
||||
else if (first_nonopt == last_nonopt)
|
||||
first_nonopt = optind;
|
||||
last_nonopt = argc;
|
||||
|
||||
optind = argc;
|
||||
}
|
||||
|
||||
/* If we have done all the ARGV-elements, stop the scan
|
||||
and back over any non-options that we skipped and permuted. */
|
||||
|
||||
if (optind == argc)
|
||||
{
|
||||
/* Set the next-arg-index to point at the non-options
|
||||
that we previously skipped, so the caller will digest them. */
|
||||
if (first_nonopt != last_nonopt)
|
||||
optind = first_nonopt;
|
||||
return EOF;
|
||||
}
|
||||
|
||||
/* If we have come to a non-option and did not permute it,
|
||||
either stop the scan or describe it to the caller and pass it by. */
|
||||
|
||||
if ((argv[optind][0] != '-' || argv[optind][1] == '\0')
|
||||
#ifdef GETOPT_COMPAT
|
||||
&& (longopts == NULL
|
||||
|| argv[optind][0] != '+' || argv[optind][1] == '\0')
|
||||
#endif /* GETOPT_COMPAT */
|
||||
)
|
||||
{
|
||||
if (ordering == REQUIRE_ORDER)
|
||||
return EOF;
|
||||
optarg = argv[optind++];
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* We have found another option-ARGV-element.
|
||||
Start decoding its characters. */
|
||||
|
||||
nextchar = (argv[optind] + 1
|
||||
+ (longopts != NULL && argv[optind][1] == '-'));
|
||||
}
|
||||
|
||||
if (longopts != NULL
|
||||
&& ((argv[optind][0] == '-'
|
||||
&& (argv[optind][1] == '-' || long_only))
|
||||
#ifdef GETOPT_COMPAT
|
||||
|| argv[optind][0] == '+'
|
||||
#endif /* GETOPT_COMPAT */
|
||||
))
|
||||
{
|
||||
const struct option *p;
|
||||
char *s = nextchar;
|
||||
int exact = 0;
|
||||
int ambig = 0;
|
||||
const struct option *pfound = NULL;
|
||||
int indfound;
|
||||
|
||||
while (*s && *s != '=')
|
||||
s++;
|
||||
|
||||
/* Test all options for either exact match or abbreviated matches. */
|
||||
for (p = longopts, option_index = 0; p->name;
|
||||
p++, option_index++)
|
||||
if (!strncmp (p->name, nextchar, s - nextchar))
|
||||
{
|
||||
if (s - nextchar == strlen (p->name))
|
||||
{
|
||||
/* Exact match found. */
|
||||
pfound = p;
|
||||
indfound = option_index;
|
||||
exact = 1;
|
||||
break;
|
||||
}
|
||||
else if (pfound == NULL)
|
||||
{
|
||||
/* First nonexact match found. */
|
||||
pfound = p;
|
||||
indfound = option_index;
|
||||
}
|
||||
else
|
||||
/* Second nonexact match found. */
|
||||
ambig = 1;
|
||||
}
|
||||
|
||||
if (ambig && !exact)
|
||||
{
|
||||
if (opterr)
|
||||
fprintf (stderr, "%s: option `%s' is ambiguous\n",
|
||||
argv[0], argv[optind]);
|
||||
nextchar += strlen (nextchar);
|
||||
optind++;
|
||||
return '?';
|
||||
}
|
||||
|
||||
if (pfound != NULL)
|
||||
{
|
||||
option_index = indfound;
|
||||
optind++;
|
||||
if (*s)
|
||||
{
|
||||
/* Don't test has_arg with >, because some C compilers don't
|
||||
allow it to be used on enums. */
|
||||
if (pfound->has_arg)
|
||||
optarg = s + 1;
|
||||
else
|
||||
{
|
||||
if (opterr)
|
||||
{
|
||||
if (argv[optind - 1][1] == '-')
|
||||
/* --option */
|
||||
fprintf (stderr,
|
||||
"%s: option `--%s' doesn't allow an argument\n",
|
||||
argv[0], pfound->name);
|
||||
else
|
||||
/* +option or -option */
|
||||
fprintf (stderr,
|
||||
"%s: option `%c%s' doesn't allow an argument\n",
|
||||
argv[0], argv[optind - 1][0], pfound->name);
|
||||
}
|
||||
nextchar += strlen (nextchar);
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
else if (pfound->has_arg == 1)
|
||||
{
|
||||
if (optind < argc)
|
||||
optarg = argv[optind++];
|
||||
else
|
||||
{
|
||||
if (opterr)
|
||||
fprintf (stderr, "%s: option `%s' requires an argument\n",
|
||||
argv[0], argv[optind - 1]);
|
||||
nextchar += strlen (nextchar);
|
||||
return optstring[0] == ':' ? ':' : '?';
|
||||
}
|
||||
}
|
||||
nextchar += strlen (nextchar);
|
||||
if (longind != NULL)
|
||||
*longind = option_index;
|
||||
if (pfound->flag)
|
||||
{
|
||||
*(pfound->flag) = pfound->val;
|
||||
return 0;
|
||||
}
|
||||
return pfound->val;
|
||||
}
|
||||
/* Can't find it as a long option. If this is not getopt_long_only,
|
||||
or the option starts with '--' or is not a valid short
|
||||
option, then it's an error.
|
||||
Otherwise interpret it as a short option. */
|
||||
if (!long_only || argv[optind][1] == '-'
|
||||
#ifdef GETOPT_COMPAT
|
||||
|| argv[optind][0] == '+'
|
||||
#endif /* GETOPT_COMPAT */
|
||||
|| my_index (optstring, *nextchar) == NULL)
|
||||
{
|
||||
if (opterr)
|
||||
{
|
||||
if (argv[optind][1] == '-')
|
||||
/* --option */
|
||||
fprintf (stderr, "%s: unrecognized option `--%s'\n",
|
||||
argv[0], nextchar);
|
||||
else
|
||||
/* +option or -option */
|
||||
fprintf (stderr, "%s: unrecognized option `%c%s'\n",
|
||||
argv[0], argv[optind][0], nextchar);
|
||||
}
|
||||
nextchar = (char *) "";
|
||||
optind++;
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
|
||||
/* Look at and handle the next option-character. */
|
||||
|
||||
{
|
||||
char c = *nextchar++;
|
||||
char *temp = my_index (optstring, c);
|
||||
|
||||
/* Increment `optind' when we start to process its last character. */
|
||||
if (*nextchar == '\0')
|
||||
++optind;
|
||||
|
||||
if (temp == NULL || c == ':')
|
||||
{
|
||||
if (opterr)
|
||||
{
|
||||
#if 0
|
||||
if (c < 040 || c >= 0177)
|
||||
fprintf (stderr, "%s: unrecognized option, character code 0%o\n",
|
||||
argv[0], c);
|
||||
else
|
||||
fprintf (stderr, "%s: unrecognized option `-%c'\n", argv[0], c);
|
||||
#else
|
||||
/* 1003.2 specifies the format of this message. */
|
||||
fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c);
|
||||
#endif
|
||||
}
|
||||
optopt = c;
|
||||
return '?';
|
||||
}
|
||||
if (temp[1] == ':')
|
||||
{
|
||||
if (temp[2] == ':')
|
||||
{
|
||||
/* This is an option that accepts an argument optionally. */
|
||||
if (*nextchar != '\0')
|
||||
{
|
||||
optarg = nextchar;
|
||||
optind++;
|
||||
}
|
||||
else
|
||||
optarg = 0;
|
||||
nextchar = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is an option that requires an argument. */
|
||||
if (*nextchar != '\0')
|
||||
{
|
||||
optarg = nextchar;
|
||||
/* If we end this ARGV-element by taking the rest as an arg,
|
||||
we must advance to the next element now. */
|
||||
optind++;
|
||||
}
|
||||
else if (optind == argc)
|
||||
{
|
||||
if (opterr)
|
||||
{
|
||||
#if 0
|
||||
fprintf (stderr, "%s: option `-%c' requires an argument\n",
|
||||
argv[0], c);
|
||||
#else
|
||||
/* 1003.2 specifies the format of this message. */
|
||||
fprintf (stderr, "%s: option requires an argument -- %c\n",
|
||||
argv[0], c);
|
||||
#endif
|
||||
}
|
||||
optopt = c;
|
||||
if (optstring[0] == ':')
|
||||
c = ':';
|
||||
else
|
||||
c = '?';
|
||||
}
|
||||
else
|
||||
/* We already incremented `optind' once;
|
||||
increment it again when taking next ARGV-elt as argument. */
|
||||
optarg = argv[optind++];
|
||||
nextchar = NULL;
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
getopt (argc, argv, optstring)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *optstring;
|
||||
{
|
||||
return _getopt_internal (argc, argv, optstring,
|
||||
(const struct option *) 0,
|
||||
(int *) 0,
|
||||
0);
|
||||
}
|
||||
|
||||
#endif /* _LIBC or not __GNU_LIBRARY__. */
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
/* Compile with -DTEST to make an executable for use in testing
|
||||
the above definition of `getopt'. */
|
||||
|
||||
int
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int c;
|
||||
int digit_optind = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
int this_option_optind = optind ? optind : 1;
|
||||
|
||||
c = getopt (argc, argv, "abc:d:0123456789");
|
||||
if (c == EOF)
|
||||
break;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
if (digit_optind != 0 && digit_optind != this_option_optind)
|
||||
printf ("digits occur in two different argv-elements.\n");
|
||||
digit_optind = this_option_optind;
|
||||
printf ("option %c\n", c);
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
printf ("option a\n");
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
printf ("option b\n");
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
printf ("option c with value `%s'\n", optarg);
|
||||
break;
|
||||
|
||||
case '?':
|
||||
break;
|
||||
|
||||
default:
|
||||
printf ("?? getopt returned character code 0%o ??\n", c);
|
||||
}
|
||||
}
|
||||
|
||||
if (optind < argc)
|
||||
{
|
||||
printf ("non-option ARGV-elements: ");
|
||||
while (optind < argc)
|
||||
printf ("%s ", argv[optind++]);
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
#endif /* TEST */
|
129
gnu/usr.bin/texinfo/info/getopt.h
Normal file
129
gnu/usr.bin/texinfo/info/getopt.h
Normal file
@ -0,0 +1,129 @@
|
||||
/* Declarations for getopt.
|
||||
Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifndef _GETOPT_H
|
||||
#define _GETOPT_H 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* For communication from `getopt' to the caller.
|
||||
When `getopt' finds an option that takes an argument,
|
||||
the argument value is returned here.
|
||||
Also, when `ordering' is RETURN_IN_ORDER,
|
||||
each non-option ARGV-element is returned here. */
|
||||
|
||||
extern char *optarg;
|
||||
|
||||
/* Index in ARGV of the next element to be scanned.
|
||||
This is used for communication to and from the caller
|
||||
and for communication between successive calls to `getopt'.
|
||||
|
||||
On entry to `getopt', zero means this is the first call; initialize.
|
||||
|
||||
When `getopt' returns EOF, this is the index of the first of the
|
||||
non-option elements that the caller should itself scan.
|
||||
|
||||
Otherwise, `optind' communicates from one call to the next
|
||||
how much of ARGV has been scanned so far. */
|
||||
|
||||
extern int optind;
|
||||
|
||||
/* Callers store zero here to inhibit the error message `getopt' prints
|
||||
for unrecognized options. */
|
||||
|
||||
extern int opterr;
|
||||
|
||||
/* Set to an option character which was unrecognized. */
|
||||
|
||||
extern int optopt;
|
||||
|
||||
/* Describe the long-named options requested by the application.
|
||||
The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
|
||||
of `struct option' terminated by an element containing a name which is
|
||||
zero.
|
||||
|
||||
The field `has_arg' is:
|
||||
no_argument (or 0) if the option does not take an argument,
|
||||
required_argument (or 1) if the option requires an argument,
|
||||
optional_argument (or 2) if the option takes an optional argument.
|
||||
|
||||
If the field `flag' is not NULL, it points to a variable that is set
|
||||
to the value given in the field `val' when the option is found, but
|
||||
left unchanged if the option is not found.
|
||||
|
||||
To have a long-named option do something other than set an `int' to
|
||||
a compiled-in constant, such as set a value from `optarg', set the
|
||||
option's `flag' field to zero and its `val' field to a nonzero
|
||||
value (the equivalent single-letter option character, if there is
|
||||
one). For long options that have a zero `flag' field, `getopt'
|
||||
returns the contents of the `val' field. */
|
||||
|
||||
struct option
|
||||
{
|
||||
#if __STDC__
|
||||
const char *name;
|
||||
#else
|
||||
char *name;
|
||||
#endif
|
||||
/* has_arg can't be an enum because some compilers complain about
|
||||
type mismatches in all the code that assumes it is an int. */
|
||||
int has_arg;
|
||||
int *flag;
|
||||
int val;
|
||||
};
|
||||
|
||||
/* Names for the values of the `has_arg' field of `struct option'. */
|
||||
|
||||
#define no_argument 0
|
||||
#define required_argument 1
|
||||
#define optional_argument 2
|
||||
|
||||
#if __STDC__
|
||||
#if defined(__GNU_LIBRARY__)
|
||||
/* Many other libraries have conflicting prototypes for getopt, with
|
||||
differences in the consts, in stdlib.h. To avoid compilation
|
||||
errors, only prototype getopt for the GNU C library. */
|
||||
extern int getopt (int argc, char *const *argv, const char *shortopts);
|
||||
#else /* not __GNU_LIBRARY__ */
|
||||
extern int getopt ();
|
||||
#endif /* not __GNU_LIBRARY__ */
|
||||
extern int getopt_long (int argc, char *const *argv, const char *shortopts,
|
||||
const struct option *longopts, int *longind);
|
||||
extern int getopt_long_only (int argc, char *const *argv,
|
||||
const char *shortopts,
|
||||
const struct option *longopts, int *longind);
|
||||
|
||||
/* Internal only. Users should not call this directly. */
|
||||
extern int _getopt_internal (int argc, char *const *argv,
|
||||
const char *shortopts,
|
||||
const struct option *longopts, int *longind,
|
||||
int long_only);
|
||||
#else /* not __STDC__ */
|
||||
extern int getopt ();
|
||||
extern int getopt_long ();
|
||||
extern int getopt_long_only ();
|
||||
|
||||
extern int _getopt_internal ();
|
||||
#endif /* not __STDC__ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _GETOPT_H */
|
176
gnu/usr.bin/texinfo/info/getopt1.c
Normal file
176
gnu/usr.bin/texinfo/info/getopt1.c
Normal file
@ -0,0 +1,176 @@
|
||||
/* getopt_long and getopt_long_only entry points for GNU getopt.
|
||||
Copyright (C) 1987, 88, 89, 90, 91, 92, 1993
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "getopt.h"
|
||||
|
||||
#if !__STDC__ && !defined(const) && IN_GCC
|
||||
#define const
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* Comment out all this code if we are using the GNU C Library, and are not
|
||||
actually compiling the library itself. This code is part of the GNU C
|
||||
Library, but also included in many other GNU distributions. Compiling
|
||||
and linking in this code is a waste when using the GNU C library
|
||||
(especially if it is a shared library). Rather than having every GNU
|
||||
program understand `configure --with-gnu-libc' and omit the object files,
|
||||
it is simpler to just do this in the source for each such file. */
|
||||
|
||||
#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
|
||||
|
||||
|
||||
/* This needs to come after some library #include
|
||||
to get __GNU_LIBRARY__ defined. */
|
||||
#ifdef __GNU_LIBRARY__
|
||||
#include <stdlib.h>
|
||||
#else
|
||||
char *getenv ();
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
int
|
||||
getopt_long (argc, argv, options, long_options, opt_index)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *options;
|
||||
const struct option *long_options;
|
||||
int *opt_index;
|
||||
{
|
||||
return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
|
||||
}
|
||||
|
||||
/* Like getopt_long, but '-' as well as '--' can indicate a long option.
|
||||
If an option that starts with '-' (not '--') doesn't match a long option,
|
||||
but does match a short option, it is parsed as a short option
|
||||
instead. */
|
||||
|
||||
int
|
||||
getopt_long_only (argc, argv, options, long_options, opt_index)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *options;
|
||||
const struct option *long_options;
|
||||
int *opt_index;
|
||||
{
|
||||
return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
|
||||
}
|
||||
|
||||
|
||||
#endif /* _LIBC or not __GNU_LIBRARY__. */
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int c;
|
||||
int digit_optind = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
int this_option_optind = optind ? optind : 1;
|
||||
int option_index = 0;
|
||||
static struct option long_options[] =
|
||||
{
|
||||
{"add", 1, 0, 0},
|
||||
{"append", 0, 0, 0},
|
||||
{"delete", 1, 0, 0},
|
||||
{"verbose", 0, 0, 0},
|
||||
{"create", 0, 0, 0},
|
||||
{"file", 1, 0, 0},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
c = getopt_long (argc, argv, "abc:d:0123456789",
|
||||
long_options, &option_index);
|
||||
if (c == EOF)
|
||||
break;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 0:
|
||||
printf ("option %s", long_options[option_index].name);
|
||||
if (optarg)
|
||||
printf (" with arg %s", optarg);
|
||||
printf ("\n");
|
||||
break;
|
||||
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
if (digit_optind != 0 && digit_optind != this_option_optind)
|
||||
printf ("digits occur in two different argv-elements.\n");
|
||||
digit_optind = this_option_optind;
|
||||
printf ("option %c\n", c);
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
printf ("option a\n");
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
printf ("option b\n");
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
printf ("option c with value `%s'\n", optarg);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
printf ("option d with value `%s'\n", optarg);
|
||||
break;
|
||||
|
||||
case '?':
|
||||
break;
|
||||
|
||||
default:
|
||||
printf ("?? getopt returned character code 0%o ??\n", c);
|
||||
}
|
||||
}
|
||||
|
||||
if (optind < argc)
|
||||
{
|
||||
printf ("non-option ARGV-elements: ");
|
||||
while (optind < argc)
|
||||
printf ("%s ", argv[optind++]);
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
#endif /* TEST */
|
667
gnu/usr.bin/texinfo/info/indices.c
Normal file
667
gnu/usr.bin/texinfo/info/indices.c
Normal file
@ -0,0 +1,667 @@
|
||||
/* indices.c -- Commands for dealing with an Info file Index. */
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#include "info.h"
|
||||
#include "indices.h"
|
||||
|
||||
/* User-visible variable controls the output of info-index-next. */
|
||||
int show_index_match = 1;
|
||||
|
||||
/* In the Info sense, an index is a menu. This variable holds the last
|
||||
parsed index. */
|
||||
static REFERENCE **index_index = (REFERENCE **)NULL;
|
||||
|
||||
/* The offset of the most recently selected index element. */
|
||||
static int index_offset = 0;
|
||||
|
||||
/* Variable which holds the last string searched for. */
|
||||
static char *index_search = (char *)NULL;
|
||||
|
||||
/* A couple of "globals" describing where the initial index was found. */
|
||||
static char *initial_index_filename = (char *)NULL;
|
||||
static char *initial_index_nodename = (char *)NULL;
|
||||
|
||||
/* A structure associating index names with index offset ranges. */
|
||||
typedef struct {
|
||||
char *name; /* The nodename of this index. */
|
||||
int first; /* The index in our list of the first entry. */
|
||||
int last; /* The index in our list of the last entry. */
|
||||
} INDEX_NAME_ASSOC;
|
||||
|
||||
/* An array associating index nodenames with index offset ranges. */
|
||||
static INDEX_NAME_ASSOC **index_nodenames = (INDEX_NAME_ASSOC **)NULL;
|
||||
static int index_nodenames_index = 0;
|
||||
static int index_nodenames_slots = 0;
|
||||
|
||||
/* Add the name of NODE, and the range of the associated index elements
|
||||
(passed in ARRAY) to index_nodenames. */
|
||||
static void
|
||||
add_index_to_index_nodenames (array, node)
|
||||
REFERENCE **array;
|
||||
NODE *node;
|
||||
{
|
||||
register int i, last;
|
||||
INDEX_NAME_ASSOC *assoc;
|
||||
|
||||
for (last = 0; array[last]; last++);
|
||||
assoc = (INDEX_NAME_ASSOC *)xmalloc (sizeof (INDEX_NAME_ASSOC));
|
||||
assoc->name = savestring (node->nodename);
|
||||
|
||||
if (!index_nodenames_index)
|
||||
{
|
||||
assoc->first = 0;
|
||||
assoc->last = last;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; index_nodenames[i + 1]; i++);
|
||||
assoc->first = 1 + index_nodenames[i]->last;
|
||||
assoc->last = assoc->first + last;
|
||||
}
|
||||
add_pointer_to_array
|
||||
(assoc, index_nodenames_index, index_nodenames, index_nodenames_slots,
|
||||
10, INDEX_NAME_ASSOC *);
|
||||
}
|
||||
|
||||
/* Find and return the indices of WINDOW's file. The indices are defined
|
||||
as the first node in the file containing the word "Index" and any
|
||||
immediately following nodes whose names also contain "Index". All such
|
||||
indices are concatenated and the result returned. If WINDOW's info file
|
||||
doesn't have any indices, a NULL pointer is returned. */
|
||||
REFERENCE **
|
||||
info_indices_of_window (window)
|
||||
WINDOW *window;
|
||||
{
|
||||
FILE_BUFFER *fb;
|
||||
|
||||
fb = file_buffer_of_window (window);
|
||||
|
||||
return (info_indices_of_file_buffer (fb));
|
||||
}
|
||||
|
||||
REFERENCE **
|
||||
info_indices_of_file_buffer (file_buffer)
|
||||
FILE_BUFFER *file_buffer;
|
||||
{
|
||||
register int i;
|
||||
REFERENCE **result = (REFERENCE **)NULL;
|
||||
|
||||
/* No file buffer, no indices. */
|
||||
if (!file_buffer)
|
||||
return ((REFERENCE **)NULL);
|
||||
|
||||
/* Reset globals describing where the index was found. */
|
||||
maybe_free (initial_index_filename);
|
||||
maybe_free (initial_index_nodename);
|
||||
initial_index_filename = (char *)NULL;
|
||||
initial_index_nodename = (char *)NULL;
|
||||
|
||||
if (index_nodenames)
|
||||
{
|
||||
for (i = 0; index_nodenames[i]; i++)
|
||||
{
|
||||
free (index_nodenames[i]->name);
|
||||
free (index_nodenames[i]);
|
||||
}
|
||||
|
||||
index_nodenames_index = 0;
|
||||
index_nodenames[0] = (INDEX_NAME_ASSOC *)NULL;
|
||||
}
|
||||
|
||||
/* Grovel the names of the nodes found in this file. */
|
||||
if (file_buffer->tags)
|
||||
{
|
||||
TAG *tag;
|
||||
|
||||
for (i = 0; tag = file_buffer->tags[i]; i++)
|
||||
{
|
||||
if (string_in_line ("Index", tag->nodename) != -1)
|
||||
{
|
||||
NODE *node;
|
||||
REFERENCE **menu;
|
||||
|
||||
/* Found one. Get its menu. */
|
||||
node = info_get_node (tag->filename, tag->nodename);
|
||||
if (!node)
|
||||
continue;
|
||||
|
||||
/* Remember the filename and nodename of this index. */
|
||||
initial_index_filename = savestring (file_buffer->filename);
|
||||
initial_index_nodename = savestring (tag->nodename);
|
||||
|
||||
menu = info_menu_of_node (node);
|
||||
|
||||
/* If we have a menu, add this index's nodename and range
|
||||
to our list of index_nodenames. */
|
||||
if (menu)
|
||||
{
|
||||
add_index_to_index_nodenames (menu, node);
|
||||
|
||||
/* Concatenate the references found so far. */
|
||||
result = info_concatenate_references (result, menu);
|
||||
}
|
||||
free (node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If there is a result, clean it up so that every entry has a filename. */
|
||||
for (i = 0; result && result[i]; i++)
|
||||
if (!result[i]->filename)
|
||||
result[i]->filename = savestring (file_buffer->filename);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
DECLARE_INFO_COMMAND (info_index_search,
|
||||
"Look up a string in the index for this file")
|
||||
{
|
||||
FILE_BUFFER *fb;
|
||||
char *line;
|
||||
|
||||
/* Reset the index offset, since this is not the info-index-next command. */
|
||||
index_offset = 0;
|
||||
|
||||
/* The user is selecting a new search string, so flush the old one. */
|
||||
maybe_free (index_search);
|
||||
index_search = (char *)NULL;
|
||||
|
||||
/* If this window's file is not the same as the one that we last built an
|
||||
index for, build and remember an index now. */
|
||||
fb = file_buffer_of_window (window);
|
||||
if (!initial_index_filename ||
|
||||
(strcmp (initial_index_filename, fb->filename) != 0))
|
||||
{
|
||||
info_free_references (index_index);
|
||||
window_message_in_echo_area ("Finding index entries...");
|
||||
index_index = info_indices_of_file_buffer (fb);
|
||||
}
|
||||
|
||||
/* If there is no index, quit now. */
|
||||
if (!index_index)
|
||||
{
|
||||
info_error ("No indices found.");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Okay, there is an index. Let the user select one of the members of it. */
|
||||
line =
|
||||
info_read_maybe_completing (window, "Index entry: ", index_index);
|
||||
|
||||
window = active_window;
|
||||
|
||||
/* User aborted? */
|
||||
if (!line)
|
||||
{
|
||||
info_abort_key (active_window, 1, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Empty line means move to the Index node. */
|
||||
if (!*line)
|
||||
{
|
||||
free (line);
|
||||
|
||||
if (initial_index_filename && initial_index_nodename)
|
||||
{
|
||||
NODE *node;
|
||||
|
||||
node =
|
||||
info_get_node (initial_index_filename, initial_index_nodename);
|
||||
set_remembered_pagetop_and_point (window);
|
||||
window_set_node_of_window (window, node);
|
||||
remember_window_and_node (window, node);
|
||||
window_clear_echo_area ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* The user typed either a completed index label, or a partial string.
|
||||
Find an exact match, or, failing that, the first index entry containing
|
||||
the partial string. So, we just call info_next_index_match () with minor
|
||||
manipulation of INDEX_OFFSET. */
|
||||
{
|
||||
int old_offset;
|
||||
|
||||
/* Start the search right after/before this index. */
|
||||
if (count < 0)
|
||||
{
|
||||
register int i;
|
||||
for (i = 0; index_index[i]; i++);
|
||||
index_offset = i;
|
||||
}
|
||||
else
|
||||
index_offset = -1;
|
||||
|
||||
old_offset == index_offset;
|
||||
|
||||
/* The "last" string searched for is this one. */
|
||||
index_search = line;
|
||||
|
||||
/* Find it, or error. */
|
||||
info_next_index_match (window, count, 0);
|
||||
|
||||
/* If the search failed, return the index offset to where it belongs. */
|
||||
if (index_offset == old_offset)
|
||||
index_offset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_INFO_COMMAND (info_next_index_match,
|
||||
"Go to the next matching index item from the last `\\[index-search]' command")
|
||||
{
|
||||
register int i;
|
||||
int partial, dir;
|
||||
NODE *node;
|
||||
|
||||
/* If there is no previous search string, the user hasn't built an index
|
||||
yet. */
|
||||
if (!index_search)
|
||||
{
|
||||
info_error ("No previous index search string.");
|
||||
return;
|
||||
}
|
||||
|
||||
/* If there is no index, that is an error. */
|
||||
if (!index_index)
|
||||
{
|
||||
info_error ("No index entries.");
|
||||
return;
|
||||
}
|
||||
|
||||
/* The direction of this search is controlled by the value of the
|
||||
numeric argument. */
|
||||
if (count < 0)
|
||||
dir = -1;
|
||||
else
|
||||
dir = 1;
|
||||
|
||||
/* Search for the next occurence of index_search. First try to find
|
||||
an exact match. */
|
||||
partial = 0;
|
||||
|
||||
for (i = index_offset + dir; (i > -1) && (index_index[i]); i += dir)
|
||||
if (strcmp (index_search, index_index[i]->label) == 0)
|
||||
break;
|
||||
|
||||
/* If that failed, look for the next substring match. */
|
||||
if ((i < 0) || (!index_index[i]))
|
||||
{
|
||||
for (i = index_offset + dir; (i > -1) && (index_index[i]); i += dir)
|
||||
if (string_in_line (index_search, index_index[i]->label) != -1)
|
||||
break;
|
||||
|
||||
if ((i > -1) && (index_index[i]))
|
||||
partial = string_in_line (index_search, index_index[i]->label);
|
||||
}
|
||||
|
||||
/* If that failed, print an error. */
|
||||
if ((i < 0) || (!index_index[i]))
|
||||
{
|
||||
info_error ("No %sindex entries containing \"%s\".",
|
||||
index_offset > 0 ? "more " : "", index_search);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Okay, we found the next one. Move the offset to the current entry. */
|
||||
index_offset = i;
|
||||
|
||||
/* Report to the user on what we have found. */
|
||||
{
|
||||
register int j;
|
||||
char *name = "CAN'T SEE THIS";
|
||||
char *match;
|
||||
|
||||
for (j = 0; index_nodenames[j]; j++)
|
||||
{
|
||||
if ((i >= index_nodenames[j]->first) &&
|
||||
(i <= index_nodenames[j]->last))
|
||||
{
|
||||
name = index_nodenames[j]->name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we had a partial match, indicate to the user which part of the
|
||||
string matched. */
|
||||
match = savestring (index_index[i]->label);
|
||||
|
||||
if (partial && show_index_match)
|
||||
{
|
||||
int j, ls, start, upper;
|
||||
|
||||
ls = strlen (index_search);
|
||||
start = partial - ls;
|
||||
upper = isupper (match[start]) ? 1 : 0;
|
||||
|
||||
for (j = 0; j < ls; j++)
|
||||
if (upper)
|
||||
match[j + start] = info_tolower (match[j + start]);
|
||||
else
|
||||
match[j + start] = info_toupper (match[j + start]);
|
||||
}
|
||||
|
||||
{
|
||||
char *format;
|
||||
|
||||
format = replace_in_documentation
|
||||
("Found \"%s\" in %s. (`\\[next-index-match]' tries to find next.)");
|
||||
|
||||
window_message_in_echo_area (format, match, name);
|
||||
}
|
||||
|
||||
free (match);
|
||||
}
|
||||
|
||||
/* Select the node corresponding to this index entry. */
|
||||
node = info_get_node (index_index[i]->filename, index_index[i]->nodename);
|
||||
|
||||
if (!node)
|
||||
{
|
||||
info_error (CANT_FILE_NODE,
|
||||
index_index[i]->filename, index_index[i]->nodename);
|
||||
return;
|
||||
}
|
||||
|
||||
set_remembered_pagetop_and_point (window);
|
||||
window_set_node_of_window (window, node);
|
||||
remember_window_and_node (window, node);
|
||||
|
||||
|
||||
/* Try to find an occurence of LABEL in this node. */
|
||||
{
|
||||
long start, loc;
|
||||
|
||||
start = window->line_starts[1] - window->node->contents;
|
||||
loc = info_target_search_node (node, index_index[i]->label, start);
|
||||
|
||||
if (loc != -1)
|
||||
{
|
||||
window->point = loc;
|
||||
window_adjust_pagetop (window);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Info APROPOS: Search every known index. */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* For every menu item in DIR, search the indices of that file for
|
||||
SEARCH_STRING. */
|
||||
REFERENCE **
|
||||
apropos_in_all_indices (search_string, inform)
|
||||
char *search_string;
|
||||
int inform;
|
||||
{
|
||||
register int i, dir_index;
|
||||
REFERENCE **all_indices = (REFERENCE **)NULL;
|
||||
REFERENCE **dir_menu = (REFERENCE **)NULL;
|
||||
NODE *dir_node;
|
||||
int printed = 0;
|
||||
|
||||
dir_node = info_get_node ("dir", "Top");
|
||||
if (dir_node)
|
||||
dir_menu = info_menu_of_node (dir_node);
|
||||
|
||||
if (!dir_menu)
|
||||
return;
|
||||
|
||||
/* For every menu item in DIR, get the associated node's file buffer and
|
||||
read the indices of that file buffer. Gather all of the indices into
|
||||
one large one. */
|
||||
for (dir_index = 0; dir_menu[dir_index]; dir_index++)
|
||||
{
|
||||
REFERENCE **this_index, *this_item;
|
||||
NODE *this_node;
|
||||
FILE_BUFFER *this_fb;
|
||||
|
||||
this_item = dir_menu[dir_index];
|
||||
|
||||
if (!this_item->filename)
|
||||
{
|
||||
if (dir_node->parent)
|
||||
this_item->filename = savestring (dir_node->parent);
|
||||
else
|
||||
this_item->filename = savestring (dir_node->filename);
|
||||
}
|
||||
|
||||
/* Find this node. If we cannot find it, try using the label of the
|
||||
entry as a file (i.e., "(LABEL)Top"). */
|
||||
this_node = info_get_node (this_item->filename, this_item->nodename);
|
||||
|
||||
if (!this_node && this_item->nodename &&
|
||||
(strcmp (this_item->label, this_item->nodename) == 0))
|
||||
this_node = info_get_node (this_item->label, "Top");
|
||||
|
||||
if (!this_node)
|
||||
continue;
|
||||
|
||||
/* Get the file buffer associated with this node. */
|
||||
{
|
||||
char *files_name;
|
||||
|
||||
files_name = this_node->parent;
|
||||
if (!files_name)
|
||||
files_name = this_node->filename;
|
||||
|
||||
this_fb = info_find_file (files_name);
|
||||
|
||||
if (this_fb && inform)
|
||||
message_in_echo_area ("Scanning indices of \"%s\"...", files_name);
|
||||
|
||||
this_index = info_indices_of_file_buffer (this_fb);
|
||||
free (this_node);
|
||||
|
||||
if (this_fb && inform)
|
||||
unmessage_in_echo_area ();
|
||||
}
|
||||
|
||||
if (this_index)
|
||||
{
|
||||
/* Remember the filename which contains this set of references. */
|
||||
for (i = 0; this_index && this_index[i]; i++)
|
||||
if (!this_index[i]->filename)
|
||||
this_index[i]->filename = savestring (this_fb->filename);
|
||||
|
||||
/* Concatenate with the other indices. */
|
||||
all_indices = info_concatenate_references (all_indices, this_index);
|
||||
}
|
||||
}
|
||||
|
||||
info_free_references (dir_menu);
|
||||
|
||||
/* Build a list of the references which contain SEARCH_STRING. */
|
||||
if (all_indices)
|
||||
{
|
||||
REFERENCE *entry, **apropos_list = (REFERENCE **)NULL;
|
||||
int apropos_list_index = 0;
|
||||
int apropos_list_slots = 0;
|
||||
|
||||
for (i = 0; (entry = all_indices[i]); i++)
|
||||
{
|
||||
if (string_in_line (search_string, entry->label) != -1)
|
||||
{
|
||||
add_pointer_to_array
|
||||
(entry, apropos_list_index, apropos_list, apropos_list_slots,
|
||||
100, REFERENCE *);
|
||||
}
|
||||
else
|
||||
{
|
||||
maybe_free (entry->label);
|
||||
maybe_free (entry->filename);
|
||||
maybe_free (entry->nodename);
|
||||
free (entry);
|
||||
}
|
||||
}
|
||||
|
||||
free (all_indices);
|
||||
all_indices = apropos_list;
|
||||
}
|
||||
return (all_indices);
|
||||
}
|
||||
|
||||
#define APROPOS_NONE \
|
||||
"No available info files reference \"%s\" in their indices."
|
||||
|
||||
void
|
||||
info_apropos (string)
|
||||
char *string;
|
||||
{
|
||||
REFERENCE **apropos_list;
|
||||
|
||||
apropos_list = apropos_in_all_indices (string, 0);
|
||||
|
||||
if (!apropos_list)
|
||||
{
|
||||
info_error (APROPOS_NONE, string);
|
||||
}
|
||||
else
|
||||
{
|
||||
register int i;
|
||||
REFERENCE *entry;
|
||||
|
||||
for (i = 0; (entry = apropos_list[i]); i++)
|
||||
fprintf (stderr, "\"(%s)%s\" -- %s\n",
|
||||
entry->filename, entry->nodename, entry->label);
|
||||
}
|
||||
info_free_references (apropos_list);
|
||||
}
|
||||
|
||||
static char *apropos_list_nodename = "*Apropos*";
|
||||
|
||||
DECLARE_INFO_COMMAND (info_index_apropos,
|
||||
"Grovel all known info file's indices for a string and build a menu")
|
||||
{
|
||||
char *line;
|
||||
|
||||
line = info_read_in_echo_area (window, "Index apropos: ");
|
||||
|
||||
window = active_window;
|
||||
|
||||
/* User aborted? */
|
||||
if (!line)
|
||||
{
|
||||
info_abort_key (window, 1, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
/* User typed something? */
|
||||
if (*line)
|
||||
{
|
||||
REFERENCE **apropos_list;
|
||||
NODE *apropos_node;
|
||||
|
||||
apropos_list = apropos_in_all_indices (line, 1);
|
||||
|
||||
if (!apropos_list)
|
||||
{
|
||||
info_error (APROPOS_NONE, line);
|
||||
}
|
||||
else
|
||||
{
|
||||
register int i;
|
||||
char *line_buffer;
|
||||
|
||||
initialize_message_buffer ();
|
||||
printf_to_message_buffer
|
||||
("\n* Menu: Nodes whoses indices contain \"%s\":\n", line);
|
||||
line_buffer = (char *)xmalloc (500);
|
||||
|
||||
for (i = 0; apropos_list[i]; i++)
|
||||
{
|
||||
int len;
|
||||
sprintf (line_buffer, "* (%s)%s::",
|
||||
apropos_list[i]->filename, apropos_list[i]->nodename);
|
||||
len = pad_to (36, line_buffer);
|
||||
sprintf (line_buffer + len, "%s", apropos_list[i]->label);
|
||||
printf_to_message_buffer ("%s\n", line_buffer);
|
||||
}
|
||||
free (line_buffer);
|
||||
}
|
||||
|
||||
apropos_node = message_buffer_to_node ();
|
||||
add_gcable_pointer (apropos_node);
|
||||
name_internal_node (apropos_node, apropos_list_nodename);
|
||||
|
||||
/* Even though this is an internal node, we don't want the window
|
||||
system to treat it specially. So we turn off the internalness
|
||||
of it here. */
|
||||
apropos_node->flags &= ~N_IsInternal;
|
||||
|
||||
/* Find/Create a window to contain this node. */
|
||||
{
|
||||
WINDOW *new;
|
||||
NODE *node;
|
||||
|
||||
set_remembered_pagetop_and_point (window);
|
||||
|
||||
/* If a window is visible and showing an apropos list already,
|
||||
re-use it. */
|
||||
for (new = windows; new; new = new->next)
|
||||
{
|
||||
node = new->node;
|
||||
|
||||
if (internal_info_node_p (node) &&
|
||||
(strcmp (node->nodename, apropos_list_nodename) == 0))
|
||||
break;
|
||||
}
|
||||
|
||||
/* If we couldn't find an existing window, try to use the next window
|
||||
in the chain. */
|
||||
if (!new && window->next)
|
||||
new = window->next;
|
||||
|
||||
/* If we still don't have a window, make a new one to contain
|
||||
the list. */
|
||||
if (!new)
|
||||
{
|
||||
WINDOW *old_active;
|
||||
|
||||
old_active = active_window;
|
||||
active_window = window;
|
||||
new = window_make_window ((NODE *)NULL);
|
||||
active_window = old_active;
|
||||
}
|
||||
|
||||
/* If we couldn't make a new window, use this one. */
|
||||
if (!new)
|
||||
new = window;
|
||||
|
||||
/* Lines do not wrap in this window. */
|
||||
new->flags |= W_NoWrap;
|
||||
|
||||
window_set_node_of_window (new, apropos_node);
|
||||
remember_window_and_node (new, apropos_node);
|
||||
active_window = new;
|
||||
}
|
||||
info_free_references (apropos_list);
|
||||
}
|
||||
free (line);
|
||||
|
||||
if (!info_error_was_printed)
|
||||
window_clear_echo_area ();
|
||||
}
|
||||
|
39
gnu/usr.bin/texinfo/info/indices.h
Normal file
39
gnu/usr.bin/texinfo/info/indices.h
Normal file
@ -0,0 +1,39 @@
|
||||
/* indices.h -- Functions defined in indices.c. */
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#ifndef _INDICES_H_
|
||||
#define _INDICES_H_
|
||||
|
||||
/* User-visible variable controls the output of info-index-next. */
|
||||
extern int show_index_match;
|
||||
|
||||
extern REFERENCE **info_indices_of_window (), **info_indices_of_file_buffer ();
|
||||
extern void info_apropos ();
|
||||
|
||||
/* For every menu item in DIR, search the indices of that file for STRING. */
|
||||
REFERENCE **apropos_in_all_indices ();
|
||||
|
||||
/* User visible functions declared in indices.c. */
|
||||
extern void info_index_search (), info_next_index_match ();
|
||||
|
||||
#endif /* !_INDICES_H_ */
|
1259
gnu/usr.bin/texinfo/info/info-stnd.info
Normal file
1259
gnu/usr.bin/texinfo/info/info-stnd.info
Normal file
File diff suppressed because it is too large
Load Diff
653
gnu/usr.bin/texinfo/info/info-utils.c
Normal file
653
gnu/usr.bin/texinfo/info/info-utils.c
Normal file
@ -0,0 +1,653 @@
|
||||
/* info-utils.c -- Useful functions for manipulating Info file quirks. */
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#include <stdio.h> /* For "NULL". Yechhh! */
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include "info-utils.h"
|
||||
|
||||
/* When non-zero, various display and input functions handle ISO Latin
|
||||
character sets correctly. */
|
||||
int ISO_Latin_p = 0;
|
||||
|
||||
/* Variable which holds the most recent filename parsed as a result of
|
||||
calling info_parse_xxx (). */
|
||||
char *info_parsed_filename = (char *)NULL;
|
||||
|
||||
/* Variable which holds the most recent nodename parsed as a result of
|
||||
calling info_parse_xxx (). */
|
||||
char *info_parsed_nodename = (char *)NULL;
|
||||
|
||||
/* Functions to remember a filename or nodename for later return. */
|
||||
static void save_filename (), saven_filename ();
|
||||
static void save_nodename (), saven_nodename ();
|
||||
|
||||
/* How to get a reference (either menu or cross). */
|
||||
static REFERENCE **info_references_internal ();
|
||||
|
||||
/* Parse the filename and nodename out of STRING. If STRING doesn't
|
||||
contain a filename (i.e., it is NOT (FILENAME)NODENAME) then set
|
||||
INFO_PARSED_FILENAME to NULL. If second argument NEWLINES_OKAY is
|
||||
non-zero, it says to allow the nodename specification to cross a
|
||||
newline boundary (i.e., only `,', `.', or `TAB' can end the spec). */
|
||||
void
|
||||
info_parse_node (string, newlines_okay)
|
||||
char *string;
|
||||
int newlines_okay;
|
||||
{
|
||||
register int i = 0;
|
||||
|
||||
/* Default the answer. */
|
||||
save_filename ((char *)NULL);
|
||||
save_nodename ((char *)NULL);
|
||||
|
||||
/* Special case of nothing passed. Return nothing. */
|
||||
if (!string || !*string)
|
||||
return;
|
||||
|
||||
string += skip_whitespace (string);
|
||||
|
||||
/* Check for (FILENAME)NODENAME. */
|
||||
if (*string == '(')
|
||||
{
|
||||
i = 0;
|
||||
/* Advance past the opening paren. */
|
||||
string++;
|
||||
|
||||
/* Find the closing paren. */
|
||||
while (string[i] && string[i] != ')')
|
||||
i++;
|
||||
|
||||
/* Remember parsed filename. */
|
||||
saven_filename (string, i);
|
||||
|
||||
/* Point directly at the nodename. */
|
||||
string += i;
|
||||
|
||||
if (*string)
|
||||
string++;
|
||||
}
|
||||
|
||||
/* Parse out nodename. */
|
||||
i = skip_node_characters (string, newlines_okay);
|
||||
saven_nodename (string, i);
|
||||
canonicalize_whitespace (info_parsed_nodename);
|
||||
if (info_parsed_nodename && !*info_parsed_nodename)
|
||||
{
|
||||
free (info_parsed_nodename);
|
||||
info_parsed_nodename = (char *)NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the node addressed by LABEL in NODE (usually one of "Prev:",
|
||||
"Next:", "Up:", "File:", or "Node:". After a call to this function,
|
||||
the global INFO_PARSED_NODENAME and INFO_PARSED_FILENAME contain
|
||||
the information. */
|
||||
void
|
||||
info_parse_label (label, node)
|
||||
char *label;
|
||||
NODE *node;
|
||||
{
|
||||
register int i;
|
||||
char *nodeline;
|
||||
|
||||
/* Default answer to failure. */
|
||||
save_nodename ((char *)NULL);
|
||||
save_filename ((char *)NULL);
|
||||
|
||||
/* Find the label in the first line of this node. */
|
||||
nodeline = node->contents;
|
||||
i = string_in_line (label, nodeline);
|
||||
|
||||
if (i == -1)
|
||||
return;
|
||||
|
||||
nodeline += i;
|
||||
nodeline += skip_whitespace (nodeline);
|
||||
info_parse_node (nodeline, DONT_SKIP_NEWLINES);
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Finding and Building Menus */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Return a NULL terminated array of REFERENCE * which represents the menu
|
||||
found in NODE. If there is no menu in NODE, just return a NULL pointer. */
|
||||
REFERENCE **
|
||||
info_menu_of_node (node)
|
||||
NODE *node;
|
||||
{
|
||||
long position;
|
||||
SEARCH_BINDING search;
|
||||
REFERENCE **menu = (REFERENCE **)NULL;
|
||||
|
||||
search.buffer = node->contents;
|
||||
search.start = 0;
|
||||
search.end = node->nodelen;
|
||||
search.flags = S_FoldCase;
|
||||
|
||||
/* Find the start of the menu. */
|
||||
position = search_forward (INFO_MENU_LABEL, &search);
|
||||
|
||||
if (position == -1)
|
||||
return ((REFERENCE **) NULL);
|
||||
|
||||
/* We have the start of the menu now. Glean menu items from the rest
|
||||
of the node. */
|
||||
search.start = position + strlen (INFO_MENU_LABEL);
|
||||
search.start += skip_line (search.buffer + search.start);
|
||||
search.start--;
|
||||
menu = info_menu_items (&search);
|
||||
return (menu);
|
||||
}
|
||||
|
||||
/* Return a NULL terminated array of REFERENCE * which represents the cross
|
||||
refrences found in NODE. If there are no cross references in NODE, just
|
||||
return a NULL pointer. */
|
||||
REFERENCE **
|
||||
info_xrefs_of_node (node)
|
||||
NODE *node;
|
||||
{
|
||||
SEARCH_BINDING search;
|
||||
|
||||
search.buffer = node->contents;
|
||||
search.start = 0;
|
||||
search.end = node->nodelen;
|
||||
search.flags = S_FoldCase;
|
||||
|
||||
return (info_xrefs (&search));
|
||||
}
|
||||
|
||||
/* Glean menu entries from BINDING->buffer + BINDING->start until we
|
||||
have looked at the entire contents of BINDING. Return an array
|
||||
of REFERENCE * that represents each menu item in this range. */
|
||||
REFERENCE **
|
||||
info_menu_items (binding)
|
||||
SEARCH_BINDING *binding;
|
||||
{
|
||||
return (info_references_internal (INFO_MENU_ENTRY_LABEL, binding));
|
||||
}
|
||||
|
||||
/* Glean cross references from BINDING->buffer + BINDING->start until
|
||||
BINDING->end. Return an array of REFERENCE * that represents each
|
||||
cross reference in this range. */
|
||||
REFERENCE **
|
||||
info_xrefs (binding)
|
||||
SEARCH_BINDING *binding;
|
||||
{
|
||||
return (info_references_internal (INFO_XREF_LABEL, binding));
|
||||
}
|
||||
|
||||
/* Glean cross references or menu items from BINDING. Return an array
|
||||
of REFERENCE * that represents the items found. */
|
||||
static REFERENCE **
|
||||
info_references_internal (label, binding)
|
||||
char *label;
|
||||
SEARCH_BINDING *binding;
|
||||
{
|
||||
SEARCH_BINDING search;
|
||||
REFERENCE **refs = (REFERENCE **)NULL;
|
||||
int refs_index = 0, refs_slots = 0;
|
||||
int searching_for_menu_items = 0;
|
||||
long position;
|
||||
|
||||
search.buffer = binding->buffer;
|
||||
search.start = binding->start;
|
||||
search.end = binding->end;
|
||||
search.flags = S_FoldCase | S_SkipDest;
|
||||
|
||||
searching_for_menu_items = (stricmp (label, INFO_MENU_ENTRY_LABEL) == 0);
|
||||
|
||||
while ((position = search_forward (label, &search)) != -1)
|
||||
{
|
||||
int offset, start;
|
||||
char *refdef;
|
||||
REFERENCE *entry;
|
||||
|
||||
search.start = position;
|
||||
search.start += skip_whitespace (search.buffer + search.start);
|
||||
start = search.start - binding->start;
|
||||
refdef = search.buffer + search.start;
|
||||
offset = string_in_line (":", refdef);
|
||||
|
||||
/* When searching for menu items, if no colon, there is no
|
||||
menu item on this line. */
|
||||
if (offset == -1)
|
||||
{
|
||||
if (searching_for_menu_items)
|
||||
continue;
|
||||
else
|
||||
{
|
||||
int temp;
|
||||
|
||||
temp = skip_line (refdef);
|
||||
offset = string_in_line (":", refdef + temp);
|
||||
if (offset == -1)
|
||||
continue; /* Give up? */
|
||||
else
|
||||
offset += temp;
|
||||
}
|
||||
}
|
||||
|
||||
entry = (REFERENCE *)xmalloc (sizeof (REFERENCE));
|
||||
entry->filename = (char *)NULL;
|
||||
entry->nodename = (char *)NULL;
|
||||
entry->label = (char *)xmalloc (offset);
|
||||
strncpy (entry->label, refdef, offset - 1);
|
||||
entry->label[offset - 1] = '\0';
|
||||
canonicalize_whitespace (entry->label);
|
||||
|
||||
refdef += offset;
|
||||
entry->start = start;
|
||||
entry->end = refdef - binding->buffer;
|
||||
|
||||
/* If this reference entry continues with another ':' then the
|
||||
nodename is the same as the label. */
|
||||
if (*refdef == ':')
|
||||
{
|
||||
entry->nodename = savestring (entry->label);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This entry continues with a specific nodename. Parse the
|
||||
nodename from the specification. */
|
||||
|
||||
refdef += skip_whitespace_and_newlines (refdef);
|
||||
|
||||
if (searching_for_menu_items)
|
||||
info_parse_node (refdef, DONT_SKIP_NEWLINES);
|
||||
else
|
||||
info_parse_node (refdef, SKIP_NEWLINES);
|
||||
|
||||
if (info_parsed_filename)
|
||||
entry->filename = savestring (info_parsed_filename);
|
||||
|
||||
if (info_parsed_nodename)
|
||||
entry->nodename = savestring (info_parsed_nodename);
|
||||
}
|
||||
|
||||
add_pointer_to_array
|
||||
(entry, refs_index, refs, refs_slots, 50, REFERENCE *);
|
||||
}
|
||||
return (refs);
|
||||
}
|
||||
|
||||
/* Get the entry associated with LABEL in MENU. Return a pointer to the
|
||||
REFERENCE if found, or NULL. */
|
||||
REFERENCE *
|
||||
info_get_labeled_reference (label, references)
|
||||
char *label;
|
||||
REFERENCE **references;
|
||||
{
|
||||
register int i;
|
||||
REFERENCE *entry;
|
||||
|
||||
for (i = 0; references && (entry = references[i]); i++)
|
||||
{
|
||||
if (strcmp (label, entry->label) == 0)
|
||||
return (entry);
|
||||
}
|
||||
return ((REFERENCE *)NULL);
|
||||
}
|
||||
|
||||
/* A utility function for concatenating REFERENCE **. Returns a new
|
||||
REFERENCE ** which is the concatenation of REF1 and REF2. The REF1
|
||||
and REF2 arrays are freed, but their contents are not. */
|
||||
REFERENCE **
|
||||
info_concatenate_references (ref1, ref2)
|
||||
REFERENCE **ref1, **ref2;
|
||||
{
|
||||
register int i, j;
|
||||
REFERENCE **result;
|
||||
int size;
|
||||
|
||||
/* With one argument passed as NULL, simply return the other arg. */
|
||||
if (!ref1)
|
||||
return (ref2);
|
||||
else if (!ref2)
|
||||
return (ref1);
|
||||
|
||||
/* Get the total size of the slots that we will need. */
|
||||
for (i = 0; ref1[i]; i++);
|
||||
size = i;
|
||||
for (i = 0; ref2[i]; i++);
|
||||
size += i;
|
||||
|
||||
result = (REFERENCE **)xmalloc ((1 + size) * sizeof (REFERENCE *));
|
||||
|
||||
/* Copy the contents over. */
|
||||
for (i = 0; ref1[i]; i++)
|
||||
result[i] = ref1[i];
|
||||
|
||||
j = i;
|
||||
for (i = 0; ref2[i]; i++)
|
||||
result[j++] = ref2[i];
|
||||
|
||||
result[j] = (REFERENCE *)NULL;
|
||||
free (ref1);
|
||||
free (ref2);
|
||||
return (result);
|
||||
}
|
||||
|
||||
/* Free the data associated with REFERENCES. */
|
||||
void
|
||||
info_free_references (references)
|
||||
REFERENCE **references;
|
||||
{
|
||||
register int i;
|
||||
REFERENCE *entry;
|
||||
|
||||
if (references)
|
||||
{
|
||||
for (i = 0; references && (entry = references[i]); i++)
|
||||
{
|
||||
maybe_free (entry->label);
|
||||
maybe_free (entry->filename);
|
||||
maybe_free (entry->nodename);
|
||||
|
||||
free (entry);
|
||||
}
|
||||
|
||||
free (references);
|
||||
}
|
||||
}
|
||||
|
||||
/* Search for sequences of whitespace or newlines in STRING, replacing
|
||||
all such sequences with just a single space. Remove whitespace from
|
||||
start and end of string. */
|
||||
void
|
||||
canonicalize_whitespace (string)
|
||||
char *string;
|
||||
{
|
||||
register int i, j;
|
||||
int len, whitespace_found, whitespace_loc;
|
||||
char *temp;
|
||||
|
||||
if (!string)
|
||||
return;
|
||||
|
||||
len = strlen (string);
|
||||
temp = (char *)xmalloc (1 + len);
|
||||
|
||||
/* Search for sequences of whitespace or newlines. Replace all such
|
||||
sequences in the string with just a single space. */
|
||||
|
||||
whitespace_found = 0;
|
||||
for (i = 0, j = 0; string[i]; i++)
|
||||
{
|
||||
if (whitespace_or_newline (string[i]))
|
||||
{
|
||||
whitespace_found++;
|
||||
whitespace_loc = i;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (whitespace_found && whitespace_loc)
|
||||
{
|
||||
whitespace_found = 0;
|
||||
temp[j++] = ' ';
|
||||
}
|
||||
|
||||
temp[j++] = string[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Kill trailing whitespace. */
|
||||
if (j && whitespace (temp[j - 1]))
|
||||
j--;
|
||||
|
||||
temp[j] = '\0';
|
||||
strcpy (string, temp);
|
||||
free (temp);
|
||||
}
|
||||
|
||||
/* String representation of a char returned by printed_representation (). */
|
||||
static char the_rep[10];
|
||||
|
||||
/* Return a pointer to a string which is the printed representation
|
||||
of CHARACTER if it were printed at HPOS. */
|
||||
char *
|
||||
printed_representation (character, hpos)
|
||||
unsigned char character;
|
||||
int hpos;
|
||||
{
|
||||
register int i = 0;
|
||||
int printable_limit;
|
||||
|
||||
if (ISO_Latin_p)
|
||||
printable_limit = 160;
|
||||
else
|
||||
printable_limit = 127;
|
||||
|
||||
if (character == '\177')
|
||||
{
|
||||
the_rep[i++] = '^';
|
||||
the_rep[i++] = '?';
|
||||
}
|
||||
else if (iscntrl (character))
|
||||
{
|
||||
switch (character)
|
||||
{
|
||||
case '\r':
|
||||
case '\n':
|
||||
the_rep[i++] = character;
|
||||
break;
|
||||
|
||||
case '\t':
|
||||
{
|
||||
int tw;
|
||||
|
||||
tw = ((hpos + 8) & 0xf8) - hpos;
|
||||
while (i < tw)
|
||||
the_rep[i++] = ' ';
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
the_rep[i++] = '^';
|
||||
the_rep[i++] = (character | 0x40);
|
||||
}
|
||||
}
|
||||
else if (character > printable_limit)
|
||||
{
|
||||
sprintf (the_rep + i, "\\%0o", character);
|
||||
i = strlen (the_rep);
|
||||
}
|
||||
else
|
||||
the_rep[i++] = character;
|
||||
|
||||
the_rep[i] = '\0';
|
||||
|
||||
return (the_rep);
|
||||
}
|
||||
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Functions Static To This File */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Amount of space allocated to INFO_PARSED_FILENAME via xmalloc (). */
|
||||
static int parsed_filename_size = 0;
|
||||
|
||||
/* Amount of space allocated to INFO_PARSED_NODENAME via xmalloc (). */
|
||||
static int parsed_nodename_size = 0;
|
||||
|
||||
static void save_string (), saven_string ();
|
||||
|
||||
/* Remember FILENAME in PARSED_FILENAME. An empty FILENAME is translated
|
||||
to a NULL pointer in PARSED_FILENAME. */
|
||||
static void
|
||||
save_filename (filename)
|
||||
char *filename;
|
||||
{
|
||||
save_string (filename, &info_parsed_filename, &parsed_filename_size);
|
||||
}
|
||||
|
||||
/* Just like save_filename (), but you pass the length of the string. */
|
||||
static void
|
||||
saven_filename (filename, len)
|
||||
char *filename;
|
||||
int len;
|
||||
{
|
||||
saven_string (filename, len,
|
||||
&info_parsed_filename, &parsed_filename_size);
|
||||
}
|
||||
|
||||
/* Remember NODENAME in PARSED_NODENAME. An empty NODENAME is translated
|
||||
to a NULL pointer in PARSED_NODENAME. */
|
||||
static void
|
||||
save_nodename (nodename)
|
||||
char *nodename;
|
||||
{
|
||||
save_string (nodename, &info_parsed_nodename, &parsed_nodename_size);
|
||||
}
|
||||
|
||||
/* Just like save_nodename (), but you pass the length of the string. */
|
||||
static void
|
||||
saven_nodename (nodename, len)
|
||||
char *nodename;
|
||||
int len;
|
||||
{
|
||||
saven_string (nodename, len,
|
||||
&info_parsed_nodename, &parsed_nodename_size);
|
||||
}
|
||||
|
||||
/* Remember STRING in STRING_P. STRING_P should currently have STRING_SIZE_P
|
||||
bytes allocated to it. An empty STRING is translated to a NULL pointer
|
||||
in STRING_P. */
|
||||
static void
|
||||
save_string (string, string_p, string_size_p)
|
||||
char *string;
|
||||
char **string_p;
|
||||
int *string_size_p;
|
||||
{
|
||||
if (!string || !*string)
|
||||
{
|
||||
if (*string_p)
|
||||
free (*string_p);
|
||||
|
||||
*string_p = (char *)NULL;
|
||||
*string_size_p = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strlen (string) >= *string_size_p)
|
||||
*string_p = (char *)xrealloc
|
||||
(*string_p, (*string_size_p = 1 + strlen (string)));
|
||||
|
||||
strcpy (*string_p, string);
|
||||
}
|
||||
}
|
||||
|
||||
/* Just like save_string (), but you also pass the length of STRING. */
|
||||
static void
|
||||
saven_string (string, len, string_p, string_size_p)
|
||||
char *string;
|
||||
int len;
|
||||
char **string_p;
|
||||
int *string_size_p;
|
||||
{
|
||||
if (!string)
|
||||
{
|
||||
if (*string_p)
|
||||
free (*string_p);
|
||||
|
||||
*string_p = (char *)NULL;
|
||||
*string_size_p = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (len >= *string_size_p)
|
||||
*string_p = (char *)xrealloc (*string_p, (*string_size_p = 1 + len));
|
||||
|
||||
strncpy (*string_p, string, len);
|
||||
(*string_p)[len] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/* Return a pointer to the part of PATHNAME that simply defines the file. */
|
||||
char *
|
||||
filename_non_directory (pathname)
|
||||
char *pathname;
|
||||
{
|
||||
char *filename;
|
||||
|
||||
filename = (char *)rindex (pathname, '/');
|
||||
|
||||
if (filename)
|
||||
filename++;
|
||||
else
|
||||
filename = pathname;
|
||||
|
||||
return (filename);
|
||||
}
|
||||
|
||||
/* Return non-zero if NODE is one especially created by Info. */
|
||||
int
|
||||
internal_info_node_p (node)
|
||||
NODE *node;
|
||||
{
|
||||
if (node &&
|
||||
(node->filename && !*node->filename) &&
|
||||
!node->parent && node->nodename)
|
||||
return (1);
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Make NODE appear to be one especially created by Info. */
|
||||
void
|
||||
name_internal_node (node, name)
|
||||
NODE *node;
|
||||
char *name;
|
||||
{
|
||||
if (!node)
|
||||
return;
|
||||
|
||||
node->filename = "";
|
||||
node->parent = (char *)NULL;
|
||||
node->nodename = name;
|
||||
node->flags |= N_IsInternal;
|
||||
}
|
||||
|
||||
/* Return the window displaying NAME, the name of an internally created
|
||||
Info window. */
|
||||
WINDOW *
|
||||
get_internal_info_window (name)
|
||||
char *name;
|
||||
{
|
||||
WINDOW *win = (WINDOW *)NULL;
|
||||
|
||||
for (win = windows; win; win = win->next)
|
||||
if (internal_info_node_p (win->node) &&
|
||||
(strcmp (win->node->nodename, name) == 0))
|
||||
break;
|
||||
|
||||
return (win);
|
||||
}
|
144
gnu/usr.bin/texinfo/info/info-utils.h
Normal file
144
gnu/usr.bin/texinfo/info/info-utils.h
Normal file
@ -0,0 +1,144 @@
|
||||
/* info-utils.h -- Exported functions and variables from info-util.c. */
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#ifndef _INFO_UTILS_H_
|
||||
#define _INFO_UTILS_H_
|
||||
|
||||
#if !defined (HAVE_RINDEX)
|
||||
#undef index
|
||||
#undef rindex
|
||||
#define index strchr
|
||||
#define rindex strrchr
|
||||
#endif
|
||||
|
||||
#if !defined (HAVE_BCOPY)
|
||||
#undef bcopy
|
||||
#define bcopy(source, dest, count) memcpy(dest, source, count)
|
||||
#endif
|
||||
|
||||
#include "nodes.h"
|
||||
#include "window.h"
|
||||
#include "search.h"
|
||||
|
||||
/* Structure which describes a node reference, such as a menu entry or
|
||||
cross reference. Arrays of such references can be built by calling
|
||||
info_menus_of_node () or info_xrefs_of_node (). */
|
||||
typedef struct {
|
||||
char *label; /* User Label. */
|
||||
char *filename; /* File where this node can be found. */
|
||||
char *nodename; /* Name of the node. */
|
||||
int start, end; /* Offsets within the containing node of LABEL. */
|
||||
} REFERENCE;
|
||||
|
||||
/* When non-zero, various display and input functions handle ISO Latin
|
||||
character sets correctly. */
|
||||
extern int ISO_Latin_p;
|
||||
|
||||
/* Variable which holds the most recent filename parsed as a result of
|
||||
calling info_parse_xxx (). */
|
||||
extern char *info_parsed_filename;
|
||||
|
||||
/* Variable which holds the most recent nodename parsed as a result of
|
||||
calling info_parse_xxx (). */
|
||||
extern char *info_parsed_nodename;
|
||||
|
||||
/* Parse the filename and nodename out of STRING. If STRING doesn't
|
||||
contain a filename (i.e., it is NOT (FILENAME)NODENAME) then set
|
||||
INFO_PARSED_FILENAME to NULL. If second argument NEWLINES_OKAY is
|
||||
non-zero, it says to allow the nodename specification to cross a
|
||||
newline boundary (i.e., only `,', `.', or `TAB' can end the spec). */
|
||||
void info_parse_node ();
|
||||
|
||||
/* Return a NULL terminated array of REFERENCE * which represents the menu
|
||||
found in NODE. If there is no menu in NODE, just return a NULL pointer. */
|
||||
extern REFERENCE **info_menu_of_node ();
|
||||
|
||||
/* Return a NULL terminated array of REFERENCE * which represents the cross
|
||||
refrences found in NODE. If there are no cross references in NODE, just
|
||||
return a NULL pointer. */
|
||||
extern REFERENCE **info_xrefs_of_node ();
|
||||
|
||||
/* Glean cross references from BINDING->buffer + BINDING->start until
|
||||
BINDING->end. Return an array of REFERENCE * that represents each
|
||||
cross reference in this range. */
|
||||
extern REFERENCE **info_xrefs ();
|
||||
|
||||
/* Get the entry associated with LABEL in REFERENCES. Return a pointer to
|
||||
the reference if found, or NULL. */
|
||||
extern REFERENCE *info_get_labeled_reference ();
|
||||
|
||||
/* Glean menu entries from BINDING->buffer + BINDING->start until we
|
||||
have looked at the entire contents of BINDING. Return an array
|
||||
of REFERENCE * that represents each menu item in this range. */
|
||||
extern REFERENCE **info_menu_items ();
|
||||
|
||||
/* A utility function for concatenating REFERENCE **. Returns a new
|
||||
REFERENCE ** which is the concatenation of REF1 and REF2. The REF1
|
||||
and REF2 arrays are freed, but their contents are not. */
|
||||
REFERENCE **info_concatenate_references ();
|
||||
|
||||
/* Free the data associated with REFERENCES. */
|
||||
extern void info_free_references ();
|
||||
|
||||
/* Search for sequences of whitespace or newlines in STRING, replacing
|
||||
all such sequences with just a single space. Remove whitespace from
|
||||
start and end of string. */
|
||||
void canonicalize_whitespace ();
|
||||
|
||||
/* Return a pointer to a string which is the printed representation
|
||||
of CHARACTER if it were printed at HPOS. */
|
||||
extern char *printed_representation ();
|
||||
|
||||
/* Return a pointer to the part of PATHNAME that simply defines the file. */
|
||||
extern char *filename_non_directory ();
|
||||
|
||||
/* Return non-zero if NODE is one especially created by Info. */
|
||||
extern int internal_info_node_p ();
|
||||
|
||||
/* Make NODE appear to be one especially created by Info, and give it NAME. */
|
||||
extern void name_internal_node ();
|
||||
|
||||
/* Return the window displaying NAME, the name of an internally created
|
||||
Info window. */
|
||||
extern WINDOW *get_internal_info_window ();
|
||||
|
||||
/* Return the node addressed by LABEL in NODE (usually one of "Prev:",
|
||||
"Next:", "Up:", "File:", or "Node:". After a call to this function,
|
||||
the global INFO_PARSED_NODENAME and INFO_PARSED_FILENAME contain
|
||||
the information. */
|
||||
extern void info_parse_label (/* label, node */);
|
||||
|
||||
#define info_label_was_found \
|
||||
(info_parsed_nodename != NULL || info_parsed_filename != NULL)
|
||||
|
||||
#define info_file_label_of_node(n) info_parse_label (INFO_FILE_LABEL, n)
|
||||
#define info_next_label_of_node(n) info_parse_label (INFO_NEXT_LABEL, n)
|
||||
#define info_up_label_of_node(n) info_parse_label (INFO_UP_LABEL, n)
|
||||
#define info_prev_label_of_node(n) \
|
||||
do { \
|
||||
info_parse_label (INFO_PREV_LABEL, n); \
|
||||
if (!info_label_was_found) \
|
||||
info_parse_label (INFO_ALTPREV_LABEL, n); \
|
||||
} while (0)
|
||||
|
||||
#endif /* !_INFO_UTILS_H_ */
|
229
gnu/usr.bin/texinfo/info/info.1
Normal file
229
gnu/usr.bin/texinfo/info/info.1
Normal file
@ -0,0 +1,229 @@
|
||||
.TH info 1 "7th December 1990"
|
||||
.SH NAME
|
||||
info \- GNU's hypertext system
|
||||
.SH SYNOPSIS
|
||||
.B info
|
||||
[
|
||||
.B \-\-option-name option-value
|
||||
]
|
||||
.B \menu-item...
|
||||
.SH COPYRIGHT
|
||||
.if n Copyright (C) 1989, 1993 Free Software Foundation, Inc.
|
||||
.if t Copyright \(co 1989, 1993 Free Software Foundation, Inc.
|
||||
.SH DESCRIPTION
|
||||
.LP
|
||||
The GNU project has a hypertext system called
|
||||
.I Info
|
||||
which allows the same source file to be either printed as a
|
||||
paper manual, or viewed using
|
||||
.B info.
|
||||
It is possible to use the
|
||||
.B info
|
||||
program from inside Emacs, or to use the stand-alone version described here.
|
||||
This manual page gives a brief summary of its capabilities.
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-\-directory directory-path
|
||||
Add
|
||||
.B directory-path
|
||||
to the list of directory paths searched when
|
||||
.B info
|
||||
needs to find a file. You may issue
|
||||
.B \-\-directory
|
||||
multiple times.
|
||||
Alternatively, you may specify a value for the environment variable
|
||||
.B INFOPATH;
|
||||
if
|
||||
.B \-\-directory
|
||||
is not given, the value of
|
||||
.B INFOPATH
|
||||
is used. The value of
|
||||
.B INFOPATH
|
||||
is a colon separated list of directory names. If you do not supply either
|
||||
.B INFOPATH
|
||||
or
|
||||
.B \-\-directory-path,
|
||||
.B info
|
||||
uses a default path.
|
||||
.TP
|
||||
.B \-f filename
|
||||
Specify a particular
|
||||
.B info
|
||||
file to visit. By default,
|
||||
.B info
|
||||
visits
|
||||
the file
|
||||
.B dir;
|
||||
if you use this option,
|
||||
.B info
|
||||
will start with
|
||||
.B (FILENAME)Top
|
||||
as the first file and node.
|
||||
.TP
|
||||
.B \-n nodename
|
||||
Specify a particular node to visit in the initial file that
|
||||
.B info
|
||||
loads. This is especially useful in conjunction with
|
||||
.B \-\-file.
|
||||
You may specify
|
||||
.B \-\-node
|
||||
multiple times.
|
||||
.TP
|
||||
.B -o file
|
||||
Direct output to
|
||||
.B file
|
||||
instead of starting an interactive
|
||||
.B info
|
||||
session.
|
||||
.TP
|
||||
.B \-h
|
||||
Produce a relatively brief description of the available
|
||||
.B info
|
||||
options.
|
||||
.TP
|
||||
.B \-\-version
|
||||
Print the version information of
|
||||
.B info
|
||||
and exit.
|
||||
.TP
|
||||
.B menu-item
|
||||
.B info
|
||||
treats its remaining arguments as the names of menu items.
|
||||
The first argument is a menu item in the initial node visited,
|
||||
while the second argument is a menu item in the first argument's
|
||||
node. You can easily move to the node of your choice by
|
||||
specifying the menu names which describe the path to that node.
|
||||
For example,
|
||||
|
||||
.B info emacs buffers
|
||||
|
||||
first selects the menu item
|
||||
.B emacs
|
||||
in the node
|
||||
.B (dir)Top,
|
||||
and then selects the menu item
|
||||
.B buffers
|
||||
in the node
|
||||
.B (emacs)Top.
|
||||
.SH COMMANDS
|
||||
When in
|
||||
.B info
|
||||
the following commands are available:
|
||||
.TP
|
||||
.B h
|
||||
Invoke the Info tutorial.
|
||||
.TP
|
||||
.B ?
|
||||
Get a short summary of
|
||||
.B info
|
||||
commands.
|
||||
.TP
|
||||
.B h
|
||||
Select the
|
||||
.B info
|
||||
node from the main directory; this is much more complete than just
|
||||
using
|
||||
.B ?.
|
||||
.TP
|
||||
.B Ctrl-g
|
||||
Abort whatever you are doing.
|
||||
.TP
|
||||
.B Ctrl-l
|
||||
Redraw the screen.
|
||||
.PP
|
||||
Selecting other nodes:
|
||||
.TP
|
||||
.B n
|
||||
Move to the "next" node of this node.
|
||||
.TP
|
||||
.B p
|
||||
Move to the "previous" node of this node.
|
||||
.TP
|
||||
.B u
|
||||
Move to this node's "up" node.
|
||||
.TP
|
||||
.B m
|
||||
Pick a menu item specified by name. Picking a menu item causes another
|
||||
node to be selected. You do not need to type a complete nodename; if
|
||||
you type a few letters and then a space or tab
|
||||
.B info
|
||||
will will try to fill in the rest of the nodename. If you ask for further
|
||||
completion without typing any more characters you'll be given a list
|
||||
of possibilities; you can also get the list with
|
||||
.B ?.
|
||||
If you type a few characters and then hit return
|
||||
.B info
|
||||
will try to do a completion, and if it is ambigous use the first possibility.
|
||||
.TP
|
||||
.B f
|
||||
Follow a cross reference. You are asked for the name of the reference,
|
||||
using command completion as for
|
||||
.B m.
|
||||
.TP
|
||||
.B l
|
||||
Move to the last node you were at.
|
||||
.PP
|
||||
Moving within a node:
|
||||
.TP
|
||||
.B Space
|
||||
Scroll forward a page.
|
||||
.TP
|
||||
.B DEL
|
||||
Scroll backward a page.
|
||||
.TP
|
||||
.B b
|
||||
Go to the beginning of this node.
|
||||
.PP
|
||||
Advanced commands:
|
||||
.TP
|
||||
.B q
|
||||
Quit
|
||||
.B info.
|
||||
.TP
|
||||
.B 1
|
||||
Pick first item in node's menu.
|
||||
.TP
|
||||
.B 2 \-\- 5
|
||||
Pick second ... fifth item in node's menu.
|
||||
.TP
|
||||
.B g
|
||||
Move to node specified by name. You may include a filename as well,
|
||||
as
|
||||
.B (FILENAME)NODENAME.
|
||||
.TP
|
||||
.B s
|
||||
Search through this
|
||||
.B info
|
||||
file for a specified string, and select the node in which
|
||||
the next occurrence is found.
|
||||
.TP
|
||||
.B M-x print-node
|
||||
Pipe the contents of the current node through the command in the
|
||||
environment variable
|
||||
.B INFO_PRINT_COMMAND.
|
||||
If the variable does not exist, the node is simply piped to
|
||||
.B lpr.
|
||||
.SH ENVIRONMENT
|
||||
.TP
|
||||
.B INFOPATHS
|
||||
A colon-separated list of directories to search for
|
||||
.B info
|
||||
files. Used if
|
||||
.B \-\-directory
|
||||
is not given.
|
||||
.TP
|
||||
.B INFO_PRINT_COMMAND
|
||||
The command used for printing.
|
||||
.SH SEE ALSO
|
||||
.BR emacs (1)
|
||||
.SH AUTHOR
|
||||
.RS
|
||||
Brian Fox, Free Software Foundation
|
||||
.br
|
||||
bfox@ai.mit.edu
|
||||
.SH MANUAL AUTHOR
|
||||
.RS
|
||||
Robert Lupton; updated by Robert J. Chassell.
|
||||
.br
|
||||
rhl@astro.princeton.edu; bob@gnu.ai.mit.edu
|
511
gnu/usr.bin/texinfo/info/info.c
Normal file
511
gnu/usr.bin/texinfo/info/info.c
Normal file
@ -0,0 +1,511 @@
|
||||
/* info.c -- Display nodes of Info files in multiple windows. */
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#include "info.h"
|
||||
#include "dribble.h"
|
||||
#include "getopt.h"
|
||||
|
||||
/* The version numbers of this version of Info. */
|
||||
int info_major_version = 2;
|
||||
int info_minor_version = 10;
|
||||
int info_patch_level = 1;
|
||||
|
||||
/* Non-zero means search all indices for APROPOS_SEARCH_STRING. */
|
||||
static int apropos_p = 0;
|
||||
|
||||
/* Variable containing the string to search for when apropos_p is non-zero. */
|
||||
static char *apropos_search_string = (char *)NULL;
|
||||
|
||||
/* Non-zero means print version info only. */
|
||||
static int print_version_p = 0;
|
||||
|
||||
/* Non-zero means print a short description of the options. */
|
||||
static int print_help_p = 0;
|
||||
|
||||
/* Array of the names of nodes that the user specified with "--node" on the
|
||||
command line. */
|
||||
static char **user_nodenames = (char **)NULL;
|
||||
static int user_nodenames_index = 0;
|
||||
static int user_nodenames_slots = 0;
|
||||
|
||||
/* String specifying the first file to load. This string can only be set
|
||||
by the user specifying "--file" on the command line. */
|
||||
static char *user_filename = (char *)NULL;
|
||||
|
||||
/* String specifying the name of the file to dump nodes to. This value is
|
||||
filled if the user speficies "--output" on the command line. */
|
||||
static char *user_output_filename = (char *)NULL;
|
||||
|
||||
/* Non-zero indicates that when "--output" is specified, all of the menu
|
||||
items of the specified nodes (and their subnodes as well) should be
|
||||
dumped in the order encountered. This basically can print a book. */
|
||||
int dump_subnodes = 0;
|
||||
|
||||
/* Structure describing the options that Info accepts. We pass this structure
|
||||
to getopt_long (). If you add or otherwise change this structure, you must
|
||||
also change the string which follows it. */
|
||||
#define APROPOS_OPTION 1
|
||||
#define DRIBBLE_OPTION 2
|
||||
#define RESTORE_OPTION 3
|
||||
static struct option long_options[] = {
|
||||
{ "apropos", 1, 0, APROPOS_OPTION },
|
||||
{ "directory", 1, 0, 'd' },
|
||||
{ "node", 1, 0, 'n' },
|
||||
{ "file", 1, 0, 'f' },
|
||||
{ "subnodes", 0, &dump_subnodes, 1 },
|
||||
{ "output", 1, 0, 'o' },
|
||||
{ "help", 0, &print_help_p, 1 },
|
||||
{ "version", 0, &print_version_p, 1 },
|
||||
{ "dribble", 1, 0, DRIBBLE_OPTION },
|
||||
{ "restore", 1, 0, RESTORE_OPTION },
|
||||
{NULL, 0, NULL, 0}
|
||||
};
|
||||
|
||||
/* String describing the shorthand versions of the long options found above. */
|
||||
static char *short_options = "d:n:f:o:s";
|
||||
|
||||
/* When non-zero, the Info window system has been initialized. */
|
||||
int info_windows_initialized_p = 0;
|
||||
|
||||
/* Some "forward" declarations. */
|
||||
static void usage (), info_short_help (), remember_info_program_name ();
|
||||
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Main Entry Point to the Info Program */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
int
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int getopt_long_index; /* Index returned by getopt_long (). */
|
||||
NODE *initial_node; /* First node loaded by Info. */
|
||||
|
||||
#if defined (NeXT) && defined (NOTDEF)
|
||||
malloc_debug (0x0ffffffff);
|
||||
#endif /* NeXT && NOTDEF */
|
||||
|
||||
remember_info_program_name (argv[0]);
|
||||
|
||||
while (1)
|
||||
{
|
||||
int option_character;
|
||||
|
||||
option_character = getopt_long
|
||||
(argc, argv, short_options, long_options, &getopt_long_index);
|
||||
|
||||
/* getopt_long () returns EOF when there are no more long options. */
|
||||
if (option_character == EOF)
|
||||
break;
|
||||
|
||||
/* If this is a long option, then get the short version of it. */
|
||||
if (option_character == 0 && long_options[getopt_long_index].flag == 0)
|
||||
option_character = long_options[getopt_long_index].val;
|
||||
|
||||
/* Case on the option that we have received. */
|
||||
switch (option_character)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
|
||||
/* User wants to add a directory. */
|
||||
case 'd':
|
||||
info_add_path (optarg, INFOPATH_PREPEND);
|
||||
break;
|
||||
|
||||
/* User is specifying a particular node. */
|
||||
case 'n':
|
||||
add_pointer_to_array (optarg, user_nodenames_index, user_nodenames,
|
||||
user_nodenames_slots, 10, char *);
|
||||
break;
|
||||
|
||||
/* User is specifying a particular Info file. */
|
||||
case 'f':
|
||||
if (user_filename)
|
||||
free (user_filename);
|
||||
|
||||
user_filename = savestring (optarg);
|
||||
break;
|
||||
|
||||
/* User is specifying the name of a file to output to. */
|
||||
case 'o':
|
||||
if (user_output_filename)
|
||||
free (user_output_filename);
|
||||
user_output_filename = savestring (optarg);
|
||||
break;
|
||||
|
||||
/* User is specifying that she wishes to dump the subnodes of
|
||||
the node that she is dumping. */
|
||||
case 's':
|
||||
dump_subnodes = 1;
|
||||
break;
|
||||
|
||||
/* User has specified a string to search all indices for. */
|
||||
case APROPOS_OPTION:
|
||||
apropos_p = 1;
|
||||
maybe_free (apropos_search_string);
|
||||
apropos_search_string = savestring (optarg);
|
||||
break;
|
||||
|
||||
/* User has specified a dribble file to receive keystrokes. */
|
||||
case DRIBBLE_OPTION:
|
||||
close_dribble_file ();
|
||||
open_dribble_file (optarg);
|
||||
break;
|
||||
|
||||
/* User has specified an alternate input stream. */
|
||||
case RESTORE_OPTION:
|
||||
info_set_input_from_file (optarg);
|
||||
break;
|
||||
|
||||
default:
|
||||
usage ();
|
||||
}
|
||||
}
|
||||
|
||||
/* If the user specified --version, then show the version and exit. */
|
||||
if (print_version_p)
|
||||
{
|
||||
printf ("GNU Info, Version %s.\n", version_string ());
|
||||
exit (0);
|
||||
}
|
||||
|
||||
/* If the `--help' option was present, show the help and exit. */
|
||||
if (print_help_p)
|
||||
{
|
||||
info_short_help ();
|
||||
exit (0);
|
||||
}
|
||||
|
||||
/* If the user hasn't specified a path for Info files, default that path
|
||||
now. */
|
||||
if (!infopath)
|
||||
{
|
||||
char *path_from_env, *getenv ();
|
||||
|
||||
path_from_env = getenv ("INFOPATH");
|
||||
|
||||
if (path_from_env)
|
||||
info_add_path (path_from_env);
|
||||
else
|
||||
info_add_path (DEFAULT_INFOPATH);
|
||||
}
|
||||
|
||||
/* If the user specified a particular filename, add the path of that
|
||||
file to the contents of INFOPATH. */
|
||||
if (user_filename)
|
||||
{
|
||||
char *directory_name, *temp;
|
||||
|
||||
directory_name = savestring (user_filename);
|
||||
temp = filename_non_directory (directory_name);
|
||||
|
||||
if (temp != directory_name)
|
||||
{
|
||||
*temp = 0;
|
||||
info_add_path (directory_name, INFOPATH_PREPEND);
|
||||
}
|
||||
|
||||
free (directory_name);
|
||||
}
|
||||
|
||||
/* If the user wants to search every known index for a given string,
|
||||
do that now, and report the results. */
|
||||
if (apropos_p)
|
||||
{
|
||||
info_apropos (apropos_search_string);
|
||||
exit (0);
|
||||
}
|
||||
|
||||
/* Get the initial Info node. It is either "(dir)Top", or what the user
|
||||
specifed with values in user_filename and user_nodenames. */
|
||||
if (user_nodenames)
|
||||
initial_node = info_get_node (user_filename, user_nodenames[0]);
|
||||
else
|
||||
initial_node = info_get_node (user_filename, (char *)NULL);
|
||||
|
||||
/* If we couldn't get the initial node, this user is in trouble. */
|
||||
if (!initial_node)
|
||||
{
|
||||
if (info_recent_file_error)
|
||||
info_error (info_recent_file_error);
|
||||
else
|
||||
info_error
|
||||
(CANT_FIND_NODE, user_nodenames ? user_nodenames[0] : "Top");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/* Special cases for when the user specifies multiple nodes. If we are
|
||||
dumping to an output file, dump all of the nodes specified. Otherwise,
|
||||
attempt to create enough windows to handle the nodes that this user wants
|
||||
displayed. */
|
||||
if (user_nodenames_index > 1)
|
||||
{
|
||||
free (initial_node);
|
||||
|
||||
if (user_output_filename)
|
||||
dump_nodes_to_file
|
||||
(user_filename, user_nodenames, user_output_filename, dump_subnodes);
|
||||
else
|
||||
begin_multiple_window_info_session (user_filename, user_nodenames);
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
/* If 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;
|
||||
|
||||
/* Remember the name of the menu entry we want. */
|
||||
arg = argv[optind++];
|
||||
|
||||
/* Build and return a list of the menu items in this node. */
|
||||
menu = info_menu_of_node (initial_node);
|
||||
|
||||
/* If there wasn't a menu item in this node, stop here, but let
|
||||
the user continue to use Info. Perhaps they wanted this node
|
||||
and didn't realize it. */
|
||||
if (!menu)
|
||||
{
|
||||
begin_info_session_with_error
|
||||
(initial_node, "There is no menu in this node.");
|
||||
exit (0);
|
||||
}
|
||||
|
||||
/* Find the specified menu item. */
|
||||
entry = info_get_labeled_reference (arg, menu);
|
||||
|
||||
/* If the item wasn't found, search the list sloppily. Perhaps this
|
||||
user typed "buffer" when they really meant "Buffers". */
|
||||
if (!entry)
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; entry = menu[i]; i++)
|
||||
if (strnicmp (entry->label, arg, strlen (arg)) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
/* 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.";
|
||||
|
||||
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 = savestring (initial_node->parent);
|
||||
else
|
||||
entry->filename = savestring (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 (!node && entry->nodename &&
|
||||
(strcmp (entry->label, entry->nodename) == 0))
|
||||
node = info_get_node (entry->label, "Top");
|
||||
|
||||
if (node)
|
||||
{
|
||||
free (initial_node);
|
||||
initial_node = node;
|
||||
info_free_references (menu);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *temp = savestring (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);
|
||||
if (info_patch_level)
|
||||
sprintf (vstring + strlen (vstring), "-p%d", info_patch_level);
|
||||
}
|
||||
return (vstring);
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Error Handling for Info */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
static char *program_name = (char *)NULL;
|
||||
|
||||
static void
|
||||
remember_info_program_name (fullpath)
|
||||
char *fullpath;
|
||||
{
|
||||
char *filename;
|
||||
|
||||
filename = filename_non_directory (fullpath);
|
||||
program_name = savestring (filename);
|
||||
}
|
||||
|
||||
/* Non-zero if an error has been signalled. */
|
||||
int info_error_was_printed = 0;
|
||||
|
||||
/* Non-zero means ring terminal bell on errors. */
|
||||
int info_error_rings_bell_p = 1;
|
||||
|
||||
/* Print FORMAT with ARG1 and ARG2. If the window system was initialized,
|
||||
then the message is printed in the echo area. Otherwise, a message is
|
||||
output to stderr. */
|
||||
void
|
||||
info_error (format, arg1, arg2)
|
||||
char *format;
|
||||
void *arg1, *arg2;
|
||||
{
|
||||
info_error_was_printed = 1;
|
||||
|
||||
if (!info_windows_initialized_p || display_inhibited)
|
||||
{
|
||||
fprintf (stderr, "%s: ", program_name);
|
||||
fprintf (stderr, format, arg1, arg2);
|
||||
fprintf (stderr, "\n");
|
||||
fflush (stderr);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!echo_area_is_active)
|
||||
{
|
||||
if (info_error_rings_bell_p)
|
||||
terminal_ring_bell ();
|
||||
window_message_in_echo_area (format, arg1, arg2);
|
||||
}
|
||||
else
|
||||
{
|
||||
NODE *temp;
|
||||
|
||||
temp = build_message_node (format, arg1, arg2);
|
||||
if (info_error_rings_bell_p)
|
||||
terminal_ring_bell ();
|
||||
inform_in_echo_area (temp->contents);
|
||||
free (temp->contents);
|
||||
free (temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Produce a very brief descripton of the available options and exit with
|
||||
an error. */
|
||||
static void
|
||||
usage ()
|
||||
{
|
||||
fprintf (stderr,"%s\n%s\n%s\n%s\n%s\n",
|
||||
"Usage: info [-d dir-path] [-f info-file] [-o output-file] [-n node-name]...",
|
||||
" [--directory dir-path] [--file info-file] [--node node-name]...",
|
||||
" [--help] [--output output-file] [--subnodes] [--version]",
|
||||
" [--dribble dribble-file] [--restore from-file]",
|
||||
" [menu-selection ...]");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/* Produce a scaled down description of the available options to Info. */
|
||||
static void
|
||||
info_short_help ()
|
||||
{
|
||||
printf ("%s", "\
|
||||
Here is a quick description of Info's options. For a more complete\n\
|
||||
description of how to use Info, type `info info options'.\n\
|
||||
\n\
|
||||
--directory DIR Add DIR to INFOPATH.\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\
|
||||
--dribble FILENAME Remember user keystrokes in FILENAME.\n\
|
||||
--restore FILENAME Read initial keystrokes from FILENAME.\n\
|
||||
--subnodes Recursively output menu items.\n\
|
||||
--help Get this help message.\n\
|
||||
--version Display Info's version information.\n\
|
||||
\n\
|
||||
Remaining arguments to Info are treated as the names of menu\n\
|
||||
items in the initial node visited. You can easily move to the\n\
|
||||
node of your choice by specifying the menu names which describe\n\
|
||||
the path to that node. For example, `info emacs buffers'.\n");
|
||||
|
||||
exit (0);
|
||||
}
|
96
gnu/usr.bin/texinfo/info/info.h
Normal file
96
gnu/usr.bin/texinfo/info/info.h
Normal file
@ -0,0 +1,96 @@
|
||||
/* info.h -- Header file which includes all of the other headers. */
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#ifndef _INFO_H_
|
||||
#define _INFO_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include "filesys.h"
|
||||
#include "display.h"
|
||||
#include "session.h"
|
||||
#include "echo_area.h"
|
||||
#include "doc.h"
|
||||
#include "footnotes.h"
|
||||
#include "gc.h"
|
||||
|
||||
/* A structure associating the nodes visited in a particular window. */
|
||||
typedef struct {
|
||||
WINDOW *window; /* The window that this list is attached to. */
|
||||
NODE **nodes; /* Array of nodes visited in this window. */
|
||||
int *pagetops; /* For each node in NODES, the pagetop. */
|
||||
long *points; /* For each node in NODES, the point. */
|
||||
int current; /* Index in NODES of the current node. */
|
||||
int nodes_index; /* Index where to add the next node. */
|
||||
int nodes_slots; /* Number of slots allocated to NODES. */
|
||||
} INFO_WINDOW;
|
||||
|
||||
/* Array of structures describing for each window which nodes have been
|
||||
visited in that window. */
|
||||
extern INFO_WINDOW **info_windows;
|
||||
|
||||
/* For handling errors. If you initialize the window system, you should
|
||||
also set info_windows_initialized_p to non-zero. It is used by the
|
||||
info_error () function to determine how to format and output errors. */
|
||||
extern int info_windows_initialized_p;
|
||||
|
||||
/* Non-zero if an error message has been printed. */
|
||||
extern int info_error_was_printed;
|
||||
|
||||
/* Non-zero means ring terminal bell on errors. */
|
||||
extern int info_error_rings_bell_p;
|
||||
|
||||
/* Print FORMAT with ARG1 and ARG2. If the window system was initialized,
|
||||
then the message is printed in the echo area. Otherwise, a message is
|
||||
output to stderr. */
|
||||
extern void info_error ();
|
||||
|
||||
/* The version numbers of Info. */
|
||||
extern int info_major_version, info_minor_version, info_patch_level;
|
||||
|
||||
/* How to get the version string for this version of Info. Returns
|
||||
something similar to "2.9". */
|
||||
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."
|
||||
|
||||
#endif /* !_INFO_H_ */
|
777
gnu/usr.bin/texinfo/info/info.info
Normal file
777
gnu/usr.bin/texinfo/info/info.info
Normal file
@ -0,0 +1,777 @@
|
||||
This is Info file info.info, produced by Makeinfo-1.55 from the input
|
||||
file info.texi.
|
||||
|
||||
This file describes how to use Info, the on-line, menu-driven GNU
|
||||
documentation system.
|
||||
|
||||
Copyright (C) 1989, 1992 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 Free Software Foundation.
|
||||
|
||||
|
||||
File: info.info, Node: Top, Next: Getting Started, Prev: (dir), Up: (dir)
|
||||
|
||||
Info: An Introduction
|
||||
*********************
|
||||
|
||||
Info is a program for reading documentation, which you are using now.
|
||||
|
||||
To learn how to use Info, type the command `h'. It brings you to a
|
||||
programmed instruction sequence.
|
||||
|
||||
To learn advanced Info commands, type `n' twice. This brings you to
|
||||
`Info for Experts', skipping over the . `Getting Started' chapter.
|
||||
|
||||
* Menu:
|
||||
|
||||
* Getting Started::
|
||||
* Advanced Info::
|
||||
* Create an Info File::
|
||||
|
||||
|
||||
File: info.info, Node: Getting Started, Next: Advanced Info, Prev: Top, Up: Top
|
||||
|
||||
Getting Started
|
||||
***************
|
||||
|
||||
This first part of the Info manual describes how to get around inside
|
||||
of Info. The second part of the manual describes various advanced Info
|
||||
commands, and how to write an Info as distinct from a Texinfo file.
|
||||
The third part is about how to generate Info files from Texinfo files.
|
||||
|
||||
* Menu:
|
||||
|
||||
* Help-Small-Screen:: Starting Info on a Small Screen
|
||||
* Help:: How to use Info
|
||||
* Help-P:: Returning to the Previous node
|
||||
* Help-^L:: The Space, Rubout, B and ^L commands.
|
||||
* Help-M:: Menus
|
||||
* Help-Adv:: Some advanced Info commands
|
||||
* Help-Q:: Quitting Info
|
||||
|
||||
|
||||
File: info.info, Node: Help-Small-Screen, Next: Help, Up: Getting Started
|
||||
|
||||
Starting Info on a Small Screen
|
||||
===============================
|
||||
|
||||
Since your terminal has an unusually small number of lines on its
|
||||
screen, it is necessary to give you special advice at the beginning.
|
||||
|
||||
If you see the text `--All----' at near the bottom right corner of
|
||||
the screen, it means the entire text you are looking at fits on the
|
||||
screen. If you see `--Top----' instead, it means that there is more
|
||||
text below that does not fit. To move forward through the text and see
|
||||
another screen full, press the Space bar, SPC. To move back up, press
|
||||
the key labeled `Rubout' or `Delete' or DEL.
|
||||
|
||||
Here are 40 lines of junk, so you can try SPC and DEL and see what
|
||||
they do. At the end are instructions of what you should do next.
|
||||
|
||||
This is line 17
|
||||
This is line 18
|
||||
This is line 19
|
||||
This is line 20
|
||||
This is line 21
|
||||
This is line 22
|
||||
This is line 23
|
||||
This is line 24
|
||||
This is line 25
|
||||
This is line 26
|
||||
This is line 27
|
||||
This is line 28
|
||||
This is line 29
|
||||
This is line 30
|
||||
This is line 31
|
||||
This is line 32
|
||||
This is line 33
|
||||
This is line 34
|
||||
This is line 35
|
||||
This is line 36
|
||||
This is line 37
|
||||
This is line 38
|
||||
This is line 39
|
||||
This is line 40
|
||||
This is line 41
|
||||
This is line 42
|
||||
This is line 43
|
||||
This is line 44
|
||||
This is line 45
|
||||
This is line 46
|
||||
This is line 47
|
||||
This is line 48
|
||||
This is line 49
|
||||
This is line 50
|
||||
This is line 51
|
||||
This is line 52
|
||||
This is line 53
|
||||
This is line 54
|
||||
This is line 55
|
||||
This is line 56
|
||||
If you have managed to get here, go back to the beginning with DEL, and
|
||||
come back here again, then you understand SPC and DEL. So now type an
|
||||
`n'--just one character; do not type the quotes and do not type the
|
||||
Return key, RET, afterward--to get to the normal start of the course.
|
||||
|
||||
|
||||
File: info.info, Node: Help, Next: Help-P, Prev: Help-Small-Screen, Up: Getting Started
|
||||
|
||||
How to use Info
|
||||
===============
|
||||
|
||||
You are talking to the program Info, for reading documentation.
|
||||
|
||||
Right now you are looking at one "Node" of Information. A node
|
||||
contains text describing a specific topic at a specific level of
|
||||
detail. This node's topic is "how to use Info".
|
||||
|
||||
The top line of a node is its "header". This node's header (look at
|
||||
it now) says that it is the node named `Help' in the file `info'. It
|
||||
says that the `Next' node after this one is the node called `Help-P'.
|
||||
An advanced Info command lets you go to any node whose name you know.
|
||||
|
||||
Besides a `Next', a node can have a `Previous' or an `Up'. This
|
||||
node has a `Previous' but no `Up', as you can see.
|
||||
|
||||
Now it is time to move on to the `Next' node, named `Help-P'.
|
||||
|
||||
>> Type `n' to move there. Type just one character; do not type
|
||||
the quotes and do not type a RET afterward.
|
||||
|
||||
`>>' in the margin means it is really time to try a command.
|
||||
|
||||
|
||||
File: info.info, Node: Help-P, Next: Help-^L, Prev: Help, Up: Getting Started
|
||||
|
||||
Returning to the Previous node
|
||||
==============================
|
||||
|
||||
This node is called `Help-P'. The `Previous' node, as you see, is
|
||||
`Help', which is the one you just came from using the `n' command.
|
||||
Another `n' command now would take you to the next node, `Help-^L'.
|
||||
|
||||
>> But do not do that yet. First, try the `p' command, which takes
|
||||
you to the `Previous' node. When you get there, you can do an `n'
|
||||
again to return here.
|
||||
|
||||
This all probably seems insultingly simple so far, but *do not* be
|
||||
led into skimming. Things will get more complicated soon. Also, do
|
||||
not try a new command until you are told it is time to. Otherwise, you
|
||||
may make Info skip past an important warning that was coming up.
|
||||
|
||||
>> Now do an `n' to get to the node `Help-^L' and learn more.
|
||||
|
||||
|
||||
File: info.info, Node: Help-^L, Next: Help-M, Prev: Help-P, Up: Getting Started
|
||||
|
||||
The Space, Rubout, B and ^L commands.
|
||||
=====================================
|
||||
|
||||
This node's header tells you that you are now at node `Help-^L', and
|
||||
that `p' would get you back to `Help-P'. The node's title is
|
||||
underlined; it says what the node is about (most nodes have titles).
|
||||
|
||||
This is a big node and it does not all fit on your display screen.
|
||||
You can tell that there is more that is not visible because you can see
|
||||
the string `--Top-----' rather than `--All----' near the bottom right
|
||||
corner of the screen.
|
||||
|
||||
The SPC, DEL and `b' commands exist to allow you to "move around" in
|
||||
a node that does not all fit on the screen at once. SPC moves forward,
|
||||
to show what was below the bottom of the screen. DEL moves backward,
|
||||
to show what was above the top of the screen (there is not anything
|
||||
above the top until you have typed some spaces).
|
||||
|
||||
>> Now try typing a SPC (afterward, type a DEL to return here).
|
||||
|
||||
When you type the SPC, the two lines that were at the bottom of the
|
||||
screen appear at the top, followed by more lines. DEL takes the two
|
||||
lines from the top and moves them to the bottom, *usually*, but if
|
||||
there are not a full screen's worth of lines above them they may not
|
||||
make it all the way to the bottom.
|
||||
|
||||
If you type a SPC when there is no more to see, it rings the bell
|
||||
and otherwise does nothing. The same goes for a DEL when the header of
|
||||
the node is visible.
|
||||
|
||||
If your screen is ever garbaged, you can tell Info to print it out
|
||||
again by typing `C-l' (`Control-L', that is--hold down "Control" and
|
||||
type an L or `l').
|
||||
|
||||
>> Type `C-l' now.
|
||||
|
||||
To move back to the beginning of the node you are on, you can type a
|
||||
lot of DELs. You can also type simply `b' for beginning.
|
||||
|
||||
>> Try that now. (I have put in enough verbiage to make sure you are
|
||||
not on the first screenful now). Then come back, typing SPC
|
||||
several times.
|
||||
|
||||
You have just learned a considerable number of commands. If you
|
||||
want to use one but have trouble remembering which, you should type a ?
|
||||
which prints out a brief list of commands. When you are finished
|
||||
looking at the list, make it go away by typing a SPC.
|
||||
|
||||
>> Type a ? now. After it finishes, type a SPC.
|
||||
|
||||
(If you are using the standalone Info reader, type `l' to return
|
||||
here.)
|
||||
|
||||
From now on, you will encounter large nodes without warning, and
|
||||
will be expected to know how to use SPC and DEL to move around in them
|
||||
without being told. Since not all terminals have the same size screen,
|
||||
it would be impossible to warn you anyway.
|
||||
|
||||
>> Now type `n' to see the description of the `m' command.
|
||||
|
||||
|
||||
File: info.info, Node: Help-M, Next: Help-Adv, Prev: Help-^L, Up: Getting Started
|
||||
|
||||
Menus
|
||||
=====
|
||||
|
||||
Menus and the `m' command
|
||||
|
||||
With only the `n' and `p' commands for moving between nodes, nodes
|
||||
are restricted to a linear sequence. Menus allow a branching
|
||||
structure. A menu is a list of other nodes you can move to. It is
|
||||
actually just part of the text of the node formatted specially so that
|
||||
Info can interpret it. The beginning of a menu is always identified by
|
||||
a line which starts with `* Menu:'. A node contains a menu if and only
|
||||
if it has a line in it which starts that way. The only menu you can
|
||||
use at any moment is the one in the node you are in. To use a menu in
|
||||
any other node, you must move to that node first.
|
||||
|
||||
After the start of the menu, each line that starts with a `*'
|
||||
identifies one subtopic. The line usually contains a brief name for
|
||||
the subtopic (followed by a `:'), the name of the node that talks about
|
||||
that subtopic, and optionally some further description of the subtopic.
|
||||
Lines in the menu that do not start with a `*' have no special
|
||||
meaning--they are only for the human reader's benefit and do not define
|
||||
additional subtopics. Here is an example:
|
||||
|
||||
* Foo: FOO's Node This tells about FOO
|
||||
|
||||
The subtopic name is Foo, and the node describing it is `FOO's Node'.
|
||||
The rest of the line is just for the reader's Information. [[ But this
|
||||
line is not a real menu item, simply because there is no line above it
|
||||
which starts with `* Menu:'.]]
|
||||
|
||||
When you use a menu to go to another node (in a way that will be
|
||||
described soon), what you specify is the subtopic name, the first thing
|
||||
in the menu line. Info uses it to find the menu line, extracts the
|
||||
node name from it, and goes to that node. The reason that there is
|
||||
both a subtopic name and a node name is that the node name must be
|
||||
meaningful to the computer and may therefore have to be ugly looking.
|
||||
The subtopic name can be chosen just to be convenient for the user to
|
||||
specify. Often the node name is convenient for the user to specify and
|
||||
so both it and the subtopic name are the same. There is an
|
||||
abbreviation for this:
|
||||
|
||||
* Foo:: This tells about FOO
|
||||
|
||||
This means that the subtopic name and node name are the same; they are
|
||||
both `Foo'.
|
||||
|
||||
>> Now use SPCs to find the menu in this node, then come back to
|
||||
the front with a `b'. As you see, a menu is actually visible in its
|
||||
node. If you cannot find a menu in a node by looking at it, then
|
||||
the node does not have a menu and the `m' command is not available.
|
||||
|
||||
The command to go to one of the subnodes is `m'--but *do not do it
|
||||
yet!* Before you use `m', you must understand the difference between
|
||||
commands and arguments. So far, you have learned several commands that
|
||||
do not need arguments. When you type one, Info processes it and is
|
||||
instantly ready for another command. The `m' command is different: it
|
||||
is incomplete without the "name of the subtopic". Once you have typed
|
||||
`m', Info tries to read the subtopic name.
|
||||
|
||||
Now look for the line containing many dashes near the bottom of the
|
||||
screen. There is one more line beneath that one, but usually it is
|
||||
blank If it is empty, Info is ready for a command, such as `n' or `b'
|
||||
or SPC or `m'. If that line contains text ending in a colon, it mean
|
||||
Info is trying to read the "argument" to a command. At such times,
|
||||
commands do not work, because Info tries to use them as the argument.
|
||||
You must either type the argument and finish the command you started,
|
||||
or type `Control-g' to cancel the command. When you have done one of
|
||||
those things, the line becomes blank again.
|
||||
|
||||
The command to go to a subnode via a menu is `m'. After you type
|
||||
the `m', the line at the bottom of the screen says `Menu item: '. You
|
||||
must then type the name of the subtopic you want, and end it with a RET.
|
||||
|
||||
You can abbreviate the subtopic name. If the abbreviation is not
|
||||
unique, the first matching subtopic is chosen. Some menus put the
|
||||
shortest possible abbreviation for each subtopic name in capital
|
||||
letters, so you can see how much you need to type. It does not matter
|
||||
whether you use upper case or lower case when you type the subtopic.
|
||||
You should not put any spaces at the end, or inside of the item name,
|
||||
except for one space where a space appears in the item in the menu.
|
||||
|
||||
Here is a menu to give you a chance to practice.
|
||||
|
||||
* Menu: The menu starts here.
|
||||
|
||||
This menu givs you three ways of going to one place, Help-FOO.
|
||||
|
||||
* Foo: Help-FOO. A node you can visit for fun.
|
||||
* Bar: Help-FOO. Strange! two ways to get to the same place.
|
||||
* Help-FOO:: And yet another!
|
||||
>> Now type just an `m' and see what happens:
|
||||
|
||||
Now you are "inside" an `m' command. Commands cannot be used now;
|
||||
the next thing you will type must be the name of a subtopic.
|
||||
|
||||
You can change your mind about doing the `m' by typing Control-g.
|
||||
|
||||
>> Try that now; notice the bottom line clear.
|
||||
|
||||
>> Then type another `m'.
|
||||
|
||||
>> Now type `BAR' item name. Do not type RET yet.
|
||||
|
||||
While you are typing the item name, you can use the DEL character to
|
||||
cancel one character at a time if you make a mistake.
|
||||
|
||||
>> Type one to cancel the `R'. You could type another `R' to
|
||||
replace it. You do not have to, since `BA' is a valid abbreviation.
|
||||
|
||||
>> Now you are ready to go. Type a RET.
|
||||
|
||||
After visiting Help-FOO, you should return here.
|
||||
|
||||
>> Type `n' to see more commands.
|
||||
|
||||
Here is another way to get to Help-FOO, a menu. You can ignore this
|
||||
if you want, or else try it (but then please come back to here).
|
||||
|
||||
* Menu:
|
||||
|
||||
* Help-FOO::
|
||||
|
||||
|
||||
File: info.info, Node: Help-FOO, Up: Help-M
|
||||
|
||||
The `u' command
|
||||
---------------
|
||||
|
||||
Congratulations! This is the node `Help-FOO'. Unlike the other
|
||||
nodes you have seen, this one has an `Up': `Help-M', the node you just
|
||||
came from via the `m' command. This is the usual convention--the nodes
|
||||
you reach from a menu have `Up' nodes that lead back to the menu.
|
||||
Menus move Down in the tree, and `Up' moves Up. `Previous', on the
|
||||
other hand, is usually used to "stay on the same level but go backwards"
|
||||
|
||||
You can go back to the node `Help-M' by typing the command `u' for
|
||||
"Up". That puts you at the *front* of the node--to get back to where
|
||||
you were reading you have to type some SPCs.
|
||||
|
||||
>> Now type `u' to move back up to `Help-M'.
|
||||
|
||||
|
||||
File: info.info, Node: Help-Adv, Next: Help-Q, Prev: Help-M, Up: Getting Started
|
||||
|
||||
Some advanced Info commands
|
||||
===========================
|
||||
|
||||
The course is almost over, so please stick with it to the end.
|
||||
|
||||
If you have been moving around to different nodes and wish to
|
||||
retrace your steps, the `l' command (`l' for "last") will do that, one
|
||||
node at a time. If you have been following directions, an `l' command
|
||||
now will get you back to `Help-M'. Another `l' command would undo the
|
||||
`u' and get you back to `Help-FOO'. Another `l' would undo the `m' and
|
||||
get you back to `Help-M'.
|
||||
|
||||
>> Try typing three `l''s, pausing in between to see what each
|
||||
`l' does.
|
||||
|
||||
Then follow directions again and you will end up back here.
|
||||
|
||||
Note the difference between `l' and `p': `l' moves to where *you*
|
||||
last were, whereas `p' always moves to the node which the header says
|
||||
is the `Previous' node (from this node, to `Help-M').
|
||||
|
||||
The `d' command gets you instantly to the Directory node. This
|
||||
node, which is the first one you saw when you entered Info, has a menu
|
||||
which leads (directly, or indirectly through other menus), to all the
|
||||
nodes that exist.
|
||||
|
||||
>> Try doing a `d', then do an `l' to return here (yes, *do*
|
||||
return).
|
||||
|
||||
Sometimes, in Info documentation, you will see a cross reference.
|
||||
Cross references look like this: *Note Cross: Help-Cross. That is a
|
||||
real, live cross reference which is named `Cross' and points at the
|
||||
node named `Help-Cross'.
|
||||
|
||||
If you wish to follow a cross reference, you must use the `f'
|
||||
command. The `f' must be followed by the cross reference name (in this
|
||||
case, `Cross'). You can use DEL to edit the name, and if you change
|
||||
your mind about following any reference you can use `Control-g' to
|
||||
cancel the command.
|
||||
|
||||
Completion is available in the `f' command; you can complete among
|
||||
all the cross reference names in the current node.
|
||||
|
||||
>> Type `f', followed by `Cross', and a RET.
|
||||
|
||||
To get a list of all the cross references in the current node, you
|
||||
can type `?' after an `f'. The `f' continues to await a cross
|
||||
reference name even after printing the list, so if you do not actually
|
||||
want to follow a reference you should type a `Control-g' to cancel the
|
||||
`f'.
|
||||
|
||||
>> Type "f?" to get a list of the footnotes in this node. Then type
|
||||
a `Control-g' and see how the `f' gives up.
|
||||
|
||||
>> Now type `n' to see the last node of the course.
|
||||
|
||||
|
||||
File: info.info, Node: Help-Cross, Up: Help-Adv
|
||||
|
||||
The node reached by the cross reference in Info
|
||||
-----------------------------------------------
|
||||
|
||||
This is the node reached by the cross reference named `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 `Next', `Previous' or `Up' pointing back to where
|
||||
you came from. In general, the `l' (el) command is the only way to get
|
||||
back there.
|
||||
|
||||
>> Type `l' to return to the node where the cross reference was.
|
||||
|
||||
|
||||
File: info.info, Node: Help-Q, Prev: Help-Adv, Up: Getting Started
|
||||
|
||||
Quitting Info
|
||||
=============
|
||||
|
||||
To get out of Info, back to what you were doing before, type `q' for
|
||||
"Quit".
|
||||
|
||||
This is the end of the course on using Info. There are some other
|
||||
commands that are not essential or are meant for experienced users;
|
||||
they are useful, and you can find them by looking in the directory for
|
||||
documentation on Info. Finding them will be a good exercise in using
|
||||
Info in the usual manner.
|
||||
|
||||
>> Type `d' to go to the Info directory node; then type `mInfo'
|
||||
and RET, to get to the node about Info and see what other help is
|
||||
available.
|
||||
|
||||
|
||||
File: info.info, Node: Advanced Info, Next: Create an Info File, Prev: Getting Started, Up: Top
|
||||
|
||||
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 *both* to
|
||||
generate an Info file and to make a printed manual. *Note Overview of
|
||||
Texinfo: (texinfo)Top.)
|
||||
|
||||
* Menu:
|
||||
|
||||
* Expert:: Advanced Info commands: g, s, e, and 1 - 5.
|
||||
* Add:: Describes how to add new nodes to the hierarchy.
|
||||
Also tells what nodes look like.
|
||||
* Menus:: How to add to or create menus in Info nodes.
|
||||
* Cross-refs:: How to add cross-references to Info nodes.
|
||||
* Tags:: How to make tag tables for Info files.
|
||||
* Checking:: Checking an Info File
|
||||
|
||||
|
||||
File: info.info, Node: Expert, Next: Add, Up: Advanced Info
|
||||
|
||||
Advanced Info Commands
|
||||
======================
|
||||
|
||||
`g', `s', `1', - `5', and `e'
|
||||
|
||||
If you know a node's name, you can go there by typing `g', the name,
|
||||
and RET. Thus, `gTopRET' would go to the node called `Top' in this
|
||||
file (its directory node). `gExpertRET' would come back here.
|
||||
|
||||
Unlike `m', `g' does not allow the use of abbreviations.
|
||||
|
||||
To go to a node in another file, you can include the filename in the
|
||||
node name by putting it at the front, in parentheses. Thus,
|
||||
`g(dir)TopRET' would go to the Info Directory node, which is node `Top'
|
||||
in the file `dir'.
|
||||
|
||||
The node name `*' specifies the whole file. So you can look at all
|
||||
of the current file by typing `g*RET' or all of any other file with
|
||||
`g(FILENAME)RET'.
|
||||
|
||||
The `s' command allows you to search a whole file for a string. It
|
||||
switches to the next node if and when that is necessary. You type `s'
|
||||
followed by the string to search for, terminated by RET. To search for
|
||||
the same string again, just `s' followed by 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 `next' pointers. But normally the two orders
|
||||
are not very different. In any case, you can always do a `b' to find
|
||||
out what node you have reached, if the header is not visible (this can
|
||||
happen, because `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 `1', `2', `3', `4', and `5'. They are
|
||||
short for the `m' command together with an argument. "1", "2", "3",
|
||||
"4", and "5". `1' goes through the first item in the current node's
|
||||
menu; `2' goes through the second item, etc. Note that numbers larger
|
||||
than 5 are not allowed. If the item you want is that far down, you are
|
||||
better off using an abbreviation for its name than counting.
|
||||
|
||||
The Info command `e' changes from Info mode to an ordinary Emacs
|
||||
editing mode, so that you can edit the text of the current node. Type
|
||||
`C-c C-c' to switch back to Info. The `e' command is allowed only if
|
||||
the variable `Info-enable-edit' is non-`nil'.
|
||||
|
||||
|
||||
File: info.info, Node: Add, Next: Menus, Prev: Expert, Up: Advanced Info
|
||||
|
||||
Adding a new node to Info
|
||||
=========================
|
||||
|
||||
To add a new topic to the list in the directory, you must:
|
||||
|
||||
1. Create a node, in some file, to document that topic.
|
||||
|
||||
2. Put that topic in the menu in the directory. *Note Menu: Menus.
|
||||
|
||||
The new node can live in an existing documentation file, or in a new
|
||||
one. It must have a ^_ character before it (invisible to the user;
|
||||
this node has one but you cannot see it), and it ends with either a ^_,
|
||||
a ^L, or the end of file. Note: If you put in a ^L to end a new node,
|
||||
be sure that there is a ^_ after it to start the next one, since ^L
|
||||
cannot *start* a node. Also, a nicer way to make a node boundary be a
|
||||
page boundary as well is to put a ^L *right after* the ^_.
|
||||
|
||||
The ^_ starting a node must be followed by a newline or a ^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 `Next', `Previous', and `Up' nodes (if there are any). As you
|
||||
can see, this node's `Up' node is the node `Top', which points at all
|
||||
the documentation for Info. The `Next' node is `Menus'.
|
||||
|
||||
The keywords "Node", "Previous", "Up" and "Next", may appear in any
|
||||
order, anywhere in the header line, but the recommended order is the
|
||||
one in this sentence. Each keyword must be followed by a colon, spaces
|
||||
and tabs, and then the appropriate name. The name may be terminated
|
||||
with a tab, a comma, or a newline. A space does not end it; node names
|
||||
may contain spaces. The case of letters in the names is insignificant.
|
||||
|
||||
A node name has two forms. A node in the current file is named by
|
||||
what appears after the `Node: ' in that node's first line. For
|
||||
example, this node's name is `Add'. A node in another file is named by
|
||||
`(FILENAME)NODE-WITHIN-FILE', as in `(info)Add' for this node. If the
|
||||
file name is relative, it is taken starting from the standard Info file
|
||||
directory of your site. The name `(FILENAME)Top' can be abbreviated to
|
||||
just `(FILENAME)'. By convention, the name `Top' is used for the
|
||||
"highest" node in any single file--the node whose `Up' points out of
|
||||
the file. The Directory node is `(dir)'. The `Top' node of a document
|
||||
file listed in the Directory should have an `Up: (dir)' in it.
|
||||
|
||||
The node name `*' is special: it refers to the entire file. Thus,
|
||||
`g*' shows you the whole current file. The use of the node `*' is to
|
||||
make it possible to make old-fashioned, unstructured files into nodes
|
||||
of the tree.
|
||||
|
||||
The `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 `Next', `Previous' and `Up' names may
|
||||
contain them. In this node, since the `Up' node is in the same file,
|
||||
it was not necessary to use one.
|
||||
|
||||
Note that the nodes in this file have a file name in the header
|
||||
line. The file names are ignored by Info, but they serve as comments
|
||||
to help identify the node for the user.
|
||||
|
||||
|
||||
File: info.info, Node: Menus, Next: Cross-refs, Prev: Add, Up: Advanced Info
|
||||
|
||||
How to Create Menus
|
||||
===================
|
||||
|
||||
Any node in the Info hierarchy may have a "menu"--a list of subnodes.
|
||||
The `m' command searches the current node's menu for the topic which it
|
||||
reads from the terminal.
|
||||
|
||||
A menu begins with a line starting with `* Menu:'. The rest of the
|
||||
line is a comment. After the starting line, every line that begins
|
||||
with a `* ' lists a single topic. The name of the topic-the argument
|
||||
that the user must give to the `m' command to select this topic--comes
|
||||
right after the star and space, and is followed by a colon, spaces and
|
||||
tabs, and the name of the node which discusses that topic. The node
|
||||
name, like node names following `Next', `Previous' and `Up', may be
|
||||
terminated with a tab, comma, or newline; it may also be terminated
|
||||
with a period.
|
||||
|
||||
If the node name and topic name are the same, than rather than
|
||||
giving the name twice, the abbreviation `* NAME::' may be used (and
|
||||
should be used, whenever possible, as it reduces the visual clutter in
|
||||
the menu).
|
||||
|
||||
It is considerate to choose the topic names so that they differ from
|
||||
each other very near the beginning--this allows the user to type short
|
||||
abbreviations. In a long menu, it is a good idea to capitalize the
|
||||
beginning of each item name which is the minimum acceptable
|
||||
abbreviation for it (a long menu is more than 5 or so entries).
|
||||
|
||||
The nodes listed in a node's menu are called its "subnodes", and it
|
||||
is their "superior". They should each have an `Up:' pointing at the
|
||||
superior. It is often useful to arrange all or most of the subnodes in
|
||||
a sequence of `Next' and `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 `(dir)Top'--that
|
||||
is, node `Top' in file `.../info/dir'. You can put new entries in that
|
||||
menu just like any other menu. The Info Directory is *not* the same as
|
||||
the file directory called `info'. It happens that many of Info's files
|
||||
live on that file directory, but they do not have to; and files on that
|
||||
directory are not automatically listed in the Info Directory node.
|
||||
|
||||
Also, although the Info node graph is claimed to be a "hierarchy",
|
||||
in fact it can be *any* directed graph. Shared structures and pointer
|
||||
cycles are perfectly possible, and can be used if they are appropriate
|
||||
to the meaning to be expressed. There is no need for all the nodes in
|
||||
a file to form a connected structure. In fact, this file has two
|
||||
connected components. You are in one of them, which is under the node
|
||||
`Top'; the other contains the node `Help' which the `h' command goes
|
||||
to. In fact, since there is no garbage collector, nothing terrible
|
||||
happens if a substructure is not pointed to, but such a substructure is
|
||||
rather useless since nobody can ever find out that it exists.
|
||||
|
||||
|
||||
File: info.info, Node: Cross-refs, Next: Tags, Prev: Menus, Up: Advanced Info
|
||||
|
||||
Creating Cross References
|
||||
=========================
|
||||
|
||||
A cross reference can be placed anywhere in the text, unlike a menu
|
||||
item which must go at the front of a line. A cross reference looks
|
||||
like a menu item except that it has `*note' instead of `*'. It
|
||||
*cannot* be terminated by a `)', because `)''s are so often part of
|
||||
node names. If you wish to enclose a cross reference in parentheses,
|
||||
terminate it with a period first. Here are two examples of cross
|
||||
references pointers:
|
||||
|
||||
*Note details: commands. (See *note 3: Full Proof.)
|
||||
|
||||
They are just examples. The places they "lead to" do not really
|
||||
exist!
|
||||
|
||||
|
||||
File: info.info, Node: Tags, Next: Checking, Prev: Cross-refs, Up: Advanced Info
|
||||
|
||||
Tag Tables for Info Files
|
||||
=========================
|
||||
|
||||
You can speed up the access to nodes of a large Info file by giving
|
||||
it a tag table. Unlike the tag table for a program, the tag table for
|
||||
an Info file lives inside the file itself and is used automatically
|
||||
whenever Info reads in the file.
|
||||
|
||||
To make a tag table, go to a node in the file using Emacs Info mode
|
||||
and type `M-x Info-tagify'. Then you must use `C-x C-s' to save the
|
||||
file.
|
||||
|
||||
Once the Info file has a tag table, you must make certain it is up
|
||||
to date. If, as a result of deletion of text, any node moves back more
|
||||
than a thousand characters in the file from the position recorded in
|
||||
the tag table, Info will no longer be able to find that node. To
|
||||
update the tag table, use the `Info-tagify' command again.
|
||||
|
||||
An Info file tag table appears at the end of the file and looks like
|
||||
this:
|
||||
|
||||
^_
|
||||
Tag Table:
|
||||
File: info, Node: Cross-refs^?21419
|
||||
File: info, Node: Tags^?22145
|
||||
^_
|
||||
End Tag Table
|
||||
|
||||
Note that it contains one line per node, and this line contains the
|
||||
beginning of the node's header (ending just after the node name), a DEL
|
||||
character, and the character position in the file of the beginning of
|
||||
the node.
|
||||
|
||||
|
||||
File: info.info, Node: Checking, Prev: Tags, Up: Advanced Info
|
||||
|
||||
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 `Next', `Previous', and `Up' is
|
||||
checked, as is every menu item and every cross reference. In addition,
|
||||
any `Next' which does not have a `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 `M-x Info-validate' while looking at any
|
||||
node of the file with Emacs Info mode.
|
||||
|
||||
|
||||
File: info.info, Node: Create an Info File, Prev: Advanced Info, Up: Top
|
||||
|
||||
Creating an Info File from a Makeinfo file
|
||||
******************************************
|
||||
|
||||
`makeinfo' is a utility that converts a Texinfo file into an Info
|
||||
file; `texinfo-format-region' and `texinfo-format-buffer' are GNU Emacs
|
||||
functions that do the same.
|
||||
|
||||
*Note Creating an Info File: (texinfo)Create an Info File, to learn
|
||||
how to create an Info file from a Texinfo file.
|
||||
|
||||
*Note Overview of Texinfo: (texinfo)Top, to learn how to write a
|
||||
Texinfo file.
|
||||
|
||||
|
||||
|
||||
Tag Table:
|
||||
Node: Top913
|
||||
Node: Getting Started1431
|
||||
Node: Help-Small-Screen2179
|
||||
Node: Help3921
|
||||
Node: Help-P4949
|
||||
Node: Help-^L5811
|
||||
Node: Help-M8462
|
||||
Node: Help-FOO14030
|
||||
Node: Help-Adv14766
|
||||
Node: Help-Cross17148
|
||||
Node: Help-Q17794
|
||||
Node: Advanced Info18434
|
||||
Node: Expert19330
|
||||
Node: Add21601
|
||||
Node: Menus24635
|
||||
Node: Cross-refs27509
|
||||
Node: Tags28211
|
||||
Node: Checking29510
|
||||
Node: Create an Info File30434
|
||||
|
||||
End Tag Table
|
689
gnu/usr.bin/texinfo/info/infodoc.c
Normal file
689
gnu/usr.bin/texinfo/info/infodoc.c
Normal file
@ -0,0 +1,689 @@
|
||||
/* infohelp.c -- Functions which build documentation nodes. */
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#include "info.h"
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Info Help Windows */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* The name of the node used in the help window. */
|
||||
static char *info_help_nodename = "*Info Help*";
|
||||
|
||||
/* A node containing printed key bindings and their documentation. */
|
||||
static NODE *internal_info_help_node = (NODE *)NULL;
|
||||
|
||||
/* The static text which appears in the internal info help node. */
|
||||
static char *info_internal_help_text[] = {
|
||||
"Basic Commands in Info Windows",
|
||||
"******************************",
|
||||
"",
|
||||
" h Invoke the Info tutorial.",
|
||||
"",
|
||||
"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.",
|
||||
"",
|
||||
"\"Advanced\" commands:",
|
||||
"--------------------",
|
||||
" q Quit Info.",
|
||||
" 1 Pick first item in node's menu.",
|
||||
" 2-9 Pick second ... ninth item in node's menu.",
|
||||
" 0 Pick last item in node's menu.",
|
||||
" 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.",
|
||||
(char *)NULL
|
||||
};
|
||||
|
||||
void
|
||||
dump_map_to_message_buffer (prefix, map)
|
||||
char *prefix;
|
||||
Keymap map;
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
if (map[i].type == ISKMAP)
|
||||
{
|
||||
char *new_prefix, *keyname;
|
||||
|
||||
keyname = pretty_keyname (i);
|
||||
new_prefix = (char *)
|
||||
xmalloc (3 + strlen (prefix) + strlen (keyname));
|
||||
sprintf (new_prefix, "%s%s%s ", prefix, *prefix ? " " : "", keyname);
|
||||
|
||||
dump_map_to_message_buffer (new_prefix, (Keymap)map[i].function);
|
||||
free (new_prefix);
|
||||
}
|
||||
else if (map[i].function)
|
||||
{
|
||||
register int last;
|
||||
char *doc, *name;
|
||||
|
||||
doc = function_documentation (map[i].function);
|
||||
name = function_name (map[i].function);
|
||||
|
||||
if (!*doc)
|
||||
continue;
|
||||
|
||||
/* Find out if there is a series of identical functions, as in
|
||||
ea_insert (). */
|
||||
for (last = i + 1; last < 256; last++)
|
||||
if ((map[last].type != ISFUNC) ||
|
||||
(map[last].function != map[i].function))
|
||||
break;
|
||||
|
||||
if (last - 1 != i)
|
||||
{
|
||||
printf_to_message_buffer
|
||||
("%s%s .. ", prefix, pretty_keyname (i));
|
||||
printf_to_message_buffer
|
||||
("%s%s\t", prefix, pretty_keyname (last - 1));
|
||||
i = last - 1;
|
||||
}
|
||||
else
|
||||
printf_to_message_buffer ("%s%s\t", prefix, pretty_keyname (i));
|
||||
|
||||
#if defined (NAMED_FUNCTIONS)
|
||||
/* Print the name of the function, and some padding before the
|
||||
documentation string is printed. */
|
||||
{
|
||||
int length_so_far;
|
||||
int desired_doc_start = 40; /* Must be multiple of 8. */
|
||||
|
||||
printf_to_message_buffer ("(%s)", name);
|
||||
length_so_far = message_buffer_length_this_line ();
|
||||
|
||||
if ((desired_doc_start + strlen (doc)) >= the_screen->width)
|
||||
printf_to_message_buffer ("\n ");
|
||||
else
|
||||
{
|
||||
while (length_so_far < desired_doc_start)
|
||||
{
|
||||
printf_to_message_buffer ("\t");
|
||||
length_so_far += character_width ('\t', length_so_far);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* NAMED_FUNCTIONS */
|
||||
printf_to_message_buffer ("%s\n", doc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* How to create internal_info_help_node. */
|
||||
static void
|
||||
create_internal_info_help_node ()
|
||||
{
|
||||
register int i;
|
||||
|
||||
initialize_message_buffer ();
|
||||
|
||||
for (i = 0; info_internal_help_text[i]; i++)
|
||||
printf_to_message_buffer ("%s\n", info_internal_help_text[i]);
|
||||
|
||||
printf_to_message_buffer ("---------------------\n\n");
|
||||
printf_to_message_buffer ("The current search path is:\n");
|
||||
printf_to_message_buffer (" \"%s\"\n", infopath);
|
||||
printf_to_message_buffer ("---------------------\n\n");
|
||||
printf_to_message_buffer ("Commands available in Info windows:\n\n");
|
||||
dump_map_to_message_buffer ("", info_keymap);
|
||||
printf_to_message_buffer ("---------------------\n\n");
|
||||
printf_to_message_buffer ("Commands available in the echo area:\n\n");
|
||||
dump_map_to_message_buffer ("", echo_area_keymap);
|
||||
|
||||
{
|
||||
char *message;
|
||||
|
||||
message = replace_in_documentation
|
||||
("--- Use `\\[history-node]' or `\\[kill-node]' to exit ---\n");
|
||||
printf_to_message_buffer ("%s", message);
|
||||
}
|
||||
|
||||
internal_info_help_node = message_buffer_to_node ();
|
||||
add_gcable_pointer (internal_info_help_node->contents);
|
||||
name_internal_node (internal_info_help_node, info_help_nodename);
|
||||
|
||||
/* Even though this is an internal node, we don't want the window
|
||||
system to treat it specially. So we turn off the internalness
|
||||
of it here. */
|
||||
internal_info_help_node->flags &= ~N_IsInternal;
|
||||
}
|
||||
|
||||
/* Return a window which is the window showing help in this Info. */
|
||||
static WINDOW *
|
||||
info_find_or_create_help_window ()
|
||||
{
|
||||
WINDOW *help_window;
|
||||
|
||||
help_window = get_internal_info_window (info_help_nodename);
|
||||
|
||||
/* If we couldn't find the help window, then make it. */
|
||||
if (!help_window)
|
||||
{
|
||||
WINDOW *window, *eligible = (WINDOW *)NULL;
|
||||
int max = 0;
|
||||
|
||||
for (window = windows; window; window = window->next)
|
||||
{
|
||||
if (window->height > max)
|
||||
{
|
||||
max = window->height;
|
||||
eligible = window;
|
||||
}
|
||||
}
|
||||
|
||||
if (!eligible)
|
||||
return ((WINDOW *)NULL);
|
||||
else
|
||||
{
|
||||
/* Make a new node containing the help text. Split the largest
|
||||
window into 2 windows, and show the help text in that window. */
|
||||
if (!internal_info_help_node)
|
||||
create_internal_info_help_node ();
|
||||
|
||||
if (eligible->height > 30)
|
||||
{
|
||||
active_window = eligible;
|
||||
help_window = window_make_window (internal_info_help_node);
|
||||
}
|
||||
else
|
||||
{
|
||||
set_remembered_pagetop_and_point (active_window);
|
||||
window_set_node_of_window
|
||||
(active_window, internal_info_help_node);
|
||||
help_window = active_window;
|
||||
}
|
||||
|
||||
remember_window_and_node (help_window, help_window->node);
|
||||
}
|
||||
}
|
||||
return (help_window);
|
||||
}
|
||||
|
||||
/* Create or move to the help window. */
|
||||
DECLARE_INFO_COMMAND (info_get_help_window, "Display help message")
|
||||
{
|
||||
WINDOW *help_window;
|
||||
|
||||
help_window = info_find_or_create_help_window ();
|
||||
if (help_window)
|
||||
{
|
||||
active_window = help_window;
|
||||
active_window->flags |= W_UpdateWindow;
|
||||
}
|
||||
else
|
||||
{
|
||||
info_error (CANT_MAKE_HELP);
|
||||
}
|
||||
}
|
||||
|
||||
/* Show the Info help node. This means that the "info" file is installed
|
||||
where it can easily be found on your system. */
|
||||
DECLARE_INFO_COMMAND (info_get_info_help_node, "Visit Info node `(info)Help'")
|
||||
{
|
||||
NODE *node;
|
||||
char *nodename;
|
||||
|
||||
/* If there is a window on the screen showing the node "(info)Help" or
|
||||
the node "(info)Help-Small-Screen", simply select that window. */
|
||||
{
|
||||
WINDOW *win;
|
||||
|
||||
for (win = windows; win; win = win->next)
|
||||
{
|
||||
if (win->node && win->node->filename &&
|
||||
(stricmp
|
||||
(filename_non_directory (win->node->filename), "info") == 0) &&
|
||||
((strcmp (win->node->nodename, "Help") == 0) ||
|
||||
(strcmp (win->node->nodename, "Help-Small-Screen") == 0)))
|
||||
{
|
||||
active_window = win;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If the current window is small, show the small screen help. */
|
||||
if (active_window->height < 24)
|
||||
nodename = "Help-Small-Screen";
|
||||
else
|
||||
nodename = "Help";
|
||||
|
||||
/* Try to get the info file for Info. */
|
||||
node = info_get_node ("Info", nodename);
|
||||
|
||||
if (!node)
|
||||
{
|
||||
if (info_recent_file_error)
|
||||
info_error (info_recent_file_error);
|
||||
else
|
||||
info_error (CANT_FILE_NODE, "Info", nodename);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If the current window is very large (greater than 45 lines),
|
||||
then split it and show the help node in another window.
|
||||
Otherwise, use the current window. */
|
||||
|
||||
if (active_window->height > 45)
|
||||
active_window = window_make_window (node);
|
||||
else
|
||||
{
|
||||
set_remembered_pagetop_and_point (active_window);
|
||||
window_set_node_of_window (active_window, node);
|
||||
}
|
||||
|
||||
remember_window_and_node (active_window, node);
|
||||
}
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Groveling Info Keymaps and Docs */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Return the documentation associated with the Info command FUNCTION. */
|
||||
char *
|
||||
function_documentation (function)
|
||||
VFunction *function;
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; function_doc_array[i].func; i++)
|
||||
if (function == function_doc_array[i].func)
|
||||
break;
|
||||
|
||||
return (replace_in_documentation (function_doc_array[i].doc));
|
||||
}
|
||||
|
||||
#if defined (NAMED_FUNCTIONS)
|
||||
/* Return the user-visible name of the function associated with the
|
||||
Info command FUNCTION. */
|
||||
char *
|
||||
function_name (function)
|
||||
|
||||
VFunction *function;
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; function_doc_array[i].func; i++)
|
||||
if (function == function_doc_array[i].func)
|
||||
break;
|
||||
|
||||
return (function_doc_array[i].func_name);
|
||||
}
|
||||
|
||||
/* Return a pointer to the function named NAME. */
|
||||
VFunction *
|
||||
named_function (name)
|
||||
char *name;
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; function_doc_array[i].func; i++)
|
||||
if (strcmp (function_doc_array[i].func_name, name) == 0)
|
||||
break;
|
||||
|
||||
return (function_doc_array[i].func);
|
||||
}
|
||||
#endif /* NAMED_FUNCTIONS */
|
||||
|
||||
/* Return the documentation associated with KEY in MAP. */
|
||||
char *
|
||||
key_documentation (key, map)
|
||||
char key;
|
||||
Keymap map;
|
||||
{
|
||||
VFunction *function = map[key].function;
|
||||
|
||||
if (function)
|
||||
return (function_documentation (function));
|
||||
else
|
||||
return ((char *)NULL);
|
||||
}
|
||||
|
||||
DECLARE_INFO_COMMAND (describe_key, "Print documentation for KEY")
|
||||
{
|
||||
char keyname[50];
|
||||
int keyname_index = 0;
|
||||
unsigned char keystroke;
|
||||
char *rep;
|
||||
Keymap map;
|
||||
|
||||
keyname[0] = '\0';
|
||||
map = window->keymap;
|
||||
|
||||
while (1)
|
||||
{
|
||||
message_in_echo_area ("Describe key: %s", keyname);
|
||||
keystroke = info_get_input_char ();
|
||||
unmessage_in_echo_area ();
|
||||
|
||||
if (Meta_p (keystroke) && (!ISO_Latin_p || key < 160))
|
||||
{
|
||||
if (map[ESC].type != ISKMAP)
|
||||
{
|
||||
window_message_in_echo_area
|
||||
("ESC %s is undefined.", pretty_keyname (UnMeta (keystroke)));
|
||||
return;
|
||||
}
|
||||
|
||||
strcpy (keyname + keyname_index, "ESC ");
|
||||
keyname_index = strlen (keyname);
|
||||
keystroke = UnMeta (keystroke);
|
||||
map = (Keymap)map[ESC].function;
|
||||
}
|
||||
|
||||
/* Add the printed representation of KEYSTROKE to our keyname. */
|
||||
rep = pretty_keyname (keystroke);
|
||||
strcpy (keyname + keyname_index, rep);
|
||||
keyname_index = strlen (keyname);
|
||||
|
||||
if (map[keystroke].function == (VFunction *)NULL)
|
||||
{
|
||||
message_in_echo_area ("%s is undefined.", keyname);
|
||||
return;
|
||||
}
|
||||
else if (map[keystroke].type == ISKMAP)
|
||||
{
|
||||
map = (Keymap)map[keystroke].function;
|
||||
strcat (keyname, " ");
|
||||
keyname_index = strlen (keyname);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *message, *fundoc, *funname = "";
|
||||
|
||||
#if defined (NAMED_FUNCTIONS)
|
||||
funname = function_name (map[keystroke].function);
|
||||
#endif /* NAMED_FUNCTIONS */
|
||||
|
||||
fundoc = function_documentation (map[keystroke].function);
|
||||
|
||||
message = (char *)xmalloc
|
||||
(10 + strlen (keyname) + strlen (fundoc) + strlen (funname));
|
||||
|
||||
#if defined (NAMED_FUNCTIONS)
|
||||
sprintf (message, "%s (%s): %s.", keyname, funname, fundoc);
|
||||
#else
|
||||
sprintf (message, "%s is defined to %s.", keyname, fundoc);
|
||||
#endif /* !NAMED_FUNCTIONS */
|
||||
|
||||
window_message_in_echo_area ("%s", message);
|
||||
free (message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* How to get the pretty printable name of a character. */
|
||||
static char rep_buffer[30];
|
||||
|
||||
char *
|
||||
pretty_keyname (key)
|
||||
unsigned char key;
|
||||
{
|
||||
char *rep;
|
||||
|
||||
if (Meta_p (key))
|
||||
{
|
||||
char temp[20];
|
||||
|
||||
rep = pretty_keyname (UnMeta (key));
|
||||
|
||||
sprintf (temp, "ESC %s", rep);
|
||||
strcpy (rep_buffer, temp);
|
||||
rep = rep_buffer;
|
||||
}
|
||||
else if (Control_p (key))
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case '\n': rep = "LFD"; break;
|
||||
case '\t': rep = "TAB"; break;
|
||||
case '\r': rep = "RET"; break;
|
||||
case ESC: rep = "ESC"; break;
|
||||
|
||||
default:
|
||||
sprintf (rep_buffer, "C-%c", UnControl (key));
|
||||
rep = rep_buffer;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case ' ': rep = "SPC"; break;
|
||||
case DEL: rep = "DEL"; break;
|
||||
default:
|
||||
rep_buffer[0] = key;
|
||||
rep_buffer[1] = '\0';
|
||||
rep = rep_buffer;
|
||||
}
|
||||
}
|
||||
return (rep);
|
||||
}
|
||||
|
||||
/* Replace the names of functions with the key that invokes them. */
|
||||
static char *where_is (), *where_is_internal ();
|
||||
|
||||
char *
|
||||
replace_in_documentation (string)
|
||||
char *string;
|
||||
{
|
||||
register int i, start, next;
|
||||
static char *result = (char *)NULL;
|
||||
|
||||
maybe_free (result);
|
||||
result = (char *)xmalloc (1 + strlen (string));
|
||||
|
||||
i = next = start = 0;
|
||||
|
||||
/* Skip to the beginning of a replaceable function. */
|
||||
for (i = start; string[i]; i++)
|
||||
{
|
||||
/* Is this the start of a replaceable function name? */
|
||||
if (string[i] == '\\' && string[i + 1] == '[')
|
||||
{
|
||||
char *fun_name, *rep;
|
||||
VFunction *function;
|
||||
|
||||
/* Copy in the old text. */
|
||||
strncpy (result + next, string + start, i - start);
|
||||
next += (i - start);
|
||||
start = i + 2;
|
||||
|
||||
/* Move to the end of the function name. */
|
||||
for (i = start; string[i] && (string[i] != ']'); i++);
|
||||
|
||||
fun_name = (char *)xmalloc (1 + i - start);
|
||||
strncpy (fun_name, string + start, i - start);
|
||||
fun_name[i - start] = '\0';
|
||||
|
||||
/* Find a key which invokes this function in the info_keymap. */
|
||||
function = named_function (fun_name);
|
||||
|
||||
/* If the internal documentation string fails, there is a
|
||||
serious problem with the associated command's documentation.
|
||||
We croak so that it can be fixed immediately. */
|
||||
if (!function)
|
||||
abort ();
|
||||
|
||||
rep = where_is (info_keymap, function);
|
||||
strcpy (result + next, rep);
|
||||
next = strlen (result);
|
||||
|
||||
start = i;
|
||||
if (string[i])
|
||||
start++;
|
||||
}
|
||||
}
|
||||
strcpy (result + next, string + start);
|
||||
return (result);
|
||||
}
|
||||
|
||||
/* Return a string of characters which could be typed from the keymap
|
||||
MAP to invoke FUNCTION. */
|
||||
static char *where_is_rep = (char *)NULL;
|
||||
static int where_is_rep_index = 0;
|
||||
static int where_is_rep_size = 0;
|
||||
|
||||
static char *
|
||||
where_is (map, function)
|
||||
Keymap map;
|
||||
VFunction *function;
|
||||
{
|
||||
char *rep;
|
||||
|
||||
if (!where_is_rep_size)
|
||||
where_is_rep = (char *)xmalloc (where_is_rep_size = 100);
|
||||
where_is_rep_index = 0;
|
||||
|
||||
rep = where_is_internal (map, function);
|
||||
|
||||
/* If it couldn't be found, return "M-x Foo". */
|
||||
if (!rep)
|
||||
{
|
||||
char *name;
|
||||
|
||||
name = function_name (function);
|
||||
|
||||
if (name)
|
||||
sprintf (where_is_rep, "M-x %s", name);
|
||||
|
||||
rep = where_is_rep;
|
||||
}
|
||||
return (rep);
|
||||
}
|
||||
|
||||
/* Return the printed rep of FUNCTION as found in MAP, or NULL. */
|
||||
static char *
|
||||
where_is_internal (map, function)
|
||||
Keymap map;
|
||||
VFunction *function;
|
||||
{
|
||||
register int i;
|
||||
|
||||
/* If the function is directly invokable in MAP, return the representation
|
||||
of that keystroke. */
|
||||
for (i = 0; i < 256; i++)
|
||||
if ((map[i].type == ISFUNC) && map[i].function == function)
|
||||
{
|
||||
sprintf (where_is_rep + where_is_rep_index, "%s", pretty_keyname (i));
|
||||
return (where_is_rep);
|
||||
}
|
||||
|
||||
/* Okay, search subsequent maps for this function. */
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
if (map[i].type == ISKMAP)
|
||||
{
|
||||
int saved_index = where_is_rep_index;
|
||||
char *rep;
|
||||
|
||||
sprintf (where_is_rep + where_is_rep_index, "%s ",
|
||||
pretty_keyname (i));
|
||||
|
||||
where_is_rep_index = strlen (where_is_rep);
|
||||
rep = where_is_internal ((Keymap)map[i].function, function);
|
||||
|
||||
if (rep)
|
||||
return (where_is_rep);
|
||||
|
||||
where_is_rep_index = saved_index;
|
||||
}
|
||||
}
|
||||
|
||||
return ((char *)NULL);
|
||||
}
|
||||
|
||||
extern char *read_function_name ();
|
||||
|
||||
DECLARE_INFO_COMMAND (info_where_is,
|
||||
"Show what to type to execute a given command")
|
||||
{
|
||||
char *command_name;
|
||||
|
||||
command_name = read_function_name ("Where is command: ", window);
|
||||
|
||||
if (!command_name)
|
||||
{
|
||||
info_abort_key (active_window, count, key);
|
||||
return;
|
||||
}
|
||||
|
||||
if (*command_name)
|
||||
{
|
||||
VFunction *function;
|
||||
|
||||
function = named_function (command_name);
|
||||
|
||||
if (function)
|
||||
{
|
||||
char *location;
|
||||
|
||||
location = where_is (active_window->keymap, function);
|
||||
|
||||
if (!location)
|
||||
{
|
||||
info_error ("`%s' is not on any keys", command_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strncmp (location, "M-x ", 4) == 0)
|
||||
window_message_in_echo_area
|
||||
("%s can only be invoked via %s.", command_name, location);
|
||||
else
|
||||
window_message_in_echo_area
|
||||
("%s can be invoked via %s.", command_name, location);
|
||||
}
|
||||
}
|
||||
else
|
||||
info_error ("There is no function named `%s'", command_name);
|
||||
}
|
||||
|
||||
free (command_name);
|
||||
}
|
||||
|
269
gnu/usr.bin/texinfo/info/infomap.c
Normal file
269
gnu/usr.bin/texinfo/info/infomap.c
Normal file
@ -0,0 +1,269 @@
|
||||
/* infomap.c -- Keymaps for Info. */
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#include "stdio.h"
|
||||
#include "ctype.h"
|
||||
#include "infomap.h"
|
||||
#include "funs.h"
|
||||
|
||||
/* Return a new keymap which has all the uppercase letters mapped to run
|
||||
the function info_do_lowercase_version (). */
|
||||
Keymap
|
||||
keymap_make_keymap ()
|
||||
{
|
||||
register int i;
|
||||
Keymap keymap;
|
||||
|
||||
keymap = (Keymap)xmalloc (256 * sizeof (KEYMAP_ENTRY));
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
keymap[i].type = ISFUNC;
|
||||
keymap[i].function = (VFunction *)NULL;
|
||||
}
|
||||
|
||||
for (i = 'A'; i < ('Z' + 1); i++)
|
||||
{
|
||||
keymap[i].type = ISFUNC;
|
||||
keymap[i].function = info_do_lowercase_version;
|
||||
}
|
||||
|
||||
return (keymap);
|
||||
}
|
||||
|
||||
/* Return a new keymap which is a copy of MAP. */
|
||||
Keymap
|
||||
keymap_copy_keymap (map)
|
||||
Keymap map;
|
||||
{
|
||||
register int i;
|
||||
Keymap keymap;
|
||||
|
||||
keymap = keymap_make_keymap ();
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
keymap[i].type = map[i].type;
|
||||
keymap[i].function = map[i].function;
|
||||
}
|
||||
return (keymap);
|
||||
}
|
||||
|
||||
/* Free the keymap and it's descendents. */
|
||||
void
|
||||
keymap_discard_keymap (map)
|
||||
Keymap (map);
|
||||
{
|
||||
register int i;
|
||||
|
||||
if (!map)
|
||||
return;
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
switch (map[i].type)
|
||||
{
|
||||
case ISFUNC:
|
||||
break;
|
||||
|
||||
case ISKMAP:
|
||||
keymap_discard_keymap ((Keymap)map[i].function);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize the standard info keymaps. */
|
||||
|
||||
Keymap info_keymap = (Keymap)NULL;
|
||||
Keymap echo_area_keymap = (Keymap)NULL;
|
||||
|
||||
void
|
||||
initialize_info_keymaps ()
|
||||
{
|
||||
register int i;
|
||||
Keymap map;
|
||||
|
||||
if (!info_keymap)
|
||||
{
|
||||
info_keymap = keymap_make_keymap ();
|
||||
info_keymap[ESC].type = ISKMAP;
|
||||
info_keymap[ESC].function = (VFunction *)keymap_make_keymap ();
|
||||
info_keymap[Control ('x')].type = ISKMAP;
|
||||
info_keymap[Control ('x')].function = (VFunction *)keymap_make_keymap ();
|
||||
echo_area_keymap = keymap_make_keymap ();
|
||||
echo_area_keymap[ESC].type = ISKMAP;
|
||||
echo_area_keymap[ESC].function = (VFunction *)keymap_make_keymap ();
|
||||
echo_area_keymap[Control ('x')].type = ISKMAP;
|
||||
echo_area_keymap[Control ('x')].function =
|
||||
(VFunction *)keymap_make_keymap ();
|
||||
}
|
||||
|
||||
/* Bind numeric arg functions for both echo area and info window maps. */
|
||||
for (i = '0'; i < '9' + 1; i++)
|
||||
{
|
||||
((Keymap) info_keymap[ESC].function)[i].function =
|
||||
((Keymap) echo_area_keymap[ESC].function)[i].function =
|
||||
info_add_digit_to_numeric_arg;
|
||||
}
|
||||
((Keymap) info_keymap[ESC].function)['-'].function =
|
||||
((Keymap) echo_area_keymap[ESC].function)['-'].function =
|
||||
info_add_digit_to_numeric_arg;
|
||||
|
||||
/* Bind the echo area routines. */
|
||||
map = echo_area_keymap;
|
||||
|
||||
/* Bind the echo area insert routines. */
|
||||
for (i = 0; i < 160; i++)
|
||||
if (isprint (i))
|
||||
map[i].function = ea_insert;
|
||||
|
||||
map[Control ('a')].function = ea_beg_of_line;
|
||||
map[Control ('b')].function = ea_backward;
|
||||
map[Control ('d')].function = ea_delete;
|
||||
map[Control ('e')].function = ea_end_of_line;
|
||||
map[Control ('f')].function = ea_forward;
|
||||
map[Control ('g')].function = ea_abort;
|
||||
map[Control ('h')].function = ea_rubout;
|
||||
map[Control ('k')].function = ea_kill_line;
|
||||
map[Control ('l')].function = info_redraw_display;
|
||||
map[Control ('q')].function = ea_quoted_insert;
|
||||
map[Control ('t')].function = ea_transpose_chars;
|
||||
map[Control ('u')].function = info_universal_argument;
|
||||
map[Control ('y')].function = ea_yank;
|
||||
|
||||
map[LFD].function = ea_newline;
|
||||
map[RET].function = ea_newline;
|
||||
map[SPC].function = ea_complete;
|
||||
map[TAB].function = ea_complete;
|
||||
map['?'].function = ea_possible_completions;
|
||||
map[DEL].function = ea_rubout;
|
||||
|
||||
/* Bind the echo area ESC keymap. */
|
||||
map = (Keymap)echo_area_keymap[ESC].function;
|
||||
|
||||
map[Control ('g')].function = ea_abort;
|
||||
map[Control ('v')].function = ea_scroll_completions_window;
|
||||
map['b'].function = ea_backward_word;
|
||||
map['d'].function = ea_kill_word;
|
||||
map['f'].function = ea_forward_word;
|
||||
#if defined (NAMED_FUNCTIONS)
|
||||
/* map['x'].function = info_execute_command; */
|
||||
#endif /* NAMED_FUNCTIONS */
|
||||
map['y'].function = ea_yank_pop;
|
||||
map['?'].function = ea_possible_completions;
|
||||
map[TAB].function = ea_tab_insert;
|
||||
map[DEL].function = ea_backward_kill_word;
|
||||
|
||||
/* Bind the echo area Control-x keymap. */
|
||||
map = (Keymap)echo_area_keymap[Control ('x')].function;
|
||||
|
||||
map['o'].function = info_next_window;
|
||||
map[DEL].function = ea_backward_kill_line;
|
||||
|
||||
/* Bind commands for Info window keymaps. */
|
||||
map = info_keymap;
|
||||
map[TAB].function = info_move_to_next_xref;
|
||||
map[LFD].function = info_select_reference_this_line;
|
||||
map[RET].function = info_select_reference_this_line;
|
||||
map[SPC].function = info_scroll_forward;
|
||||
map[Control ('a')].function = info_beginning_of_line;
|
||||
map[Control ('b')].function = info_backward_char;
|
||||
map[Control ('e')].function = info_end_of_line;
|
||||
map[Control ('f')].function = info_forward_char;
|
||||
map[Control ('g')].function = info_abort_key;
|
||||
map[Control ('h')].function = info_get_help_window;
|
||||
map[Control ('l')].function = info_redraw_display;
|
||||
map[Control ('n')].function = info_next_line;
|
||||
map[Control ('p')].function = info_prev_line;
|
||||
map[Control ('r')].function = isearch_backward;
|
||||
map[Control ('s')].function = isearch_forward;
|
||||
map[Control ('u')].function = info_universal_argument;
|
||||
map[Control ('v')].function = info_scroll_forward;
|
||||
map[','].function = info_next_index_match;
|
||||
|
||||
for (i = '1'; i < '9' + 1; i++)
|
||||
map[i].function = info_menu_digit;
|
||||
map['0'].function = info_last_menu_item;
|
||||
|
||||
map['<'].function = info_first_node;
|
||||
map['>'].function = info_last_node;
|
||||
map['?'].function = info_get_help_window;
|
||||
map['['].function = info_global_prev_node;
|
||||
map[']'].function = info_global_next_node;
|
||||
|
||||
map['b'].function = info_beginning_of_node;
|
||||
map['d'].function = info_dir_node;
|
||||
map['e'].function = info_end_of_node;
|
||||
map['f'].function = info_xref_item;
|
||||
map['g'].function = info_goto_node;
|
||||
map['h'].function = info_get_info_help_node;
|
||||
map['i'].function = info_index_search;
|
||||
map['l'].function = info_history_node;
|
||||
map['m'].function = info_menu_item;
|
||||
map['n'].function = info_next_node;
|
||||
map['p'].function = info_prev_node;
|
||||
map['q'].function = info_quit;
|
||||
map['r'].function = info_xref_item;
|
||||
map['s'].function = info_search;
|
||||
map['t'].function = info_top_node;
|
||||
map['u'].function = info_up_node;
|
||||
map[DEL].function = info_scroll_backward;
|
||||
|
||||
/* Bind members in the ESC map for Info windows. */
|
||||
map = (Keymap)info_keymap[ESC].function;
|
||||
map[Control ('f')].function = info_show_footnotes;
|
||||
map[Control ('g')].function = info_abort_key;
|
||||
map[TAB].function = info_move_to_prev_xref;
|
||||
map[Control ('v')].function = info_scroll_other_window;
|
||||
map['<'].function = info_beginning_of_node;
|
||||
map['>'].function = info_end_of_node;
|
||||
map['b'].function = info_backward_word;
|
||||
map['f'].function = info_forward_word;
|
||||
map['r'].function = info_move_to_window_line;
|
||||
map['v'].function = info_scroll_backward;
|
||||
#if defined (NAMED_FUNCTIONS)
|
||||
map['x'].function = info_execute_command;
|
||||
#endif /* NAMED_FUNCTIONS */
|
||||
|
||||
/* Bind members in the Control-X map for Info windows. */
|
||||
map = (Keymap)info_keymap[Control ('x')].function;
|
||||
|
||||
map[Control ('b')].function = list_visited_nodes;
|
||||
map[Control ('c')].function = info_quit;
|
||||
map[Control ('f')].function = info_view_file;
|
||||
map[Control ('g')].function = info_abort_key;
|
||||
map[Control ('v')].function = info_view_file;
|
||||
map['0'].function = info_delete_window;
|
||||
map['1'].function = info_keep_one_window;
|
||||
map['2'].function = info_split_window;
|
||||
map['^'].function = info_grow_window;
|
||||
map['b'].function = select_visited_node;
|
||||
map['k'].function = info_kill_node;
|
||||
map['o'].function = info_next_window;
|
||||
map['t'].function = info_tile_windows;
|
||||
map['w'].function = info_toggle_wrap;
|
||||
}
|
||||
|
||||
|
82
gnu/usr.bin/texinfo/info/infomap.h
Normal file
82
gnu/usr.bin/texinfo/info/infomap.h
Normal file
@ -0,0 +1,82 @@
|
||||
/* infomap.h -- Description of a keymap in Info and related functions. */
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#ifndef _INFOMAP_H_
|
||||
#define _INFOMAP_H_
|
||||
|
||||
#include "general.h"
|
||||
|
||||
#define ESC '\033'
|
||||
#define DEL '\177'
|
||||
#define TAB '\011'
|
||||
#define RET '\r'
|
||||
#define LFD '\n'
|
||||
#define SPC ' '
|
||||
|
||||
#define meta_character_threshold (DEL + 1)
|
||||
#define control_character_threshold (SPC)
|
||||
|
||||
#define meta_character_bit 0x80
|
||||
#define control_character_bit 0x40
|
||||
|
||||
#define Meta_p(c) (((c) > meta_character_threshold))
|
||||
#define Control_p(c) ((c) < control_character_threshold)
|
||||
|
||||
#define Meta(c) ((c) | (meta_character_bit))
|
||||
#define UnMeta(c) ((c) & (~meta_character_bit))
|
||||
#define Control(c) ((toupper (c)) & (~control_character_bit))
|
||||
#define UnControl(c) (tolower ((c) | control_character_bit))
|
||||
|
||||
/* A keymap contains one entry for each key in the ASCII set.
|
||||
Each entry consists of a type and a pointer.
|
||||
FUNCTION is the address of a function to run, or the
|
||||
address of a keymap to indirect through.
|
||||
TYPE says which kind of thing FUNCTION is. */
|
||||
typedef struct {
|
||||
char type;
|
||||
VFunction *function;
|
||||
} KEYMAP_ENTRY;
|
||||
|
||||
typedef KEYMAP_ENTRY *Keymap;
|
||||
|
||||
/* The values that TYPE can have in a keymap entry. */
|
||||
#define ISFUNC 0
|
||||
#define ISKMAP 1
|
||||
|
||||
extern Keymap info_keymap;
|
||||
extern Keymap echo_area_keymap;
|
||||
|
||||
/* Return a new keymap which has all the uppercase letters mapped to run
|
||||
the function info_do_lowercase_version (). */
|
||||
extern Keymap keymap_make_keymap ();
|
||||
|
||||
/* Return a new keymap which is a copy of MAP. */
|
||||
extern Keymap keymap_copy_keymap ();
|
||||
|
||||
/* Free MAP and it's descendents. */
|
||||
extern void keymap_discard_keymap ();
|
||||
|
||||
/* Initialize the info keymaps. */
|
||||
extern void initialize_info_keymaps ();
|
||||
|
||||
#endif /* _INFOMAP_H_ */
|
195
gnu/usr.bin/texinfo/info/m-x.c
Normal file
195
gnu/usr.bin/texinfo/info/m-x.c
Normal file
@ -0,0 +1,195 @@
|
||||
/* m-x.c -- Meta-X minibuffer reader. */
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#include "info.h"
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Reading Named Commands */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Read the name of an Info function in the echo area and return the
|
||||
name. A return value of NULL indicates that no function name could
|
||||
be read. */
|
||||
char *
|
||||
read_function_name (prompt, window)
|
||||
char *prompt;
|
||||
WINDOW *window;
|
||||
{
|
||||
register int i;
|
||||
char *line;
|
||||
REFERENCE **array = (REFERENCE **)NULL;
|
||||
int array_index = 0, array_slots = 0;
|
||||
|
||||
/* Make an array of REFERENCE which actually contains the names of
|
||||
the functions available in Info. */
|
||||
for (i = 0; function_doc_array[i].func; i++)
|
||||
{
|
||||
REFERENCE *entry;
|
||||
|
||||
entry = (REFERENCE *)xmalloc (sizeof (REFERENCE));
|
||||
entry->label = savestring (function_doc_array[i].func_name);
|
||||
entry->nodename = (char *)NULL;
|
||||
entry->filename = (char *)NULL;
|
||||
|
||||
add_pointer_to_array
|
||||
(entry, array_index, array, array_slots, 200, REFERENCE *);
|
||||
}
|
||||
|
||||
line = info_read_completing_in_echo_area (window, prompt, array);
|
||||
|
||||
info_free_references (array);
|
||||
|
||||
if (!echo_area_is_active)
|
||||
window_clear_echo_area ();
|
||||
|
||||
return (line);
|
||||
}
|
||||
|
||||
DECLARE_INFO_COMMAND (describe_command,
|
||||
"Read the name of an Info command and describe it")
|
||||
{
|
||||
char *line;
|
||||
|
||||
line = read_function_name ("Describe command: ", window);
|
||||
|
||||
if (!line)
|
||||
{
|
||||
info_abort_key (active_window, count, key);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Describe the function named in "LINE". */
|
||||
if (*line)
|
||||
{
|
||||
char *fundoc;
|
||||
VFunction *fun;
|
||||
|
||||
fun = named_function (line);
|
||||
|
||||
if (!fun)
|
||||
return;
|
||||
|
||||
window_message_in_echo_area ("%s: %s.",
|
||||
line, function_documentation (fun));
|
||||
}
|
||||
free (line);
|
||||
}
|
||||
|
||||
DECLARE_INFO_COMMAND (info_execute_command,
|
||||
"Read a command name in the echo area and execute it")
|
||||
{
|
||||
char *line;
|
||||
|
||||
/* Ask the completer to read a reference for us. */
|
||||
if (info_explicit_arg || count != 1)
|
||||
{
|
||||
char *prompt;
|
||||
|
||||
prompt = (char *)xmalloc (20);
|
||||
sprintf (prompt, "%d M-x ", count);
|
||||
line = read_function_name (prompt, window);
|
||||
}
|
||||
else
|
||||
line = read_function_name ("M-x ", window);
|
||||
|
||||
/* User aborted? */
|
||||
if (!line)
|
||||
{
|
||||
info_abort_key (active_window, count, key);
|
||||
return;
|
||||
}
|
||||
|
||||
/* User accepted "default"? (There is none.) */
|
||||
if (!*line)
|
||||
{
|
||||
free (line);
|
||||
return;
|
||||
}
|
||||
|
||||
/* User wants to execute a named command. Do it. */
|
||||
{
|
||||
VFunction *function;
|
||||
|
||||
if ((active_window != the_echo_area) &&
|
||||
(strncmp (line, "echo-area-", 10) == 0))
|
||||
{
|
||||
free (line);
|
||||
info_error ("Cannot execute an `echo-area' command here.");
|
||||
return;
|
||||
}
|
||||
|
||||
function = named_function (line);
|
||||
free (line);
|
||||
|
||||
if (!function)
|
||||
return;
|
||||
|
||||
(*function) (active_window, count, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Okay, now that we have M-x, let the user set the screen height. */
|
||||
DECLARE_INFO_COMMAND (set_screen_height,
|
||||
"Set the height of the displayed window")
|
||||
{
|
||||
int new_height;
|
||||
|
||||
if (info_explicit_arg || count != 1)
|
||||
new_height = count;
|
||||
else
|
||||
{
|
||||
char prompt[80];
|
||||
char *line;
|
||||
|
||||
new_height = screenheight;
|
||||
|
||||
sprintf (prompt, "Set screen height to (%d): ", new_height);
|
||||
|
||||
line = info_read_in_echo_area (window, prompt);
|
||||
|
||||
/* If the user aborted, do that now. */
|
||||
if (!line)
|
||||
{
|
||||
info_abort_key (active_window, count, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Find out what the new height is supposed to be. */
|
||||
if (*line)
|
||||
new_height = atoi (line);
|
||||
|
||||
/* Clear the echo area if it isn't active. */
|
||||
if (!echo_area_is_active)
|
||||
window_clear_echo_area ();
|
||||
|
||||
free (line);
|
||||
}
|
||||
|
||||
terminal_clear_screen ();
|
||||
display_clear_display (the_display);
|
||||
screenheight = new_height;
|
||||
display_initialize_display (screenwidth, screenheight);
|
||||
window_new_screen_size (screenwidth, screenheight);
|
||||
}
|
321
gnu/usr.bin/texinfo/info/nodemenu.c
Normal file
321
gnu/usr.bin/texinfo/info/nodemenu.c
Normal file
@ -0,0 +1,321 @@
|
||||
/* nodemenu.c -- Produce a menu of all visited nodes. */
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#include "info.h"
|
||||
|
||||
/* Return a line describing the format of a node information line. */
|
||||
static char *
|
||||
nodemenu_format_info ()
|
||||
{
|
||||
return ("\n\
|
||||
* Menu:\n\
|
||||
(File)Node Lines Size Containing File\n\
|
||||
---------- ----- ---- ---------------");
|
||||
}
|
||||
|
||||
/* Produce a formatted line of information about NODE. Here is what we want
|
||||
the output listing to look like:
|
||||
|
||||
* Menu:
|
||||
(File)Node Lines Size Containing File
|
||||
---------- ----- ---- ---------------
|
||||
* (emacs)Buffers:: 48 2230 /usr/gnu/info/emacs/emacs-1
|
||||
* (autoconf)Writing configure.in:: 123 58789 /usr/gnu/info/autoconf/autoconf-1
|
||||
* (dir)Top:: 40 589 /usr/gnu/info/dir
|
||||
*/
|
||||
static char *
|
||||
format_node_info (node)
|
||||
NODE *node;
|
||||
{
|
||||
register int i, len;
|
||||
char *parent, *containing_file;
|
||||
static char *line_buffer = (char *)NULL;
|
||||
|
||||
if (!line_buffer)
|
||||
line_buffer = (char *)xmalloc (1000);
|
||||
|
||||
if (node->parent)
|
||||
{
|
||||
parent = filename_non_directory (node->parent);
|
||||
if (!parent)
|
||||
parent = node->parent;
|
||||
}
|
||||
else
|
||||
parent = (char *)NULL;
|
||||
|
||||
containing_file = node->filename;
|
||||
|
||||
if (!parent && !*containing_file)
|
||||
sprintf (line_buffer, "* %s::", node->nodename);
|
||||
else
|
||||
{
|
||||
char *file = (char *)NULL;
|
||||
|
||||
if (parent)
|
||||
file = parent;
|
||||
else
|
||||
file = filename_non_directory (containing_file);
|
||||
|
||||
if (!file)
|
||||
file = containing_file;
|
||||
|
||||
if (!*file)
|
||||
file = "dir";
|
||||
|
||||
sprintf (line_buffer, "* (%s)%s::", file, node->nodename);
|
||||
}
|
||||
|
||||
len = pad_to (36, line_buffer);
|
||||
|
||||
{
|
||||
int lines = 1;
|
||||
|
||||
for (i = 0; i < node->nodelen; i++)
|
||||
if (node->contents[i] == '\n')
|
||||
lines++;
|
||||
|
||||
sprintf (line_buffer + len, "%d", lines);
|
||||
}
|
||||
|
||||
len = pad_to (44, line_buffer);
|
||||
sprintf (line_buffer + len, "%d", node->nodelen);
|
||||
|
||||
if (node->filename && *(node->filename))
|
||||
{
|
||||
len = pad_to (51, line_buffer);
|
||||
sprintf (line_buffer + len, node->filename);
|
||||
}
|
||||
|
||||
return (savestring (line_buffer));
|
||||
}
|
||||
|
||||
/* Little string comparison routine for qsort (). */
|
||||
static int
|
||||
compare_strings (string1, string2)
|
||||
char **string1, **string2;
|
||||
{
|
||||
return (stricmp (*string1, *string2));
|
||||
}
|
||||
|
||||
/* The name of the nodemenu node. */
|
||||
static char *nodemenu_nodename = "*Node Menu*";
|
||||
|
||||
/* Produce an informative listing of all the visited nodes, and return it
|
||||
in a node. If FILTER_FUNC is non-null, it is a function which filters
|
||||
which nodes will appear in the listing. FILTER_FUNC takes an argument
|
||||
of NODE, and returns non-zero if the node should appear in the listing. */
|
||||
NODE *
|
||||
get_visited_nodes (filter_func)
|
||||
Function *filter_func;
|
||||
{
|
||||
register int i, iw_index;
|
||||
INFO_WINDOW *info_win;
|
||||
NODE *node;
|
||||
char **lines = (char **)NULL;
|
||||
int lines_index = 0, lines_slots = 0;
|
||||
|
||||
if (!info_windows)
|
||||
return ((NODE *)NULL);
|
||||
|
||||
for (iw_index = 0; info_win = info_windows[iw_index]; iw_index++)
|
||||
{
|
||||
for (i = 0; i < info_win->nodes_index; i++)
|
||||
{
|
||||
node = info_win->nodes[i];
|
||||
|
||||
/* We skip mentioning "*Node Menu*" nodes. */
|
||||
if (internal_info_node_p (node) &&
|
||||
(strcmp (node->nodename, nodemenu_nodename) == 0))
|
||||
continue;
|
||||
|
||||
if (node && (!filter_func || (*filter_func) (node)))
|
||||
{
|
||||
char *line;
|
||||
|
||||
line = format_node_info (node);
|
||||
add_pointer_to_array
|
||||
(line, lines_index, lines, lines_slots, 20, char *);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Sort the array of information lines. */
|
||||
qsort (lines, lines_index, sizeof (char *), compare_strings);
|
||||
|
||||
/* Delete duplicates. */
|
||||
{
|
||||
register int j, newlen;
|
||||
char **temp;
|
||||
|
||||
for (i = 0, newlen = 1; i < lines_index - 1; i++)
|
||||
{
|
||||
if (strcmp (lines[i], lines[i + 1]) == 0)
|
||||
{
|
||||
free (lines[i]);
|
||||
lines[i] = (char *)NULL;
|
||||
}
|
||||
else
|
||||
newlen++;
|
||||
}
|
||||
|
||||
/* We have free ()'d and marked all of the duplicate slots. Copy the
|
||||
live slots rather than pruning the dead slots. */
|
||||
temp = (char **)xmalloc ((1 + newlen) * sizeof (char *));
|
||||
for (i = 0, j = 0; i < lines_index; i++)
|
||||
if (lines[i])
|
||||
temp[j++] = lines[i];
|
||||
|
||||
temp[j] = (char *)NULL;
|
||||
free (lines);
|
||||
lines = temp;
|
||||
lines_index = newlen;
|
||||
}
|
||||
|
||||
initialize_message_buffer ();
|
||||
printf_to_message_buffer
|
||||
("Here is a menu of nodes you could select with info-history-node:\n");
|
||||
printf_to_message_buffer ("%s\n", nodemenu_format_info ());
|
||||
for (i = 0; i < lines_index; i++)
|
||||
{
|
||||
printf_to_message_buffer ("%s\n", lines[i]);
|
||||
free (lines[i]);
|
||||
}
|
||||
free (lines);
|
||||
|
||||
node = message_buffer_to_node ();
|
||||
add_gcable_pointer (node->contents);
|
||||
return (node);
|
||||
}
|
||||
|
||||
DECLARE_INFO_COMMAND (list_visited_nodes,
|
||||
"Make a window containing a menu of all of the currently visited nodes")
|
||||
{
|
||||
WINDOW *new;
|
||||
NODE *node;
|
||||
|
||||
set_remembered_pagetop_and_point (window);
|
||||
|
||||
/* If a window is visible and showing the buffer list already, re-use it. */
|
||||
for (new = windows; new; new = new->next)
|
||||
{
|
||||
node = new->node;
|
||||
|
||||
if (internal_info_node_p (node) &&
|
||||
(strcmp (node->nodename, nodemenu_nodename) == 0))
|
||||
break;
|
||||
}
|
||||
|
||||
/* If we couldn't find an existing window, try to use the next window
|
||||
in the chain. */
|
||||
if (!new && window->next)
|
||||
new = window->next;
|
||||
|
||||
/* If we still don't have a window, make a new one to contain the list. */
|
||||
if (!new)
|
||||
{
|
||||
WINDOW *old_active;
|
||||
|
||||
old_active = active_window;
|
||||
active_window = window;
|
||||
new = window_make_window ((NODE *)NULL);
|
||||
active_window = old_active;
|
||||
}
|
||||
|
||||
/* If we couldn't make a new window, use this one. */
|
||||
if (!new)
|
||||
new = window;
|
||||
|
||||
/* Lines do not wrap in this window. */
|
||||
new->flags |= W_NoWrap;
|
||||
node = get_visited_nodes ((Function *)NULL);
|
||||
name_internal_node (node, nodemenu_nodename);
|
||||
|
||||
/* Even if this is an internal node, we don't want the window
|
||||
system to treat it specially. So we turn off the internalness
|
||||
of it here. */
|
||||
node->flags &= ~N_IsInternal;
|
||||
|
||||
/* If this window is already showing a node menu, reuse the existing node
|
||||
slot. */
|
||||
{
|
||||
int remember_me = 1;
|
||||
|
||||
#if defined (NOTDEF)
|
||||
if (internal_info_node_p (new->node) &&
|
||||
(strcmp (new->node->nodename, nodemenu_nodename) == 0))
|
||||
remember_me = 0;
|
||||
#endif /* NOTDEF */
|
||||
|
||||
window_set_node_of_window (new, node);
|
||||
|
||||
if (remember_me)
|
||||
remember_window_and_node (new, node);
|
||||
}
|
||||
|
||||
active_window = new;
|
||||
}
|
||||
|
||||
DECLARE_INFO_COMMAND (select_visited_node,
|
||||
"Select a node which has been previously visited in a visible window")
|
||||
{
|
||||
char *line;
|
||||
NODE *node;
|
||||
REFERENCE **menu;
|
||||
|
||||
node = get_visited_nodes ((Function *)NULL);
|
||||
|
||||
menu = info_menu_of_node (node);
|
||||
free (node);
|
||||
|
||||
line =
|
||||
info_read_completing_in_echo_area (window, "Select visited node: ", menu);
|
||||
|
||||
window = active_window;
|
||||
|
||||
/* User aborts, just quit. */
|
||||
if (!line)
|
||||
{
|
||||
info_abort_key (window, 0, 0);
|
||||
info_free_references (menu);
|
||||
return;
|
||||
}
|
||||
|
||||
if (*line)
|
||||
{
|
||||
REFERENCE *entry;
|
||||
|
||||
/* Find the selected label in the references. */
|
||||
entry = info_get_labeled_reference (line, menu);
|
||||
|
||||
if (!entry)
|
||||
info_error ("The reference disappeared! (%s).", line);
|
||||
else
|
||||
info_select_reference (window, entry);
|
||||
}
|
||||
|
||||
free (line);
|
||||
info_free_references (menu);
|
||||
|
||||
if (!info_error_was_printed)
|
||||
window_clear_echo_area ();
|
||||
}
|
1167
gnu/usr.bin/texinfo/info/nodes.c
Normal file
1167
gnu/usr.bin/texinfo/info/nodes.c
Normal file
File diff suppressed because it is too large
Load Diff
164
gnu/usr.bin/texinfo/info/nodes.h
Normal file
164
gnu/usr.bin/texinfo/info/nodes.h
Normal file
@ -0,0 +1,164 @@
|
||||
/* nodes.h -- How we represent nodes internally. */
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#ifndef _NODES_H_
|
||||
#define _NODES_H_
|
||||
|
||||
#include "general.h"
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* User Code Interface */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Callers generally only want the node itself. This structure is used
|
||||
to pass node information around. None of the information in this
|
||||
structure should ever be directly freed. The structure itself can
|
||||
be passed to free (). Note that NODE->parent is non-null if this
|
||||
node's file is a subfile. In that case, NODE->parent is the logical
|
||||
name of the file containing this node. Both names are given as full
|
||||
paths, so you might have: node->filename = "/usr/gnu/info/emacs-1",
|
||||
with node->parent = "/usr/gnu/info/emacs". */
|
||||
typedef struct {
|
||||
char *filename; /* The physical file containing this node. */
|
||||
char *parent; /* Non-null is the logical file name. */
|
||||
char *nodename; /* The name of this node. */
|
||||
char *contents; /* Characters appearing in this node. */
|
||||
long nodelen; /* The length of the CONTENTS member. */
|
||||
int flags; /* See immediately below. */
|
||||
} NODE;
|
||||
|
||||
/* Defines that can appear in NODE->flags. All informative. */
|
||||
#define N_HasTagsTable 0x01 /* This node was found through a tags table. */
|
||||
#define N_TagsIndirect 0x02 /* The tags table was an indirect one. */
|
||||
#define N_UpdateTags 0x04 /* The tags table is out of date. */
|
||||
#define N_IsCompressed 0x08 /* The file is compressed on disk. */
|
||||
#define N_IsInternal 0x10 /* This node was made by Info. */
|
||||
#define N_CannotGC 0x20 /* File buffer cannot be gc'ed. */
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Internal Data Structures */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Some defines describing details about Info file contents. */
|
||||
|
||||
/* String Constants. */
|
||||
#define INFO_FILE_LABEL "File:"
|
||||
#define INFO_NODE_LABEL "Node:"
|
||||
#define INFO_PREV_LABEL "Prev:"
|
||||
#define INFO_ALTPREV_LABEL "Previous:"
|
||||
#define INFO_NEXT_LABEL "Next:"
|
||||
#define INFO_UP_LABEL "Up:"
|
||||
#define INFO_MENU_LABEL "\n* Menu:"
|
||||
#define INFO_MENU_ENTRY_LABEL "\n* "
|
||||
#define INFO_XREF_LABEL "*Note"
|
||||
#define TAGS_TABLE_END_LABEL "\nEnd Tag Table"
|
||||
#define TAGS_TABLE_BEG_LABEL "Tag Table:\n"
|
||||
#define INDIRECT_TAGS_TABLE_LABEL "Indirect:\n"
|
||||
#define TAGS_TABLE_IS_INDIRECT_LABEL "(Indirect)"
|
||||
|
||||
/* Character Constants. */
|
||||
#define INFO_COOKIE '\037'
|
||||
#define INFO_FF '\014'
|
||||
#define INFO_TAGSEP '\177'
|
||||
|
||||
/* For each logical file that we have loaded, we keep a list of the names
|
||||
of the nodes that are found in that file. A pointer to a node in an
|
||||
info file is called a "tag". For split files, the tag pointer is
|
||||
"indirect"; that is, the pointer also contains the name of the split
|
||||
file where the node can be found. For non-split files, the filename
|
||||
member in the structure below simply contains the name of the current
|
||||
file. The following structure describes a single node within a file. */
|
||||
typedef struct {
|
||||
char *filename; /* The file where this node can be found. */
|
||||
char *nodename; /* The node pointed to by this tag. */
|
||||
long nodestart; /* The offset of the start of this node. */
|
||||
long nodelen; /* The length of this node. */
|
||||
} TAG;
|
||||
|
||||
/* The following structure is used to remember information about the contents
|
||||
of Info files that we have loaded at least once before. The FINFO member
|
||||
is present so that we can reload the file if it has been modified since
|
||||
last being loaded. All of the arrays appearing within this structure
|
||||
are NULL terminated, and each array which can change size has a
|
||||
corresponding SLOTS member which says how many slots have been allocated
|
||||
(with malloc ()) for this array. */
|
||||
typedef struct {
|
||||
char *filename; /* The filename used to find this file. */
|
||||
char *fullpath; /* The full pathname of this info file. */
|
||||
struct stat finfo; /* Information about this file. */
|
||||
char *contents; /* The contents of this particular file. */
|
||||
long filesize; /* The number of bytes this file expands to. */
|
||||
char **subfiles; /* If non-null, the list of subfiles. */
|
||||
TAG **tags; /* If non-null, the indirect tags table. */
|
||||
int tags_slots; /* Number of slots allocated for TAGS. */
|
||||
int flags; /* Various flags. Mimics of N_* flags. */
|
||||
} FILE_BUFFER;
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Externally Visible Functions */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Array of FILE_BUFFER * which represents the currently loaded info files. */
|
||||
extern FILE_BUFFER **info_loaded_files;
|
||||
|
||||
/* The number of slots currently allocated to INFO_LOADED_FILES. */
|
||||
extern int info_loaded_files_slots;
|
||||
|
||||
/* Locate the file named by FILENAME, and return the information structure
|
||||
describing this file. The file may appear in our list of loaded files
|
||||
already, or it may not. If it does not already appear, find the file,
|
||||
and add it to the list of loaded files. If the file cannot be found,
|
||||
return a NULL FILE_BUFFER *. */
|
||||
extern FILE_BUFFER *info_find_file ();
|
||||
|
||||
/* Force load the file named FILENAME, and return the information structure
|
||||
describing this file. Even if the file was already loaded, this loads
|
||||
a new buffer, rebuilds tags and nodes, and returns a new FILE_BUFFER *. */
|
||||
extern FILE_BUFFER *info_load_file ();
|
||||
|
||||
/* Return a pointer to a NODE structure for the Info node (FILENAME)NODENAME.
|
||||
FILENAME can be passed as NULL, in which case the filename of "dir" is used.
|
||||
NODENAME can be passed as NULL, in which case the nodename of "Top" is used.
|
||||
If the node cannot be found, return a NULL pointer. */
|
||||
extern NODE *info_get_node ();
|
||||
|
||||
/* Return a pointer to a NODE structure for the Info node NODENAME in
|
||||
FILE_BUFFER. NODENAME can be passed as NULL, in which case the
|
||||
nodename of "Top" is used. If the node cannot be found, return a
|
||||
NULL pointer. */
|
||||
extern NODE *info_get_node_of_file_buffer ();
|
||||
|
||||
/* Grovel FILE_BUFFER->contents finding tags and nodes, and filling in the
|
||||
various slots. This can also be used to rebuild a tag or node table. */
|
||||
extern void build_tags_and_nodes ();
|
||||
|
||||
/* When non-zero, this is a string describing the most recent file error. */
|
||||
extern char *info_recent_file_error;
|
||||
|
||||
#endif /* !_NODES_H_ */
|
566
gnu/usr.bin/texinfo/info/search.c
Normal file
566
gnu/usr.bin/texinfo/info/search.c
Normal file
@ -0,0 +1,566 @@
|
||||
/* search.c -- How to search large bodies of text. */
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include "general.h"
|
||||
#include "search.h"
|
||||
#include "nodes.h"
|
||||
|
||||
#if !defined (NULL)
|
||||
# define NULL 0x0
|
||||
#endif /* !NULL */
|
||||
|
||||
/* The search functions take two arguments:
|
||||
|
||||
1) a string to search for, and
|
||||
|
||||
2) a pointer to a SEARCH_BINDING which contains the buffer, start,
|
||||
and end of the search.
|
||||
|
||||
They return a long, which is the offset from the start of the buffer
|
||||
at which the match was found. An offset of -1 indicates failure. */
|
||||
|
||||
/* A function which makes a binding with buffer and bounds. */
|
||||
SEARCH_BINDING *
|
||||
make_binding (buffer, start, end)
|
||||
char *buffer;
|
||||
long start, end;
|
||||
{
|
||||
SEARCH_BINDING *binding;
|
||||
|
||||
binding = (SEARCH_BINDING *)xmalloc (sizeof (SEARCH_BINDING));
|
||||
binding->buffer = buffer;
|
||||
binding->start = start;
|
||||
binding->end = end;
|
||||
binding->flags = 0;
|
||||
|
||||
return (binding);
|
||||
}
|
||||
|
||||
/* Make a copy of BINDING without duplicating the data. */
|
||||
SEARCH_BINDING *
|
||||
copy_binding (binding)
|
||||
SEARCH_BINDING *binding;
|
||||
{
|
||||
SEARCH_BINDING *copy;
|
||||
|
||||
copy = make_binding (binding->buffer, binding->start, binding->end);
|
||||
copy->flags = binding->flags;
|
||||
return (copy);
|
||||
}
|
||||
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* The Actual Searching Functions */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Search forwards or backwards for the text delimited by BINDING.
|
||||
The search is forwards if BINDING->start is greater than BINDING->end. */
|
||||
long
|
||||
search (string, binding)
|
||||
char *string;
|
||||
SEARCH_BINDING *binding;
|
||||
{
|
||||
long result;
|
||||
|
||||
/* If the search is backwards, then search backwards, otherwise forwards. */
|
||||
if (binding->start > binding->end)
|
||||
result = search_backward (string, binding);
|
||||
else
|
||||
result = search_forward (string, binding);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
/* Search forwards for STRING through the text delimited in BINDING. */
|
||||
long
|
||||
search_forward (string, binding)
|
||||
char *string;
|
||||
SEARCH_BINDING *binding;
|
||||
{
|
||||
register int c, i, len;
|
||||
register char *buff, *end;
|
||||
char *alternate = (char *)NULL;
|
||||
|
||||
len = strlen (string);
|
||||
|
||||
/* We match characters in the search buffer against STRING and ALTERNATE.
|
||||
ALTERNATE is a case reversed version of STRING; this is cheaper than
|
||||
case folding each character before comparison. Alternate is only
|
||||
used if the case folding bit is turned on in the passed BINDING. */
|
||||
|
||||
if (binding->flags & S_FoldCase)
|
||||
{
|
||||
alternate = savestring (string);
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
if (islower (alternate[i]))
|
||||
alternate[i] = toupper (alternate[i]);
|
||||
else if (isupper (alternate[i]))
|
||||
alternate[i] = tolower (alternate[i]);
|
||||
}
|
||||
}
|
||||
|
||||
buff = binding->buffer + binding->start;
|
||||
end = binding->buffer + binding->end + 1;
|
||||
|
||||
while (buff < (end - len))
|
||||
{
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
c = buff[i];
|
||||
|
||||
if ((c != string[i]) && (!alternate || c != alternate[i]))
|
||||
break;
|
||||
}
|
||||
|
||||
if (!string[i])
|
||||
{
|
||||
if (alternate)
|
||||
free (alternate);
|
||||
if (binding->flags & S_SkipDest)
|
||||
buff += len;
|
||||
return ((long) (buff - binding->buffer));
|
||||
}
|
||||
|
||||
buff++;
|
||||
}
|
||||
|
||||
if (alternate)
|
||||
free (alternate);
|
||||
|
||||
return ((long) -1);
|
||||
}
|
||||
|
||||
/* Search for STRING backwards through the text delimited in BINDING. */
|
||||
long
|
||||
search_backward (input_string, binding)
|
||||
char *input_string;
|
||||
SEARCH_BINDING *binding;
|
||||
{
|
||||
register int c, i, len;
|
||||
register char *buff, *end;
|
||||
char *string;
|
||||
char *alternate = (char *)NULL;
|
||||
|
||||
len = strlen (input_string);
|
||||
|
||||
/* Reverse the characters in the search string. */
|
||||
string = (char *)xmalloc (1 + len);
|
||||
for (c = 0, i = len - 1; input_string[c]; c++, i--)
|
||||
string[i] = input_string[c];
|
||||
|
||||
string[c] = '\0';
|
||||
|
||||
/* We match characters in the search buffer against STRING and ALTERNATE.
|
||||
ALTERNATE is a case reversed version of STRING; this is cheaper than
|
||||
case folding each character before comparison. ALTERNATE is only
|
||||
used if the case folding bit is turned on in the passed BINDING. */
|
||||
|
||||
if (binding->flags & S_FoldCase)
|
||||
{
|
||||
alternate = savestring (string);
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
if (islower (alternate[i]))
|
||||
alternate[i] = toupper (alternate[i]);
|
||||
else if (isupper (alternate[i]))
|
||||
alternate[i] = tolower (alternate[i]);
|
||||
}
|
||||
}
|
||||
|
||||
buff = binding->buffer + binding->start;
|
||||
end = binding->buffer + binding->end;
|
||||
|
||||
while (buff > end + len)
|
||||
{
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
c = *(buff - i);
|
||||
|
||||
if (c != string[i] && (alternate && c != alternate[i]))
|
||||
break;
|
||||
}
|
||||
|
||||
if (!string[i])
|
||||
{
|
||||
free (string);
|
||||
if (alternate)
|
||||
free (alternate);
|
||||
|
||||
if (binding->flags & S_SkipDest)
|
||||
buff -= len;
|
||||
return ((long) (1 + (buff - binding->buffer)));
|
||||
}
|
||||
|
||||
buff--;
|
||||
}
|
||||
|
||||
free (string);
|
||||
if (alternate)
|
||||
free (alternate);
|
||||
|
||||
return ((long) -1);
|
||||
}
|
||||
|
||||
/* Find STRING in LINE, returning the offset of the end of the string.
|
||||
Return an offset of -1 if STRING does not appear in LINE. The search
|
||||
is bound by the end of the line (i.e., either NEWLINE or 0). */
|
||||
int
|
||||
string_in_line (string, line)
|
||||
char *string, *line;
|
||||
{
|
||||
register int end;
|
||||
SEARCH_BINDING binding;
|
||||
|
||||
/* Find the end of the line. */
|
||||
for (end = 0; line[end] && line[end] != '\n'; end++);
|
||||
|
||||
/* Search for STRING within these confines. */
|
||||
binding.buffer = line;
|
||||
binding.start = 0;
|
||||
binding.end = end;
|
||||
binding.flags = S_FoldCase | S_SkipDest;
|
||||
|
||||
return (search_forward (string, &binding));
|
||||
}
|
||||
|
||||
/* Return non-zero if STRING is the first text to appear at BINDING. */
|
||||
int
|
||||
looking_at (string, binding)
|
||||
char *string;
|
||||
SEARCH_BINDING *binding;
|
||||
{
|
||||
long search_end;
|
||||
|
||||
search_end = search (string, binding);
|
||||
|
||||
/* If the string was not found, SEARCH_END is -1. If the string was found,
|
||||
but not right away, SEARCH_END is != binding->start. Otherwise, the
|
||||
string was found at binding->start. */
|
||||
return (search_end == binding->start);
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Small String Searches */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Function names that start with "skip" are passed a string, and return
|
||||
an offset from the start of that string. Function names that start
|
||||
with "find" are passed a SEARCH_BINDING, and return an absolute position
|
||||
marker of the item being searched for. "Find" functions return a value
|
||||
of -1 if the item being looked for couldn't be found. */
|
||||
|
||||
/* Return the index of the first non-whitespace character in STRING. */
|
||||
int
|
||||
skip_whitespace (string)
|
||||
char *string;
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; string && whitespace (string[i]); i++);
|
||||
return (i);
|
||||
}
|
||||
|
||||
/* Return the index of the first non-whitespace or newline character in
|
||||
STRING. */
|
||||
int
|
||||
skip_whitespace_and_newlines (string)
|
||||
char *string;
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; string && (whitespace (string[i]) || string[i] == '\n'); i++);
|
||||
return (i);
|
||||
}
|
||||
|
||||
/* Return the index of the first whitespace character in STRING. */
|
||||
int
|
||||
skip_non_whitespace (string)
|
||||
char *string;
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; string && !whitespace (string[i]); i++);
|
||||
return (i);
|
||||
}
|
||||
|
||||
/* Return the index of the first non-node character in STRING. Note that
|
||||
this function contains quite a bit of hair to ignore periods in some
|
||||
special cases. This is because we here at GNU ship some info files which
|
||||
contain nodenames that contain periods. No such nodename can start with
|
||||
a period, or continue with whitespace, newline, or ')' immediately following
|
||||
the period. If second argument NEWLINES_OKAY is non-zero, newlines should
|
||||
be skipped while parsing out the nodename specification. */
|
||||
int
|
||||
skip_node_characters (string, newlines_okay)
|
||||
char *string;
|
||||
int newlines_okay;
|
||||
{
|
||||
register int c, i = 0;
|
||||
int paren_seen = 0;
|
||||
int paren = 0;
|
||||
|
||||
/* Handle special case. This is when another function has parsed out the
|
||||
filename component of the node name, and we just want to parse out the
|
||||
nodename proper. In that case, a period at the start of the nodename
|
||||
indicates an empty nodename. */
|
||||
if (string && *string == '.')
|
||||
return (0);
|
||||
|
||||
if (string && *string == '(')
|
||||
{
|
||||
paren++;
|
||||
paren_seen++;
|
||||
i++;
|
||||
}
|
||||
|
||||
for (; string && (c = string[i]); i++)
|
||||
{
|
||||
if (paren)
|
||||
{
|
||||
if (c == '(')
|
||||
paren++;
|
||||
else if (c == ')')
|
||||
paren--;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If the character following the close paren is a space or period,
|
||||
then this node name has no more characters associated with it. */
|
||||
if (c == '\t' ||
|
||||
c == ',' ||
|
||||
c == INFO_TAGSEP ||
|
||||
((!newlines_okay) && (c == '\n')) ||
|
||||
((paren_seen && string[i - 1] == ')') &&
|
||||
(c == ' ' || c == '.')) ||
|
||||
(c == '.' &&
|
||||
((!string[i + 1]) ||
|
||||
(whitespace_or_newline (string[i + 1])) ||
|
||||
(string[i + 1] == ')'))))
|
||||
break;
|
||||
}
|
||||
return (i);
|
||||
}
|
||||
|
||||
/* Unix doesn't have stricmp () functions. */
|
||||
int
|
||||
stricmp (string1, string2)
|
||||
char *string1, *string2;
|
||||
{
|
||||
char ch1, ch2;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
ch1 = *string1++;
|
||||
ch2 = *string2++;
|
||||
|
||||
if (!(ch1 | ch2))
|
||||
return (0);
|
||||
|
||||
ch1 = info_toupper (ch1);
|
||||
ch2 = info_toupper (ch2);
|
||||
|
||||
if (ch1 != ch2)
|
||||
return (ch1 - ch2);
|
||||
}
|
||||
}
|
||||
|
||||
/* Compare at most COUNT characters from string1 to string2. Case
|
||||
doesn't matter. */
|
||||
int
|
||||
strnicmp (string1, string2, count)
|
||||
char *string1, *string2;
|
||||
int count;
|
||||
{
|
||||
register char ch1, ch2;
|
||||
|
||||
while (count)
|
||||
{
|
||||
ch1 = *string1++;
|
||||
ch2 = *string2++;
|
||||
|
||||
ch1 = info_toupper (ch1);
|
||||
ch2 = info_toupper (ch2);
|
||||
|
||||
if (ch1 == ch2)
|
||||
count--;
|
||||
else
|
||||
break;
|
||||
}
|
||||
return (count);
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Searching FILE_BUFFER's */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Return the absolute position of the first occurence of a node separator in
|
||||
BINDING-buffer. The search starts at BINDING->start. Return -1 if no node
|
||||
separator was found. */
|
||||
long
|
||||
find_node_separator (binding)
|
||||
SEARCH_BINDING *binding;
|
||||
{
|
||||
register long i;
|
||||
char *body;
|
||||
|
||||
body = binding->buffer;
|
||||
|
||||
/* A node is started by [^L]^_[^L]\n. That is to say, the C-l's are
|
||||
optional, but the DELETE and NEWLINE are not. This separator holds
|
||||
true for all separated elements in an Info file, including the tags
|
||||
table (if present) and the indirect tags table (if present). */
|
||||
for (i = binding->start; i < binding->end - 1; i++)
|
||||
if (((body[i] == INFO_FF && body[i + 1] == INFO_COOKIE) &&
|
||||
(body[i + 2] == '\n' ||
|
||||
(body[i + 2] == INFO_FF && body[i + 3] == '\n'))) ||
|
||||
((body[i] == INFO_COOKIE) &&
|
||||
(body[i + 1] == '\n' ||
|
||||
(body[i + 1] == INFO_FF && body[i + 2] == '\n'))))
|
||||
return (i);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* Return the length of the node separator characters that BODY is
|
||||
currently pointing at. */
|
||||
int
|
||||
skip_node_separator (body)
|
||||
char *body;
|
||||
{
|
||||
register int i;
|
||||
|
||||
i = 0;
|
||||
|
||||
if (body[i] == INFO_FF)
|
||||
i++;
|
||||
|
||||
if (body[i++] != INFO_COOKIE)
|
||||
return (0);
|
||||
|
||||
if (body[i] == INFO_FF)
|
||||
i++;
|
||||
|
||||
if (body[i++] != '\n')
|
||||
return (0);
|
||||
|
||||
return (i);
|
||||
}
|
||||
|
||||
/* Return the number of characters from STRING to the start of
|
||||
the next line. */
|
||||
int
|
||||
skip_line (string)
|
||||
char *string;
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; string && string[i] && string[i] != '\n'; i++);
|
||||
|
||||
if (string[i] == '\n')
|
||||
i++;
|
||||
|
||||
return (i);
|
||||
}
|
||||
|
||||
/* Return the absolute position of the beginning of a tags table in this
|
||||
binding starting the search at binding->start. */
|
||||
long
|
||||
find_tags_table (binding)
|
||||
SEARCH_BINDING *binding;
|
||||
{
|
||||
SEARCH_BINDING search;
|
||||
long position;
|
||||
|
||||
search.buffer = binding->buffer;
|
||||
search.start = binding->start;
|
||||
search.end = binding->end;
|
||||
search.flags = S_FoldCase;
|
||||
|
||||
while ((position = find_node_separator (&search)) != -1 )
|
||||
{
|
||||
search.start = position;
|
||||
search.start += skip_node_separator (search.buffer + search.start);
|
||||
|
||||
if (looking_at (TAGS_TABLE_BEG_LABEL, &search))
|
||||
return (position);
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* Return the absolute position of the node named NODENAME in BINDING.
|
||||
This is a brute force search, and we wish to avoid it when possible.
|
||||
This function is called when a tag (indirect or otherwise) doesn't
|
||||
really point to the right node. It returns the absolute position of
|
||||
the separator preceding the node. */
|
||||
long
|
||||
find_node_in_binding (nodename, binding)
|
||||
char *nodename;
|
||||
SEARCH_BINDING *binding;
|
||||
{
|
||||
register long position;
|
||||
register int offset, namelen;
|
||||
SEARCH_BINDING search;
|
||||
|
||||
namelen = strlen (nodename);
|
||||
|
||||
search.buffer = binding->buffer;
|
||||
search.start = binding->start;
|
||||
search.end = binding->end;
|
||||
search.flags = 0;
|
||||
|
||||
while ((position = find_node_separator (&search)) != -1)
|
||||
{
|
||||
search.start = position;
|
||||
search.start += skip_node_separator (search.buffer + search.start);
|
||||
|
||||
offset = string_in_line (INFO_NODE_LABEL, search.buffer + search.start);
|
||||
|
||||
if (offset == -1)
|
||||
continue;
|
||||
|
||||
search.start += offset;
|
||||
search.start += skip_whitespace (search.buffer + search.start);
|
||||
offset = skip_node_characters
|
||||
(search.buffer + search.start, DONT_SKIP_NEWLINES);
|
||||
|
||||
/* Notice that this is an exact match. You cannot grovel through
|
||||
the buffer with this function looking for random nodes. */
|
||||
if ((offset == namelen) &&
|
||||
(search.buffer[search.start] == nodename[0]) &&
|
||||
(strncmp (search.buffer + search.start, nodename, offset) == 0))
|
||||
return (position);
|
||||
}
|
||||
return (-1);
|
||||
}
|
78
gnu/usr.bin/texinfo/info/search.h
Normal file
78
gnu/usr.bin/texinfo/info/search.h
Normal file
@ -0,0 +1,78 @@
|
||||
/* search.h -- Structure used to search large bodies of text, with bounds. */
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
/* The search functions take two arguments:
|
||||
|
||||
1) a string to search for, and
|
||||
|
||||
2) a pointer to a SEARCH_BINDING which contains the buffer, start,
|
||||
and end of the search.
|
||||
|
||||
They return a long, which is the offset from the start of the buffer
|
||||
at which the match was found. An offset of -1 indicates failure. */
|
||||
|
||||
#ifndef _SEARCH_H_
|
||||
#define _SEARCH_H_
|
||||
|
||||
typedef struct {
|
||||
char *buffer; /* The buffer of text to search. */
|
||||
long start; /* Offset of the start of the search. */
|
||||
long end; /* Offset of the end of the searh. */
|
||||
int flags; /* Flags controlling the type of search. */
|
||||
} SEARCH_BINDING;
|
||||
|
||||
#define S_FoldCase 0x01 /* Set means fold case in searches. */
|
||||
#define S_SkipDest 0x02 /* Set means return pointing after the dest. */
|
||||
|
||||
SEARCH_BINDING *make_binding (), *copy_binding ();
|
||||
extern long search_forward (), search_backward (), search ();
|
||||
extern int looking_at ();
|
||||
|
||||
/* Note that STRING_IN_LINE () always returns the offset of the 1st character
|
||||
after the string. */
|
||||
extern int string_in_line ();
|
||||
|
||||
/* Unix doesn't have stricmp () functions. */
|
||||
/* strcmp (), but caseless. */
|
||||
extern int stricmp ();
|
||||
|
||||
/* Compare at most COUNT characters from STRING1 to STRING2. Case
|
||||
doesn't matter. */
|
||||
extern int strnicmp ();
|
||||
|
||||
/* Function names that start with "skip" are passed a string, and return
|
||||
an offset from the start of that string. Function names that start
|
||||
with "find" are passed a SEARCH_BINDING, and return an absolute position
|
||||
marker of the item being searched for. "Find" functions return a value
|
||||
of -1 if the item being looked for couldn't be found. */
|
||||
extern int skip_whitespace (), skip_non_whitespace ();
|
||||
extern int skip_whitespace_and_newlines (), skip_line ();
|
||||
extern int skip_node_characters (), skip_node_separator ();
|
||||
#define DONT_SKIP_NEWLINES 0
|
||||
#define SKIP_NEWLINES 1
|
||||
|
||||
extern long find_node_separator (), find_tags_table ();
|
||||
extern long find_node_in_binding ();
|
||||
|
||||
#endif /* !_SEARCH_H_ */
|
||||
|
4167
gnu/usr.bin/texinfo/info/session.c
Normal file
4167
gnu/usr.bin/texinfo/info/session.c
Normal file
File diff suppressed because it is too large
Load Diff
146
gnu/usr.bin/texinfo/info/session.h
Normal file
146
gnu/usr.bin/texinfo/info/session.h
Normal file
@ -0,0 +1,146 @@
|
||||
/* session.h -- Functions found in session.c. */
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#ifndef _SESSION_H_
|
||||
#define _SESSION_H_
|
||||
|
||||
#include "general.h"
|
||||
#include "dribble.h"
|
||||
|
||||
/* All commands that can be invoked from within info_session () receive
|
||||
arguments in the same way. This simple define declares the header
|
||||
of a function named NAME, with associated documentation DOC. The
|
||||
documentation string is groveled out of the source files by the
|
||||
utility program `builddoc', which is also responsible for making
|
||||
the documentation/function-pointer maps. */
|
||||
#define DECLARE_INFO_COMMAND(name, doc) \
|
||||
void name (window, count, key) WINDOW *window; int count; unsigned char key;
|
||||
|
||||
/* Variables found in session.h. */
|
||||
extern VFunction *info_last_executed_command;
|
||||
|
||||
/* Variable controlling the garbage collection of files briefly visited
|
||||
during searches. Such files are normally gc'ed, unless they were
|
||||
compressed to begin with. If this variable is non-zero, it says
|
||||
to gc even those file buffer contents which had to be uncompressed. */
|
||||
extern int gc_compressed_files;
|
||||
|
||||
/* When non-zero, tiling takes place automatically when info_split_window
|
||||
is called. */
|
||||
extern int auto_tiling_p;
|
||||
|
||||
/* Variable controlling the behaviour of default scrolling when you are
|
||||
already at the bottom of a node. */
|
||||
extern int info_scroll_behaviour;
|
||||
extern char *info_scroll_choices[];
|
||||
|
||||
/* Values for info_scroll_behaviour. */
|
||||
#define IS_Continuous 0 /* Try to get first menu item, or failing that, the
|
||||
"Next:" pointer, or failing that, the "Up:" and
|
||||
"Next:" of the up. */
|
||||
#define IS_NextOnly 1 /* Try to get "Next:" menu item. */
|
||||
#define IS_PageOnly 2 /* Simply give up at the bottom of a node. */
|
||||
|
||||
/* Utility functions found in session.c */
|
||||
extern void info_dispatch_on_key ();
|
||||
extern unsigned char info_get_input_char (), info_get_another_input_char ();
|
||||
extern unsigned char info_input_pending_p ();
|
||||
extern void remember_window_and_node (), set_remembered_pagetop_and_point ();
|
||||
extern void set_window_pagetop (), info_set_node_of_window ();
|
||||
extern char *pretty_keyseq ();
|
||||
extern void initialize_keyseq (), add_char_to_keyseq ();
|
||||
extern void info_gather_typeahead ();
|
||||
extern FILE_BUFFER *file_buffer_of_window ();
|
||||
extern long info_search_in_node (), info_target_search_node ();
|
||||
extern void info_select_reference ();
|
||||
extern int info_any_buffered_input_p ();
|
||||
extern void print_node ();
|
||||
extern void dump_node_to_file (), dump_nodes_to_file ();
|
||||
|
||||
/* Do the physical deletion of WINDOW, and forget this window and
|
||||
associated nodes. */
|
||||
extern void info_delete_window_internal ();
|
||||
|
||||
/* Tell Info that input is coming from the file FILENAME. */
|
||||
extern void info_set_input_from_file ();
|
||||
|
||||
#define return_if_control_g(val) \
|
||||
do { \
|
||||
info_gather_typeahead (); \
|
||||
if (info_input_pending_p () == Control ('g')) \
|
||||
return (val); \
|
||||
} while (0)
|
||||
|
||||
/* The names of the functions that run an info session. */
|
||||
|
||||
/* Starting an info session. */
|
||||
extern void begin_multiple_window_info_session (), begin_info_session ();
|
||||
extern void begin_info_session_with_error (), info_session ();
|
||||
extern void info_read_and_dispatch ();
|
||||
|
||||
/* Moving the point within a node. */
|
||||
extern void info_next_line (), info_prev_line ();
|
||||
extern void info_end_of_line (), info_beginning_of_line ();
|
||||
extern void info_forward_char (), info_backward_char ();
|
||||
extern void info_forward_word (), info_backward_word ();
|
||||
extern void info_beginning_of_node (), info_end_of_node ();
|
||||
extern void info_move_to_prev_xref (), info_move_to_next_xref ();
|
||||
|
||||
/* Scrolling text within a window. */
|
||||
extern void info_scroll_forward (), info_scroll_backward ();
|
||||
extern void info_redraw_display (), info_toggle_wrap ();
|
||||
extern void info_move_to_window_line ();
|
||||
|
||||
/* Manipulating multiple windows. */
|
||||
extern void info_split_window (), info_delete_window ();
|
||||
extern void info_keep_one_window (), info_grow_window ();
|
||||
extern void info_scroll_other_window (), info_tile_windows ();
|
||||
extern void info_next_window (), info_prev_window ();
|
||||
|
||||
/* Selecting nodes. */
|
||||
extern void info_next_node (), info_prev_node (), info_up_node ();
|
||||
extern void info_last_node (), info_first_node (), info_history_node ();
|
||||
extern void info_goto_node (), info_top_node (), info_dir_node ();
|
||||
extern void info_global_next_node (), info_global_prev_node ();
|
||||
extern void info_kill_node (), info_view_file ();
|
||||
|
||||
/* Selecting cross references. */
|
||||
extern void info_menu_digit (), info_menu_item (), info_xref_item ();
|
||||
extern void info_find_menu (), info_select_reference_this_line ();
|
||||
|
||||
/* Hacking numeric arguments. */
|
||||
extern int info_explicit_arg, info_numeric_arg, info_numeric_arg_sign;
|
||||
|
||||
extern void info_add_digit_to_numeric_arg (), info_universal_argument ();
|
||||
extern void info_initialize_numeric_arg (), info_numeric_arg_digit_loop ();
|
||||
|
||||
/* Searching commands. */
|
||||
extern void info_search (), isearch_forward (), isearch_backward ();
|
||||
|
||||
/* Dumping and printing nodes. */
|
||||
extern void info_print_node ();
|
||||
|
||||
/* Miscellaneous commands. */
|
||||
extern void info_abort_key (), info_quit (), info_do_lowercase_version ();
|
||||
|
||||
#endif /* _SESSION_H_ */
|
177
gnu/usr.bin/texinfo/info/signals.c
Normal file
177
gnu/usr.bin/texinfo/info/signals.c
Normal file
@ -0,0 +1,177 @@
|
||||
/* signals.c -- Install and maintain Info signal handlers. */
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#include "info.h"
|
||||
#include "signals.h"
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Pretending That We Have POSIX Signals */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
#if !defined (_POSIX_VERSION)
|
||||
/* Perform OPERATION on NEWSET, perhaps leaving information in OLDSET. */
|
||||
static void
|
||||
sigprocmask (operation, newset, oldset)
|
||||
int operation, *newset, *oldset;
|
||||
{
|
||||
switch (operation)
|
||||
{
|
||||
case SIG_UNBLOCK:
|
||||
#if defined (HAVE_SIGSETMASK)
|
||||
sigsetmask (sigblock (0) & ~(*newset));
|
||||
#endif /* HAVE_SIGSETMASK */
|
||||
break;
|
||||
|
||||
case SIG_BLOCK:
|
||||
*oldset = sigblock (*newset);
|
||||
break;
|
||||
|
||||
case SIG_SETMASK:
|
||||
#if defined (HAVE_SIGSETMASK)
|
||||
sigsetmask (*newset);
|
||||
#endif /* HAVE_SIGSETMASK */
|
||||
break;
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
#endif /* !_POSIX_VERSION */
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Signal Handling for Info */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
typedef void SigHandlerType;
|
||||
typedef SigHandlerType SigHandler ();
|
||||
|
||||
static SigHandlerType info_signal_handler ();
|
||||
static SigHandler *old_TSTP, *old_TTOU, *old_TTIN;
|
||||
static SigHandler *old_WINCH, *old_INT;
|
||||
|
||||
void
|
||||
initialize_info_signal_handler ()
|
||||
{
|
||||
#if defined (SIGTSTP)
|
||||
old_TSTP = (SigHandler *) signal (SIGTSTP, info_signal_handler);
|
||||
old_TTOU = (SigHandler *) signal (SIGTTOU, info_signal_handler);
|
||||
old_TTIN = (SigHandler *) signal (SIGTTIN, info_signal_handler);
|
||||
#endif /* SIGTSTP */
|
||||
|
||||
#if defined (SIGWINCH)
|
||||
old_WINCH = (SigHandler *) signal (SIGWINCH, info_signal_handler);
|
||||
#endif
|
||||
|
||||
#if defined (SIGINT)
|
||||
old_INT = (SigHandler *) signal (SIGINT, info_signal_handler);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
redisplay_after_signal ()
|
||||
{
|
||||
terminal_clear_screen ();
|
||||
display_clear_display (the_display);
|
||||
window_mark_chain (windows, W_UpdateWindow);
|
||||
display_update_display (windows);
|
||||
display_cursor_at_point (active_window);
|
||||
fflush (stdout);
|
||||
}
|
||||
|
||||
static SigHandlerType
|
||||
info_signal_handler (sig)
|
||||
int sig;
|
||||
{
|
||||
SigHandler **old_signal_handler;
|
||||
|
||||
switch (sig)
|
||||
{
|
||||
#if defined (SIGTSTP)
|
||||
case SIGTSTP:
|
||||
case SIGTTOU:
|
||||
case SIGTTIN:
|
||||
#endif
|
||||
#if defined (SIGINT)
|
||||
case SIGINT:
|
||||
#endif
|
||||
{
|
||||
#if defined (SIGTSTP)
|
||||
if (sig == SIGTSTP)
|
||||
old_signal_handler = &old_TSTP;
|
||||
if (sig == SIGTTOU)
|
||||
old_signal_handler = &old_TTOU;
|
||||
if (sig == SIGTTIN)
|
||||
old_signal_handler = &old_TTIN;
|
||||
#endif /* SIGTSTP */
|
||||
if (sig == SIGINT)
|
||||
old_signal_handler = &old_INT;
|
||||
|
||||
/* For stop signals, restore the terminal IO, leave the cursor
|
||||
at the bottom of the window, and stop us. */
|
||||
terminal_goto_xy (0, screenheight - 1);
|
||||
terminal_clear_to_eol ();
|
||||
fflush (stdout);
|
||||
terminal_unprep_terminal ();
|
||||
signal (sig, *old_signal_handler);
|
||||
UNBLOCK_SIGNAL (sig);
|
||||
kill (getpid (), sig);
|
||||
|
||||
/* The program is returning now. Restore our signal handler,
|
||||
turn on terminal handling, redraw the screen, and place the
|
||||
cursor where it belongs. */
|
||||
terminal_prep_terminal ();
|
||||
*old_signal_handler = (SigHandler *) signal (sig, info_signal_handler);
|
||||
redisplay_after_signal ();
|
||||
fflush (stdout);
|
||||
}
|
||||
break;
|
||||
|
||||
#if defined (SIGWINCH)
|
||||
case SIGWINCH:
|
||||
{
|
||||
/* Turn off terminal IO, tell our parent that the window has changed,
|
||||
then reinitialize the terminal and rebuild our windows. */
|
||||
old_signal_handler = &old_WINCH;
|
||||
terminal_goto_xy (0, 0);
|
||||
fflush (stdout);
|
||||
terminal_unprep_terminal ();
|
||||
signal (sig, *old_signal_handler);
|
||||
UNBLOCK_SIGNAL (sig);
|
||||
kill (getpid (), sig);
|
||||
|
||||
/* After our old signal handler returns... */
|
||||
terminal_get_screen_size ();
|
||||
terminal_prep_terminal ();
|
||||
display_initialize_display (screenwidth, screenheight);
|
||||
window_new_screen_size (screenwidth, screenheight, (VFunction *)NULL);
|
||||
*old_signal_handler = (SigHandler *) signal (sig, info_signal_handler);
|
||||
redisplay_after_signal ();
|
||||
}
|
||||
break;
|
||||
#endif /* SIGWINCH */
|
||||
}
|
||||
}
|
85
gnu/usr.bin/texinfo/info/signals.h
Normal file
85
gnu/usr.bin/texinfo/info/signals.h
Normal file
@ -0,0 +1,85 @@
|
||||
/* signals.h -- Header to include system dependent signal definitions. */
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#ifndef _SIGNALS_H_
|
||||
#define _SIGNALS_H_
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
#define HAVE_SIGSETMASK
|
||||
|
||||
#if !defined (_POSIX_VERSION) && !defined (sigmask)
|
||||
# define sigmask(x) (1 << ((x)-1))
|
||||
#endif /* !POSIX && !sigmask */
|
||||
|
||||
#if !defined (_POSIX_VERSION)
|
||||
# if !defined (SIG_BLOCK)
|
||||
# define SIG_UNBLOCK 1
|
||||
# define SIG_BLOCK 2
|
||||
# define SIG_SETMASK 3
|
||||
# endif /* SIG_BLOCK */
|
||||
|
||||
/* Type of a signal set. */
|
||||
# define sigset_t int
|
||||
|
||||
/* Make SET have no signals in it. */
|
||||
# define sigemptyset(set) (*(set) = (sigset_t)0x0)
|
||||
|
||||
/* Make SET have the full range of signal specifications possible. */
|
||||
# define sigfillset(set) (*(set) = (sigset_t)0xffffffffff)
|
||||
|
||||
/* Add SIG to the contents of SET. */
|
||||
# define sigaddset(set, sig) *(set) |= sigmask (sig)
|
||||
|
||||
/* Delete SIG from the contents of SET. */
|
||||
# define sigdelset(set, sig) *(set) &= ~(sigmask (sig))
|
||||
|
||||
/* Tell if SET contains SIG. */
|
||||
# define sigismember(set, sig) (*(set) & (sigmask (sig)))
|
||||
|
||||
/* Suspend the process until the reception of one of the signals
|
||||
not present in SET. */
|
||||
# define sigsuspend(set) sigpause (*(set))
|
||||
#endif /* !_POSIX_VERSION */
|
||||
|
||||
/* These definitions are used both in POSIX and non-POSIX implementations. */
|
||||
|
||||
#define BLOCK_SIGNAL(sig) \
|
||||
do { \
|
||||
sigset_t nvar, ovar; \
|
||||
sigemptyset (&nvar); \
|
||||
sigemptyset (&ovar); \
|
||||
sigaddset (&nvar, sig); \
|
||||
sigprocmask (SIG_BLOCK, &nvar, &ovar); \
|
||||
} while (0)
|
||||
|
||||
#define UNBLOCK_SIGNAL(sig) \
|
||||
do { \
|
||||
sigset_t nvar, ovar; \
|
||||
sigemptyset (&ovar); \
|
||||
sigemptyset (&nvar); \
|
||||
sigaddset (&nvar, sig); \
|
||||
sigprocmask (SIG_UNBLOCK, &nvar, &ovar); \
|
||||
} while (0)
|
||||
|
||||
#endif /* !_SIGNALS_H_ */
|
64
gnu/usr.bin/texinfo/info/termdep.h
Normal file
64
gnu/usr.bin/texinfo/info/termdep.h
Normal file
@ -0,0 +1,64 @@
|
||||
/* termdep.h -- System things that terminal.c depends on. */
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#if defined (HAVE_SYS_FCNTL_H)
|
||||
#include <sys/fcntl.h>
|
||||
#else
|
||||
#include <fcntl.h>
|
||||
#endif /* !HAVE_SYS_FCNTL_H */
|
||||
|
||||
#if defined (HAVE_TERMIO_H)
|
||||
#include <termio.h>
|
||||
#include <string.h>
|
||||
#if defined (HAVE_SYS_PTEM_H)
|
||||
#if !defined (M_XENIX)
|
||||
#include <sys/stream.h>
|
||||
#include <sys/ptem.h>
|
||||
#undef TIOCGETC
|
||||
#else /* M_XENIX */
|
||||
#define tchars tc
|
||||
#endif /* M_XENIX */
|
||||
#endif /* HAVE_SYS_PTEM_H */
|
||||
#else /* !HAVE_TERMIO_H */
|
||||
#include <sys/file.h>
|
||||
#include <sgtty.h>
|
||||
#include <strings.h>
|
||||
#endif /* !HAVE_TERMIO_H */
|
||||
|
||||
#if defined (HAVE_SYS_TTOLD_H)
|
||||
#include <sys/ttold.h>
|
||||
#endif /* HAVE_SYS_TTOLD_H */
|
||||
|
||||
#if !defined (HAVE_RINDEX)
|
||||
#undef index
|
||||
#undef rindex
|
||||
#define index strchr
|
||||
#define rindex strrchr
|
||||
#endif
|
||||
|
||||
#if !defined (HAVE_BCOPY)
|
||||
#undef bcopy
|
||||
#define bcopy(source, dest, count) memcpy(dest, source, count)
|
||||
#endif
|
||||
|
||||
/* eof */
|
745
gnu/usr.bin/texinfo/info/terminal.c
Normal file
745
gnu/usr.bin/texinfo/info/terminal.c
Normal file
@ -0,0 +1,745 @@
|
||||
/* terminal.c -- How to handle the physical terminal for Info. */
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
This file has appeared in prior works by the Free Software Foundation;
|
||||
thus it carries copyright dates from 1988 through 1993.
|
||||
|
||||
Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include "terminal.h"
|
||||
#include "termdep.h"
|
||||
|
||||
extern void *xmalloc (), *xrealloc ();
|
||||
|
||||
/* The Unix termcap interface code. */
|
||||
|
||||
extern int tgetnum (), tgetflag (), tgetent ();
|
||||
extern char *tgetstr (), *tgoto ();
|
||||
extern char *getenv ();
|
||||
extern void tputs ();
|
||||
|
||||
/* Function "hooks". If you make one of these point to a function, that
|
||||
function is called when appropriate instead of its namesake. Your
|
||||
function is called with exactly the same arguments that were passed
|
||||
to the namesake function. */
|
||||
VFunction *terminal_begin_inverse_hook = (VFunction *)NULL;
|
||||
VFunction *terminal_end_inverse_hook = (VFunction *)NULL;
|
||||
VFunction *terminal_prep_terminal_hook = (VFunction *)NULL;
|
||||
VFunction *terminal_unprep_terminal_hook = (VFunction *)NULL;
|
||||
VFunction *terminal_up_line_hook = (VFunction *)NULL;
|
||||
VFunction *terminal_down_line_hook = (VFunction *)NULL;
|
||||
VFunction *terminal_clear_screen_hook = (VFunction *)NULL;
|
||||
VFunction *terminal_clear_to_eol_hook = (VFunction *)NULL;
|
||||
VFunction *terminal_get_screen_size_hook = (VFunction *)NULL;
|
||||
VFunction *terminal_goto_xy_hook = (VFunction *)NULL;
|
||||
VFunction *terminal_initialize_terminal_hook = (VFunction *)NULL;
|
||||
VFunction *terminal_new_terminal_hook = (VFunction *)NULL;
|
||||
VFunction *terminal_put_text_hook = (VFunction *)NULL;
|
||||
VFunction *terminal_ring_bell_hook = (VFunction *)NULL;
|
||||
VFunction *terminal_write_chars_hook = (VFunction *)NULL;
|
||||
VFunction *terminal_scroll_terminal_hook = (VFunction *)NULL;
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Terminal and Termcap */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* On Solaris2, sys/types.h #includes sys/reg.h, which #defines PC.
|
||||
Unfortunately, PC is a global variable used by the termcap library. */
|
||||
#undef PC
|
||||
|
||||
/* TERMCAP requires these variables, whether we access them or not. */
|
||||
char PC;
|
||||
char *BC, *UP;
|
||||
short ospeed;
|
||||
|
||||
/* A buffer which holds onto the current terminal description, and a pointer
|
||||
used to float within it. */
|
||||
static char *term_buffer = (char *)NULL;
|
||||
static char *term_string_buffer = (char *)NULL;
|
||||
|
||||
/* Some strings to control terminal actions. These are output by tputs (). */
|
||||
static char *term_goto, *term_clreol, *term_cr, *term_clrpag;
|
||||
static char *term_begin_use, *term_end_use;
|
||||
static char *term_AL, *term_DL, *term_al, *term_dl;
|
||||
|
||||
/* How to go up a line. */
|
||||
static char *term_up;
|
||||
|
||||
/* How to go down a line. */
|
||||
static char *term_dn;
|
||||
|
||||
/* An audible bell, if the terminal can be made to make noise. */
|
||||
static char *audible_bell;
|
||||
|
||||
/* A visible bell, if the terminal can be made to flash the screen. */
|
||||
static char *visible_bell;
|
||||
|
||||
/* The string to write to turn on the meta key, if this term has one. */
|
||||
static char *term_mm;
|
||||
|
||||
/* The string to write to turn off the meta key, if this term has one. */
|
||||
static char *term_mo;
|
||||
|
||||
/* The string to turn on inverse mode, if this term has one. */
|
||||
static char *term_invbeg;
|
||||
|
||||
/* The string to turn off inverse mode, if this term has one. */
|
||||
static char *term_invend;
|
||||
|
||||
static void
|
||||
output_character_function (c)
|
||||
int c;
|
||||
{
|
||||
putc (c, stdout);
|
||||
}
|
||||
|
||||
/* Macro to send STRING to the terminal. */
|
||||
#define send_to_terminal(string) \
|
||||
do { \
|
||||
if (string) \
|
||||
tputs (string, 1, output_character_function); \
|
||||
} while (0)
|
||||
|
||||
/* Tell the terminal that we will be doing cursor addressable motion. */
|
||||
static void
|
||||
terminal_begin_using_terminal ()
|
||||
{
|
||||
send_to_terminal (term_begin_use);
|
||||
}
|
||||
|
||||
/* Tell the terminal that we will not be doing any more cursor addressable
|
||||
motion. */
|
||||
static void
|
||||
terminal_end_using_terminal ()
|
||||
{
|
||||
send_to_terminal (term_end_use);
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Necessary Terminal Functions */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* The functions and variables on this page implement the user visible
|
||||
portion of the terminal interface. */
|
||||
|
||||
/* The width and height of the terminal. */
|
||||
int screenwidth, screenheight;
|
||||
|
||||
/* Non-zero means this terminal can't really do anything. */
|
||||
int terminal_is_dumb_p = 0;
|
||||
|
||||
/* Non-zero means that this terminal has a meta key. */
|
||||
int terminal_has_meta_p = 0;
|
||||
|
||||
/* Non-zero means that this terminal can produce a visible bell. */
|
||||
int terminal_has_visible_bell_p = 0;
|
||||
|
||||
/* Non-zero means to use that visible bell if at all possible. */
|
||||
int terminal_use_visible_bell_p = 0;
|
||||
|
||||
/* Non-zero means that the terminal can do scrolling. */
|
||||
int terminal_can_scroll = 0;
|
||||
|
||||
/* The key sequences output by the arrow keys, if this terminal has any. */
|
||||
char *term_ku, *term_kd, *term_kr, *term_kl;
|
||||
|
||||
/* Move the cursor to the terminal location of X and Y. */
|
||||
void
|
||||
terminal_goto_xy (x, y)
|
||||
int x, y;
|
||||
{
|
||||
if (terminal_goto_xy_hook)
|
||||
(*terminal_goto_xy_hook) (x, y);
|
||||
else
|
||||
{
|
||||
if (term_goto)
|
||||
tputs (tgoto (term_goto, x, y), 1, output_character_function);
|
||||
}
|
||||
}
|
||||
|
||||
/* Print STRING to the terminal at the current position. */
|
||||
void
|
||||
terminal_put_text (string)
|
||||
char *string;
|
||||
{
|
||||
if (terminal_put_text_hook)
|
||||
(*terminal_put_text_hook) (string);
|
||||
else
|
||||
{
|
||||
printf ("%s", string);
|
||||
}
|
||||
}
|
||||
|
||||
/* Print NCHARS from STRING to the terminal at the current position. */
|
||||
void
|
||||
terminal_write_chars (string, nchars)
|
||||
char *string;
|
||||
int nchars;
|
||||
{
|
||||
if (terminal_write_chars_hook)
|
||||
(*terminal_write_chars_hook) (string, nchars);
|
||||
else
|
||||
{
|
||||
if (nchars)
|
||||
fwrite (string, 1, nchars, stdout);
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear from the current position of the cursor to the end of the line. */
|
||||
void
|
||||
terminal_clear_to_eol ()
|
||||
{
|
||||
if (terminal_clear_to_eol_hook)
|
||||
(*terminal_clear_to_eol_hook) ();
|
||||
else
|
||||
{
|
||||
send_to_terminal (term_clreol);
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear the entire terminal screen. */
|
||||
void
|
||||
terminal_clear_screen ()
|
||||
{
|
||||
if (terminal_clear_screen_hook)
|
||||
(*terminal_clear_screen_hook) ();
|
||||
else
|
||||
{
|
||||
send_to_terminal (term_clrpag);
|
||||
}
|
||||
}
|
||||
|
||||
/* Move the cursor up one line. */
|
||||
void
|
||||
terminal_up_line ()
|
||||
{
|
||||
if (terminal_up_line_hook)
|
||||
(*terminal_up_line_hook) ();
|
||||
else
|
||||
{
|
||||
send_to_terminal (term_up);
|
||||
}
|
||||
}
|
||||
|
||||
/* Move the cursor down one line. */
|
||||
void
|
||||
terminal_down_line ()
|
||||
{
|
||||
if (terminal_down_line_hook)
|
||||
(*terminal_down_line_hook) ();
|
||||
else
|
||||
{
|
||||
send_to_terminal (term_dn);
|
||||
}
|
||||
}
|
||||
|
||||
/* Turn on reverse video if possible. */
|
||||
void
|
||||
terminal_begin_inverse ()
|
||||
{
|
||||
if (terminal_begin_inverse_hook)
|
||||
(*terminal_begin_inverse_hook) ();
|
||||
else
|
||||
{
|
||||
send_to_terminal (term_invbeg);
|
||||
}
|
||||
}
|
||||
|
||||
/* Turn off reverse video if possible. */
|
||||
void
|
||||
terminal_end_inverse ()
|
||||
{
|
||||
if (terminal_end_inverse_hook)
|
||||
(*terminal_end_inverse_hook) ();
|
||||
else
|
||||
{
|
||||
send_to_terminal (term_invend);
|
||||
}
|
||||
}
|
||||
|
||||
/* Ring the terminal bell. The bell is run visibly if it both has one and
|
||||
terminal_use_visible_bell_p is non-zero. */
|
||||
void
|
||||
terminal_ring_bell ()
|
||||
{
|
||||
if (terminal_ring_bell_hook)
|
||||
(*terminal_ring_bell_hook) ();
|
||||
else
|
||||
{
|
||||
if (terminal_has_visible_bell_p && terminal_use_visible_bell_p)
|
||||
send_to_terminal (visible_bell);
|
||||
else
|
||||
send_to_terminal (audible_bell);
|
||||
}
|
||||
}
|
||||
|
||||
/* At the line START, delete COUNT lines from the terminal display. */
|
||||
static void
|
||||
terminal_delete_lines (start, count)
|
||||
int start, count;
|
||||
{
|
||||
int lines;
|
||||
|
||||
/* Normalize arguments. */
|
||||
if (start < 0)
|
||||
start = 0;
|
||||
|
||||
lines = screenheight - start;
|
||||
terminal_goto_xy (0, start);
|
||||
if (term_DL)
|
||||
tputs (tgoto (term_DL, 0, count), lines, output_character_function);
|
||||
else
|
||||
{
|
||||
while (count--)
|
||||
tputs (term_dl, lines, output_character_function);
|
||||
}
|
||||
|
||||
fflush (stdout);
|
||||
}
|
||||
|
||||
/* At the line START, insert COUNT lines in the terminal display. */
|
||||
static void
|
||||
terminal_insert_lines (start, count)
|
||||
int start, count;
|
||||
{
|
||||
int lines;
|
||||
|
||||
/* Normalize arguments. */
|
||||
if (start < 0)
|
||||
start = 0;
|
||||
|
||||
lines = screenheight - start;
|
||||
terminal_goto_xy (0, start);
|
||||
|
||||
if (term_AL)
|
||||
tputs (tgoto (term_AL, 0, count), lines, output_character_function);
|
||||
else
|
||||
{
|
||||
while (count--)
|
||||
tputs (term_al, lines, output_character_function);
|
||||
}
|
||||
|
||||
fflush (stdout);
|
||||
}
|
||||
|
||||
/* Scroll an area of the terminal, starting with the region from START
|
||||
to END, AMOUNT lines. If AMOUNT is negative, the lines are scrolled
|
||||
towards the top of the screen, else they are scrolled towards the
|
||||
bottom of the screen. */
|
||||
void
|
||||
terminal_scroll_terminal (start, end, amount)
|
||||
int start, end, amount;
|
||||
{
|
||||
if (!terminal_can_scroll)
|
||||
return;
|
||||
|
||||
/* Any scrolling at all? */
|
||||
if (amount == 0)
|
||||
return;
|
||||
|
||||
if (terminal_scroll_terminal_hook)
|
||||
(*terminal_scroll_terminal_hook) (start, end, amount);
|
||||
else
|
||||
{
|
||||
/* If we are scrolling down, delete AMOUNT lines at END. Then insert
|
||||
AMOUNT lines at START. */
|
||||
if (amount > 0)
|
||||
{
|
||||
terminal_delete_lines (end, amount);
|
||||
terminal_insert_lines (start, amount);
|
||||
}
|
||||
|
||||
/* If we are scrolling up, delete AMOUNT lines before START. This
|
||||
actually does the upwards scroll. Then, insert AMOUNT lines
|
||||
after the already scrolled region (i.e., END - AMOUNT). */
|
||||
if (amount < 0)
|
||||
{
|
||||
int abs_amount = -amount;
|
||||
terminal_delete_lines (start - abs_amount, abs_amount);
|
||||
terminal_insert_lines (end - abs_amount, abs_amount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Re-initialize the terminal considering that the TERM/TERMCAP variable
|
||||
has changed. */
|
||||
void
|
||||
terminal_new_terminal (terminal_name)
|
||||
char *terminal_name;
|
||||
{
|
||||
if (terminal_new_terminal_hook)
|
||||
(*terminal_new_terminal_hook) (terminal_name);
|
||||
else
|
||||
{
|
||||
terminal_initialize_terminal (terminal_name);
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the global variables SCREENWIDTH and SCREENHEIGHT. */
|
||||
void
|
||||
terminal_get_screen_size ()
|
||||
{
|
||||
if (terminal_get_screen_size_hook)
|
||||
(*terminal_get_screen_size_hook) ();
|
||||
else
|
||||
{
|
||||
screenwidth = screenheight = 0;
|
||||
|
||||
#if defined (TIOCGWINSZ)
|
||||
{
|
||||
struct winsize window_size;
|
||||
|
||||
if (ioctl (fileno (stdout), TIOCGWINSZ, &window_size) == 0)
|
||||
{
|
||||
screenwidth = (int) window_size.ws_col;
|
||||
screenheight = (int) window_size.ws_row;
|
||||
}
|
||||
}
|
||||
#endif /* TIOCGWINSZ */
|
||||
|
||||
/* Environment variable COLUMNS overrides setting of "co". */
|
||||
if (screenwidth <= 0)
|
||||
{
|
||||
char *sw = getenv ("COLUMNS");
|
||||
|
||||
if (sw)
|
||||
screenwidth = atoi (sw);
|
||||
|
||||
if (screenwidth <= 0)
|
||||
screenwidth = tgetnum ("co");
|
||||
}
|
||||
|
||||
/* Environment variable LINES overrides setting of "li". */
|
||||
if (screenheight <= 0)
|
||||
{
|
||||
char *sh = getenv ("LINES");
|
||||
|
||||
if (sh)
|
||||
screenheight = atoi (sh);
|
||||
|
||||
if (screenheight <= 0)
|
||||
screenheight = tgetnum ("li");
|
||||
}
|
||||
|
||||
/* If all else fails, default to 80x24 terminal. */
|
||||
if (screenwidth <= 0)
|
||||
screenwidth = 80;
|
||||
|
||||
if (screenheight <= 0)
|
||||
screenheight = 24;
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize the terminal which is known as TERMINAL_NAME. If this terminal
|
||||
doesn't have cursor addressability, TERMINAL_IS_DUMB_P becomes non-zero.
|
||||
The variables SCREENHEIGHT and SCREENWIDTH are set to the dimensions that
|
||||
this terminal actually has. The variable TERMINAL_HAS_META_P becomes non-
|
||||
zero if this terminal supports a Meta key. Finally, the terminal screen is
|
||||
cleared. */
|
||||
void
|
||||
terminal_initialize_terminal (terminal_name)
|
||||
char *terminal_name;
|
||||
{
|
||||
char *term, *buffer;
|
||||
|
||||
terminal_is_dumb_p = 0;
|
||||
|
||||
if (terminal_initialize_terminal_hook)
|
||||
{
|
||||
(*terminal_initialize_terminal_hook) (terminal_name);
|
||||
return;
|
||||
}
|
||||
|
||||
term = terminal_name ? terminal_name : getenv ("TERM");
|
||||
|
||||
if (!term_string_buffer)
|
||||
term_string_buffer = (char *)xmalloc (2048);
|
||||
|
||||
if (!term_buffer)
|
||||
term_buffer = (char *)xmalloc (2048);
|
||||
|
||||
buffer = term_string_buffer;
|
||||
|
||||
term_clrpag = term_cr = term_clreol = (char *)NULL;
|
||||
|
||||
if (!term)
|
||||
term = "dumb";
|
||||
|
||||
if (tgetent (term_buffer, term) <= 0)
|
||||
{
|
||||
terminal_is_dumb_p = 1;
|
||||
screenwidth = 80;
|
||||
screenheight = 24;
|
||||
term_cr = "\r";
|
||||
term_up = term_dn = audible_bell = visible_bell = (char *)NULL;
|
||||
term_ku = term_kd = term_kl = term_kr = (char *)NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
BC = tgetstr ("pc", &buffer);
|
||||
PC = BC ? *BC : 0;
|
||||
|
||||
#if defined (TIOCGETP)
|
||||
{
|
||||
struct sgttyb sg;
|
||||
|
||||
if (ioctl (fileno (stdout), TIOCGETP, &sg) != -1)
|
||||
ospeed = sg.sg_ospeed;
|
||||
else
|
||||
ospeed = B9600;
|
||||
}
|
||||
#else
|
||||
ospeed = B9600;
|
||||
#endif /* !TIOCGETP */
|
||||
|
||||
term_cr = tgetstr ("cr", &buffer);
|
||||
term_clreol = tgetstr ("ce", &buffer);
|
||||
term_clrpag = tgetstr ("cl", &buffer);
|
||||
term_goto = tgetstr ("cm", &buffer);
|
||||
|
||||
/* Find out about this terminals scrolling capability. */
|
||||
term_AL = tgetstr ("AL", &buffer);
|
||||
term_DL = tgetstr ("DL", &buffer);
|
||||
term_al = tgetstr ("al", &buffer);
|
||||
term_dl = tgetstr ("dl", &buffer);
|
||||
|
||||
terminal_can_scroll = ((term_AL || term_al) && (term_DL || term_dl));
|
||||
|
||||
term_invbeg = tgetstr ("mr", &buffer);
|
||||
if (term_invbeg)
|
||||
term_invend = tgetstr ("me", &buffer);
|
||||
else
|
||||
term_invend = (char *)NULL;
|
||||
|
||||
if (!term_cr)
|
||||
term_cr = "\r";
|
||||
|
||||
terminal_get_screen_size ();
|
||||
|
||||
term_up = tgetstr ("up", &buffer);
|
||||
term_dn = tgetstr ("dn", &buffer);
|
||||
visible_bell = tgetstr ("vb", &buffer);
|
||||
terminal_has_visible_bell_p = (visible_bell != (char *)NULL);
|
||||
audible_bell = tgetstr ("bl", &buffer);
|
||||
if (!audible_bell)
|
||||
audible_bell = "\007";
|
||||
term_begin_use = tgetstr ("ti", &buffer);
|
||||
term_end_use = tgetstr ("te", &buffer);
|
||||
|
||||
/* Check to see if this terminal has a meta key. */
|
||||
terminal_has_meta_p = (tgetflag ("km") || tgetflag ("MT"));
|
||||
if (terminal_has_meta_p)
|
||||
{
|
||||
term_mm = tgetstr ("mm", &buffer);
|
||||
term_mo = tgetstr ("mo", &buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
term_mm = (char *)NULL;
|
||||
term_mo = (char *)NULL;
|
||||
}
|
||||
|
||||
/* Attempt to find the arrow keys. */
|
||||
term_ku = tgetstr ("ku", &buffer);
|
||||
term_kd = tgetstr ("kd", &buffer);
|
||||
term_kr = tgetstr ("kr", &buffer);
|
||||
term_kl = tgetstr ("kl", &buffer);
|
||||
|
||||
/* If this terminal is not cursor addressable, then it is really dumb. */
|
||||
if (!term_goto)
|
||||
terminal_is_dumb_p = 1;
|
||||
|
||||
terminal_begin_using_terminal ();
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* How to Read Characters From the Terminal */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
#if defined (TIOCGETC)
|
||||
/* A buffer containing the terminal interrupt characters upon entry
|
||||
to Info. */
|
||||
struct tchars original_tchars;
|
||||
#endif
|
||||
|
||||
#if defined (TIOCGLTC)
|
||||
/* A buffer containing the local terminal mode characters upon entry
|
||||
to Info. */
|
||||
struct ltchars original_ltchars;
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_TERMIO_H)
|
||||
/* A buffer containing the terminal mode flags upon entry to info. */
|
||||
struct termio original_termio, ttybuff;
|
||||
#else /* !HAVE_TERMIO_H */
|
||||
/* Buffers containing the terminal mode flags upon entry to info. */
|
||||
int original_tty_flags = 0;
|
||||
int original_lmode;
|
||||
struct sgttyb ttybuff;
|
||||
#endif /* !HAVE_TERMIO_H */
|
||||
|
||||
/* Prepare to start using the terminal to read characters singly. */
|
||||
void
|
||||
terminal_prep_terminal ()
|
||||
{
|
||||
int tty;
|
||||
|
||||
if (terminal_prep_terminal_hook)
|
||||
{
|
||||
(*terminal_prep_terminal_hook) ();
|
||||
return;
|
||||
}
|
||||
|
||||
tty = fileno (stdin);
|
||||
|
||||
#if defined (HAVE_TERMIO_H)
|
||||
ioctl (tty, TCGETA, &original_termio);
|
||||
ioctl (tty, TCGETA, &ttybuff);
|
||||
ttybuff.c_iflag &= (~ISTRIP & ~INLCR & ~IGNCR & ~ICRNL & ~IXON);
|
||||
ttybuff.c_oflag &= (~ONLCR & ~OCRNL);
|
||||
ttybuff.c_lflag &= (~ICANON & ~ECHO);
|
||||
|
||||
ttybuff.c_cc[VMIN] = 1;
|
||||
ttybuff.c_cc[VTIME] = 0;
|
||||
|
||||
if (ttybuff.c_cc[VINTR] = '\177')
|
||||
ttybuff.c_cc[VINTR] = -1;
|
||||
|
||||
if (ttybuff.c_cc[VQUIT] = '\177')
|
||||
ttybuff.c_cc[VQUIT] = -1;
|
||||
|
||||
ioctl (tty, TCSETA, &ttybuff);
|
||||
|
||||
#else /* !HAVE_TERMIO_H */
|
||||
|
||||
ioctl (tty, TIOCGETP, &ttybuff);
|
||||
|
||||
if (!original_tty_flags)
|
||||
original_tty_flags = ttybuff.sg_flags;
|
||||
|
||||
/* Make this terminal pass 8 bits around while we are using it. */
|
||||
#if defined (PASS8)
|
||||
ttybuff.sg_flags |= PASS8;
|
||||
#endif /* PASS8 */
|
||||
|
||||
#if defined (TIOCLGET) && defined (LPASS8)
|
||||
{
|
||||
int flags;
|
||||
ioctl (tty, TIOCLGET, &flags);
|
||||
original_lmode = flags;
|
||||
flags |= LPASS8;
|
||||
ioctl (tty, TIOCLSET, &flags);
|
||||
}
|
||||
#endif /* TIOCLGET && LPASS8 */
|
||||
|
||||
#if defined (TIOCGETC)
|
||||
{
|
||||
struct tchars temp;
|
||||
|
||||
ioctl (tty, TIOCGETC, &original_tchars);
|
||||
temp = original_tchars;
|
||||
|
||||
/* C-s and C-q. */
|
||||
temp.t_startc = temp.t_stopc = -1;
|
||||
|
||||
/* Often set to C-d. */
|
||||
temp.t_eofc = -1;
|
||||
|
||||
/* If the a quit or interrupt character conflicts with one of our
|
||||
commands, then make it go away. */
|
||||
if (temp.t_intrc == '\177')
|
||||
temp.t_intrc = -1;
|
||||
|
||||
if (temp.t_quitc == '\177')
|
||||
temp.t_quitc = -1;
|
||||
|
||||
ioctl (tty, TIOCSETC, &temp);
|
||||
}
|
||||
#endif /* TIOCGETC */
|
||||
|
||||
#if defined (TIOCGLTC)
|
||||
{
|
||||
struct ltchars temp;
|
||||
|
||||
ioctl (tty, TIOCGLTC, &original_ltchars);
|
||||
temp = original_ltchars;
|
||||
|
||||
/* Make the interrupt keys go away. Just enough to make people happy. */
|
||||
temp.t_lnextc = -1; /* C-v. */
|
||||
temp.t_dsuspc = -1; /* C-y. */
|
||||
temp.t_flushc = -1; /* C-o. */
|
||||
ioctl (tty, TIOCSLTC, &temp);
|
||||
}
|
||||
#endif /* TIOCGLTC */
|
||||
|
||||
ttybuff.sg_flags &= ~ECHO;
|
||||
ttybuff.sg_flags |= CBREAK;
|
||||
ioctl (tty, TIOCSETN, &ttybuff);
|
||||
#endif /* !HAVE_TERMIO_H */
|
||||
}
|
||||
|
||||
/* Restore the tty settings back to what they were before we started using
|
||||
this terminal. */
|
||||
void
|
||||
terminal_unprep_terminal ()
|
||||
{
|
||||
int tty;
|
||||
|
||||
if (terminal_unprep_terminal_hook)
|
||||
{
|
||||
(*terminal_unprep_terminal_hook) ();
|
||||
return;
|
||||
}
|
||||
|
||||
tty = fileno (stdin);
|
||||
|
||||
#if defined (HAVE_TERMIO_H)
|
||||
ioctl (tty, TCSETA, &original_termio);
|
||||
#else /* !HAVE_TERMIO_H */
|
||||
ioctl (tty, TIOCGETP, &ttybuff);
|
||||
ttybuff.sg_flags = original_tty_flags;
|
||||
ioctl (tty, TIOCSETN, &ttybuff);
|
||||
|
||||
#if defined (TIOCGETC)
|
||||
ioctl (tty, TIOCSETC, &original_tchars);
|
||||
#endif /* TIOCGETC */
|
||||
|
||||
#if defined (TIOCGLTC)
|
||||
ioctl (tty, TIOCSLTC, &original_ltchars);
|
||||
#endif /* TIOCGLTC */
|
||||
|
||||
#if defined (TIOCLGET) && defined (LPASS8)
|
||||
ioctl (tty, TIOCLSET, &original_lmode);
|
||||
#endif /* TIOCLGET && LPASS8 */
|
||||
|
||||
#endif /* !HAVE_TERMIO_H */
|
||||
terminal_end_using_terminal ();
|
||||
}
|
||||
|
126
gnu/usr.bin/texinfo/info/terminal.h
Normal file
126
gnu/usr.bin/texinfo/info/terminal.h
Normal file
@ -0,0 +1,126 @@
|
||||
/* terminal.h -- The external interface to terminal I/O. */
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#ifndef _TERMINAL_H_
|
||||
#define _TERMINAL_H_
|
||||
|
||||
/* We use the following data type to talk about pointers to functions. */
|
||||
#if !defined (__FUNCTION_DEF)
|
||||
# define __FUNCTION_DEF
|
||||
typedef int Function ();
|
||||
typedef void VFunction ();
|
||||
#endif /* _FUNCTION_DEF */
|
||||
|
||||
/* For almost every function externally visible from terminal.c, there is
|
||||
a corresponding "hook" function which can be bound in order to replace
|
||||
the functionality of the one found in terminal.c. This is how we go
|
||||
about implemented X window display. */
|
||||
|
||||
/* The width and height of the terminal. */
|
||||
extern int screenwidth, screenheight;
|
||||
|
||||
/* Non-zero means this terminal can't really do anything. */
|
||||
extern int terminal_is_dumb_p;
|
||||
|
||||
/* Non-zero means that this terminal has a meta key. */
|
||||
extern int terminal_has_meta_p;
|
||||
|
||||
/* Non-zero means that this terminal can produce a visible bell. */
|
||||
extern int terminal_has_visible_bell_p;
|
||||
|
||||
/* Non-zero means to use that visible bell if at all possible. */
|
||||
extern int terminal_use_visible_bell_p;
|
||||
|
||||
/* Non-zero means that this terminal can scroll lines up and down. */
|
||||
extern int terminal_can_scroll;
|
||||
|
||||
/* Initialize the terminal which is known as TERMINAL_NAME. If this terminal
|
||||
doesn't have cursor addressability, TERMINAL_IS_DUMB_P becomes non-zero.
|
||||
The variables SCREENHEIGHT and SCREENWIDTH are set to the dimensions that
|
||||
this terminal actually has. The variable TERMINAL_HAS_META_P becomes non-
|
||||
zero if this terminal supports a Meta key. */
|
||||
extern void terminal_initialize_terminal ();
|
||||
extern VFunction *terminal_initialize_terminal_hook;
|
||||
|
||||
/* Return the current screen width and height in the variables
|
||||
SCREENWIDTH and SCREENHEIGHT. */
|
||||
extern void terminal_get_screen_size ();
|
||||
extern VFunction *terminal_get_screen_size_hook;
|
||||
|
||||
/* Save and restore tty settings. */
|
||||
extern void terminal_prep_terminal (), terminal_unprep_terminal ();
|
||||
extern VFunction *terminal_prep_terminal_hook, *terminal_unprep_terminal_hook;
|
||||
|
||||
/* Re-initialize the terminal to TERMINAL_NAME. */
|
||||
extern void terminal_new_terminal ();
|
||||
extern VFunction *terminal_new_terminal_hook;
|
||||
|
||||
/* Move the cursor to the terminal location of X and Y. */
|
||||
extern void terminal_goto_xy ();
|
||||
extern VFunction *terminal_goto_xy_hook;
|
||||
|
||||
/* Print STRING to the terminal at the current position. */
|
||||
extern void terminal_put_text ();
|
||||
extern VFunction *terminal_put_text_hook;
|
||||
|
||||
/* Print NCHARS from STRING to the terminal at the current position. */
|
||||
extern void terminal_write_chars ();
|
||||
extern VFunction *terminal_write_chars_hook;
|
||||
|
||||
/* Clear from the current position of the cursor to the end of the line. */
|
||||
extern void terminal_clear_to_eol ();
|
||||
extern VFunction *terminal_clear_to_eol_hook;
|
||||
|
||||
/* Clear the entire terminal screen. */
|
||||
extern void terminal_clear_screen ();
|
||||
extern VFunction *terminal_clear_screen_hook;
|
||||
|
||||
/* Move the cursor up one line. */
|
||||
extern void terminal_up_line ();
|
||||
extern VFunction *terminal_up_line_hook;
|
||||
|
||||
/* Move the cursor down one line. */
|
||||
extern void terminal_down_line ();
|
||||
extern VFunction *terminal_down_line_hook;
|
||||
|
||||
/* Turn on reverse video if possible. */
|
||||
extern void terminal_begin_inverse ();
|
||||
extern VFunction *terminal_begin_inverse_hook;
|
||||
|
||||
/* Turn off reverse video if possible. */
|
||||
extern void terminal_end_inverse ();
|
||||
extern VFunction *terminal_end_inverse_hook;
|
||||
|
||||
/* Scroll an area of the terminal, starting with the region from START
|
||||
to END, AMOUNT lines. If AMOUNT is negative, the lines are scrolled
|
||||
towards the top of the screen, else they are scrolled towards the
|
||||
bottom of the screen. */
|
||||
extern void terminal_scroll_terminal ();
|
||||
extern VFunction *terminal_scroll_terminal_hook;
|
||||
|
||||
/* Ring the terminal bell. The bell is run visibly if it both has one and
|
||||
terminal_use_visible_bell_p is non-zero. */
|
||||
extern void terminal_ring_bell ();
|
||||
extern VFunction *terminal_ring_bell_hook;
|
||||
|
||||
#endif /* !_TERMINAL_H_ */
|
379
gnu/usr.bin/texinfo/info/tilde.c
Normal file
379
gnu/usr.bin/texinfo/info/tilde.c
Normal file
@ -0,0 +1,379 @@
|
||||
/* tilde.c -- Tilde expansion code (~/foo := $HOME/foo). */
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
This file has appeared in prior works by the Free Software Foundation;
|
||||
thus it carries copyright dates from 1988 through 1993.
|
||||
|
||||
Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#if defined (__GNUC__)
|
||||
# define alloca __builtin_alloca
|
||||
#else /* !__GNUC__ */
|
||||
# if defined (_AIX)
|
||||
#pragma alloca
|
||||
# else /* !_AIX */
|
||||
# if defined (HAVE_ALLOCA_H)
|
||||
# include <alloca.h>
|
||||
# endif /* HAVE_ALLOCA_H */
|
||||
# endif /* !AIX */
|
||||
#endif /* !__GNUC__ */
|
||||
|
||||
#include "tilde.h"
|
||||
#include <pwd.h>
|
||||
|
||||
#if !defined (savestring)
|
||||
#define savestring(x) (char *)strcpy (xmalloc (1 + strlen (x)), (x))
|
||||
#endif /* !savestring */
|
||||
|
||||
#if !defined (NULL)
|
||||
# define NULL 0x0
|
||||
#endif
|
||||
|
||||
#if defined (TEST) || defined (STATIC_MALLOC)
|
||||
static char *xmalloc (), *xrealloc ();
|
||||
#else
|
||||
extern char *xmalloc (), *xrealloc ();
|
||||
#endif /* TEST || STATIC_MALLOC */
|
||||
|
||||
/* The default value of tilde_additional_prefixes. This is set to
|
||||
whitespace preceding a tilde so that simple programs which do not
|
||||
perform any word separation get desired behaviour. */
|
||||
static char *default_prefixes[] =
|
||||
{ " ~", "\t~", (char *)NULL };
|
||||
|
||||
/* The default value of tilde_additional_suffixes. This is set to
|
||||
whitespace or newline so that simple programs which do not
|
||||
perform any word separation get desired behaviour. */
|
||||
static char *default_suffixes[] =
|
||||
{ " ", "\n", (char *)NULL };
|
||||
|
||||
/* If non-null, this contains the address of a function to call if the
|
||||
standard meaning for expanding a tilde fails. The function is called
|
||||
with the text (sans tilde, as in "foo"), and returns a malloc()'ed string
|
||||
which is the expansion, or a NULL pointer if there is no expansion. */
|
||||
Function *tilde_expansion_failure_hook = (Function *)NULL;
|
||||
|
||||
/* When non-null, this is a NULL terminated array of strings which
|
||||
are duplicates for a tilde prefix. Bash uses this to expand
|
||||
`=~' and `:~'. */
|
||||
char **tilde_additional_prefixes = default_prefixes;
|
||||
|
||||
/* When non-null, this is a NULL terminated array of strings which match
|
||||
the end of a username, instead of just "/". Bash sets this to
|
||||
`:' and `=~'. */
|
||||
char **tilde_additional_suffixes = default_suffixes;
|
||||
|
||||
/* Find the start of a tilde expansion in STRING, and return the index of
|
||||
the tilde which starts the expansion. Place the length of the text
|
||||
which identified this tilde starter in LEN, excluding the tilde itself. */
|
||||
static int
|
||||
tilde_find_prefix (string, len)
|
||||
char *string;
|
||||
int *len;
|
||||
{
|
||||
register int i, j, string_len;
|
||||
register char **prefixes = tilde_additional_prefixes;
|
||||
|
||||
string_len = strlen (string);
|
||||
*len = 0;
|
||||
|
||||
if (!*string || *string == '~')
|
||||
return (0);
|
||||
|
||||
if (prefixes)
|
||||
{
|
||||
for (i = 0; i < string_len; i++)
|
||||
{
|
||||
for (j = 0; prefixes[j]; j++)
|
||||
{
|
||||
if (strncmp (string + i, prefixes[j], strlen (prefixes[j])) == 0)
|
||||
{
|
||||
*len = strlen (prefixes[j]) - 1;
|
||||
return (i + *len);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return (string_len);
|
||||
}
|
||||
|
||||
/* Find the end of a tilde expansion in STRING, and return the index of
|
||||
the character which ends the tilde definition. */
|
||||
static int
|
||||
tilde_find_suffix (string)
|
||||
char *string;
|
||||
{
|
||||
register int i, j, string_len;
|
||||
register char **suffixes = tilde_additional_suffixes;
|
||||
|
||||
string_len = strlen (string);
|
||||
|
||||
for (i = 0; i < string_len; i++)
|
||||
{
|
||||
if (string[i] == '/' || !string[i])
|
||||
break;
|
||||
|
||||
for (j = 0; suffixes && suffixes[j]; j++)
|
||||
{
|
||||
if (strncmp (string + i, suffixes[j], strlen (suffixes[j])) == 0)
|
||||
return (i);
|
||||
}
|
||||
}
|
||||
return (i);
|
||||
}
|
||||
|
||||
/* Return a new string which is the result of tilde expanding STRING. */
|
||||
char *
|
||||
tilde_expand (string)
|
||||
char *string;
|
||||
{
|
||||
char *result, *tilde_expand_word ();
|
||||
int result_size, result_index;
|
||||
|
||||
result_size = result_index = 0;
|
||||
result = (char *)NULL;
|
||||
|
||||
/* Scan through STRING expanding tildes as we come to them. */
|
||||
while (1)
|
||||
{
|
||||
register int start, end;
|
||||
char *tilde_word, *expansion;
|
||||
int len;
|
||||
|
||||
/* Make START point to the tilde which starts the expansion. */
|
||||
start = tilde_find_prefix (string, &len);
|
||||
|
||||
/* Copy the skipped text into the result. */
|
||||
if ((result_index + start + 1) > result_size)
|
||||
result = (char *)xrealloc (result, 1 + (result_size += (start + 20)));
|
||||
|
||||
strncpy (result + result_index, string, start);
|
||||
result_index += start;
|
||||
|
||||
/* Advance STRING to the starting tilde. */
|
||||
string += start;
|
||||
|
||||
/* Make END be the index of one after the last character of the
|
||||
username. */
|
||||
end = tilde_find_suffix (string);
|
||||
|
||||
/* If both START and END are zero, we are all done. */
|
||||
if (!start && !end)
|
||||
break;
|
||||
|
||||
/* Expand the entire tilde word, and copy it into RESULT. */
|
||||
tilde_word = (char *)xmalloc (1 + end);
|
||||
strncpy (tilde_word, string, end);
|
||||
tilde_word[end] = '\0';
|
||||
string += end;
|
||||
|
||||
expansion = tilde_expand_word (tilde_word);
|
||||
free (tilde_word);
|
||||
|
||||
len = strlen (expansion);
|
||||
if ((result_index + len + 1) > result_size)
|
||||
result = (char *)xrealloc (result, 1 + (result_size += (len + 20)));
|
||||
|
||||
strcpy (result + result_index, expansion);
|
||||
result_index += len;
|
||||
free (expansion);
|
||||
}
|
||||
|
||||
result[result_index] = '\0';
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
/* Do the work of tilde expansion on FILENAME. FILENAME starts with a
|
||||
tilde. If there is no expansion, call tilde_expansion_failure_hook. */
|
||||
char *
|
||||
tilde_expand_word (filename)
|
||||
char *filename;
|
||||
{
|
||||
char *dirname;
|
||||
|
||||
dirname = filename ? savestring (filename) : (char *)NULL;
|
||||
|
||||
if (dirname && *dirname == '~')
|
||||
{
|
||||
char *temp_name;
|
||||
if (!dirname[1] || dirname[1] == '/')
|
||||
{
|
||||
/* Prepend $HOME to the rest of the string. */
|
||||
char *temp_home = (char *)getenv ("HOME");
|
||||
|
||||
/* If there is no HOME variable, look up the directory in
|
||||
the password database. */
|
||||
if (!temp_home)
|
||||
{
|
||||
/* extern struct passwd *getpwuid (); */
|
||||
struct passwd *entry;
|
||||
|
||||
entry = getpwuid (getuid ());
|
||||
if (entry)
|
||||
temp_home = entry->pw_dir;
|
||||
}
|
||||
|
||||
temp_name = (char *)alloca (1 + strlen (&dirname[1])
|
||||
+ (temp_home ? strlen (temp_home) : 0));
|
||||
temp_name[0] = '\0';
|
||||
if (temp_home)
|
||||
strcpy (temp_name, temp_home);
|
||||
strcat (temp_name, &dirname[1]);
|
||||
free (dirname);
|
||||
dirname = savestring (temp_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct passwd *getpwnam (), *user_entry;
|
||||
char *username = (char *)alloca (257);
|
||||
int i, c;
|
||||
|
||||
for (i = 1; c = dirname[i]; i++)
|
||||
{
|
||||
if (c == '/')
|
||||
break;
|
||||
else
|
||||
username[i - 1] = c;
|
||||
}
|
||||
username[i - 1] = '\0';
|
||||
|
||||
if (!(user_entry = getpwnam (username)))
|
||||
{
|
||||
/* If the calling program has a special syntax for
|
||||
expanding tildes, and we couldn't find a standard
|
||||
expansion, then let them try. */
|
||||
if (tilde_expansion_failure_hook)
|
||||
{
|
||||
char *expansion;
|
||||
|
||||
expansion =
|
||||
(char *)(*tilde_expansion_failure_hook) (username);
|
||||
|
||||
if (expansion)
|
||||
{
|
||||
temp_name = (char *)alloca (1 + strlen (expansion)
|
||||
+ strlen (&dirname[i]));
|
||||
strcpy (temp_name, expansion);
|
||||
strcat (temp_name, &dirname[i]);
|
||||
free (expansion);
|
||||
goto return_name;
|
||||
}
|
||||
}
|
||||
/* We shouldn't report errors. */
|
||||
}
|
||||
else
|
||||
{
|
||||
temp_name = (char *)alloca (1 + strlen (user_entry->pw_dir)
|
||||
+ strlen (&dirname[i]));
|
||||
strcpy (temp_name, user_entry->pw_dir);
|
||||
strcat (temp_name, &dirname[i]);
|
||||
return_name:
|
||||
free (dirname);
|
||||
dirname = savestring (temp_name);
|
||||
}
|
||||
endpwent ();
|
||||
}
|
||||
}
|
||||
return (dirname);
|
||||
}
|
||||
|
||||
|
||||
#if defined (TEST)
|
||||
#undef NULL
|
||||
#include <stdio.h>
|
||||
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
char *result, line[512];
|
||||
int done = 0;
|
||||
|
||||
while (!done)
|
||||
{
|
||||
printf ("~expand: ");
|
||||
fflush (stdout);
|
||||
|
||||
if (!gets (line))
|
||||
strcpy (line, "done");
|
||||
|
||||
if ((strcmp (line, "done") == 0) ||
|
||||
(strcmp (line, "quit") == 0) ||
|
||||
(strcmp (line, "exit") == 0))
|
||||
{
|
||||
done = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
result = tilde_expand (line);
|
||||
printf (" --> %s\n", result);
|
||||
free (result);
|
||||
}
|
||||
exit (0);
|
||||
}
|
||||
|
||||
static void memory_error_and_abort ();
|
||||
|
||||
static char *
|
||||
xmalloc (bytes)
|
||||
int bytes;
|
||||
{
|
||||
char *temp = (char *)malloc (bytes);
|
||||
|
||||
if (!temp)
|
||||
memory_error_and_abort ();
|
||||
return (temp);
|
||||
}
|
||||
|
||||
static char *
|
||||
xrealloc (pointer, bytes)
|
||||
char *pointer;
|
||||
int bytes;
|
||||
{
|
||||
char *temp;
|
||||
|
||||
if (!pointer)
|
||||
temp = (char *)malloc (bytes);
|
||||
else
|
||||
temp = (char *)realloc (pointer, bytes);
|
||||
|
||||
if (!temp)
|
||||
memory_error_and_abort ();
|
||||
|
||||
return (temp);
|
||||
}
|
||||
|
||||
static void
|
||||
memory_error_and_abort ()
|
||||
{
|
||||
fprintf (stderr, "readline: Out of virtual memory!\n");
|
||||
abort ();
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* compile-command: "gcc -g -DTEST -o tilde tilde.c"
|
||||
* end:
|
||||
*/
|
||||
#endif /* TEST */
|
||||
|
62
gnu/usr.bin/texinfo/info/tilde.h
Normal file
62
gnu/usr.bin/texinfo/info/tilde.h
Normal file
@ -0,0 +1,62 @@
|
||||
/* tilde.h: Externally available variables and function in libtilde.a. */
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
This file has appeared in prior works by the Free Software Foundation;
|
||||
thus it carries copyright dates from 1988 through 1993.
|
||||
|
||||
Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#ifndef _TILDE_H_
|
||||
#define _TILDE_H_
|
||||
|
||||
/* Function pointers can be declared as (Function *)foo. */
|
||||
#if !defined (__FUNCTION_DEF)
|
||||
# define __FUNCTION_DEF
|
||||
typedef int Function ();
|
||||
typedef void VFunction ();
|
||||
#endif /* _FUNCTION_DEF */
|
||||
|
||||
/* If non-null, this contains the address of a function to call if the
|
||||
standard meaning for expanding a tilde fails. The function is called
|
||||
with the text (sans tilde, as in "foo"), and returns a malloc()'ed string
|
||||
which is the expansion, or a NULL pointer if there is no expansion. */
|
||||
extern Function *tilde_expansion_failure_hook;
|
||||
|
||||
/* When non-null, this is a NULL terminated array of strings which
|
||||
are duplicates for a tilde prefix. Bash uses this to expand
|
||||
`=~' and `:~'. */
|
||||
extern char **tilde_additional_prefixes;
|
||||
|
||||
/* When non-null, this is a NULL terminated array of strings which match
|
||||
the end of a username, instead of just "/". Bash sets this to
|
||||
`:' and `=~'. */
|
||||
extern char **tilde_additional_suffixes;
|
||||
|
||||
/* Return a new string which is the result of tilde expanding STRING. */
|
||||
extern char *tilde_expand ();
|
||||
|
||||
/* Do the work of tilde expansion on FILENAME. FILENAME starts with a
|
||||
tilde. If there is no expansion, call tilde_expansion_failure_hook. */
|
||||
extern char *tilde_expand_word ();
|
||||
|
||||
#endif
|
||||
|
272
gnu/usr.bin/texinfo/info/variables.c
Normal file
272
gnu/usr.bin/texinfo/info/variables.c
Normal file
@ -0,0 +1,272 @@
|
||||
/* variables.c -- How to manipulate user visible variables in Info. */
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#include "info.h"
|
||||
#include "variables.h"
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* User Visible Variables in Info */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Choices used by the completer when reading a zero/non-zero value for
|
||||
a variable. */
|
||||
static char *on_off_choices[] = { "Off", "On", (char *)NULL };
|
||||
|
||||
VARIABLE_ALIST info_variables[] = {
|
||||
{ "automatic-footnotes",
|
||||
"When \"On\", footnotes appear and disappear automatically",
|
||||
&auto_footnotes_p, (char **)on_off_choices },
|
||||
|
||||
{ "automatic-tiling",
|
||||
"When \"On\", creating or deleting a window resizes other windows",
|
||||
&auto_tiling_p, (char **)on_off_choices },
|
||||
|
||||
{ "visible-bell",
|
||||
"When \"On\", flash the screen instead of ringing the bell",
|
||||
&terminal_use_visible_bell_p, (char **)on_off_choices },
|
||||
|
||||
{ "errors-ring-bell",
|
||||
"When \"On\", errors cause the bell to ring",
|
||||
&info_error_rings_bell_p, (char **)on_off_choices },
|
||||
|
||||
{ "gc-compressed-files",
|
||||
"When \"On\", Info garbage collects files which had to be uncompressed",
|
||||
&gc_compressed_files, (char **)on_off_choices },
|
||||
{ "show-index-match",
|
||||
"When \"On\", the portion of the matched search string is highlighted",
|
||||
&show_index_match, (char **)on_off_choices },
|
||||
|
||||
{ "scroll-behaviour",
|
||||
"Controls what happens when scrolling is requested at the end of a node",
|
||||
&info_scroll_behaviour, (char **)info_scroll_choices },
|
||||
|
||||
{ "scroll-step",
|
||||
"The number lines to scroll when the cursor moves out of the window",
|
||||
&window_scroll_step, (char **)NULL },
|
||||
|
||||
{ "ISO-Latin",
|
||||
"When \"On\", Info accepts and displays ISO Latin characters",
|
||||
&ISO_Latin_p, (char **)on_off_choices },
|
||||
|
||||
{ (char *)NULL, (char *)NULL, (int *)NULL, (char **)NULL }
|
||||
};
|
||||
|
||||
DECLARE_INFO_COMMAND (describe_variable, "Explain the use of a variable")
|
||||
{
|
||||
VARIABLE_ALIST *var;
|
||||
char *description;
|
||||
|
||||
/* Get the variable's name. */
|
||||
var = read_variable_name ("Describe variable: ", window);
|
||||
|
||||
if (!var)
|
||||
return;
|
||||
|
||||
description = (char *)xmalloc (20 + strlen (var->name) + strlen (var->doc));
|
||||
|
||||
if (var->choices)
|
||||
sprintf (description, "%s (%s): %s.",
|
||||
var->name, var->choices[*(var->value)], var->doc);
|
||||
else
|
||||
sprintf (description, "%s (%d): %s.", var->name, *(var->value), var->doc);
|
||||
|
||||
window_message_in_echo_area ("%s", description);
|
||||
free (description);
|
||||
}
|
||||
|
||||
DECLARE_INFO_COMMAND (set_variable, "Set the value of an Info variable")
|
||||
{
|
||||
VARIABLE_ALIST *var;
|
||||
char *line;
|
||||
|
||||
/* Get the variable's name and value. */
|
||||
var = read_variable_name ("Set variable: ", window);
|
||||
|
||||
if (!var)
|
||||
return;
|
||||
|
||||
/* Read a new value for this variable. */
|
||||
{
|
||||
char prompt[100];
|
||||
|
||||
if (!var->choices)
|
||||
{
|
||||
int potential_value;
|
||||
|
||||
if (info_explicit_arg || count != 1)
|
||||
potential_value = count;
|
||||
else
|
||||
potential_value = *(var->value);
|
||||
|
||||
sprintf (prompt, "Set %s to value (%d): ",
|
||||
var->name, potential_value);
|
||||
line = info_read_in_echo_area (active_window, prompt);
|
||||
|
||||
/* If no error was printed, clear the echo area. */
|
||||
if (!info_error_was_printed)
|
||||
window_clear_echo_area ();
|
||||
|
||||
/* User aborted? */
|
||||
if (!line)
|
||||
return;
|
||||
|
||||
/* If the user specified a value, get that, otherwise, we are done. */
|
||||
canonicalize_whitespace (line);
|
||||
if (*line)
|
||||
*(var->value) = atoi (line);
|
||||
else
|
||||
*(var->value) = potential_value;
|
||||
|
||||
free (line);
|
||||
}
|
||||
else
|
||||
{
|
||||
register int i;
|
||||
REFERENCE **array = (REFERENCE **)NULL;
|
||||
int array_index = 0;
|
||||
int array_slots = 0;
|
||||
|
||||
for (i = 0; var->choices[i]; i++)
|
||||
{
|
||||
REFERENCE *entry;
|
||||
|
||||
entry = (REFERENCE *)xmalloc (sizeof (REFERENCE));
|
||||
entry->label = savestring (var->choices[i]);
|
||||
entry->nodename = (char *)NULL;
|
||||
entry->filename = (char *)NULL;
|
||||
|
||||
add_pointer_to_array
|
||||
(entry, array_index, array, array_slots, 10, REFERENCE *);
|
||||
}
|
||||
|
||||
sprintf (prompt, "Set %s to value (%s): ",
|
||||
var->name, var->choices[*(var->value)]);
|
||||
|
||||
/* Ask the completer to read a variable value for us. */
|
||||
line = info_read_completing_in_echo_area (window, prompt, array);
|
||||
|
||||
info_free_references (array);
|
||||
|
||||
if (!echo_area_is_active)
|
||||
window_clear_echo_area ();
|
||||
|
||||
/* User aborted? */
|
||||
if (!line)
|
||||
{
|
||||
info_abort_key (active_window, 0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* User accepted default choice? If so, no change. */
|
||||
if (!*line)
|
||||
{
|
||||
free (line);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Find the choice in our list of choices. */
|
||||
for (i = 0; var->choices[i]; i++)
|
||||
if (strcmp (var->choices[i], line) == 0)
|
||||
break;
|
||||
|
||||
if (var->choices[i])
|
||||
*(var->value) = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Read the name of an Info variable in the echo area and return the
|
||||
address of a VARIABLE_ALIST member. A return value of NULL indicates
|
||||
that no variable could be read. */
|
||||
VARIABLE_ALIST *
|
||||
read_variable_name (prompt, window)
|
||||
char *prompt;
|
||||
WINDOW *window;
|
||||
{
|
||||
register int i;
|
||||
char *line;
|
||||
REFERENCE **variables;
|
||||
|
||||
/* Get the completion array of variable names. */
|
||||
variables = make_variable_completions_array ();
|
||||
|
||||
/* Ask the completer to read a variable for us. */
|
||||
line =
|
||||
info_read_completing_in_echo_area (window, prompt, variables);
|
||||
|
||||
info_free_references (variables);
|
||||
|
||||
if (!echo_area_is_active)
|
||||
window_clear_echo_area ();
|
||||
|
||||
/* User aborted? */
|
||||
if (!line)
|
||||
{
|
||||
info_abort_key (active_window, 0, 0);
|
||||
return ((VARIABLE_ALIST *)NULL);
|
||||
}
|
||||
|
||||
/* User accepted "default"? (There is none.) */
|
||||
if (!*line)
|
||||
{
|
||||
free (line);
|
||||
return ((VARIABLE_ALIST *)NULL);
|
||||
}
|
||||
|
||||
/* Find the variable in our list of variables. */
|
||||
for (i = 0; info_variables[i].name; i++)
|
||||
if (strcmp (info_variables[i].name, line) == 0)
|
||||
break;
|
||||
|
||||
if (!info_variables[i].name)
|
||||
return ((VARIABLE_ALIST *)NULL);
|
||||
else
|
||||
return (&(info_variables[i]));
|
||||
}
|
||||
|
||||
/* Make an array of REFERENCE which actually contains the names of the
|
||||
variables available in Info. */
|
||||
REFERENCE **
|
||||
make_variable_completions_array ()
|
||||
{
|
||||
register int i;
|
||||
REFERENCE **array = (REFERENCE **)NULL;
|
||||
int array_index = 0, array_slots = 0;
|
||||
|
||||
for (i = 0; info_variables[i].name; i++)
|
||||
{
|
||||
REFERENCE *entry;
|
||||
|
||||
entry = (REFERENCE *)xmalloc (sizeof (REFERENCE));
|
||||
entry->label = savestring (info_variables[i].name);
|
||||
entry->nodename = (char *)NULL;
|
||||
entry->filename = (char *)NULL;
|
||||
|
||||
add_pointer_to_array
|
||||
(entry, array_index, array, array_slots, 200, REFERENCE *);
|
||||
}
|
||||
|
||||
return (array);
|
||||
}
|
64
gnu/usr.bin/texinfo/info/variables.h
Normal file
64
gnu/usr.bin/texinfo/info/variables.h
Normal file
@ -0,0 +1,64 @@
|
||||
/* variables.h -- Description of user visible variables in Info. */
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#ifndef _VARIABLES_H_
|
||||
#define _VARIABLES_H_
|
||||
|
||||
/* A variable (in the Info sense) is an integer value with a user-visible
|
||||
name. You may supply an array of strings to complete over when the
|
||||
variable is set; in that case, the variable is set to the index of the
|
||||
string that the user chose. If you supply a null list, the user can
|
||||
set the variable to a numeric value. */
|
||||
|
||||
/* Structure describing a user visible variable. */
|
||||
typedef struct {
|
||||
char *name; /* Polite name. */
|
||||
char *doc; /* Documentation string. */
|
||||
int *value; /* Address of value. */
|
||||
char **choices; /* Array of strings or NULL if numeric only. */
|
||||
} VARIABLE_ALIST;
|
||||
|
||||
/* Read the name of an Info variable in the echo area and return the
|
||||
address of a VARIABLE_ALIST member. A return value of NULL indicates
|
||||
that no variable could be read. */
|
||||
extern VARIABLE_ALIST *read_variable_name ();
|
||||
|
||||
/* Make an array of REFERENCE which actually contains the names of the
|
||||
variables available in Info. */
|
||||
extern REFERENCE **make_variable_completions_array ();
|
||||
|
||||
/* Set the value of an info variable. */
|
||||
extern void set_variable ();
|
||||
|
||||
/* The list of user-visible variables. */
|
||||
extern int auto_footnotes_p;
|
||||
extern int auto_tiling_p;
|
||||
extern int terminal_use_visible_bell_p;
|
||||
extern int info_error_rings_bell_p;
|
||||
extern int gc_compressed_files;
|
||||
extern int show_index_match;
|
||||
extern int info_scroll_behaviour;
|
||||
extern int window_scroll_step;
|
||||
extern int ISO_Latin_p;
|
||||
|
||||
#endif /* _VARIABLES_H_ */
|
1478
gnu/usr.bin/texinfo/info/window.c
Normal file
1478
gnu/usr.bin/texinfo/info/window.c
Normal file
File diff suppressed because it is too large
Load Diff
229
gnu/usr.bin/texinfo/info/window.h
Normal file
229
gnu/usr.bin/texinfo/info/window.h
Normal file
@ -0,0 +1,229 @@
|
||||
/* window.h -- Structure and flags used in manipulating Info windows. */
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#ifndef _WINDOW_H_
|
||||
#define _WINDOW_H_
|
||||
|
||||
#include "nodes.h"
|
||||
#include "infomap.h"
|
||||
|
||||
/* Smallest number of visible lines in a window. The actual height is
|
||||
always one more than this number because each window has a modeline. */
|
||||
#define WINDOW_MIN_HEIGHT 2
|
||||
|
||||
/* Smallest number of screen lines that can be used to fully present a
|
||||
window. This number includes the modeline of the window. */
|
||||
#define WINDOW_MIN_SIZE (WINDOW_MIN_HEIGHT + 1)
|
||||
|
||||
/* The exact same elements are used within the WINDOW_STATE structure and a
|
||||
subsection of the WINDOW structure. We could define a structure which
|
||||
contains this elements, and include that structure in each of WINDOW_STATE
|
||||
and WINDOW. But that would lead references in the code such as
|
||||
window->state->node which we would like to avoid. Instead, we #define the
|
||||
elements here, and simply include the define in both data structures. Thus,
|
||||
if you need to change window state information, here is where you would
|
||||
do it. NB> The last element does NOT end with a semi-colon. */
|
||||
#define WINDOW_STATE_DECL \
|
||||
NODE *node; /* The node displayed in this window. */ \
|
||||
int pagetop; /* LINE_STARTS[PAGETOP] is first line in WINDOW. */ \
|
||||
long point /* Offset within NODE of the cursor position. */
|
||||
|
||||
/* Structure which defines a window. Windows are doubly linked, next
|
||||
and prev. The list of windows is kept on WINDOWS. The structure member
|
||||
window->height is the total height of the window. The position location
|
||||
(0, window->height + window->first_row) is the first character of this
|
||||
windows modeline. The number of lines that can be displayed in a window
|
||||
is equal to window->height - 1. */
|
||||
typedef struct __window__ {
|
||||
struct __window__ *next; /* Next window in this chain. */
|
||||
struct __window__ *prev; /* Previous window in this chain. */
|
||||
int width; /* Width of this window. */
|
||||
int height; /* Height of this window. */
|
||||
int first_row; /* Offset of the first line in the_screen. */
|
||||
int goal_column; /* The column we would like the cursor to appear in. */
|
||||
Keymap keymap; /* Keymap used to read commands in this window. */
|
||||
WINDOW_STATE_DECL; /* Node, pagetop and point. */
|
||||
char *modeline; /* Calculated text of the modeline for this window. */
|
||||
char **line_starts; /* Array of printed line starts for this node. */
|
||||
int line_count; /* Number of lines appearing in LINE_STARTS. */
|
||||
int flags; /* See below for details. */
|
||||
} WINDOW;
|
||||
|
||||
typedef struct {
|
||||
WINDOW_STATE_DECL; /* What gets saved. */
|
||||
} WINDOW_STATE;
|
||||
|
||||
#define W_UpdateWindow 0x01 /* WINDOW needs updating. */
|
||||
#define W_WindowIsPerm 0x02 /* This WINDOW is a permanent object. */
|
||||
#define W_WindowVisible 0x04 /* This WINDOW is currently visible. */
|
||||
#define W_InhibitMode 0x08 /* This WINDOW has no modeline. */
|
||||
#define W_NoWrap 0x10 /* Lines do not wrap in this window. */
|
||||
#define W_InputWindow 0x20 /* Window accepts input. */
|
||||
#define W_TempWindow 0x40 /* Window is less important. */
|
||||
|
||||
extern WINDOW *windows; /* List of visible Info windows. */
|
||||
extern WINDOW *active_window; /* The currently active window. */
|
||||
extern WINDOW *the_screen; /* The Info screen is just another window. */
|
||||
extern WINDOW *the_echo_area; /* THE_ECHO_AREA is a window in THE_SCREEN. */
|
||||
|
||||
/* Global variable control redisplay of scrolled windows. If non-zero, it
|
||||
is the desired number of lines to scroll the window in order to make
|
||||
point visible. A user might set this to 1 for smooth scrolling. If
|
||||
set to zero, the line containing point is centered within the window. */
|
||||
extern int window_scroll_step;
|
||||
|
||||
/* Make the modeline member for WINDOW. */
|
||||
extern void window_make_modeline ();
|
||||
|
||||
/* Initalize the window system by creating THE_SCREEN and THE_ECHO_AREA.
|
||||
Create the first window ever, and make it permanent.
|
||||
You pass WIDTH and HEIGHT; the dimensions of the total screen size. */
|
||||
extern void window_initialize_windows ();
|
||||
|
||||
/* Make a new window showing NODE, and return that window structure.
|
||||
The new window is made to be the active window. If NODE is passed
|
||||
as NULL, then show the node showing in the active window. If the
|
||||
window could not be made return a NULL pointer. The active window
|
||||
is not changed.*/
|
||||
extern WINDOW *window_make_window ();
|
||||
|
||||
/* Delete WINDOW from the list of known windows. If this window was the
|
||||
active window, make the next window in the chain be the active window,
|
||||
or the previous window in the chain if there is no next window. */
|
||||
extern void window_delete_window ();
|
||||
|
||||
/* A function to call when the screen changes size, and some windows have
|
||||
to get deleted. The function is called with the window to be deleted
|
||||
as an argument, and it can't do anything about the window getting deleted;
|
||||
it can only clean up dangling references to that window. */
|
||||
extern VFunction *window_deletion_notifier;
|
||||
|
||||
/* Set WINDOW to display NODE. */
|
||||
extern void window_set_node_of_window ();
|
||||
|
||||
/* Tell the window system that the size of the screen has changed. This
|
||||
causes lots of interesting things to happen. The permanent windows
|
||||
are resized, as well as every visible window. You pass WIDTH and HEIGHT;
|
||||
the dimensions of the total screen size. */
|
||||
extern void window_new_screen_size ();
|
||||
|
||||
/* Change the height of WINDOW by AMOUNT. This also automagically adjusts
|
||||
the previous and next windows in the chain. If there is only one user
|
||||
window, then no change takes place. */
|
||||
extern void window_change_window_height ();
|
||||
|
||||
/* Adjust the pagetop of WINDOW such that the cursor point will be visible. */
|
||||
extern void window_adjust_pagetop ();
|
||||
|
||||
/* Tile all of the windows currently displayed in the global variable
|
||||
WINDOWS. If argument DO_INTERNALS is non-zero, tile windows displaying
|
||||
internal nodes as well. */
|
||||
#define DONT_TILE_INTERNALS 0
|
||||
#define TILE_INTERNALS 1
|
||||
extern void window_tile_windows ();
|
||||
|
||||
/* Toggle the state of line wrapping in WINDOW. This can do a bit of fancy
|
||||
redisplay. */
|
||||
extern void window_toggle_wrap ();
|
||||
|
||||
/* For every window in CHAIN, set the flags member to have FLAG set. */
|
||||
extern void window_mark_chain ();
|
||||
|
||||
/* For every window in CHAIN, clear the flags member of FLAG. */
|
||||
extern void window_unmark_chain ();
|
||||
|
||||
/* Make WINDOW start displaying at PERCENT percentage of its node. */
|
||||
extern void window_goto_percentage ();
|
||||
|
||||
/* Build a new node which has FORMAT printed with ARG1 and ARG2 as the
|
||||
contents. */
|
||||
extern NODE *build_message_node ();
|
||||
|
||||
/* Useful functions can be called from outside of window.c. */
|
||||
extern void initialize_message_buffer ();
|
||||
|
||||
/* Print FORMAT with ARG1,2 to the end of the current message buffer. */
|
||||
extern void printf_to_message_buffer ();
|
||||
|
||||
/* Convert the contents of the message buffer to a node. */
|
||||
extern NODE *message_buffer_to_node ();
|
||||
|
||||
/* Return the length of the most recently printed line in message buffer. */
|
||||
extern int message_buffer_length_this_line ();
|
||||
|
||||
/* Pad STRING to COUNT characters by inserting blanks. */
|
||||
extern int pad_to ();
|
||||
|
||||
/* Make a message appear in the echo area, built from FORMAT, ARG1 and ARG2.
|
||||
The arguments are treated similar to printf () arguments, but not all of
|
||||
printf () hair is present. The message appears immediately. If there was
|
||||
already a message appearing in the echo area, it is removed. */
|
||||
extern void window_message_in_echo_area ();
|
||||
|
||||
/* Place a temporary message in the echo area built from FORMAT, ARG1
|
||||
and ARG2. The message appears immediately, but does not destroy
|
||||
any existing message. A future call to unmessage_in_echo_area ()
|
||||
restores the old contents. */
|
||||
extern void message_in_echo_area ();
|
||||
extern void unmessage_in_echo_area ();
|
||||
|
||||
/* Clear the echo area, removing any message that is already present.
|
||||
The echo area is cleared immediately. */
|
||||
extern void window_clear_echo_area ();
|
||||
|
||||
/* Quickly guess the approximate number of lines to that NODE would
|
||||
take to display. This really only counts carriage returns. */
|
||||
extern int window_physical_lines ();
|
||||
|
||||
/* Calculate a list of line starts for the node belonging to WINDOW. The line
|
||||
starts are pointers to the actual text within WINDOW->NODE. */
|
||||
extern void calculate_line_starts ();
|
||||
|
||||
/* Given WINDOW, recalculate the line starts for the node it displays. */
|
||||
extern void recalculate_line_starts ();
|
||||
|
||||
/* Return the number of characters it takes to display CHARACTER on the
|
||||
screen at HPOS. */
|
||||
extern int character_width ();
|
||||
|
||||
/* Return the number of characters it takes to display STRING on the
|
||||
screen at HPOS. */
|
||||
extern int string_width ();
|
||||
|
||||
/* Return the index of the line containing point. */
|
||||
extern int window_line_of_point ();
|
||||
|
||||
/* Get and return the goal column for this window. */
|
||||
extern int window_get_goal_column ();
|
||||
|
||||
/* Get and return the printed column offset of the cursor in this window. */
|
||||
extern int window_get_cursor_column ();
|
||||
|
||||
/* Get and Set the node, pagetop, and point of WINDOW. */
|
||||
extern void window_get_state (), window_set_state ();
|
||||
|
||||
/* Count the number of characters in LINE that precede the printed column
|
||||
offset of GOAL. */
|
||||
extern int window_chars_to_goal ();
|
||||
|
||||
#endif /* !_WINDOW_H_ */
|
78
gnu/usr.bin/texinfo/info/xmalloc.c
Normal file
78
gnu/usr.bin/texinfo/info/xmalloc.c
Normal file
@ -0,0 +1,78 @@
|
||||
/* xmalloc.c -- safe versions of malloc and realloc */
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
This file has appeared in prior works by the Free Software Foundation;
|
||||
thus it carries copyright dates from 1988 through 1993.
|
||||
|
||||
Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#if !defined (ALREADY_HAVE_XMALLOC)
|
||||
#include <stdio.h>
|
||||
|
||||
static void memory_error_and_abort ();
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Memory Allocation and Deallocation. */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Return a pointer to free()able block of memory large enough
|
||||
to hold BYTES number of bytes. If the memory cannot be allocated,
|
||||
print an error message and abort. */
|
||||
void *
|
||||
xmalloc (bytes)
|
||||
int bytes;
|
||||
{
|
||||
void *temp = (void *)malloc (bytes);
|
||||
|
||||
if (!temp)
|
||||
memory_error_and_abort ("xmalloc");
|
||||
return (temp);
|
||||
}
|
||||
|
||||
void *
|
||||
xrealloc (pointer, bytes)
|
||||
void *pointer;
|
||||
int bytes;
|
||||
{
|
||||
void *temp;
|
||||
|
||||
if (!pointer)
|
||||
temp = (void *)malloc (bytes);
|
||||
else
|
||||
temp = (void *)realloc (pointer, bytes);
|
||||
|
||||
if (!temp)
|
||||
memory_error_and_abort ("xrealloc");
|
||||
|
||||
return (temp);
|
||||
}
|
||||
|
||||
static void
|
||||
memory_error_and_abort (fname)
|
||||
char *fname;
|
||||
{
|
||||
fprintf (stderr, "%s: Out of virtual memory!\n", fname);
|
||||
abort ();
|
||||
}
|
||||
#endif /* !ALREADY_HAVE_XMALLOC */
|
20
gnu/usr.bin/texinfo/makedoc/Makefile
Normal file
20
gnu/usr.bin/texinfo/makedoc/Makefile
Normal file
@ -0,0 +1,20 @@
|
||||
#
|
||||
# Bmakefile for GNU info
|
||||
#
|
||||
# $id$
|
||||
#
|
||||
|
||||
PROG= makedoc
|
||||
|
||||
SRCS+= makedoc.c xmalloc.c
|
||||
|
||||
CFLAGS+= -I${.CURDIR}/../info -I${.CURDIR}
|
||||
CFLAGS+= -DNAMED_FUNCTIONS=1 -DSTDC_HEADERS=1
|
||||
CFLAGS+= -DHAVE_UNISTD_H=1 -DHAVE_STRING_H=1 -DHAVE_VARARGS_H=1
|
||||
CFLAGS+= -DHAVE_SYS_FCNTL_H=1 -DHAVE_SETVBUF=1 -DHAVE_GETCWD=1 -DHAVE_BZERO=1
|
||||
CFLAGS+= -DHAVE_RINDEX=1 -DHAVE_VFPRINTF=1 -DHAVE_VSPRINTF=1
|
||||
CFLAGS+= -DHAVE_SYS_TIME_H=1 -DDEFAULT_INFOPATH='"${INFODIR}"'
|
||||
|
||||
.include "../../Makefile.inc"
|
||||
.include <bsd.prog.mk>
|
||||
|
477
gnu/usr.bin/texinfo/makedoc/makedoc.c
Normal file
477
gnu/usr.bin/texinfo/makedoc/makedoc.c
Normal file
@ -0,0 +1,477 @@
|
||||
/* makedoc.c -- Make DOC.C and FUNS.H from input files. */
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
/* This program grovels the contents of the source files passed as arguments
|
||||
and writes out a file of function pointers and documentation strings, and
|
||||
a header file which describes the contents. This only does the functions
|
||||
declared with DECLARE_INFO_COMMAND. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/stat.h>
|
||||
#include "general.h"
|
||||
|
||||
#if !defined (O_RDONLY)
|
||||
#if defined (HAVE_SYS_FCNTL_H)
|
||||
#include <sys/fcntl.h>
|
||||
#else /* !HAVE_SYS_FCNTL_H */
|
||||
#include <fcntl.h>
|
||||
#endif /* !HAVE_SYS_FCNTL_H */
|
||||
#endif /* !O_RDONLY */
|
||||
|
||||
extern void *xmalloc (), *xrealloc ();
|
||||
static void fatal_file_error ();
|
||||
|
||||
/* Name of the header file which receives the declarations of functions. */
|
||||
static char *funs_filename = "funs.h";
|
||||
|
||||
/* Name of the documentation to function pointer file. */
|
||||
static char *doc_filename = "doc.c";
|
||||
|
||||
static char *doc_header[] = {
|
||||
"/* doc.c -- Generated structure containing function names and doc strings.",
|
||||
"",
|
||||
" This file was automatically made from various source files with the",
|
||||
" command \"%s\". DO NOT EDIT THIS FILE, only \"%s.c\".",
|
||||
(char *)NULL
|
||||
};
|
||||
|
||||
static char *doc_header_1[] = {
|
||||
" An entry in the array FUNCTION_DOC_ARRAY is made for each command",
|
||||
" found in the above files; each entry consists of a function pointer,",
|
||||
#if defined (NAMED_FUNCTIONS)
|
||||
" a string which is the user-visible name of the function,",
|
||||
#endif /* NAMED_FUNCTIONS */
|
||||
" and a string which documents its purpose. */",
|
||||
"",
|
||||
"#include \"doc.h\"",
|
||||
"#include \"funs.h\"",
|
||||
"",
|
||||
"FUNCTION_DOC function_doc_array[] = {",
|
||||
"",
|
||||
(char *)NULL
|
||||
};
|
||||
|
||||
/* How to remember the locations of the functions found so that Emacs
|
||||
can use the information in a tag table. */
|
||||
typedef struct {
|
||||
char *name; /* Name of the tag. */
|
||||
int line; /* Line number at which it appears. */
|
||||
long char_offset; /* Character offset at which it appears. */
|
||||
} EMACS_TAG;
|
||||
|
||||
typedef struct {
|
||||
char *filename; /* Name of the file containing entries. */
|
||||
long entrylen; /* Total number of characters in tag block. */
|
||||
EMACS_TAG **entries; /* Entries found in FILENAME. */
|
||||
int entries_index;
|
||||
int entries_slots;
|
||||
} EMACS_TAG_BLOCK;
|
||||
|
||||
EMACS_TAG_BLOCK **emacs_tags = (EMACS_TAG_BLOCK **)NULL;
|
||||
int emacs_tags_index = 0;
|
||||
int emacs_tags_slots = 0;
|
||||
|
||||
#define DECLARATION_STRING "\nDECLARE_INFO_COMMAND"
|
||||
|
||||
static void process_one_file ();
|
||||
static void maybe_dump_tags ();
|
||||
static FILE *must_fopen ();
|
||||
|
||||
int
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
register int i;
|
||||
int tags_only = 0;
|
||||
FILE *funs_stream, *doc_stream;
|
||||
|
||||
for (i = 1; i < argc; i++)
|
||||
if (strcmp (argv[i], "-tags") == 0)
|
||||
{
|
||||
tags_only++;
|
||||
break;
|
||||
}
|
||||
|
||||
if (tags_only)
|
||||
{
|
||||
funs_filename = "/dev/null";
|
||||
doc_filename = "/dev/null";
|
||||
}
|
||||
|
||||
funs_stream = must_fopen (funs_filename, "w");
|
||||
doc_stream = must_fopen (doc_filename, "w");
|
||||
|
||||
fprintf (funs_stream,
|
||||
"/* %s -- Generated declarations for Info commands. */\n",
|
||||
funs_filename);
|
||||
|
||||
for (i = 0; doc_header[i]; i++)
|
||||
{
|
||||
fprintf (doc_stream, doc_header[i], argv[0], argv[0]);
|
||||
fprintf (doc_stream, "\n");
|
||||
}
|
||||
|
||||
fprintf (doc_stream,
|
||||
" Source files groveled to make this file include:\n\n");
|
||||
|
||||
for (i = 1; i < argc; i++)
|
||||
fprintf (doc_stream, "\t%s\n", argv[i]);
|
||||
|
||||
fprintf (doc_stream, "\n");
|
||||
|
||||
for (i = 0; doc_header_1[i]; i++)
|
||||
fprintf (doc_stream, "%s\n", doc_header_1[i]);
|
||||
|
||||
|
||||
for (i = 1; i < argc; i++)
|
||||
{
|
||||
char *curfile;
|
||||
curfile = argv[i];
|
||||
|
||||
if (*curfile == '-')
|
||||
continue;
|
||||
|
||||
fprintf (doc_stream, "/* Commands found in \"%s\". */\n", curfile);
|
||||
fprintf (funs_stream, "\n/* Functions declared in \"%s\". */\n",
|
||||
curfile);
|
||||
|
||||
process_one_file (curfile, doc_stream, funs_stream);
|
||||
}
|
||||
|
||||
fprintf (doc_stream,
|
||||
" { (VFunction *)NULL, (char *)NULL, (char *)NULL }\n};\n");
|
||||
|
||||
fclose (funs_stream);
|
||||
fclose (doc_stream);
|
||||
|
||||
if (tags_only)
|
||||
maybe_dump_tags (stdout);
|
||||
exit (0);
|
||||
}
|
||||
|
||||
/* Dumping out the contents of an Emacs tags table. */
|
||||
static void
|
||||
maybe_dump_tags (stream)
|
||||
FILE *stream;
|
||||
{
|
||||
register int i;
|
||||
|
||||
/* Print out the information for each block. */
|
||||
for (i = 0; i < emacs_tags_index; i++)
|
||||
{
|
||||
register int j;
|
||||
register EMACS_TAG_BLOCK *block;
|
||||
register EMACS_TAG *etag;
|
||||
long block_len;
|
||||
|
||||
block_len = 0;
|
||||
block = emacs_tags[i];
|
||||
|
||||
/* Calculate the length of the dumped block first. */
|
||||
for (j = 0; j < block->entries_index; j++)
|
||||
{
|
||||
char digits[30];
|
||||
etag = block->entries[j];
|
||||
block_len += 3 + strlen (etag->name);
|
||||
sprintf (digits, "%d,%d", etag->line, etag->char_offset);
|
||||
block_len += strlen (digits);
|
||||
}
|
||||
|
||||
/* Print out the defining line. */
|
||||
fprintf (stream, "\f\n%s,%d\n", block->filename, block_len);
|
||||
|
||||
/* Print out the individual tags. */
|
||||
for (j = 0; j < block->entries_index; j++)
|
||||
{
|
||||
etag = block->entries[j];
|
||||
|
||||
fprintf (stream, "%s,\177%d,%d\n",
|
||||
etag->name, etag->line, etag->char_offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Keeping track of names, line numbers and character offsets of functions
|
||||
found in source files. */
|
||||
static EMACS_TAG_BLOCK *
|
||||
make_emacs_tag_block (filename)
|
||||
char *filename;
|
||||
{
|
||||
EMACS_TAG_BLOCK *block;
|
||||
|
||||
block = (EMACS_TAG_BLOCK *)xmalloc (sizeof (EMACS_TAG_BLOCK));
|
||||
block->filename = savestring (filename);
|
||||
block->entrylen = 0;
|
||||
block->entries = (EMACS_TAG **)NULL;
|
||||
block->entries_index = 0;
|
||||
block->entries_slots = 0;
|
||||
return (block);
|
||||
}
|
||||
|
||||
static void
|
||||
add_tag_to_block (block, name, line, char_offset)
|
||||
EMACS_TAG_BLOCK *block;
|
||||
char *name;
|
||||
int line;
|
||||
long char_offset;
|
||||
{
|
||||
EMACS_TAG *tag;
|
||||
|
||||
tag = (EMACS_TAG *)xmalloc (sizeof (EMACS_TAG));
|
||||
tag->name = name;
|
||||
tag->line = line;
|
||||
tag->char_offset = char_offset;
|
||||
add_pointer_to_array (tag, block->entries_index, block->entries,
|
||||
block->entries_slots, 50, EMACS_TAG *);
|
||||
}
|
||||
|
||||
/* Read the file represented by FILENAME into core, and search it for Info
|
||||
function declarations. Output the declarations in various forms to the
|
||||
DOC_STREAM and FUNS_STREAM. */
|
||||
static void
|
||||
process_one_file (filename, doc_stream, funs_stream)
|
||||
char *filename;
|
||||
FILE *doc_stream, *funs_stream;
|
||||
{
|
||||
int descriptor, decl_len;
|
||||
char *buffer, *decl_str;
|
||||
struct stat finfo;
|
||||
long offset;
|
||||
EMACS_TAG_BLOCK *block;
|
||||
|
||||
if (stat (filename, &finfo) == -1)
|
||||
fatal_file_error (filename);
|
||||
|
||||
descriptor = open (filename, O_RDONLY, 0666);
|
||||
|
||||
if (descriptor == -1)
|
||||
fatal_file_error (filename);
|
||||
|
||||
buffer = (char *)xmalloc (1 + finfo.st_size);
|
||||
read (descriptor, buffer, finfo.st_size);
|
||||
close (descriptor);
|
||||
|
||||
offset = 0;
|
||||
decl_str = DECLARATION_STRING;
|
||||
decl_len = strlen (decl_str);
|
||||
|
||||
block = make_emacs_tag_block (filename);
|
||||
|
||||
while (1)
|
||||
{
|
||||
long point = 0;
|
||||
long line_start = 0;
|
||||
int line_number = 0;
|
||||
|
||||
char *func, *doc;
|
||||
#if defined (NAMED_FUNCTIONS)
|
||||
char *func_name;
|
||||
#endif /* NAMED_FUNCTIONS */
|
||||
|
||||
for (; offset < (finfo.st_size - decl_len); offset++)
|
||||
{
|
||||
if (buffer[offset] == '\n')
|
||||
{
|
||||
line_number++;
|
||||
line_start = offset + 1;
|
||||
}
|
||||
|
||||
if (strncmp (buffer + offset, decl_str, decl_len) == 0)
|
||||
{
|
||||
offset += decl_len;
|
||||
point = offset;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!point)
|
||||
break;
|
||||
|
||||
/* Skip forward until we find the open paren. */
|
||||
while (point < finfo.st_size)
|
||||
{
|
||||
if (buffer[point] == '\n')
|
||||
{
|
||||
line_number++;
|
||||
line_start = point + 1;
|
||||
}
|
||||
else if (buffer[point] == '(')
|
||||
break;
|
||||
|
||||
point++;
|
||||
}
|
||||
|
||||
while (point++ < finfo.st_size)
|
||||
{
|
||||
if (!whitespace_or_newline (buffer[point]))
|
||||
break;
|
||||
else if (buffer[point] == '\n')
|
||||
{
|
||||
line_number++;
|
||||
line_start = point + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (point >= finfo.st_size)
|
||||
break;
|
||||
|
||||
/* Now looking at name of function. Get it. */
|
||||
for (offset = point; buffer[offset] != ','; offset++);
|
||||
func = (char *)xmalloc (1 + (offset - point));
|
||||
strncpy (func, buffer + point, offset - point);
|
||||
func[offset - point] = '\0';
|
||||
|
||||
/* Remember this tag in the current block. */
|
||||
{
|
||||
char *tag_name;
|
||||
|
||||
tag_name = (char *)xmalloc (1 + (offset - line_start));
|
||||
strncpy (tag_name, buffer + line_start, offset - line_start);
|
||||
tag_name[offset - line_start] = '\0';
|
||||
add_tag_to_block (block, tag_name, line_number, point);
|
||||
}
|
||||
|
||||
#if defined (NAMED_FUNCTIONS)
|
||||
/* Generate the user-visible function name from the function's name. */
|
||||
{
|
||||
register int i;
|
||||
char *name_start;
|
||||
|
||||
name_start = func;
|
||||
|
||||
if (strncmp (name_start, "info_", 5) == 0)
|
||||
name_start += 5;
|
||||
|
||||
func_name = savestring (name_start);
|
||||
|
||||
/* Fix up "ea" commands. */
|
||||
if (strncmp (func_name, "ea_", 3) == 0)
|
||||
{
|
||||
char *temp_func_name;
|
||||
|
||||
temp_func_name = (char *)xmalloc (10 + strlen (func_name));
|
||||
strcpy (temp_func_name, "echo_area_");
|
||||
strcat (temp_func_name, func_name + 3);
|
||||
free (func_name);
|
||||
func_name = temp_func_name;
|
||||
}
|
||||
|
||||
for (i = 0; func_name[i]; i++)
|
||||
if (func_name[i] == '_')
|
||||
func_name[i] = '-';
|
||||
}
|
||||
#endif /* NAMED_FUNCTIONS */
|
||||
|
||||
/* Find doc string. */
|
||||
point = offset + 1;
|
||||
|
||||
while (point < finfo.st_size)
|
||||
{
|
||||
if (buffer[point] == '\n')
|
||||
{
|
||||
line_number++;
|
||||
line_start = point + 1;
|
||||
}
|
||||
|
||||
if (buffer[point] == '"')
|
||||
break;
|
||||
else
|
||||
point++;
|
||||
}
|
||||
|
||||
offset = point + 1;
|
||||
|
||||
while (offset < finfo.st_size)
|
||||
{
|
||||
if (buffer[offset] == '\n')
|
||||
{
|
||||
line_number++;
|
||||
line_start = offset + 1;
|
||||
}
|
||||
|
||||
if (buffer[offset] == '\\')
|
||||
offset += 2;
|
||||
else if (buffer[offset] == '"')
|
||||
break;
|
||||
else
|
||||
offset++;
|
||||
}
|
||||
|
||||
offset++;
|
||||
if (offset >= finfo.st_size)
|
||||
break;
|
||||
|
||||
doc = (char *)xmalloc (1 + (offset - point));
|
||||
strncpy (doc, buffer + point, offset - point);
|
||||
doc[offset - point] = '\0';
|
||||
|
||||
#if defined (NAMED_FUNCTIONS)
|
||||
fprintf (doc_stream, " { %s, \"%s\", %s },\n", func, func_name, doc);
|
||||
free (func_name);
|
||||
#else /* !NAMED_FUNCTIONS */
|
||||
fprintf (doc_stream, " { %s, %s },\n", func, doc);
|
||||
#endif /* !NAMED_FUNCTIONS */
|
||||
|
||||
fprintf (funs_stream, "extern void %s ();\n", func);
|
||||
free (func);
|
||||
free (doc);
|
||||
}
|
||||
free (buffer);
|
||||
|
||||
/* If we created any tags, remember this file on our global list. Otherwise,
|
||||
free the memory already allocated to it. */
|
||||
if (block->entries)
|
||||
add_pointer_to_array (block, emacs_tags_index, emacs_tags,
|
||||
emacs_tags_slots, 10, EMACS_TAG_BLOCK *);
|
||||
else
|
||||
{
|
||||
free (block->filename);
|
||||
free (block);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fatal_file_error (filename)
|
||||
char *filename;
|
||||
{
|
||||
fprintf (stderr, "Couldn't manipulate the file %s.\n", filename);
|
||||
exit (2);
|
||||
}
|
||||
|
||||
static FILE *
|
||||
must_fopen (filename, mode)
|
||||
char *filename, *mode;
|
||||
{
|
||||
FILE *stream;
|
||||
|
||||
stream = fopen (filename, mode);
|
||||
if (!stream)
|
||||
fatal_file_error (filename);
|
||||
|
||||
return (stream);
|
||||
}
|
||||
|
78
gnu/usr.bin/texinfo/makedoc/xmalloc.c
Normal file
78
gnu/usr.bin/texinfo/makedoc/xmalloc.c
Normal file
@ -0,0 +1,78 @@
|
||||
/* xmalloc.c -- safe versions of malloc and realloc */
|
||||
|
||||
/* This file is part of GNU Info, a program for reading online documentation
|
||||
stored in Info format.
|
||||
|
||||
This file has appeared in prior works by the Free Software Foundation;
|
||||
thus it carries copyright dates from 1988 through 1993.
|
||||
|
||||
Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Written by Brian Fox (bfox@ai.mit.edu). */
|
||||
|
||||
#if !defined (ALREADY_HAVE_XMALLOC)
|
||||
#include <stdio.h>
|
||||
|
||||
static void memory_error_and_abort ();
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Memory Allocation and Deallocation. */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Return a pointer to free()able block of memory large enough
|
||||
to hold BYTES number of bytes. If the memory cannot be allocated,
|
||||
print an error message and abort. */
|
||||
void *
|
||||
xmalloc (bytes)
|
||||
int bytes;
|
||||
{
|
||||
void *temp = (void *)malloc (bytes);
|
||||
|
||||
if (!temp)
|
||||
memory_error_and_abort ("xmalloc");
|
||||
return (temp);
|
||||
}
|
||||
|
||||
void *
|
||||
xrealloc (pointer, bytes)
|
||||
void *pointer;
|
||||
int bytes;
|
||||
{
|
||||
void *temp;
|
||||
|
||||
if (!pointer)
|
||||
temp = (void *)malloc (bytes);
|
||||
else
|
||||
temp = (void *)realloc (pointer, bytes);
|
||||
|
||||
if (!temp)
|
||||
memory_error_and_abort ("xrealloc");
|
||||
|
||||
return (temp);
|
||||
}
|
||||
|
||||
static void
|
||||
memory_error_and_abort (fname)
|
||||
char *fname;
|
||||
{
|
||||
fprintf (stderr, "%s: Out of virtual memory!\n", fname);
|
||||
abort ();
|
||||
}
|
||||
#endif /* !ALREADY_HAVE_XMALLOC */
|
21
gnu/usr.bin/texinfo/makeinfo/Makefile
Normal file
21
gnu/usr.bin/texinfo/makeinfo/Makefile
Normal file
@ -0,0 +1,21 @@
|
||||
#
|
||||
# Bmakefile for GNU info
|
||||
#
|
||||
# $id$
|
||||
#
|
||||
|
||||
PROG= makeinfo
|
||||
|
||||
SRCS+= makeinfo.c getopt1.c getopt.c
|
||||
.PATH: ${.CURDIR}/../info
|
||||
|
||||
CFLAGS+= -I${.CURDIR}/../info -I${.CURDIR}
|
||||
CFLAGS+= -DNAMED_FUNCTIONS=1 -DSTDC_HEADERS=1
|
||||
CFLAGS+= -DHAVE_UNISTD_H=1 -DHAVE_STRING_H=1 -DHAVE_VARARGS_H=1
|
||||
CFLAGS+= -DHAVE_SYS_FCNTL_H=1 -DHAVE_SETVBUF=1 -DHAVE_GETCWD=1 -DHAVE_BZERO=1
|
||||
CFLAGS+= -DHAVE_RINDEX=1 -DHAVE_VFPRINTF=1 -DHAVE_VSPRINTF=1
|
||||
CFLAGS+= -DHAVE_SYS_TIME_H=1 -DDEFAULT_INFOPATH='"${INFODIR}"'
|
||||
|
||||
.include "../../Makefile.inc"
|
||||
.include <bsd.prog.mk>
|
||||
|
7549
gnu/usr.bin/texinfo/makeinfo/makeinfo.c
Normal file
7549
gnu/usr.bin/texinfo/makeinfo/makeinfo.c
Normal file
File diff suppressed because it is too large
Load Diff
96
gnu/usr.bin/texinfo/misc/Makefile
Normal file
96
gnu/usr.bin/texinfo/misc/Makefile
Normal file
@ -0,0 +1,96 @@
|
||||
# Generated automatically from Makefile.in by configure.
|
||||
# Makefile for GNU Texindex.
|
||||
# Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
#### Start of system configuration section. ####
|
||||
|
||||
srcdir = .
|
||||
VPATH = $(srcdir):$(common)
|
||||
|
||||
common = $(srcdir)/../libtxi
|
||||
|
||||
CC = gcc
|
||||
INSTALL = /usr/bin/install -c
|
||||
INSTALL_PROGRAM = $(INSTALL)
|
||||
INSTALL_DATA = $(INSTALL) -m 644
|
||||
|
||||
LN = ln
|
||||
RM = rm -f
|
||||
TAR = tar
|
||||
MKDIR = mkdir
|
||||
|
||||
DEFS = -DSTDC_HEADERS=1 -DHAVE_UNISTD_H=1 -DHAVE_STRING_H=1 -DHAVE_VARARGS_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_FCNTL_H=1 -DHAVE_SETVBUF=1 -DHAVE_GETCWD=1 -DHAVE_BZERO=1 -DHAVE_RINDEX=1 -DHAVE_VFPRINTF=1 -DHAVE_VSPRINTF=1
|
||||
LIBS = -L../libtxi -ltxi
|
||||
LOADLIBES = $(LIBS)
|
||||
|
||||
SHELL = /bin/sh
|
||||
|
||||
CFLAGS = -g
|
||||
LDFLAGS = -g
|
||||
|
||||
prefix = /usr/local
|
||||
exec_prefix = $(prefix)
|
||||
bindir = $(exec_prefix)/bin
|
||||
# Prefix for each installed program, normally empty or `g'.
|
||||
binprefix =
|
||||
libdir = $(prefix)/lib
|
||||
# Prefix for each installed man page, normally empty or `g'.
|
||||
manprefix =
|
||||
mandir = $(prefix)/man/man1
|
||||
manext = 1
|
||||
infodir = $(prefix)/info
|
||||
|
||||
#### End of system configuration section. ####
|
||||
|
||||
all: texindex
|
||||
sub-all: all
|
||||
|
||||
.c.o:
|
||||
$(CC) -c $(CPPFLAGS) $(DEFS) -I. -I$(srcdir) -I$(common) $(CFLAGS) $<
|
||||
|
||||
|
||||
install: all
|
||||
$(INSTALL_PROGRAM) texindex $(bindir)/texindex
|
||||
$(INSTALL_PROGRAM) $(srcdir)/texi2dvi $(bindir)/texi2dvi
|
||||
|
||||
uninstall:
|
||||
rm -f $(bindir)/texindex $(bindir)/texi2dvi
|
||||
|
||||
Makefile: Makefile.in ../config.status
|
||||
cd ..; sh config.status
|
||||
|
||||
TAGS:
|
||||
etags *.c *.h $(common)/getopt*.c $(common)/getopt.h
|
||||
|
||||
clean:
|
||||
rm -f *.o a.out core core.* texindex
|
||||
|
||||
mostlyclean: clean
|
||||
|
||||
distclean: clean
|
||||
rm -f Makefile config.status
|
||||
|
||||
realclean: distclean
|
||||
rm -f TAGS
|
||||
|
||||
texindex: texindex.o ../libtxi/libtxi.a
|
||||
$(CC) $(LDFLAGS) -o texindex texindex.o $(LOADLIBES)
|
||||
|
||||
texindex.o: texindex.c $(common)/getopt.h
|
||||
|
||||
# Prevent GNU make v3 from overflowing arg limit on SysV.
|
||||
.NOEXPORT:
|
95
gnu/usr.bin/texinfo/misc/Makefile.in
Normal file
95
gnu/usr.bin/texinfo/misc/Makefile.in
Normal file
@ -0,0 +1,95 @@
|
||||
# Makefile for GNU Texindex.
|
||||
# Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
#### Start of system configuration section. ####
|
||||
|
||||
srcdir = @srcdir@
|
||||
VPATH = $(srcdir):$(common)
|
||||
|
||||
common = $(srcdir)/../libtxi
|
||||
|
||||
CC = @CC@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
|
||||
LN = ln
|
||||
RM = rm -f
|
||||
TAR = tar
|
||||
MKDIR = mkdir
|
||||
|
||||
DEFS = @DEFS@
|
||||
LIBS = -L../libtxi -ltxi @LIBS@
|
||||
LOADLIBES = $(LIBS)
|
||||
|
||||
SHELL = /bin/sh
|
||||
|
||||
CFLAGS = -g
|
||||
LDFLAGS = -g
|
||||
|
||||
prefix = /usr/local
|
||||
exec_prefix = $(prefix)
|
||||
bindir = $(exec_prefix)/bin
|
||||
# Prefix for each installed program, normally empty or `g'.
|
||||
binprefix =
|
||||
libdir = $(prefix)/lib
|
||||
# Prefix for each installed man page, normally empty or `g'.
|
||||
manprefix =
|
||||
mandir = $(prefix)/man/man1
|
||||
manext = 1
|
||||
infodir = $(prefix)/info
|
||||
|
||||
#### End of system configuration section. ####
|
||||
|
||||
all: texindex
|
||||
sub-all: all
|
||||
|
||||
.c.o:
|
||||
$(CC) -c $(CPPFLAGS) $(DEFS) -I. -I$(srcdir) -I$(common) $(CFLAGS) $<
|
||||
|
||||
|
||||
install: all
|
||||
$(INSTALL_PROGRAM) texindex $(bindir)/texindex
|
||||
$(INSTALL_PROGRAM) $(srcdir)/texi2dvi $(bindir)/texi2dvi
|
||||
|
||||
uninstall:
|
||||
rm -f $(bindir)/texindex $(bindir)/texi2dvi
|
||||
|
||||
Makefile: Makefile.in ../config.status
|
||||
cd ..; sh config.status
|
||||
|
||||
TAGS:
|
||||
etags *.c *.h $(common)/getopt*.c $(common)/getopt.h
|
||||
|
||||
clean:
|
||||
rm -f *.o a.out core core.* texindex
|
||||
|
||||
mostlyclean: clean
|
||||
|
||||
distclean: clean
|
||||
rm -f Makefile config.status
|
||||
|
||||
realclean: distclean
|
||||
rm -f TAGS
|
||||
|
||||
texindex: texindex.o ../libtxi/libtxi.a
|
||||
$(CC) $(LDFLAGS) -o texindex texindex.o $(LOADLIBES)
|
||||
|
||||
texindex.o: texindex.c $(common)/getopt.h
|
||||
|
||||
# Prevent GNU make v3 from overflowing arg limit on SysV.
|
||||
.NOEXPORT:
|
171
gnu/usr.bin/texinfo/misc/NEWS
Normal file
171
gnu/usr.bin/texinfo/misc/NEWS
Normal file
@ -0,0 +1,171 @@
|
||||
This release of Info is version 2.8. Please read the file README.
|
||||
|
||||
Changes since 2.5 beta:
|
||||
|
||||
Note that versions 2.6 and 2.7 Beta were only released to a select group.
|
||||
|
||||
* "info-" removed from the front of M-x commands.
|
||||
|
||||
* Automatic footnote display. When you enter a node which contains
|
||||
footnotes, and the variable "automatic-footnotes" is "On", Info pops
|
||||
up a window containing the footnotes. Likewise, when you leave that
|
||||
node, the window containing the footnotes goes away.
|
||||
|
||||
* Cleaner built in documentation, and documentation functions.
|
||||
|
||||
Use:
|
||||
o `M-x describe-variable' to read a variable's documenation
|
||||
o `M-x describe-key' to find out what a particular keystroke does.
|
||||
o `M-x describe-function' to read a function's documentation.
|
||||
o `M-x where-is' to find out what keys invoke a particular function.
|
||||
|
||||
* Info can "tile" the displayed windows (via "M-x tile-windows"). If
|
||||
the variable "automatic-tiling" is "On", then splitting a window or
|
||||
deleting a window causes the remaining windows to be retiled.
|
||||
|
||||
* You can save every keystroke you type in a "dribble file" by using the
|
||||
`--dribble FILENAME' option. You can initially read keystrokes from an
|
||||
alternate input stream with `--restore FILENAME', or by redirecting
|
||||
input on the command line `info < old-dribble'.
|
||||
|
||||
* New behaviour of menu items. If the label is the same as the
|
||||
target node name, and the node couldn't be found in the current file,
|
||||
treat the label as a file name. For example, a menu entry in "DIR"
|
||||
might contain:
|
||||
|
||||
* Emacs:: Cool text-editor.
|
||||
|
||||
Info would not find the node "(dir)Emacs", so just plain "(emacs)"
|
||||
would be tried.
|
||||
|
||||
* New variable "ISO-Latin" allows you to use European machines with
|
||||
8-bit character sets.
|
||||
|
||||
* Cleanups in echo area reading, and redisplay. Cleanups in handling the
|
||||
window which shows possible completions.
|
||||
|
||||
* Info can now read files that have been compressed. An array in filesys.c
|
||||
maps extensions to programs that can decompress stdin, and write the results
|
||||
to stdout. Currently, ".Z"/uncompress, ".z"/gunzip, and ".Y"/unyabba are
|
||||
supported. The modeline for a compressed file shows "zz" in it.
|
||||
|
||||
* There is a new variable "gc-compressed-files" which, if non-zero, says
|
||||
it is okay to reclaim the file buffer space allocated to a file which
|
||||
was compressed, if, and only if, that file's contents do not appear in
|
||||
any history node.
|
||||
|
||||
* New file `nodemenu.c' implements a few functions for manipulating
|
||||
previously visited nodes. `C-x C-b' (list-visited-nodes) produces a
|
||||
menu of the nodes that could be reached by info-history-node in some
|
||||
window. `C-x b' (select-visited-node) is similar, but reads one of
|
||||
the node names with completion.
|
||||
|
||||
* Keystroke `M-r' (move_to_screen_line) allows the user to place the cursor at
|
||||
the start of a specific screen line. Without a numeric argument, place the
|
||||
cursor on the center line; with an arg, place the cursor on that line.
|
||||
|
||||
* Interruptible display implemented. Basic display speedups and hacks.
|
||||
* The message "*** Tags Out of Date ***" now means what it says.
|
||||
* Index searching with `,' (info-index-next) has been improved.
|
||||
* When scrolling with C-v, C-M-v, or M-v, only "Page Only" scrolling
|
||||
will happen.
|
||||
|
||||
* Continous scrolling (along with `]' (info-global-next) and `['
|
||||
(info-global-prev) works better. `]' and `[' accept numeric
|
||||
arguments, moving that many nodes in that case.
|
||||
|
||||
* `C-x w' (info-toggle-wrap) controls how lines wider than the width
|
||||
of the screen are displayed. If a line is too long, a `$' is
|
||||
displayed in the rightmost column of the window.
|
||||
|
||||
* There are some new variables for controlling the behaviour of Info
|
||||
interactively. The current list of variables is as follows:
|
||||
|
||||
Variable Name Default Value Description
|
||||
------------- ------------- -----------
|
||||
`automatic-footnotes' On When "On", footnotes appear and
|
||||
disappear automatically.
|
||||
|
||||
`automatic-tiling' Off When "On", creating of deleting a
|
||||
window resizes other windows.
|
||||
|
||||
`visible-bell' Off If non-zero, try to use a visible bell.
|
||||
|
||||
`errors-ring-bell' On If non-zero, errors cause a ring.
|
||||
|
||||
`show-index-match' On If non-zero, the portion of the string
|
||||
matched is highlighted by changing its
|
||||
case.
|
||||
|
||||
`scroll-behaviour' Continuous One of "Continuous", "Next Only", or
|
||||
"Page Only". "Page Only" prevents you from
|
||||
scrolling past the bottom or top of a node.
|
||||
"Next Only" causes the Next or Prev node to
|
||||
be selected when you scroll past the bottom
|
||||
or top of a node. "Continous" moves
|
||||
linearly through the files hierchichal
|
||||
structure.
|
||||
|
||||
`scroll-step' 0 Controls how scrolling is done for you when
|
||||
the cursor moves out of the current window.
|
||||
Non-zero means it is the number of lines
|
||||
you would like the screen to shift. A
|
||||
value of 0 means to center the line
|
||||
containing the cursor in the window.
|
||||
|
||||
`gc-compressed-files' Off If non-zero means it is okay to reclaim the
|
||||
file buffer space allocated to a file which
|
||||
was compressed, if, and only if, that
|
||||
file's contents do not appear in the node
|
||||
list of any window.
|
||||
|
||||
`ISO-Latin' Off Non-zero means that you are using an ISO
|
||||
Latin character set. By default, standard
|
||||
ASCII characters are assumed.
|
||||
________________________________________
|
||||
This release of Info is version 2.5 beta.
|
||||
|
||||
Changes since 2.4 beta:
|
||||
|
||||
* Index (i) and (,) commands fully implemented.
|
||||
* "configure" script now shipped with Info.
|
||||
* New function "set-variable" allows users to set various variables.
|
||||
* User-settable behaviour on end or beginning of node scrolling. This
|
||||
supercedes the SPC and DEL changes in 2.3 beta.
|
||||
|
||||
________________________________________
|
||||
This release of Info is version 2.4 beta.
|
||||
|
||||
Changes since 2.3 beta:
|
||||
|
||||
* info-last-node now means move to the last node of this info file.
|
||||
* info-history-node means move backwards through this window's node history.
|
||||
* info-first-node moves to the first node in the Info file. This node is
|
||||
not necessarily "Top"!
|
||||
* SPC and DEL can select the Next or Prev node after printing an informative
|
||||
message when pressed at the end/beg of a node.
|
||||
|
||||
----------------------------------------
|
||||
This release of Info is version 2.3 beta.
|
||||
|
||||
Changes since 2.2 beta:
|
||||
|
||||
* M-x command lines if NAMED_COMMANDS is #defined. Variable in Makefile.
|
||||
* Screen height changes made quite robust.
|
||||
* Interactive function "set-screen-height" implements user height changes.
|
||||
* Scrolling on some terminals is faster now.
|
||||
* C-l with numeric arguement is fixed.
|
||||
|
||||
----------------------------------------
|
||||
This release of Info is version 2.2 beta.
|
||||
|
||||
Changes since 2.0:
|
||||
|
||||
* C-g can now interrupt multi-file searches.
|
||||
* Incremental search is fully implemented.
|
||||
* Loading large tag tables is much faster now.
|
||||
* makedoc.c replaces shell script, speeding incremental builds.
|
||||
* Scrolling in redisplay is implemented.
|
||||
* Recursive uses of the echo area made more robust.
|
||||
* Garbage collection of unreferenced nodes.
|
||||
|
54
gnu/usr.bin/texinfo/misc/README
Normal file
54
gnu/usr.bin/texinfo/misc/README
Normal file
@ -0,0 +1,54 @@
|
||||
Please Emacs, use -*- text -*- mode when editing this file.
|
||||
|
||||
* The file RELEASE contains information about what has changed
|
||||
since the last release.
|
||||
|
||||
* The file INSTALL contains instructions on how to install Info.
|
||||
(Type "./configure" and then "make".)
|
||||
|
||||
This is the README file GNU Info version 2.8. This marks the first
|
||||
non-beta release.
|
||||
|
||||
Thu Jan 21 14:50:52 1993
|
||||
|
||||
----------------------------------------
|
||||
Version 2.7 beta, Wed Dec 30 02:02:38 1992
|
||||
Version 2.6 beta, Tue Dec 22 03:58:07 1992
|
||||
Version 2.5 beta, Tue Dec 8 14:50:35 1992
|
||||
Version 2.4 beta, Sat Nov 28 14:34:02 1992
|
||||
Version 2.3 beta, Fri Nov 27 01:04:13 1992
|
||||
Version 2.2 beta, Tue Nov 24 09:36:08 1992
|
||||
Version 2.1 beta, Tue Nov 17 23:29:36 1992
|
||||
|
||||
Info 2.0 is a complete rewrite of the original standalone Info I wrote
|
||||
in 1987, the first program I wrote for rms. That program was
|
||||
something like my second Unix program ever, and my die-hard machine
|
||||
language coding habits tended to show through. I found the original
|
||||
Info hard to read and maintain, and thus decided to write this one.
|
||||
|
||||
The rewrite consists of about 12,000 lines of code written in about 12
|
||||
days. I believe this version of Info to be in much better shape than
|
||||
the original Info, and the only reason it is in Beta test is because
|
||||
of its short life span.
|
||||
|
||||
Info 2.0 is substantially different from its original standalone
|
||||
predecessor. It appears almost identical to the GNU Emacs version,
|
||||
but has the advantages of smaller size, ease of portability, and a
|
||||
built in library which can be used in other programs (to get or
|
||||
display documentation from Info files, for example).
|
||||
|
||||
I eagerly await responses to this newer version of Info; comments on
|
||||
its portability, ease of use and user interface, code quality, and
|
||||
general usefulness are all of interest to me, and I will appreciate
|
||||
any comments that you would care to make.
|
||||
|
||||
A full listing of the commands available in Info can be gotten by
|
||||
typing `?' while within an Info window. This produces a node in a
|
||||
window which can be viewed just like any Info node.
|
||||
|
||||
So, please send your comments, bug reports, and suggestions to
|
||||
|
||||
bfox@ai.mit.edu
|
||||
|
||||
Thanks for beta testing this software.
|
||||
|
238
gnu/usr.bin/texinfo/misc/deref.c
Normal file
238
gnu/usr.bin/texinfo/misc/deref.c
Normal file
@ -0,0 +1,238 @@
|
||||
/*
|
||||
* deref.c
|
||||
|
||||
* compile command: gcc -g -o deref deref.c
|
||||
|
||||
* execute command: deref filename.texi > newfile.texi
|
||||
|
||||
* To: bob@gnu.ai.mit.edu
|
||||
* Subject: another tool
|
||||
* Date: 18 Dec 91 16:03:13 EST (Wed)
|
||||
* From: gatech!skeeve!arnold@eddie.mit.edu (Arnold D. Robbins)
|
||||
*
|
||||
* Here is deref.c. It turns texinfo cross references back into the
|
||||
* one argument form. It has the same limitations as fixref; one xref per
|
||||
* line and can't cross lines. You can use it to find references that do
|
||||
* cross a line boundary this way:
|
||||
*
|
||||
* deref < manual > /dev/null 2>errs
|
||||
*
|
||||
* (This assumes bash or /bin/sh.) The file errs will have list of lines
|
||||
* where deref could not find matching braces.
|
||||
*
|
||||
* A gawk manual processed by deref goes through makeinfo without complaint.
|
||||
* Compile with gcc and you should be set.
|
||||
*
|
||||
* Enjoy,
|
||||
*
|
||||
* Arnold
|
||||
* -----------
|
||||
*/
|
||||
|
||||
/*
|
||||
* deref.c
|
||||
*
|
||||
* Make all texinfo references into the one argument form.
|
||||
*
|
||||
* Arnold Robbins
|
||||
* arnold@skeeve.atl.ga.us
|
||||
* December, 1991
|
||||
*
|
||||
* Copyright, 1991, Arnold Robbins
|
||||
*/
|
||||
|
||||
/*
|
||||
* LIMITATIONS:
|
||||
* One texinfo cross reference per line.
|
||||
* Cross references may not cross newlines.
|
||||
* Use of fgets for input (to be fixed).
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
|
||||
/* for gcc on the 3B1, delete if this gives you grief */
|
||||
extern int fclose (FILE * fp);
|
||||
extern int fprintf (FILE * fp, const char *str,...);
|
||||
|
||||
extern char *strerror (int errno);
|
||||
extern char *strchr (char *cp, int ch);
|
||||
extern int strncmp (const char *s1, const char *s2, int count);
|
||||
|
||||
extern int errno;
|
||||
|
||||
void process (FILE * fp);
|
||||
void repair (char *line, char *ref, int toffset);
|
||||
|
||||
int Errs = 0;
|
||||
char *Name = "stdin";
|
||||
int Line = 0;
|
||||
char *Me;
|
||||
|
||||
/* main --- handle arguments, global vars for errors */
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
Me = argv[0];
|
||||
|
||||
if (argc == 1)
|
||||
process (stdin);
|
||||
else
|
||||
for (argc--, argv++; *argv != NULL; argc--, argv++)
|
||||
{
|
||||
if (argv[0][0] == '-' && argv[0][1] == '\0')
|
||||
{
|
||||
Name = "stdin";
|
||||
Line = 0;
|
||||
process (stdin);
|
||||
}
|
||||
else if ((fp = fopen (*argv, "r")) != NULL)
|
||||
{
|
||||
Name = *argv;
|
||||
Line = 0;
|
||||
process (fp);
|
||||
fclose (fp);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (stderr, "%s: can not open: %s\n",
|
||||
*argv, strerror (errno));
|
||||
Errs++;
|
||||
}
|
||||
}
|
||||
return Errs != 0;
|
||||
}
|
||||
|
||||
/* isref --- decide if we've seen a texinfo cross reference */
|
||||
|
||||
int
|
||||
isref (char *cp)
|
||||
{
|
||||
if (strncmp (cp, "@ref{", 5) == 0)
|
||||
return 5;
|
||||
if (strncmp (cp, "@xref{", 6) == 0)
|
||||
return 6;
|
||||
if (strncmp (cp, "@pxref{", 7) == 0)
|
||||
return 7;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* process --- read files, look for references, fix them up */
|
||||
|
||||
void
|
||||
process (FILE * fp)
|
||||
{
|
||||
char buf[BUFSIZ];
|
||||
char *cp;
|
||||
int count;
|
||||
|
||||
while (fgets (buf, sizeof buf, fp) != NULL)
|
||||
{
|
||||
Line++;
|
||||
cp = strchr (buf, '@');
|
||||
if (cp == NULL)
|
||||
{
|
||||
fputs (buf, stdout);
|
||||
continue;
|
||||
}
|
||||
do
|
||||
{
|
||||
count = isref (cp);
|
||||
if (count == 0)
|
||||
{
|
||||
cp++;
|
||||
cp = strchr (cp, '@');
|
||||
if (cp == NULL)
|
||||
{
|
||||
fputs (buf, stdout);
|
||||
goto next;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
/* got one */
|
||||
repair (buf, cp, count);
|
||||
break;
|
||||
}
|
||||
while (cp != NULL);
|
||||
next:;
|
||||
}
|
||||
}
|
||||
|
||||
/* repair --- turn all texinfo cross references into the one argument form */
|
||||
|
||||
void
|
||||
repair (char *line, char *ref, int toffset)
|
||||
{
|
||||
int braces = 1; /* have seen first left brace */
|
||||
char *cp;
|
||||
|
||||
ref += toffset;
|
||||
|
||||
/* output line up to and including left brace in reference */
|
||||
for (cp = line; cp <= ref; cp++)
|
||||
putchar (*cp);
|
||||
|
||||
/* output node name */
|
||||
for (; *cp && *cp != '}' && *cp != ',' && *cp != '\n'; cp++)
|
||||
putchar (*cp);
|
||||
|
||||
if (*cp != '}')
|
||||
{ /* could have been one arg xref */
|
||||
/* skip to matching right brace */
|
||||
for (; braces > 0; cp++)
|
||||
{
|
||||
switch (*cp)
|
||||
{
|
||||
case '@':
|
||||
cp++; /* blindly skip next character */
|
||||
break;
|
||||
case '{':
|
||||
braces++;
|
||||
break;
|
||||
case '}':
|
||||
braces--;
|
||||
break;
|
||||
case '\n':
|
||||
case '\0':
|
||||
Errs++;
|
||||
fprintf (stderr,
|
||||
"%s: %s: %d: mismatched braces\n",
|
||||
Me, Name, Line);
|
||||
goto out;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
out:
|
||||
;
|
||||
}
|
||||
|
||||
putchar ('}');
|
||||
if (*cp == '}')
|
||||
cp++;
|
||||
|
||||
/* now the rest of the line */
|
||||
for (; *cp; cp++)
|
||||
putchar (*cp);
|
||||
return;
|
||||
}
|
||||
|
||||
/* strerror --- return error string, delete if in your library */
|
||||
|
||||
char *
|
||||
strerror (int errno)
|
||||
{
|
||||
static char buf[100];
|
||||
extern int sys_nerr;
|
||||
extern char *sys_errlist[];
|
||||
|
||||
if (errno < sys_nerr && errno >= 0)
|
||||
return sys_errlist[errno];
|
||||
|
||||
sprintf (buf, "unknown error %d", errno);
|
||||
return buf;
|
||||
}
|
84
gnu/usr.bin/texinfo/misc/fixfonts
Executable file
84
gnu/usr.bin/texinfo/misc/fixfonts
Executable file
@ -0,0 +1,84 @@
|
||||
#!/bin/sh
|
||||
# Make links named `lcircle10' for all TFM and GF/PK files, if no
|
||||
# lcircle10 files already exist.
|
||||
|
||||
# Don't override definition of prefix and/or libdir if they are
|
||||
# already defined in the environment.
|
||||
if test "z${prefix}" = "z" ; then
|
||||
prefix=/usr/local
|
||||
else
|
||||
# prefix may contain references to other variables, thanks to make.
|
||||
eval prefix=\""${prefix}"\"
|
||||
fi
|
||||
|
||||
if test "z${libdir}" = "z" ; then
|
||||
libdir="${prefix}/lib/tex"
|
||||
else
|
||||
# libdir may contain references to other variables, thanks to make.
|
||||
eval libdir=\""${libdir}"\"
|
||||
fi
|
||||
|
||||
texlibdir="${libdir}"
|
||||
texfontdir="${texlibdir}/fonts"
|
||||
|
||||
# Directories for the different font formats, in case they're not all
|
||||
# stored in one place.
|
||||
textfmdir="${textfmdir-${texfontdir}}"
|
||||
texpkdir="${texpkdir-${texfontdir}}"
|
||||
texgfdir="${texgfdir-${texfontdir}}"
|
||||
|
||||
test "z${TMPDIR}" = "z" && TMPDIR="/tmp"
|
||||
|
||||
tempfile="${TMPDIR}/circ$$"
|
||||
tempfile2="${TMPDIR}/circ2$$"
|
||||
|
||||
# EXIT SIGHUP SIGINT SIGQUIT SIGTERM
|
||||
#trap 'rm -f "${tempfile}" "${tempfile2}"' 0 1 2 3 15
|
||||
|
||||
# Find all the fonts with names that include `circle'.
|
||||
(cd "${texfontdir}"; find . -name '*circle*' -print > "${tempfile}")
|
||||
|
||||
# If they have lcircle10.tfm, assume everything is there, and quit.
|
||||
if grep 'lcircle10\.tfm' "${tempfile}" > /dev/null 2>&1 ; then
|
||||
echo "Found lcircle10.tfm."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# No TFM file for lcircle. Make a link to circle10.tfm if it exists,
|
||||
# and then make a link to the bitmap files.
|
||||
grep 'circle10\.tfm' "${tempfile}" > "${tempfile2}" \
|
||||
|| {
|
||||
echo "I can't find any circle fonts in ${texfontdir}.
|
||||
If it isn't installed somewhere else, you need to get the Metafont sources
|
||||
from somewhere, e.g., labrea.stanford.edu:pub/tex/latex/circle10.mf, and
|
||||
run Metafont on them."
|
||||
exit 1
|
||||
}
|
||||
|
||||
# We have circle10.tfm. (If we have it more than once, take the first
|
||||
# one.) Make the link.
|
||||
tempfile2_line1="`sed -ne '1p;q' \"${tempfile2}\"`"
|
||||
ln "${tempfile2_line1}" "${textfmdir}/lcircle10.tfm"
|
||||
echo "Linked to ${tempfile2_line1}."
|
||||
|
||||
# Now make a link for the PK files, if any.
|
||||
(cd "${texpkdir}"
|
||||
for f in `grep 'circle10.*pk' "${tempfile}"` ; do
|
||||
set - `echo "$f" \
|
||||
| sed -ne '/\//!s/^/.\//;s/\(.*\)\/\([^\/][^\/]*\)$/\1 \2/;p'`
|
||||
ln "$f" "${1}/l${2}"
|
||||
echo "Linked to $f."
|
||||
done
|
||||
)
|
||||
|
||||
# And finally for the GF files.
|
||||
(cd "${texgfdir}"
|
||||
for f in `grep 'circle10.*gf' "${tempfile}"` ; do
|
||||
set - `echo "$f" \
|
||||
| sed -ne '/\//!s/^/.\//;s/\(.*\)\/\([^\/][^\/]*\)$/\1 \2/;p'`
|
||||
ln "$f" "${1}/l${2}"
|
||||
echo "Linked to $f."
|
||||
done
|
||||
)
|
||||
|
||||
# eof
|
35
gnu/usr.bin/texinfo/misc/mkinstalldirs
Executable file
35
gnu/usr.bin/texinfo/misc/mkinstalldirs
Executable file
@ -0,0 +1,35 @@
|
||||
#!/bin/sh
|
||||
# Make directory hierarchy.
|
||||
# Written by Noah Friedman <friedman@prep.ai.mit.edu>
|
||||
# Public domain.
|
||||
|
||||
defaultIFS='
|
||||
'
|
||||
IFS="${IFS-${defaultIFS}}"
|
||||
|
||||
errstatus=0
|
||||
|
||||
for file in ${1+"$@"} ; do
|
||||
oIFS="${IFS}"
|
||||
# Some sh's can't handle IFS=/ for some reason.
|
||||
IFS='%'
|
||||
set - `echo ${file} | sed -e 's@/@%@g' -e 's@^%@/@'`
|
||||
IFS="${oIFS}"
|
||||
|
||||
pathcomp=''
|
||||
|
||||
for d in ${1+"$@"} ; do
|
||||
pathcomp="${pathcomp}${d}"
|
||||
|
||||
if test ! -d "${pathcomp}"; then
|
||||
echo "mkdir $pathcomp" 1>&2
|
||||
mkdir "${pathcomp}" || errstatus=$?
|
||||
fi
|
||||
|
||||
pathcomp="${pathcomp}/"
|
||||
done
|
||||
done
|
||||
|
||||
exit $errstatus
|
||||
|
||||
# eof
|
71
gnu/usr.bin/texinfo/misc/tex3patch
Executable file
71
gnu/usr.bin/texinfo/misc/tex3patch
Executable file
@ -0,0 +1,71 @@
|
||||
#!/bin/sh
|
||||
# Auxiliary script to work around TeX 3.0 bug. ---- tex3patch ----
|
||||
# patches texinfo.tex in current directory, or in directory given as arg.
|
||||
|
||||
ANYVERSION=no
|
||||
|
||||
for arg in $1 $2
|
||||
do
|
||||
case $arg in
|
||||
--dammit | -d ) ANYVERSION=yes ;;
|
||||
|
||||
* ) dir=$arg
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -z "$dir" ]; then
|
||||
dir='.'
|
||||
fi
|
||||
|
||||
if [ \( 2 -lt $# \) -o \
|
||||
\( ! -f $dir/texinfo.tex \) ]; then
|
||||
echo "To patch texinfo.tex for peaceful coexistence with Unix TeX 3.0,"
|
||||
echo "run $0"
|
||||
echo "with no arguments in the same directory as texinfo.tex; or run"
|
||||
echo " $0 DIRECTORY"
|
||||
echo "(where DIRECTORY is a path leading to texinfo.tex)."
|
||||
exit
|
||||
fi
|
||||
|
||||
if [ -z "$TMPDIR" ]; then
|
||||
TMPDIR=/tmp
|
||||
fi
|
||||
|
||||
echo "Checking for \`dummy.tfm'"
|
||||
|
||||
( cd $TMPDIR; tex '\relax \batchmode \font\foo=dummy \bye' )
|
||||
|
||||
grep -s '3.0' $TMPDIR/texput.log
|
||||
if [ 1 = "$?" -a "$ANYVERSION" != "yes" ]; then
|
||||
echo "You probably do not need this patch,"
|
||||
echo "since your TeX does not seem to be version 3.0."
|
||||
echo "If you insist on applying the patch, run $0"
|
||||
echo "again with the option \`--dammit'"
|
||||
exit
|
||||
fi
|
||||
|
||||
grep -s 'file not found' $TMPDIR/texput.log
|
||||
if [ 0 = $? ]; then
|
||||
echo "This patch requires the dummy font metric file \`dummy.tfm',"
|
||||
echo "which does not seem to be part of your TeX installation."
|
||||
echo "Please get your TeX maintainer to install \`dummy.tfm',"
|
||||
echo "then run this script again."
|
||||
exit
|
||||
fi
|
||||
rm $TMPDIR/texput.log
|
||||
|
||||
echo "Patching $dir/texinfo.tex"
|
||||
|
||||
sed -e 's/%%*\\font\\nullfont/\\font\\nullfont/' \
|
||||
$dir/texinfo.tex >$TMPDIR/texinfo.tex
|
||||
mv $dir/texinfo.tex $dir/texinfo.tex-distrib; mv $TMPDIR/texinfo.tex $dir
|
||||
|
||||
if [ 0 = $? ]; then
|
||||
echo "Patched $dir/texinfo.tex to avoid TeX 3.0 bug."
|
||||
echo "The original version is saved as $dir/texinfo.tex-distrib."
|
||||
else
|
||||
echo "Patch failed. Sorry."
|
||||
fi
|
||||
----------------------------------------tex3patch ends
|
||||
|
||||
|
263
gnu/usr.bin/texinfo/misc/texi2dvi
Executable file
263
gnu/usr.bin/texinfo/misc/texi2dvi
Executable file
@ -0,0 +1,263 @@
|
||||
#!/bin/sh
|
||||
# texi2dvi -- smartly produce DVI files from texinfo sources
|
||||
#
|
||||
# Copyright (C) 1992, 1993 Free Software Foundation.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, you can either send email to this
|
||||
# program's author (see below) or write to:
|
||||
#
|
||||
# Free Software Foundation, Inc.
|
||||
# 675 Mass Ave.
|
||||
# Cambridge, MA 02139, USA.
|
||||
#
|
||||
# Please send bug reports, etc. to bug-texinfo@prep.ai.mit.edu
|
||||
# If possible, please send a copy of the output of the script called with
|
||||
# the `--debug' option when making a bug report.
|
||||
#
|
||||
# Version 0.4
|
||||
# Last modified 26-Mar-93
|
||||
#
|
||||
|
||||
# Please note that in the interest of general portability, some common
|
||||
# bourne shell constructs were avoided because they weren't guaranteed to
|
||||
# be available in some earlier implementations. I've tried to make this as
|
||||
# portable as possible.
|
||||
#
|
||||
# Among the more interesting lossages I noticed with some bourne shells
|
||||
# are:
|
||||
# 1) Some don't have an `unset' builtin
|
||||
# 2) In some implementations the `shift' builtin can't take a
|
||||
# numerical argument.
|
||||
|
||||
progname=`basename $0`
|
||||
|
||||
usage="Usage: ${progname} {-D} {-h} [file1] {file2} {...}
|
||||
{--debug} {--help}
|
||||
|
||||
Options in braces are optional. Those in brackets are required.
|
||||
"
|
||||
|
||||
if test $# -eq 0 ; then
|
||||
echo "${usage}" 1>&2;
|
||||
exit 1
|
||||
fi
|
||||
|
||||
backup_extension=".bak"
|
||||
texindex="texindex"
|
||||
tex="tex"
|
||||
bq="\`" # To prevent hairy quoting and escaping later.
|
||||
eq="'"
|
||||
orig_pwd="`pwd`"
|
||||
|
||||
if test "z${TEXINDEX}" != "z" ; then
|
||||
texindex="${TEXINDEX}"
|
||||
fi
|
||||
|
||||
if test "z${TEX}" != "z" ; then
|
||||
tex="${TEX}"
|
||||
fi
|
||||
|
||||
# Save this so we can construct a new TEXINPUTS path for each file to be
|
||||
# processed.
|
||||
TEXINPUTS_orig="${TEXINPUTS}"
|
||||
export TEXINPUTS
|
||||
|
||||
# Parse command line options
|
||||
|
||||
# "unset" option variables to make sure they weren't accidentally
|
||||
# exported
|
||||
debug=""
|
||||
|
||||
# If you add new commands be sure to change the wildcards below to make
|
||||
# sure they are unambiguous (i.e. only match one possible long option)
|
||||
# Be sure to show at least one instance of the full long option name to
|
||||
# document what the long option is canonically called.
|
||||
while test $# -gt 0 ; do
|
||||
case z$1 in
|
||||
z-D | z--debug | z--d* )
|
||||
debug="t"
|
||||
shift
|
||||
;;
|
||||
z-h | z--help | z--h* )
|
||||
echo "${usage}" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
z-- )
|
||||
shift
|
||||
break
|
||||
;;
|
||||
z-* )
|
||||
echo "${progname}: ${bq}${1}${eq} is not a valid option." 1>&2
|
||||
echo "" 1>&2
|
||||
echo "${usage}" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
* )
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# See if there are any command line args left (which will be interpreted as
|
||||
# filename arguments)
|
||||
if test $# -eq 0 ; then
|
||||
echo "${progname}: at least one file name is required as an argument." 1>&2
|
||||
echo "" 1>&2
|
||||
echo "${usage}" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
test "z${debug}" = "zt" && set -x
|
||||
|
||||
# Texify files
|
||||
for command_line_filename in ${1+"$@"} ; do
|
||||
# Roughly equivalent to `dirname ...`, but more portable
|
||||
directory="`echo ${command_line_filename} | sed 's/\/[^\/]*$//'`"
|
||||
filename_texi="`basename ${command_line_filename}`"
|
||||
# Strip off the last extension part (probably .texinfo or .texi)
|
||||
filename_noext="`echo ${filename_texi} | sed 's/\.[^.]*$//'`"
|
||||
|
||||
# If directory and file are the same, then it's probably because there's
|
||||
# no pathname component. Set dirname to `.', the current directory.
|
||||
if test "z${directory}" = "z${command_line_filename}" ; then
|
||||
directory="."
|
||||
fi
|
||||
|
||||
# Source file might @include additional texinfo sources. Put `.' and
|
||||
# directory where source file(s) reside in TEXINPUTS before anything
|
||||
# else. `.' goes first to ensure that any old .aux, .cps, etc. files in
|
||||
# ${directory} don't get used in preference to fresher files in `.'.
|
||||
TEXINPUTS=".:${directory}:${TEXINPUTS_orig}"
|
||||
|
||||
# "Unset" variables that might have values from previous iterations and
|
||||
# which won't be completely reset later.
|
||||
definite_index_files=""
|
||||
|
||||
# See if file exists here. If it doesn't we're in trouble since, even
|
||||
# though the user may be able to reenter a valid filename at the tex
|
||||
# prompt (assuming they're attending the terminal), this script won't be
|
||||
# able to find the right index files and so forth.
|
||||
if test ! -r "${command_line_filename}" ; then
|
||||
echo "${progname}: ${command_line_filename}: No such file or permission denied." 1>&2
|
||||
continue;
|
||||
fi
|
||||
|
||||
# Find all files having root filename with a two-letter extension,
|
||||
# determine whether they're really index files, and save them. Foo.aux
|
||||
# is actually the cross-references file, but we need to keep track of
|
||||
# that too.
|
||||
possible_index_files="`eval echo ${filename_noext}.?? ${filename_noext}.aux`"
|
||||
for this_file in ${possible_index_files} ; do
|
||||
# If file is empty, forget it.
|
||||
if test ! -s "${this_file}" ; then
|
||||
continue;
|
||||
fi
|
||||
|
||||
# Examine first character of file. If it's not a backslash or
|
||||
# single quote, then it's definitely not an index or xref file.
|
||||
first_character="`sed -n '1s/^\(.\).*$/\1/p;q' ${this_file}`"
|
||||
if test "${first_character}" = "\\" -o "${first_character}" = "'" ; then
|
||||
definite_index_files="${definite_index_files} ${this_file}"
|
||||
fi
|
||||
done
|
||||
orig_index_files="${definite_index_files}"
|
||||
orig_index_files_sans_aux="`echo ${definite_index_files} \
|
||||
| sed 's/'${filename_noext}'\.aux//;
|
||||
s/^[ ]*//;s/[ ]*$//;'`"
|
||||
|
||||
# Now save copies of original index files so we have some means of
|
||||
# comparison later.
|
||||
for index_file_to_save in ${orig_index_files} ; do
|
||||
cp "${index_file_to_save}" "${index_file_to_save}${backup_extension}"
|
||||
done
|
||||
|
||||
# Run texindex on current index files. If they already exist, and
|
||||
# after running TeX a first time the index files don't change, then
|
||||
# there's no reason to run TeX again. But we won't know that if the
|
||||
# index files are out of date or nonexistent.
|
||||
if test "${orig_index_files_sans_aux}" ; then
|
||||
${texindex} ${orig_index_files_sans_aux}
|
||||
fi
|
||||
|
||||
if ${tex} ${command_line_filename} ; then # TeX run first time
|
||||
definite_index_files=""
|
||||
# Get list of new index files
|
||||
possible_index_files="`eval echo ${filename_noext}.?? ${filename_noext}.aux`"
|
||||
for this_file in ${possible_index_files} ; do
|
||||
# If file is empty, forget it.
|
||||
if test ! -s ${this_file} ; then
|
||||
continue;
|
||||
fi
|
||||
|
||||
# Examine first character of file. If it's not a backslash or
|
||||
# single quote, then it's definitely not an index or xref file.
|
||||
first_character="`sed -n '1s/^\(.\).*$/\1/p;q' ${this_file}`"
|
||||
if test "${first_character}" = "\\" -o "${first_character}" = "'" ; then
|
||||
definite_index_files="${definite_index_files} ${this_file}"
|
||||
fi
|
||||
done
|
||||
new_index_files="${definite_index_files}"
|
||||
new_index_files_sans_aux="`echo ${definite_index_files} \
|
||||
| sed 's/'${filename_noext}'\.aux//;
|
||||
s/^[ ]*//;s/[ ]*$//;'`"
|
||||
|
||||
# If old and new list don't at least have the same file list, then one
|
||||
# file or another has definitely changed.
|
||||
if test "${orig_index_files}" != "${new_index_files}" ; then
|
||||
index_files_changed_p=t
|
||||
else
|
||||
# File list is the same. We must compare each file until we find a
|
||||
# difference.
|
||||
index_files_changed_p=""
|
||||
for this_file in ${new_index_files} ; do
|
||||
# cmp -s will return nonzero exit status if files differ.
|
||||
cmp -s "${this_file}" "${this_file}${backup_extension}"
|
||||
if test $? -ne 0 ; then
|
||||
# We only need to keep comparing until we find *one* that
|
||||
# differs, because we'll have to run texindex & tex no
|
||||
# matter what.
|
||||
index_files_changed_p=t
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# If index files have changed since TeX has been run, or if the aux
|
||||
# file wasn't present originally, run texindex and TeX again.
|
||||
if test "${index_files_changed_p}" ; then
|
||||
retval=0
|
||||
if test "${new_index_files_sans_aux}" ; then
|
||||
${texindex} ${new_index_files_sans_aux}
|
||||
retval=$?
|
||||
fi
|
||||
if test ${retval} -eq 0 ; then
|
||||
${tex} "${command_line_filename}"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Generate list of files to delete, then call rm once with the entire
|
||||
# list. This is significantly faster than multiple executions of rm.
|
||||
file_list=""
|
||||
for file in ${orig_index_files} ; do
|
||||
file_list="${file_list} ${file}${backup_extension}"
|
||||
done
|
||||
if test "${file_list}" ; then
|
||||
rm -f ${file_list}
|
||||
fi
|
||||
done
|
||||
|
||||
#
|
||||
# eof
|
||||
#
|
1700
gnu/usr.bin/texinfo/misc/texindex.c
Normal file
1700
gnu/usr.bin/texinfo/misc/texindex.c
Normal file
File diff suppressed because it is too large
Load Diff
21
gnu/usr.bin/texinfo/texindex/Makefile
Normal file
21
gnu/usr.bin/texinfo/texindex/Makefile
Normal file
@ -0,0 +1,21 @@
|
||||
#
|
||||
# Bmakefile for GNU info
|
||||
#
|
||||
# $id$
|
||||
#
|
||||
|
||||
PROG= texindex
|
||||
|
||||
SRCS+= texindex.c getopt1.c getopt.c
|
||||
.PATH: ${.CURDIR}/../info
|
||||
|
||||
CFLAGS+= -I${.CURDIR}/../info -I${.CURDIR}
|
||||
CFLAGS+= -DNAMED_FUNCTIONS=1 -DSTDC_HEADERS=1
|
||||
CFLAGS+= -DHAVE_UNISTD_H=1 -DHAVE_STRING_H=1 -DHAVE_VARARGS_H=1
|
||||
CFLAGS+= -DHAVE_SYS_FCNTL_H=1 -DHAVE_SETVBUF=1 -DHAVE_GETCWD=1 -DHAVE_BZERO=1
|
||||
CFLAGS+= -DHAVE_RINDEX=1 -DHAVE_VFPRINTF=1 -DHAVE_VSPRINTF=1
|
||||
CFLAGS+= -DHAVE_SYS_TIME_H=1 -DDEFAULT_INFOPATH='"${INFODIR}"'
|
||||
|
||||
.include "../../Makefile.inc"
|
||||
.include <bsd.prog.mk>
|
||||
|
1700
gnu/usr.bin/texinfo/texindex/texindex.c
Normal file
1700
gnu/usr.bin/texinfo/texindex/texindex.c
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user