1
0
Fork 0

Adding upstream version 8.2.

Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
This commit is contained in:
Daniel Baumann 2025-06-21 08:05:58 +02:00
parent d2b2af6dd3
commit 3a96b6e8dc
Signed by: daniel.baumann
GPG key ID: BCC918A2ABD66424
160 changed files with 152075 additions and 0 deletions

1450
CHANGELOG Normal file

File diff suppressed because it is too large Load diff

1941
CHANGES Normal file

File diff suppressed because it is too large Load diff

674
COPYING Normal file
View file

@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.

310
INSTALL Normal file
View file

@ -0,0 +1,310 @@
Basic Installation
==================
These are installation instructions for Readline-8.2.
The simplest way to compile readline is:
1. `cd' to the directory containing the readline source code and type
`./configure' to configure readline for your system. If you're
using `csh' on an old version of System V, you might need to type
`sh ./configure' instead to prevent `csh' from trying to execute
`configure' itself.
Running `configure' takes some time. While running, it prints some
messages telling which features it is checking for.
2. Type `make' to compile readline and build the static readline
and history libraries. If supported, the shared readline and history
libraries will be built also. See below for instructions on compiling
the other parts of the distribution. Typing `make everything' will
cause the static and shared libraries (if supported) and the example
programs to be built.
3. Type `make install' to install the static readline and history
libraries, the readline include files, the documentation, and, if
supported, the shared readline and history libraries.
4. You can remove the created libraries and object files from the
build directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile readline for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the readline developers, and should be used with care.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It
uses those values to create a `Makefile' in the build directory,
and Makefiles in the `doc', `shlib', and `examples'
subdirectories. It also creates a `config.h' file containing
system-dependent definitions. Finally, it creates a shell script
`config.status' that you can run in the future to recreate the
current configuration, a file `config.cache' that saves the
results of its tests to speed up reconfiguring, and a file
`config.log' containing compiler output (useful mainly for
debugging `configure').
If you need to do unusual things to compile readline, please try
to figure out how `configure' could check whether to do them, and
mail diffs or instructions to <bug-readline@gnu.org> so they can
be considered for the next release. If at some point
`config.cache' contains results you don't want to keep, you may
remove or edit it.
The file `configure.in' is used to create `configure' by a
program called `autoconf'. You only need `configure.in' if you
want to change it or regenerate `configure' using a newer version
of `autoconf'. The readline `configure.in' requires autoconf
version 2.69 or newer.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. You can give `configure'
initial values for variables by setting them in the environment. Using
a Bourne-compatible shell, you can do that on the command line like
this:
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
Or on systems that have the `env' program, you can do it like this:
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
Compiling For Multiple Architectures
====================================
You can compile readline for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you must use a version of `make' that
supports the `VPATH' variable, such as GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
If you have to use a `make' that does not supports the `VPATH'
variable, you have to compile readline for one architecture at a
time in the source code directory. After you have installed
readline for one architecture, use `make distclean' before
reconfiguring for another architecture.
Installation Names
==================
By default, `make install' will install the readline libraries in
`/usr/local/lib', the include files in
`/usr/local/include/readline', the man pages in `/usr/local/man',
and the info files in `/usr/local/info'. You can specify an
installation prefix other than `/usr/local' by giving `configure'
the option `--prefix=PATH' or by supplying a value for the
DESTDIR variable when running `make install'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files.
If you give `configure' the option `--exec-prefix=PATH', the
readline Makefiles will use PATH as the prefix for installing the
libraries. Documentation and other data files will still use the
regular prefix.
Specifying the System Type
==========================
There may be some features `configure' can not figure out
automatically, but need to determine by the type of host readline
will run on. Usually `configure' can figure that out, but if it
prints a message saying it can not guess the host type, give it
the `--host=TYPE' option. TYPE can either be a short name for
the system type, such as `sun4', or a canonical name with three
fields: CPU-COMPANY-SYSTEM (e.g., i386-unknown-freebsd4.2).
See the file `config.sub' for the possible values of each field.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: the readline `configure' looks for a site script, but not
all `configure' scripts do.
Operation Controls
==================
`configure' recognizes the following options to control how it
operates.
`--cache-file=FILE'
Use and save the results of the tests in FILE instead of
`./config.cache'. Set FILE to `/dev/null' to disable caching, for
debugging `configure'.
`--help'
Print a summary of the options to `configure', and exit.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made.
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`--version'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`configure' also accepts some other, not widely useful, options.
Optional Features
=================
The readline `configure' recognizes two `--with-PACKAGE' options:
`--with-curses'
This tells readline that it can find the termcap library functions
(tgetent, et al.) in the curses library, rather than a separate
termcap library. Readline uses the termcap functions, but does not
usually link with the termcap or curses library itself, allowing
applications which link with readline the to choose an appropriate
library. This option tells readline to link the example programs with
the curses library rather than libtermcap.
`--with-shared-termcap-library'
This tells the readline build process to link the shared version of
libreadline against a shared version of the curses or termcap library
(see the description of SHLIB_LIBS below under `Shared Libraries').
This relieves the application of having to link with curses or termcap
itself, but does not allow the application to choose which library to
use. This is only effective on systems that build shared libraries (see
below; the default for shared libraries is `yes').
`configure' also recognizes several `--enable-FEATURE' options:
`--enable-bracketed-paste-default'
Enable bracketed paste by default, so the initial value of the
`enable-bracketed-paste' Readline variable is `on'. The default
is `yes'.
`--enable-install-examples'
Install the readline example programs as part of `make install'.
`--enable-multibyte'
Build with support for multibyte characters enabled on systems with the
necessary framework (locale definitions, C library functions, etc.). The
default is `yes'.
`--enable-shared'
Build the shared libraries by default on supported platforms. The
default is `yes'.
`--enable-static'
Build the static libraries by default. The default is `yes'.
Shared Libraries
================
There is support for building shared versions of the readline and
history libraries. The configure script creates a Makefile in
the `shlib' subdirectory, and typing `make shared' will cause
shared versions of the readline and history libraries to be built
on supported platforms.
If `configure' is given the `--enable-shared' option, it will attempt
to build the shared libraries by default on supported platforms. This
option is enabled by default.
Configure calls the script support/shobj-conf to test whether or
not shared library creation is supported and to generate the values
of variables that are substituted into shlib/Makefile. If you
try to build shared libraries on an unsupported platform, `make'
will display a message asking you to update support/shobj-conf for
your platform.
If you need to update support/shobj-conf, you will need to create
a `stanza' for your operating system and compiler. The script uses
the value of host_os and ${CC} as determined by configure. For
instance, FreeBSD 4.2 with any version of gcc is identified as
`freebsd4.2-gcc*'.
In the stanza for your operating system-compiler pair, you will need to
define several variables. They are:
SHOBJ_CC The C compiler used to compile source files into shareable
object files. This is normally set to the value of ${CC}
by configure, and should not need to be changed.
SHOBJ_CFLAGS Flags to pass to the C compiler ($SHOBJ_CC) to create
position-independent code. If you are using gcc, this
should probably be set to `-fpic'.
SHOBJ_LD The link editor to be used to create the shared library from
the object files created by $SHOBJ_CC. If you are using
gcc, a value of `gcc' will probably work.
SHOBJ_LDFLAGS Flags to pass to SHOBJ_LD to enable shared object creation.
If you are using gcc, `-shared' may be all that is necessary.
These should be the flags needed for generic shared object
creation.
SHLIB_XLDFLAGS Additional flags to pass to SHOBJ_LD for shared library
creation. Many systems use the -R option to the link
editor to embed a path within the library for run-time
library searches. A reasonable value for such systems would
be `-R$(libdir)'.
SHLIB_LIBS Any additional libraries that shared libraries should be
linked against when they are created.
SHLIB_LIBPREF The prefix to use when generating the filename of the shared
library. The default is `lib'; Cygwin uses `cyg'.
SHLIB_LIBSUFF The suffix to add to `libreadline' and `libhistory' when
generating the filename of the shared library. Many systems
use `so'; HP-UX uses `sl'.
SHLIB_LIBVERSION The string to append to the filename to indicate the version
of the shared library. It should begin with $(SHLIB_LIBSUFF),
and possibly include version information that allows the
run-time loader to load the version of the shared library
appropriate for a particular program. Systems using shared
libraries similar to SunOS 4.x use major and minor library
version numbers; for those systems a value of
`$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)$(SHLIB_MINOR)' is appropriate.
Systems based on System V Release 4 don't use minor version
numbers; use `$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' on those systems.
Other Unix versions use different schemes.
SHLIB_DLLVERSION The version number for shared libraries that determines API
compatibility between readline versions and the underlying
system. Used only on Cygwin. Defaults to $SHLIB_MAJOR, but
can be overridden at configuration time by defining DLLVERSION
in the environment.
SHLIB_DOT The character used to separate the name of the shared library
from the suffix and version information. The default is `.';
systems like Cygwin which don't separate version information
from the library name should set this to the empty string.
SHLIB_STATUS Set this to `supported' when you have defined the other
necessary variables. Make uses this to determine whether
or not shared library creation should be attempted. If
shared libraries are not supported, this will be set to
`unsupported'.
You should look at the existing stanzas in support/shobj-conf for ideas.
Once you have updated support/shobj-conf, re-run configure and type
`make shared' or `make'. The shared libraries will be created in the
shlib subdirectory.
If shared libraries are created, `make install' will install them.
You may install only the shared libraries by running `make
install-shared' from the top-level build directory. Running `make
install' in the shlib subdirectory will also work. If you don't want
to install any created shared libraries, run `make install-static'.

171
MANIFEST Normal file
View file

@ -0,0 +1,171 @@
#
# Master distribution manifest for the standalone readline distribution
#
doc d
examples d
examples/autoconf d
examples/rlfe d
support d
shlib d
m4 d
COPYING f
README f
MANIFEST f
INSTALL f
CHANGELOG f
CHANGES f
NEWS f
USAGE f
aclocal.m4 f
config.h.in f
configure f 755
configure.ac f
m4/codeset.m4 f
Makefile.in f
readline.pc.in f
history.pc.in f
ansi_stdlib.h f
chardefs.h f
colors.h f
history.h f
histlib.h f
keymaps.h f
parse-colors.h f
posixdir.h f
posixjmp.h f
posixselect.h f
posixstat.h f
posixtime.h f
readline.h f
rlconf.h f
rldefs.h f
rlmbutil.h f
rlprivate.h f
rlshell.h f
rlstdc.h f
rltty.h f
rltypedefs.h f
rlwinsize.h f
tcap.h f
tilde.h f
xmalloc.h f
bind.c f
callback.c f
colors.c f
compat.c f
complete.c f
display.c f
emacs_keymap.c f
funmap.c f
input.c f
isearch.c f
keymaps.c f
kill.c f
macro.c f
mbutil.c f
misc.c f
nls.c f
parens.c f
parse-colors.c f
readline.c f
rltty.c f
savestring.c f
search.c f
shell.c f
signals.c f
terminal.c f
text.c f
tilde.c f
undo.c f
util.c f
vi_keymap.c f
vi_mode.c f
xfree.c f
xmalloc.c f
history.c f
histexpand.c f
histfile.c f
histsearch.c f
patchlevel f
shlib/Makefile.in f
support/config.guess f
support/config.rpath f
support/config.sub f
support/install.sh f
support/mkdirs f
support/mkdist f
support/mkinstalldirs f
support/shobj-conf f
support/shlib-install f
support/wcwidth.c f
doc/Makefile.in f
doc/texinfo.tex f
doc/version.texi f
doc/fdl.texi f
doc/rlman.texi f
doc/rltech.texi f
doc/rluser.texi f
doc/rluserman.texi f
doc/history.texi f
doc/hstech.texi f
doc/hsuser.texi f
doc/readline.3 f
doc/history.3 f
doc/texi2dvi f
doc/texi2html f
examples/Makefile.in f
examples/excallback.c f
examples/fileman.c f
examples/manexamp.c f
examples/readlinebuf.h f
examples/rl-fgets.c f
examples/rlbasic.c f
examples/rlcat.c f
examples/rlevent.c f
examples/rlkeymaps.c f
examples/rltest.c f
examples/rl-callbacktest.c f
examples/rl-timeout.c f
examples/rl-test-timeout f
examples/rl.c f
examples/rlptytest.c f
examples/rlversion.c f
examples/histexamp.c f
examples/hist_erasedups.c f
examples/hist_purgecmd.c f
examples/Inputrc f
examples/autoconf/BASH_CHECK_LIB_TERMCAP f
examples/autoconf/RL_LIB_READLINE_VERSION f
examples/autoconf/wi_LIB_READLINE f
examples/rlfe/ChangeLog f
examples/rlfe/Makefile.in f
examples/rlfe/README f
examples/rlfe/config.h.in f
examples/rlfe/configure f 755
examples/rlfe/configure.in f
examples/rlfe/extern.h f
examples/rlfe/os.h f
examples/rlfe/pty.c f
examples/rlfe/rlfe.c f
examples/rlfe/screen.h f
examples/rlwrap-0.30.tar.gz f
# formatted documentation, from MANIFEST.doc
doc/readline.ps f
doc/history.ps f
doc/rluserman.ps f
doc/readline.dvi f
doc/history.dvi f
doc/rluserman.dvi f
doc/readline.info f
doc/history.info f
doc/rluserman.info f
doc/readline.html f
doc/history.html f
doc/rluserman.html f
doc/readline.0 f
doc/history.0 f
doc/readline_3.ps f
doc/history_3.ps f
doc/history.pdf f
doc/readline.pdf f
doc/rluserman.pdf f

610
Makefile.in Normal file
View file

@ -0,0 +1,610 @@
## -*- text -*- ##
# Master Makefile for the GNU readline library.
# Copyright (C) 1994-2018 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 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
RL_LIBRARY_VERSION = @LIBVERSION@
RL_LIBRARY_NAME = readline
PACKAGE = @PACKAGE_NAME@
VERSION = @PACKAGE_VERSION@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_VERSION = @PACKAGE_VERSION@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
srcdir = @srcdir@
VPATH = @srcdir@
top_srcdir = @top_srcdir@
BUILD_DIR = @BUILD_DIR@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
CC = @CC@
RANLIB = @RANLIB@
AR = @AR@
ARFLAGS = @ARFLAGS@
RM = rm -f
CP = cp
MV = mv
@SET_MAKE@
SHELL = @MAKE_SHELL@
prefix = @prefix@
exec_prefix = @exec_prefix@
datarootdir = @datarootdir@
bindir = @bindir@
libdir = @libdir@
mandir = @mandir@
includedir = @includedir@
datadir = @datadir@
localedir = @localedir@
pkgconfigdir = ${libdir}/pkgconfig
infodir = @infodir@
docdir = @docdir@
man3dir = $(mandir)/man3
# Support an alternate destination root directory for package building
DESTDIR =
# Programs to make tags files.
ETAGS = etags
CTAGS = ctags -w
CFLAGS = @CFLAGS@
LOCAL_CFLAGS = @LOCAL_CFLAGS@ -DRL_LIBRARY_VERSION='"$(RL_LIBRARY_VERSION)"' @BRACKETED_PASTE@
CPPFLAGS = @CPPFLAGS@
DEFS = @DEFS@ @CROSS_COMPILE@
LOCAL_DEFS = @LOCAL_DEFS@
TERMCAP_LIB = @TERMCAP_LIB@
# For libraries which include headers from other libraries.
INCLUDES = -I. -I$(srcdir)
XCCFLAGS = $(ASAN_CFLAGS) $(DEFS) $(LOCAL_DEFS) $(INCLUDES) $(CPPFLAGS)
CCFLAGS = $(XCCFLAGS) $(LOCAL_CFLAGS) $(CFLAGS)
# could add -Werror here
GCC_LINT_FLAGS = -ansi -Wall -Wshadow -Wpointer-arith -Wcast-qual \
-Wwrite-strings -Wstrict-prototypes \
-Wmissing-prototypes -Wno-implicit -pedantic
GCC_LINT_CFLAGS = $(XCCFLAGS) $(GCC_LINT_FLAGS) @CFLAGS@ @LOCAL_CFLAGS@
ASAN_XCFLAGS = -fsanitize=address -fno-omit-frame-pointer
ASAN_XLDFLAGS = -fsanitize=address
install_examples = @EXAMPLES_INSTALL_TARGET@
.c.o:
${RM} $@
$(CC) -c $(CCFLAGS) $<
# The name of the main library target.
LIBRARY_NAME = libreadline.a
STATIC_LIBS = libreadline.a libhistory.a
# The C code source files for this library.
CSOURCES = $(srcdir)/readline.c $(srcdir)/funmap.c $(srcdir)/keymaps.c \
$(srcdir)/vi_mode.c $(srcdir)/parens.c $(srcdir)/rltty.c \
$(srcdir)/complete.c $(srcdir)/bind.c $(srcdir)/isearch.c \
$(srcdir)/display.c $(srcdir)/signals.c $(srcdir)/emacs_keymap.c \
$(srcdir)/vi_keymap.c $(srcdir)/util.c $(srcdir)/kill.c \
$(srcdir)/undo.c $(srcdir)/macro.c $(srcdir)/input.c \
$(srcdir)/callback.c $(srcdir)/terminal.c $(srcdir)/xmalloc.c $(srcdir)/xfree.c \
$(srcdir)/history.c $(srcdir)/histsearch.c $(srcdir)/histexpand.c \
$(srcdir)/histfile.c $(srcdir)/nls.c $(srcdir)/search.c \
$(srcdir)/shell.c $(srcdir)/savestring.c $(srcdir)/tilde.c \
$(srcdir)/text.c $(srcdir)/misc.c $(srcdir)/compat.c \
$(srcdir)/mbutil.c
# The header files for this library.
HSOURCES = $(srcdir)/readline.h $(srcdir)/rldefs.h $(srcdir)/chardefs.h \
$(srcdir)/keymaps.h $(srcdir)/history.h $(srcdir)/histlib.h \
$(srcdir)/posixstat.h $(srcdir)/posixdir.h $(srcdir)/posixjmp.h \
$(srcdir)/tilde.h $(srcdir)/rlconf.h $(srcdir)/rltty.h \
$(srcdir)/ansi_stdlib.h $(srcdir)/tcap.h $(srcdir)/rlstdc.h \
$(srcdir)/xmalloc.h $(srcdir)/rlprivate.h $(srcdir)/rlshell.h \
$(srcdir)/rltypedefs.h $(srcdir)/rlmbutil.h \
$(srcdir)/colors.h $(srcdir)/parse-colors.h
HISTOBJ = history.o histexpand.o histfile.o histsearch.o shell.o mbutil.o
TILDEOBJ = tilde.o
COLORSOBJ = colors.o parse-colors.o
OBJECTS = readline.o vi_mode.o funmap.o keymaps.o parens.o search.o \
rltty.o complete.o bind.o isearch.o display.o signals.o \
util.o kill.o undo.o macro.o input.o callback.o terminal.o \
text.o nls.o misc.o $(HISTOBJ) $(TILDEOBJ) $(COLORSOBJ) \
xmalloc.o xfree.o compat.o
# The texinfo files which document this library.
DOCSOURCE = doc/rlman.texinfo doc/rltech.texinfo doc/rluser.texinfo
DOCOBJECT = doc/readline.dvi
DOCSUPPORT = doc/Makefile
DOCUMENTATION = $(DOCSOURCE) $(DOCOBJECT) $(DOCSUPPORT)
CREATED_MAKEFILES = Makefile doc/Makefile examples/Makefile shlib/Makefile
CREATED_CONFIGURE = config.status config.h config.cache config.log \
stamp-config stamp-h readline.pc history.pc
CREATED_TAGS = TAGS tags
INSTALLED_HEADERS = readline.h chardefs.h keymaps.h history.h tilde.h \
rlstdc.h rlconf.h rltypedefs.h
OTHER_DOCS = $(srcdir)/CHANGES $(srcdir)/INSTALL $(srcdir)/README
OTHER_INSTALLED_DOCS = CHANGES INSTALL README
##########################################################################
TARGETS = @STATIC_TARGET@ @SHARED_TARGET@
INSTALL_TARGETS = @STATIC_INSTALL_TARGET@ @SHARED_INSTALL_TARGET@
all: $(TARGETS)
everything: all examples
asan:
${MAKE} ${MFLAGS} ASAN_CFLAGS='${ASAN_XCFLAGS}' ASAN_LDFLAGS='${ASAN_XLDFLAGS}' everything
static: $(STATIC_LIBS)
libreadline.a: $(OBJECTS)
$(RM) $@
$(AR) $(ARFLAGS) $@ $(OBJECTS)
-test -n "$(RANLIB)" && $(RANLIB) $@
libhistory.a: $(HISTOBJ) xmalloc.o xfree.o
$(RM) $@
$(AR) $(ARFLAGS) $@ $(HISTOBJ) xmalloc.o xfree.o
-test -n "$(RANLIB)" && $(RANLIB) $@
# Since tilde.c is shared between readline and bash, make sure we compile
# it with the right flags when it's built as part of readline
tilde.o: tilde.c
rm -f $@
$(CC) $(CCFLAGS) -DREADLINE_LIBRARY -c $(srcdir)/tilde.c
readline: $(OBJECTS) readline.h rldefs.h chardefs.h ./libreadline.a
$(CC) $(CCFLAGS) -DREADLINE_LIBRARY -o $@ $(top_srcdir)/examples/rl.c ./libreadline.a ${TERMCAP_LIB}
lint: force
$(MAKE) $(MFLAGS) CCFLAGS='$(GCC_LINT_CFLAGS)' static
Makefile makefile: config.status $(srcdir)/Makefile.in
CONFIG_FILES=Makefile CONFIG_HEADERS= $(SHELL) ./config.status
Makefiles makefiles: config.status $(srcdir)/Makefile.in
@for mf in $(CREATED_MAKEFILES); do \
CONFIG_FILES=$$mf CONFIG_HEADERS= $(SHELL) ./config.status ; \
done
config.status: configure
$(SHELL) ./config.status --recheck
config.h: stamp-h
stamp-h: config.status $(srcdir)/config.h.in
CONFIG_FILES= CONFIG_HEADERS=config.h ./config.status
echo > $@
#$(srcdir)/configure: $(srcdir)/configure.ac ## Comment-me-out in distribution
# cd $(srcdir) && autoconf ## Comment-me-out in distribution
shared: force
-test -d shlib || mkdir shlib
( cd shlib ; ${MAKE} ${MFLAGS} all )
documentation: force
-test -d doc || mkdir doc
-( cd doc && $(MAKE) $(MFLAGS) )
examples: force
-test -d examples || mkdir examples
-(cd examples && ${MAKE} ${MFLAGS} all )
force:
install: $(INSTALL_TARGETS)
install-headers: installdirs ${INSTALLED_HEADERS}
for f in ${INSTALLED_HEADERS}; do \
$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(includedir)/readline ; \
done
uninstall-headers:
-test -n "$(includedir)" && cd $(DESTDIR)$(includedir)/readline && \
${RM} ${INSTALLED_HEADERS}
maybe-uninstall-headers: uninstall-headers
install-pc: installdirs
-$(INSTALL_DATA) $(BUILD_DIR)/readline.pc $(DESTDIR)$(pkgconfigdir)/readline.pc
-$(INSTALL_DATA) $(BUILD_DIR)/history.pc $(DESTDIR)$(pkgconfigdir)/history.pc
uninstall-pc:
-test -n "$(pkgconfigdir)" && cd $(DESTDIR)$(pkgconfigdir) && \
${RM} readline.pc history.pc
maybe-uninstall-pc: uninstall-pc
install-static: installdirs $(STATIC_LIBS) install-headers install-doc ${install_examples} install-pc
-$(MV) $(DESTDIR)$(libdir)/libreadline.a $(DESTDIR)$(libdir)/libreadline.old
$(INSTALL_DATA) libreadline.a $(DESTDIR)$(libdir)/libreadline.a
-test -n "$(RANLIB)" && $(RANLIB) $(DESTDIR)$(libdir)/libreadline.a
-$(MV) $(DESTDIR)$(libdir)/libhistory.a $(DESTDIR)$(libdir)/libhistory.old
$(INSTALL_DATA) libhistory.a $(DESTDIR)$(libdir)/libhistory.a
-test -n "$(RANLIB)" && $(RANLIB) $(DESTDIR)$(libdir)/libhistory.a
installdirs: $(srcdir)/support/mkinstalldirs
-$(SHELL) $(srcdir)/support/mkinstalldirs $(DESTDIR)$(includedir) \
$(DESTDIR)$(includedir)/readline $(DESTDIR)$(libdir) \
$(DESTDIR)$(infodir) $(DESTDIR)$(man3dir) $(DESTDIR)$(docdir) \
$(DESTDIR)$(pkgconfigdir)
uninstall: uninstall-headers uninstall-doc uninstall-examples uninstall-pc
-test -n "$(DESTDIR)$(libdir)" && cd $(DESTDIR)$(libdir) && \
${RM} libreadline.a libreadline.old libhistory.a libhistory.old $(SHARED_LIBS)
-( cd shlib; ${MAKE} ${MFLAGS} DESTDIR=${DESTDIR} uninstall )
install-shared: installdirs install-headers shared install-doc install-pc
( cd shlib ; ${MAKE} ${MFLAGS} DESTDIR=${DESTDIR} install )
uninstall-shared: maybe-uninstall-headers maybe-uninstall-pc
-( cd shlib; ${MAKE} ${MFLAGS} DESTDIR=${DESTDIR} uninstall )
install-examples: installdirs install-headers
-( cd examples ; ${MAKE} ${MFLAGS} DESTDIR=${DESTDIR} install )
uninstall-examples: maybe-uninstall-headers
-( cd examples; ${MAKE} ${MFLAGS} DESTDIR=${DESTDIR} uninstall )
install-doc: installdirs
$(INSTALL_DATA) $(OTHER_DOCS) $(DESTDIR)$(docdir)
-( if test -d doc ; then \
cd doc && \
${MAKE} ${MFLAGS} infodir=$(infodir) DESTDIR=${DESTDIR} install; \
fi )
uninstall-doc:
-( cd $(DESTDIR)$(docdir) && ${RM} ${OTHER_INSTALLED_DOCS} )
-( if test -d doc ; then \
cd doc && \
${MAKE} ${MFLAGS} infodir=$(infodir) DESTDIR=${DESTDIR} uninstall; \
fi )
TAGS: force
-( cd $(srcdir) && $(ETAGS) $(CSOURCES) $(HSOURCES) )
tags: force
-( cd $(srcdir) && $(CTAGS) $(CSOURCES) $(HSOURCES) )
clean: force
$(RM) $(OBJECTS) $(STATIC_LIBS)
$(RM) readline readline.exe
( cd shlib && $(MAKE) $(MFLAGS) $@ )
-( cd doc && $(MAKE) $(MFLAGS) $@ )
-( cd examples && $(MAKE) $(MFLAGS) $@ )
mostlyclean: clean
( cd shlib && $(MAKE) $(MFLAGS) $@ )
-( cd doc && $(MAKE) $(MFLAGS) $@ )
-( cd examples && $(MAKE) $(MFLAGS) $@ )
distclean maintainer-clean: clean
( cd shlib && $(MAKE) $(MFLAGS) $@ )
-( cd doc && $(MAKE) $(MFLAGS) $@ )
-( cd examples && $(MAKE) $(MFLAGS) $@ )
$(RM) Makefile
$(RM) $(CREATED_CONFIGURE)
$(RM) $(CREATED_TAGS)
readline.pc: config.status $(srcdir)/readline.pc.in
$(SHELL) config.status
history.pc: config.status $(srcdir)/history.pc.in
$(SHELL) config.status
info dvi html pdf ps:
-( cd doc && $(MAKE) $(MFLAGS) $@ )
install-info:
install-dvi:
install-html:
install-pdf:
install-ps:
check:
installcheck:
dist: force
@echo Readline distributions are created using $(srcdir)/support/mkdist.
@echo Here is a sample of the necessary commands:
@echo bash $(srcdir)/support/mkdist -m $(srcdir)/MANIFEST -s $(srcdir) -r $(RL_LIBRARY_NAME) $(RL_LIBRARY_VERSION)
@echo tar cf $(RL_LIBRARY_NAME)-${RL_LIBRARY_VERSION}.tar ${RL_LIBRARY_NAME}-$(RL_LIBRARY_VERSION)
@echo gzip $(RL_LIBRARY_NAME)-$(RL_LIBRARY_VERSION).tar
# Tell versions [3.59,3.63) of GNU make not to export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
# Dependencies
bind.o: ansi_stdlib.h posixstat.h
bind.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
bind.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h
bind.o: history.h
callback.o: rlconf.h
callback.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
callback.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h
compat.o: ${BUILD_DIR}/config.h
compat.o: rlstdc.h rltypedefs.h
complete.o: ansi_stdlib.h posixdir.h posixstat.h
complete.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
complete.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h
display.o: ansi_stdlib.h posixstat.h
display.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
display.o: tcap.h
display.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h
display.o: history.h rlstdc.h
funmap.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h
funmap.o: rlconf.h ansi_stdlib.h rlstdc.h
funmap.o: ${BUILD_DIR}/config.h
histexpand.o: ansi_stdlib.h
histexpand.o: history.h histlib.h rlstdc.h rltypedefs.h
histexpand.o: ${BUILD_DIR}/config.h
histfile.o: ansi_stdlib.h
histfile.o: history.h histlib.h rlstdc.h rltypedefs.h
histfile.o: ${BUILD_DIR}/config.h
history.o: ansi_stdlib.h
history.o: history.h histlib.h rlstdc.h rltypedefs.h
history.o: ${BUILD_DIR}/config.h
histsearch.o: ansi_stdlib.h
histsearch.o: history.h histlib.h rlstdc.h rltypedefs.h
histsearch.o: ${BUILD_DIR}/config.h
input.o: ansi_stdlib.h
input.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
input.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h
isearch.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
isearch.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h
isearch.o: ansi_stdlib.h history.h rlstdc.h
keymaps.o: emacs_keymap.c vi_keymap.c
keymaps.o: keymaps.h rltypedefs.h chardefs.h rlconf.h ansi_stdlib.h
keymaps.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h
keymaps.o: ${BUILD_DIR}/config.h rlstdc.h
kill.o: ansi_stdlib.h
kill.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
kill.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h
kill.o: history.h rlstdc.h
macro.o: ansi_stdlib.h
macro.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
macro.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h
macro.o: history.h rlstdc.h
mbutil.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
mbutil.o: readline.h keymaps.h rltypedefs.h chardefs.h rlstdc.h
misc.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h
misc.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
misc.o: history.h rlstdc.h ansi_stdlib.h
nls.o: ansi_stdlib.h
nls.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
nls.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h
nls.o: history.h rlstdc.h
parens.o: rlconf.h
parens.o: ${BUILD_DIR}/config.h
parens.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h
readline.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h
readline.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
readline.o: history.h rlstdc.h
readline.o: posixstat.h ansi_stdlib.h posixjmp.h
rltty.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
rltty.o: rltty.h
rltty.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h
savestring.o: ${BUILD_DIR}/config.h
search.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
search.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h
search.o: ansi_stdlib.h history.h rlstdc.h
shell.o: ${BUILD_DIR}/config.h
shell.o: ansi_stdlib.h
signals.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
signals.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h
signals.o: history.h rlstdc.h
terminal.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
terminal.o: tcap.h
terminal.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h
terminal.o: history.h rlstdc.h
text.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h
text.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
text.o: history.h rlstdc.h ansi_stdlib.h
tilde.o: ansi_stdlib.h
tilde.o: ${BUILD_DIR}/config.h
tilde.o: tilde.h
undo.o: ansi_stdlib.h
undo.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
undo.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h
undo.o: history.h rlstdc.h
util.o: posixjmp.h ansi_stdlib.h
util.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
util.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h
vi_mode.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
vi_mode.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h
vi_mode.o: history.h ansi_stdlib.h rlstdc.h
xfree.o: ${BUILD_DIR}/config.h
xfree.o: ansi_stdlib.h
xmalloc.o: ${BUILD_DIR}/config.h
xmalloc.o: ansi_stdlib.h
colors.o: ${BUILD_DIR}/config.h colors.h
colors.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h
colors.o: rlconf.h
colors.o: ansi_stdlib.h posixstat.h
parse-colors.o: ${BUILD_DIR}/config.h colors.h parse-colors.h
parse-colors.o: rldefs.h rlconf.h
parse-colors.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h rlstdc.h
bind.o: rlshell.h
histfile.o: rlshell.h
nls.o: rlshell.h
readline.o: rlshell.h
shell.o: rlshell.h
terminal.o: rlshell.h
histexpand.o: rlshell.h
bind.o: rlprivate.h
callback.o: rlprivate.h
complete.o: rlprivate.h
display.o: rlprivate.h
input.o: rlprivate.h
isearch.o: rlprivate.h
kill.o: rlprivate.h
macro.o: rlprivate.h
mbutil.o: rlprivate.h
misc.o: rlprivate.h
nls.o: rlprivate.h
parens.o: rlprivate.h
readline.o: rlprivate.h
rltty.o: rlprivate.h
search.o: rlprivate.h
signals.o: rlprivate.h
terminal.o: rlprivate.h
text.o: rlprivate.h
undo.o: rlprivate.h
util.o: rlprivate.h
vi_mode.o: rlprivate.h
colors.o: rlprivate.h
parse-colors.o: rlprivate.h
bind.o: xmalloc.h
callback.o: xmalloc.h
complete.o: xmalloc.h
display.o: xmalloc.h
funmap.o: xmalloc.h
histexpand.o: xmalloc.h
histfile.o: xmalloc.h
history.o: xmalloc.h
input.o: xmalloc.h
isearch.o: xmalloc.h
keymaps.o: xmalloc.h
kill.o: xmalloc.h
macro.o: xmalloc.h
mbutil.o: xmalloc.h
misc.o: xmalloc.h
readline.o: xmalloc.h
savestring.o: xmalloc.h
search.o: xmalloc.h
shell.o: xmalloc.h
terminal.o: xmalloc.h
text.o: xmalloc.h
tilde.o: xmalloc.h
undo.o: xmalloc.h
util.o: xmalloc.h
vi_mode.o: xmalloc.h
xfree.o: xmalloc.h
xmalloc.o: xmalloc.h
colors.o: xmalloc.h
parse-colors.o: xmalloc.h
complete.o: rlmbutil.h
display.o: rlmbutil.h
histexpand.o: rlmbutil.h
input.o: rlmbutil.h
isearch.o: rlmbutil.h
mbutil.o: rlmbutil.h
misc.o: rlmbutil.h
readline.o: rlmbutil.h
search.o: rlmbutil.h
text.o: rlmbutil.h
vi_mode.o: rlmbutil.h
bind.o: $(srcdir)/bind.c
callback.o: $(srcdir)/callback.c
compat.o: $(srcdir)/compat.c
complete.o: $(srcdir)/complete.c
display.o: $(srcdir)/display.c
funmap.o: $(srcdir)/funmap.c
input.o: $(srcdir)/input.c
isearch.o: $(srcdir)/isearch.c
keymaps.o: $(srcdir)/keymaps.c $(srcdir)/emacs_keymap.c $(srcdir)/vi_keymap.c
kill.o: $(srcdir)/kill.c
macro.o: $(srcdir)/macro.c
mbutil.o: $(srcdir)/mbutil.c
misc.o: $(srcdir)/misc.c
nls.o: $(srcdir)/nls.c
parens.o: $(srcdir)/parens.c
readline.o: $(srcdir)/readline.c
rltty.o: $(srcdir)/rltty.c
savestring.o: $(srcdir)/savestring.c
search.o: $(srcdir)/search.c
shell.o: $(srcdir)/shell.c
signals.o: $(srcdir)/signals.c
terminal.o: $(srcdir)/terminal.c
text.o: $(srcdir)/text.c
tilde.o: $(srcdir)/tilde.c
undo.o: $(srcdir)/undo.c
util.o: $(srcdir)/util.c
vi_mode.o: $(srcdir)/vi_mode.c
xfree.o: $(srcdir)/xfree.c
xmalloc.o: $(srcdir)/xmalloc.c
colors.o: $(srcdir)/parse-colors.c
parse-colors.o: $(srcdir)/parse-colors.c
histexpand.o: $(srcdir)/histexpand.c
histfile.o: $(srcdir)/histfile.c
history.o: $(srcdir)/history.c
histsearch.o: $(srcdir)/histsearch.c
bind.o: bind.c
callback.o: callback.c
compat.o: compat.c
complete.o: complete.c
display.o: display.c
funmap.o: funmap.c
input.o: input.c
isearch.o: isearch.c
keymaps.o: keymaps.c emacs_keymap.c vi_keymap.c
kill.o: kill.c
macro.o: macro.c
mbutil.o: mbutil.c
misc.o: misc.c
nls.o: nls.c
parens.o: parens.c
readline.o: readline.c
rltty.o: rltty.c
savestring.o: savestring.c
search.o: search.c
shell.o: shell.c
signals.o: signals.c
terminal.o: terminal.c
text.o: text.c
tilde.o: tilde.c
undo.o: undo.c
util.o: util.c
vi_mode.o: vi_mode.c
xfree.o: xfree.c
xmalloc.o: xmalloc.c
histexpand.o: histexpand.c
histfile.o: histfile.c
history.o: history.c
histsearch.o: histsearch.c

485
NEWS Normal file
View file

@ -0,0 +1,485 @@
This is a terse description of the new features added to readline-8.2 since
the release of readline-8.1.
New Features in Readline
a. There is now an HS_HISTORY_VERSION containing the version number of the
history library for applications to use.
b. History expansion better understands multiple history expansions that may
contain strings that would ordinarily inhibit history expansion (e.g.,
`abc!$!$').
c. There is a new framework for readline timeouts, including new public
functions to set timeouts and query how much time is remaining before a
timeout hits, and a hook function that can trigger when readline times
out. There is a new state value to indicate a timeout.
d. Automatically bind termcap key sequences for page-up and page-down to
history-search-backward and history-search-forward, respectively.
e. There is a new `fetch-history' bindable command that retrieves the history
entry corresponding to its numeric argument. Negative arguments count back
from the end of the history.
f. `vi-undo' is now a bindable command.
g. There is a new option: `enable-active-region'. This separates control of
the active region and bracketed-paste. It has the same default value as
bracketed-paste, and enabling bracketed paste enables the active region.
Users can now turn off the active region while leaving bracketed paste
enabled.
h. rl_completer_word_break_characters is now `const char *' like
rl_basic_word_break_characters.
i. Readline looks in $LS_COLORS for a custom filename extension
(*.readline-colored-completion-prefix) and uses that as the default color
for the common prefix displayed when `colored-completion-prefix' is set.
j. Two new bindable string variables: active-region-start-color and
active-region-end-color. The first sets the color used to display the
active region; the second turns it off. If set, these are used in place
of terminal standout mode.
k. New readline state (RL_STATE_EOF) and application-visible variable
(rl_eof_found) to allow applications to detect when readline reads EOF
before calling the deprep-terminal hook.
l. There is a new configuration option: --with-shared-termcap-library, which
forces linking the shared readline library with the shared termcap (or
curses/ncurses/termlib) library so applications don't have to do it.
m. Readline now checks for changes to locale settings (LC_ALL/LC_CTYPE/LANG)
each time it is called, and modifies the appropriate locale-specific display
and key binding variables when the locale changes.
-------------------------------------------------------------------------------
This is a terse description of the new features added to readline-8.1 since
the release of readline-8.0.
New Features in Readline
a. If a second consecutive completion attempt produces matches where the first
did not, treat it as a new completion attempt and insert a match as
appropriate.
b. Bracketed paste mode works in more places: incremental search strings, vi
overstrike mode, character search, and reading numeric arguments.
c. Readline automatically switches to horizontal scrolling if the terminal has
only one line.
d. Unbinding all key sequences bound to a particular readline function now
descends into keymaps for multi-key sequences.
e. rl-clear-display: new bindable command that clears the screen and, if
possible, the scrollback buffer (bound to emacs mode M-C-l by default).
f. New active mark and face feature: when enabled, it will highlight the text
inserted by a bracketed paste (the `active region') and the text found by
incremental and non-incremental history searches. This is tied to bracketed
paste and can be disabled by turning off bracketed paste.
g. Readline sets the mark in several additional commands.
h. Bracketed paste mode is enabled by default. There is a configure-time
option (--enable-bracketed-paste-default) to set the default to on or off.
i. Readline tries to take advantage of the more regular structure of UTF-8
characters to identify the beginning and end of characters when moving
through the line buffer.
j. The bindable operate-and-get-next command (and its default bindings) are
now part of readline instead of a bash-specific addition.
k. The signal cleanup code now blocks SIGINT while processing after a SIGINT.
-------------------------------------------------------------------------------
This is a terse description of the new features added to readline-8.0 since
the release of readline-7.0.
New Features in Readline
a. Non-incremental vi-mode search (`N', `n') can search for a shell pattern, as
Posix specifies (uses fnmatch(3) if available).
b. There are new `next-screen-line' and `previous-screen-line' bindable
commands, which move the cursor to the same column in the next, or previous,
physical line, respectively.
c. There are default key bindings for control-arrow-key key combinations.
d. A negative argument (-N) to `quoted-insert' means to insert the next N
characters using quoted-insert.
e. New public function: rl_check_signals(), which allows applications to
respond to signals that readline catches while waiting for input using
a custom read function.
f. There is new support for conditionally testing the readline version in an
inputrc file, with a full set of arithmetic comparison operators available.
g. There is a simple variable comparison facility available for use within an
inputrc file. Allowable operators are equality and inequality; string
variables may be compared to a value; boolean variables must be compared to
either `on' or `off'; variable names are separated from the operator by
whitespace.
h. The history expansion library now understands command and process
substitution and extended globbing and allows them to appear anywhere in a
word.
i. The history library has a new variable that allows applications to set the
initial quoting state, so quoting state can be inherited from a previous
line.
j. Readline now allows application-defined keymap names; there is a new public
function, rl_set_keymap_name(), to do that.
k. The "Insert" keypad key, if available, now puts readline into overwrite
mode.
-------------------------------------------------------------------------------
This is a terse description of the new features added to readline-7.0 since
the release of readline-6.3.
New Features in Readline
a. The history truncation code now uses the same error recovery mechanism as
the history writing code, and restores the old version of the history file
on error. The error recovery mechanism handles symlinked history files.
b. There is a new bindable variable, `enable-bracketed-paste', which enables
support for a terminal's bracketed paste mode.
c. The editing mode indicators can now be strings and are user-settable
(new `emacs-mode-string', `vi-cmd-mode-string' and `vi-ins-mode-string'
variables). Mode strings can contain invisible character sequences.
Setting mode strings to null strings restores the defaults.
d. Prompt expansion adds the mode string to the last line of a multi-line
prompt (one with embedded newlines).
e. There is a new bindable variable, `colored-completion-prefix', which, if
set, causes the common prefix of a set of possible completions to be
displayed in color.
f. There is a new bindable command `vi-yank-pop', a vi-mode version of emacs-
mode yank-pop.
g. The redisplay code underwent several efficiency improvements for multibyte
locales.
h. The insert-char function attempts to batch-insert all pending typeahead
that maps to self-insert, as long as it is coming from the terminal.
i. rl_callback_sigcleanup: a new application function that can clean up and
unset any state set by readline's callback mode. Intended to be used
after a signal.
j. If an incremental search string has its last character removed with DEL, the
resulting empty search string no longer matches the previous line.
k. If readline reads a history file that begins with `#' (or the value of
the history comment character) and has enabled history timestamps, the history
entries are assumed to be delimited by timestamps. This allows multi-line
history entries.
l. Readline now throws an error if it parses a key binding without a terminating
`:' or whitespace.
m. The default binding for ^W in vi mode now uses word boundaries specified
by Posix (vi-unix-word-rubout is bindable command name).
n. rl_clear_visible_line: new application-callable function; clears all
screen lines occupied by the current visible readline line.
o. rl_tty_set_echoing: application-callable function that controls whether
or not readline thinks it is echoing terminal output.
p. Handle >| and strings of digits preceding and following redirection
specifications as single tokens when tokenizing the line for history
expansion.
q. Fixed a bug with displaying completions when the prefix display length
is greater than the length of the completions to be displayed.
r. The :p history modifier now applies to the entire line, so any expansion
specifying :p causes the line to be printed instead of expanded.
s. New application-callable function: rl_pending_signal(): returns the signal
number of any signal readline has caught but not yet handled.
t. New application-settable variable: rl_persistent_signal_handlers: if set
to a non-zero value, readline will enable the readline-6.2 signal handler
behavior in callback mode: handlers are installed when
rl_callback_handler_install is called and removed removed when a complete
line has been read.
-------------------------------------------------------------------------------
This is a terse description of the new features added to readline-6.3 since
the release of readline-6.2.
New Features in Readline
a. Readline is now more responsive to SIGHUP and other fatal signals when
reading input from the terminal or performing word completion but no
longer attempts to run any not-allowable functions from a signal handler
context.
b. There are new bindable commands to search the history for the string of
characters between the beginning of the line and the point
(history-substring-search-forward, history-substring-search-backward)
c. Readline allows quoted strings as the values of variables when setting
them with `set'. As a side effect, trailing spaces and tabs are ignored
when setting a string variable's value.
d. The history library creates a backup of the history file when writing it
and restores the backup on a write error.
e. New application-settable variable: rl_filename_stat_hook: a function called
with a filename before using it in a call to stat(2). Bash uses it to
expand shell variables so things like $HOME/Downloads have a slash
appended.
f. New bindable function `print-last-kbd-macro', prints the most-recently-
defined keyboard macro in a reusable format.
g. New user-settable variable `colored-stats', enables use of colored text
to denote file types when displaying possible completions (colored analog
of visible-stats).
h. New user-settable variable `keyseq-timout', acts as an inter-character
timeout when reading input or incremental search strings.
i. New application-callable function: rl_clear_history. Clears the history list
and frees all readline-associated private data.
j. New user-settable variable, show-mode-in-prompt, adds a characters to the
beginning of the prompt indicating the current editing mode.
k. New application-settable variable: rl_input_available_hook; function to be
called when readline detects there is data available on its input file
descriptor.
l. Readline calls an application-set event hook (rl_event_hook) after it gets
a signal while reading input (read returns -1/EINTR but readline does not
handle the signal immediately) to allow the application to handle or
otherwise note it.
m. If the user-settable variable `history-size' is set to a value less than
0, the history list size is unlimited.
n. New application-settable variable: rl_signal_event_hook; function that is
called when readline is reading terminal input and read(2) is interrupted
by a signal. Currently not called for SIGHUP or SIGTERM.
-------------------------------------------------------------------------------
This is a terse description of the new features added to readline-6.2 since
the release of readline-6.1.
a. The history library does not try to write the history filename in the
current directory if $HOME is unset. This closes a potential security
problem if the application does not specify a history filename.
b. New bindable variable `completion-display-width' to set the number of
columns used when displaying completions.
c. New bindable variable `completion-case-map' to cause case-insensitive
completion to treat `-' and `_' as identical.
d. There are new bindable vi-mode command names to avoid readline's case-
insensitive matching not allowing them to be bound separately.
e. New bindable variable `menu-complete-display-prefix' causes the menu
completion code to display the common prefix of the possible completions
before cycling through the list, instead of after.
-------------------------------------------------------------------------------
This is a terse description of the new features added to readline-6.1 since
the release of readline-6.0.
New Features in Readline
a. New bindable function: menu-complete-backward.
b. In the vi insertion keymap, C-n is now bound to menu-complete by default,
and C-p to menu-complete-backward.
c. When in vi command mode, repeatedly hitting ESC now does nothing, even
when ESC introduces a bound key sequence. This is closer to how
historical vi behaves.
d. New bindable function: skip-csi-sequence. Can be used as a default to
consume key sequences generated by keys like Home and End without having
to bind all keys.
e. New application-settable function: rl_filename_rewrite_hook. Can be used
to rewrite or modify filenames read from the file system before they are
compared to the word to be completed.
f. New bindable variable: skip-completed-text, active when completing in the
middle of a word. If enabled, it means that characters in the completion
that match characters in the remainder of the word are "skipped" rather
than inserted into the line.
g. The pre-readline-6.0 version of menu completion is available as
"old-menu-complete" for users who do not like the readline-6.0 version.
h. New bindable variable: echo-control-characters. If enabled, and the
tty ECHOCTL bit is set, controls the echoing of characters corresponding
to keyboard-generated signals.
i. New bindable variable: enable-meta-key. Controls whether or not readline
sends the smm/rmm sequences if the terminal indicates it has a meta key
that enables eight-bit characters.
-------------------------------------------------------------------------------
This is a terse description of the new features added to readline-6.0 since
the release of readline-5.2.
New Features in Readline
a. A new variable, rl_sort_completion_matches; allows applications to inhibit
match list sorting (but beware: some things don't work right if
applications do this).
b. A new variable, rl_completion_invoking_key; allows applications to discover
the key that invoked rl_complete or rl_menu_complete.
c. The functions rl_block_sigint and rl_release_sigint are now public and
available to calling applications who want to protect critical sections
(like redisplay).
d. The functions rl_save_state and rl_restore_state are now public and
available to calling applications; documented rest of readline's state
flag values.
e. A new user-settable variable, `history-size', allows setting the maximum
number of entries in the history list.
f. There is a new implementation of menu completion, with several improvements
over the old; the most notable improvement is a better `completions
browsing' mode.
g. The menu completion code now uses the rl_menu_completion_entry_function
variable, allowing applications to provide their own menu completion
generators.
h. There is support for replacing a prefix of a pathname with a `...' when
displaying possible completions. This is controllable by setting the
`completion-prefix-display-length' variable. Matches with a common prefix
longer than this value have the common prefix replaced with `...'.
i. There is a new `revert-all-at-newline' variable. If enabled, readline will
undo all outstanding changes to all history lines when `accept-line' is
executed.
-------------------------------------------------------------------------------
This is a terse description of the new features added to readline-5.2 since
the release of readline-5.1.
New Features in Readline
a. Calling applications can now set the keyboard timeout to 0, allowing
poll-like behavior.
b. The value of SYS_INPUTRC (configurable at compilation time) is now used as
the default last-ditch startup file.
c. The history file reading functions now allow windows-like \r\n line
terminators.
-------------------------------------------------------------------------------
This is a terse description of the new features added to readline-5.1 since
the release of readline-5.0.
New Features in Readline
a. The key sequence sent by the keypad `delete' key is now automatically
bound to delete-char.
b. A negative argument to menu-complete now cycles backward through the
completion list.
c. A new bindable readline variable: bind-tty-special-chars. If non-zero,
readline will bind the terminal special characters to their readline
equivalents when it's called (on by default).
d. New bindable command: vi-rubout. Saves deleted text for possible
reinsertion, as with any vi-mode `text modification' command; `X' is bound
to this in vi command mode.
e. If the rl_completion_query_items is set to a value < 0, readline never
asks the user whether or not to view the possible completions.
f. New application-callable auxiliary function, rl_variable_value, returns
a string corresponding to a readline variable's value.
g. When parsing inputrc files and variable binding commands, the parser
strips trailing whitespace from values assigned to boolean variables
before checking them.
h. A new external application-controllable variable that allows the LINES
and COLUMNS environment variables to set the window size regardless of
what the kernel returns.
-------------------------------------------------------------------------------
This is a terse description of the new features added to readline-5.0 since
the release of readline-4.3.
New Features in Readline
a. History expansion has a new `a' modifier equivalent to the `g' modifier
for compatibility with the BSD csh.
b. History expansion has a new `G' modifier equivalent to the BSD csh `g'
modifier, which performs a substitution once per word.
c. All non-incremental search operations may now undo the operation of
replacing the current line with the history line.
d. The text inserted by an `a' command in vi mode can be reinserted with
`.'.
e. New bindable variable, `show-all-if-unmodified'. If set, the readline
completer will list possible completions immediately if there is more
than one completion and partial completion cannot be performed.
f. There is a new application-callable `free_history_entry()' function.
g. History list entries now contain timestamp information; the history file
functions know how to read and write timestamp information associated
with each entry.
h. Four new key binding functions have been added:
rl_bind_key_if_unbound()
rl_bind_key_if_unbound_in_map()
rl_bind_keyseq_if_unbound()
rl_bind_keyseq_if_unbound_in_map()
i. New application variable, rl_completion_quote_character, set to any
quote character readline finds before it calls the application completion
function.
j. New application variable, rl_completion_suppress_quote, settable by an
application completion function. If set to non-zero, readline does not
attempt to append a closing quote to a completed word.
k. New application variable, rl_completion_found_quote, set to a non-zero
value if readline determines that the word to be completed is quoted.
Set before readline calls any application completion function.
l. New function hook, rl_completion_word_break_hook, called when readline
needs to break a line into words when completion is attempted. Allows
the word break characters to vary based on position in the line.
m. New bindable command: unix-filename-rubout. Does the same thing as
unix-word-rubout, but adds `/' to the set of word delimiters.
n. When listing completions, directories have a `/' appended if the
`mark-directories' option has been enabled.

196
README Normal file
View file

@ -0,0 +1,196 @@
Introduction
============
This is the Gnu Readline library, version 8.2.
The Readline library provides a set of functions for use by applications
that allow users to edit command lines as they are typed in. Both
Emacs and vi editing modes are available. The Readline library includes
additional functions to maintain a list of previously-entered command
lines, to recall and perhaps reedit those lines, and perform csh-like
history expansion on previous commands.
The history facilities are also placed into a separate library, the
History library, as part of the build process. The History library
may be used without Readline in applications which desire its
capabilities.
The Readline library is free software, distributed under the terms of
the [GNU] General Public License as published by the Free Software
Foundation, version 3 of the License. For more information, see the
file COPYING.
To build the library, try typing `./configure', then `make'. The
configuration process is automated, so no further intervention should
be necessary. Readline builds with `gcc' by default if it is
available. If you want to use `cc' instead, type
CC=cc ./configure
if you are using a Bourne-style shell. If you are not, the following
may work:
env CC=cc ./configure
Read the file INSTALL in this directory for more information about how
to customize and control the build process.
The file rlconf.h contains C preprocessor defines that enable and disable
certain Readline features.
The special make target `everything' will build the static and shared
libraries (if the target platform supports them) and the examples.
Examples
========
There are several example programs that use Readline features in the
examples directory. The `rl' program is of particular interest. It
is a command-line interface to Readline, suitable for use in shell
scripts in place of `read'.
Shared Libraries
================
There is skeletal support for building shared versions of the
Readline and History libraries. The configure script creates
a Makefile in the `shlib' subdirectory, and typing `make shared'
will cause shared versions of the Readline and History libraries
to be built on supported platforms.
If `configure' is given the `--enable-shared' option, it will attempt
to build the shared libraries by default on supported platforms.
Configure calls the script support/shobj-conf to test whether or
not shared library creation is supported and to generate the values
of variables that are substituted into shlib/Makefile. If you
try to build shared libraries on an unsupported platform, `make'
will display a message asking you to update support/shobj-conf for
your platform.
If you need to update support/shobj-conf, you will need to create
a `stanza' for your operating system and compiler. The script uses
the value of host_os and ${CC} as determined by configure. For
instance, FreeBSD 4.2 with any version of gcc is identified as
`freebsd4.2-gcc*'.
In the stanza for your operating system-compiler pair, you will need to
define several variables. They are:
SHOBJ_CC The C compiler used to compile source files into shareable
object files. This is normally set to the value of ${CC}
by configure, and should not need to be changed.
SHOBJ_CFLAGS Flags to pass to the C compiler ($SHOBJ_CC) to create
position-independent code. If you are using gcc, this
should probably be set to `-fpic'.
SHOBJ_LD The link editor to be used to create the shared library from
the object files created by $SHOBJ_CC. If you are using
gcc, a value of `gcc' will probably work.
SHOBJ_LDFLAGS Flags to pass to SHOBJ_LD to enable shared object creation.
If you are using gcc, `-shared' may be all that is necessary.
These should be the flags needed for generic shared object
creation.
SHLIB_XLDFLAGS Additional flags to pass to SHOBJ_LD for shared library
creation. Many systems use the -R option to the link
editor to embed a path within the library for run-time
library searches. A reasonable value for such systems would
be `-R$(libdir)'.
SHLIB_LIBS Any additional libraries that shared libraries should be
linked against when they are created.
SHLIB_LIBPREF The prefix to use when generating the filename of the shared
library. The default is `lib'; Cygwin uses `cyg'.
SHLIB_LIBSUFF The suffix to add to `libreadline' and `libhistory' when
generating the filename of the shared library. Many systems
use `so'; HP-UX uses `sl'.
SHLIB_LIBVERSION The string to append to the filename to indicate the version
of the shared library. It should begin with $(SHLIB_LIBSUFF),
and possibly include version information that allows the
run-time loader to load the version of the shared library
appropriate for a particular program. Systems using shared
libraries similar to SunOS 4.x use major and minor library
version numbers; for those systems a value of
`$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)$(SHLIB_MINOR)' is appropriate.
Systems based on System V Release 4 don't use minor version
numbers; use `$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' on those systems.
Other Unix versions use different schemes.
SHLIB_DLLVERSION The version number for shared libraries that determines API
compatibility between readline versions and the underlying
system. Used only on Cygwin. Defaults to $SHLIB_MAJOR, but
can be overridden at configuration time by defining DLLVERSION
in the environment.
SHLIB_DOT The character used to separate the name of the shared library
from the suffix and version information. The default is `.';
systems like Cygwin which don't separate version information
from the library name should set this to the empty string.
SHLIB_STATUS Set this to `supported' when you have defined the other
necessary variables. Make uses this to determine whether
or not shared library creation should be attempted.
You should look at the existing stanzas in support/shobj-conf for ideas.
Once you have updated support/shobj-conf, re-run configure and type
`make shared'. The shared libraries will be created in the shlib
subdirectory.
If shared libraries are created, `make install' will install them.
You may install only the shared libraries by running `make
install-shared' from the top-level build directory. Running `make
install' in the shlib subdirectory will also work. If you don't want
to install any created shared libraries, run `make install-static'.
Documentation
=============
The documentation for the Readline and History libraries appears in
the `doc' subdirectory. There are three texinfo files and a
Unix-style manual page describing the facilities available in the
Readline library. The texinfo files include both user and
programmer's manuals. HTML versions of the manuals appear in the
`doc' subdirectory as well.
Usage
=====
Our position on the use of Readline through a shared-library linking
mechanism is that there is no legal difference between shared-library
linking and static linking--either kind of linking combines various
modules into a single larger work. The conditions for using Readline
in a larger work are stated in section 3 of the GNU GPL.
Reporting Bugs
==============
Bug reports for Readline should be sent to:
bug-readline@gnu.org
When reporting a bug, please include the following information:
* the version number and release status of Readline (e.g., 4.2-release)
* the machine and OS that it is running on
* a list of the compilation flags or the contents of `config.h', if
appropriate
* a description of the bug
* a recipe for recreating the bug reliably
* a fix for the bug if you have one!
If you would like to contact the Readline maintainer directly, send mail
to bash-maintainers@gnu.org.
Since Readline is developed along with bash, the bug-bash@gnu.org mailing
list (mirrored to the Usenet newsgroup gnu.bash.bug) often contains
Readline bug reports and fixes.
Chet Ramey
chet.ramey@case.edu

37
USAGE Normal file
View file

@ -0,0 +1,37 @@
From rms@gnu.org Thu Jul 22 20:37:55 1999
Flags: 10
Return-Path: rms@gnu.org
Received: from arthur.INS.CWRU.Edu (root@arthur.INS.CWRU.Edu [129.22.8.215]) by odin.INS.CWRU.Edu with ESMTP (8.8.6+cwru/CWRU-2.4-ins)
id UAA25349; Thu, 22 Jul 1999 20:37:54 -0400 (EDT) (from rms@gnu.org for <chet@odin.INS.CWRU.Edu>)
Received: from nike.ins.cwru.edu (root@nike.INS.CWRU.Edu [129.22.8.219]) by arthur.INS.CWRU.Edu with ESMTP (8.8.8+cwru/CWRU-3.6)
id UAA05311; Thu, 22 Jul 1999 20:37:51 -0400 (EDT) (from rms@gnu.org for <chet@po.cwru.edu>)
Received: from pele.santafe.edu (pele.santafe.edu [192.12.12.119]) by nike.ins.cwru.edu with ESMTP (8.8.7/CWRU-2.5-bsdi)
id UAA13350; Thu, 22 Jul 1999 20:37:50 -0400 (EDT) (from rms@gnu.org for <chet@nike.ins.cwru.edu>)
Received: from wijiji.santafe.edu (wijiji [192.12.12.5])
by pele.santafe.edu (8.9.1/8.9.1) with ESMTP id SAA10831
for <chet@nike.ins.cwru.edu>; Thu, 22 Jul 1999 18:37:47 -0600 (MDT)
Received: (from rms@localhost)
by wijiji.santafe.edu (8.9.1b+Sun/8.9.1) id SAA01089;
Thu, 22 Jul 1999 18:37:46 -0600 (MDT)
Date: Thu, 22 Jul 1999 18:37:46 -0600 (MDT)
Message-Id: <199907230037.SAA01089@wijiji.santafe.edu>
X-Authentication-Warning: wijiji.santafe.edu: rms set sender to rms@gnu.org using -f
From: Richard Stallman <rms@gnu.org>
To: chet@nike.ins.cwru.edu
Subject: Use of Readline
Reply-to: rms@gnu.org
I think Allbery's suggestion is a good one. So please add this text
in a suitable place. Please don't put it in the GPL itself; that
should be the same as the GPL everywhere else. Putting it in the
README and/or the documentation would be a good idea.
======================================================================
Our position on the use of Readline through a shared-library linking
mechanism is that there is no legal difference between shared-library
linking and static linking--either kind of linking combines various
modules into a single larger work. The conditions for using Readline
in a larger work are stated in section 3 of the GNU GPL.

2267
aclocal.m4 vendored Normal file

File diff suppressed because it is too large Load diff

54
ansi_stdlib.h Normal file
View file

@ -0,0 +1,54 @@
/* ansi_stdlib.h -- An ANSI Standard stdlib.h. */
/* A minimal stdlib.h containing extern declarations for those functions
that bash uses. */
/* Copyright (C) 1993 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
Bash 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 3 of the License, or
(at your option) any later version.
Bash 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 Bash. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined (_STDLIB_H_)
#define _STDLIB_H_ 1
/* String conversion functions. */
extern int atoi ();
extern double atof ();
extern double strtod ();
/* Memory allocation functions. */
/* Generic pointer type. */
#ifndef PTR_T
#if defined (__STDC__)
# define PTR_T void *
#else
# define PTR_T char *
#endif
#endif /* PTR_T */
extern PTR_T malloc ();
extern PTR_T realloc ();
extern void free ();
/* Other miscellaneous functions. */
extern void abort ();
extern void exit ();
extern char *getenv ();
extern void qsort ();
#endif /* _STDLIB_H */

3082
bind.c Normal file

File diff suppressed because it is too large Load diff

378
callback.c Normal file
View file

@ -0,0 +1,378 @@
/* callback.c -- functions to use readline as an X `callback' mechanism. */
/* Copyright (C) 1987-2022 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
Readline 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 3 of the License, or
(at your option) any later version.
Readline 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 Readline. If not, see <http://www.gnu.org/licenses/>.
*/
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include "rlconf.h"
#if defined (READLINE_CALLBACKS)
#include <sys/types.h>
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif
#include <stdio.h>
/* System-specific feature definitions and include files. */
#include "rldefs.h"
#include "readline.h"
#include "rlprivate.h"
#include "xmalloc.h"
/* Private data for callback registration functions. See comments in
rl_callback_read_char for more details. */
_rl_callback_func_t *_rl_callback_func = 0;
_rl_callback_generic_arg *_rl_callback_data = 0;
/* Applications can set this to non-zero to have readline's signal handlers
installed during the entire duration of reading a complete line, as in
readline-6.2. This should be used with care, because it can result in
readline receiving signals and not handling them until it's called again
via rl_callback_read_char, thereby stealing them from the application.
By default, signal handlers are only active while readline is active. */
int rl_persistent_signal_handlers = 0;
/* **************************************************************** */
/* */
/* Callback Readline Functions */
/* */
/* **************************************************************** */
/* Allow using readline in situations where a program may have multiple
things to handle at once, and dispatches them via select(). Call
rl_callback_handler_install() with the prompt and a function to call
whenever a complete line of input is ready. The user must then
call rl_callback_read_char() every time some input is available, and
rl_callback_read_char() will call the user's function with the complete
text read in at each end of line. The terminal is kept prepped
all the time, except during calls to the user's function. Signal
handlers are only installed when the application calls back into
readline, so readline doesn't `steal' signals from the application. */
rl_vcpfunc_t *rl_linefunc; /* user callback function */
static int in_handler; /* terminal_prepped and signals set? */
/* Make sure the terminal is set up, initialize readline, and prompt. */
static void
_rl_callback_newline (void)
{
rl_initialize ();
if (in_handler == 0)
{
in_handler = 1;
if (rl_prep_term_function)
(*rl_prep_term_function) (_rl_meta_flag);
#if defined (HANDLE_SIGNALS)
if (rl_persistent_signal_handlers)
rl_set_signals ();
#endif
}
readline_internal_setup ();
RL_CHECK_SIGNALS ();
}
/* Install a readline handler, set up the terminal, and issue the prompt. */
void
rl_callback_handler_install (const char *prompt, rl_vcpfunc_t *linefunc)
{
rl_set_prompt (prompt);
RL_SETSTATE (RL_STATE_CALLBACK);
rl_linefunc = linefunc;
_rl_callback_newline ();
}
#if defined (HANDLE_SIGNALS)
#define CALLBACK_READ_RETURN() \
do { \
if (rl_persistent_signal_handlers == 0) \
rl_clear_signals (); \
return; \
} while (0)
#else
#define CALLBACK_READ_RETURN() return
#endif
/* Read one character, and dispatch to the handler if it ends the line. */
void
rl_callback_read_char (void)
{
char *line;
int eof, jcode;
static procenv_t olevel;
if (rl_linefunc == NULL)
{
_rl_errmsg ("readline_callback_read_char() called with no handler!");
abort ();
}
eof = 0;
memcpy ((void *)olevel, (void *)_rl_top_level, sizeof (procenv_t));
#if defined (HAVE_POSIX_SIGSETJMP)
jcode = sigsetjmp (_rl_top_level, 0);
#else
jcode = setjmp (_rl_top_level);
#endif
if (jcode)
{
(*rl_redisplay_function) ();
_rl_want_redisplay = 0;
memcpy ((void *)_rl_top_level, (void *)olevel, sizeof (procenv_t));
/* If we longjmped because of a timeout, handle it here. */
if (RL_ISSTATE (RL_STATE_TIMEOUT))
{
RL_SETSTATE (RL_STATE_DONE);
rl_done = 1;
}
CALLBACK_READ_RETURN ();
}
#if defined (HANDLE_SIGNALS)
/* Install signal handlers only when readline has control. */
if (rl_persistent_signal_handlers == 0)
rl_set_signals ();
#endif
do
{
RL_CHECK_SIGNALS ();
if (RL_ISSTATE (RL_STATE_ISEARCH))
{
eof = _rl_isearch_callback (_rl_iscxt);
if (eof == 0 && (RL_ISSTATE (RL_STATE_ISEARCH) == 0) && RL_ISSTATE (RL_STATE_INPUTPENDING))
rl_callback_read_char ();
CALLBACK_READ_RETURN ();
}
else if (RL_ISSTATE (RL_STATE_NSEARCH))
{
eof = _rl_nsearch_callback (_rl_nscxt);
CALLBACK_READ_RETURN ();
}
#if defined (VI_MODE)
/* States that can occur while in state VIMOTION have to be checked
before RL_STATE_VIMOTION */
else if (RL_ISSTATE (RL_STATE_CHARSEARCH))
{
int k;
k = _rl_callback_data->i2;
eof = (*_rl_callback_func) (_rl_callback_data);
/* If the function `deregisters' itself, make sure the data is
cleaned up. */
if (_rl_callback_func == 0) /* XXX - just sanity check */
{
if (_rl_callback_data)
{
_rl_callback_data_dispose (_rl_callback_data);
_rl_callback_data = 0;
}
}
/* Messy case where vi motion command can be char search */
if (RL_ISSTATE (RL_STATE_VIMOTION))
{
_rl_vi_domove_motion_cleanup (k, _rl_vimvcxt);
_rl_internal_char_cleanup ();
CALLBACK_READ_RETURN ();
}
_rl_internal_char_cleanup ();
}
else if (RL_ISSTATE (RL_STATE_VIMOTION))
{
eof = _rl_vi_domove_callback (_rl_vimvcxt);
/* Should handle everything, including cleanup, numeric arguments,
and turning off RL_STATE_VIMOTION */
if (RL_ISSTATE (RL_STATE_NUMERICARG) == 0)
_rl_internal_char_cleanup ();
CALLBACK_READ_RETURN ();
}
#endif
else if (RL_ISSTATE (RL_STATE_NUMERICARG))
{
eof = _rl_arg_callback (_rl_argcxt);
if (eof == 0 && (RL_ISSTATE (RL_STATE_NUMERICARG) == 0) && RL_ISSTATE (RL_STATE_INPUTPENDING))
rl_callback_read_char ();
/* XXX - this should handle _rl_last_command_was_kill better */
else if (RL_ISSTATE (RL_STATE_NUMERICARG) == 0)
_rl_internal_char_cleanup ();
CALLBACK_READ_RETURN ();
}
else if (RL_ISSTATE (RL_STATE_MULTIKEY))
{
eof = _rl_dispatch_callback (_rl_kscxt); /* For now */
while ((eof == -1 || eof == -2) && RL_ISSTATE (RL_STATE_MULTIKEY) && _rl_kscxt && (_rl_kscxt->flags & KSEQ_DISPATCHED))
eof = _rl_dispatch_callback (_rl_kscxt);
if (RL_ISSTATE (RL_STATE_MULTIKEY) == 0)
{
_rl_internal_char_cleanup ();
_rl_want_redisplay = 1;
}
}
else if (_rl_callback_func)
{
/* This allows functions that simply need to read an additional
character (like quoted-insert) to register a function to be
called when input is available. _rl_callback_data is a
pointer to a struct that has the argument count originally
passed to the registering function and space for any additional
parameters. */
eof = (*_rl_callback_func) (_rl_callback_data);
/* If the function `deregisters' itself, make sure the data is
cleaned up. */
if (_rl_callback_func == 0)
{
if (_rl_callback_data)
{
_rl_callback_data_dispose (_rl_callback_data);
_rl_callback_data = 0;
}
_rl_internal_char_cleanup ();
}
}
else
eof = readline_internal_char ();
RL_CHECK_SIGNALS ();
if (rl_done == 0 && _rl_want_redisplay)
{
(*rl_redisplay_function) ();
_rl_want_redisplay = 0;
}
/* Make sure application hooks can see whether we saw EOF. */
if (eof > 0)
{
rl_eof_found = eof;
RL_SETSTATE(RL_STATE_EOF);
}
if (rl_done)
{
line = readline_internal_teardown (eof);
if (rl_deprep_term_function)
(*rl_deprep_term_function) ();
#if defined (HANDLE_SIGNALS)
rl_clear_signals ();
#endif
in_handler = 0;
if (rl_linefunc) /* just in case */
(*rl_linefunc) (line);
/* If the user did not clear out the line, do it for him. */
if (rl_line_buffer[0])
_rl_init_line_state ();
/* Redisplay the prompt if readline_handler_{install,remove}
not called. */
if (in_handler == 0 && rl_linefunc)
_rl_callback_newline ();
}
}
while (rl_pending_input || _rl_pushed_input_available () || RL_ISSTATE (RL_STATE_MACROINPUT));
CALLBACK_READ_RETURN ();
}
/* Remove the handler, and make sure the terminal is in its normal state. */
void
rl_callback_handler_remove (void)
{
rl_linefunc = NULL;
RL_UNSETSTATE (RL_STATE_CALLBACK);
RL_CHECK_SIGNALS ();
if (in_handler)
{
in_handler = 0;
if (rl_deprep_term_function)
(*rl_deprep_term_function) ();
#if defined (HANDLE_SIGNALS)
rl_clear_signals ();
#endif
}
}
_rl_callback_generic_arg *
_rl_callback_data_alloc (int count)
{
_rl_callback_generic_arg *arg;
arg = (_rl_callback_generic_arg *)xmalloc (sizeof (_rl_callback_generic_arg));
arg->count = count;
arg->i1 = arg->i2 = 0;
return arg;
}
void
_rl_callback_data_dispose (_rl_callback_generic_arg *arg)
{
xfree (arg);
}
/* Make sure that this agrees with cases in rl_callback_read_char */
void
rl_callback_sigcleanup (void)
{
if (RL_ISSTATE (RL_STATE_CALLBACK) == 0)
return;
if (RL_ISSTATE (RL_STATE_ISEARCH))
_rl_isearch_cleanup (_rl_iscxt, 0);
else if (RL_ISSTATE (RL_STATE_NSEARCH))
_rl_nsearch_cleanup (_rl_nscxt, 0);
else if (RL_ISSTATE (RL_STATE_VIMOTION))
RL_UNSETSTATE (RL_STATE_VIMOTION);
else if (RL_ISSTATE (RL_STATE_NUMERICARG))
{
_rl_argcxt = 0;
RL_UNSETSTATE (RL_STATE_NUMERICARG);
}
else if (RL_ISSTATE (RL_STATE_MULTIKEY))
RL_UNSETSTATE (RL_STATE_MULTIKEY);
if (RL_ISSTATE (RL_STATE_CHARSEARCH))
RL_UNSETSTATE (RL_STATE_CHARSEARCH);
_rl_callback_func = 0;
}
#endif

165
chardefs.h Normal file
View file

@ -0,0 +1,165 @@
/* chardefs.h -- Character definitions for readline. */
/* Copyright (C) 1994-2021 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
Readline 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 3 of the License, or
(at your option) any later version.
Readline 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 Readline. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _CHARDEFS_H_
#define _CHARDEFS_H_
#include <ctype.h>
#if defined (HAVE_CONFIG_H)
# if defined (HAVE_STRING_H)
# include <string.h>
# endif /* HAVE_STRING_H */
# if defined (HAVE_STRINGS_H)
# include <strings.h>
# endif /* HAVE_STRINGS_H */
#else
# include <string.h>
#endif /* !HAVE_CONFIG_H */
#ifndef whitespace
#define whitespace(c) (((c) == ' ') || ((c) == '\t'))
#endif
#ifdef CTRL
# undef CTRL
#endif
#ifdef UNCTRL
# undef UNCTRL
#endif
/* Some character stuff. */
#define control_character_threshold 0x020 /* Smaller than this is control. */
#define control_character_mask 0x1f /* 0x20 - 1 */
#define meta_character_threshold 0x07f /* Larger than this is Meta. */
#define control_character_bit 0x40 /* 0x000000, must be off. */
#define meta_character_bit 0x080 /* x0000000, must be on. */
#define largest_char 255 /* Largest character value. */
#define CTRL_CHAR(c) ((c) < control_character_threshold && (((c) & 0x80) == 0))
#define META_CHAR(c) ((c) > meta_character_threshold && (c) <= largest_char)
#define CTRL(c) ((c) & control_character_mask)
#define META(c) ((c) | meta_character_bit)
#define UNMETA(c) ((c) & (~meta_character_bit))
#define UNCTRL(c) _rl_to_upper(((c)|control_character_bit))
#ifndef UCHAR_MAX
# define UCHAR_MAX 255
#endif
#ifndef CHAR_MAX
# define CHAR_MAX 127
#endif
/* use this as a proxy for C89 */
#if defined (HAVE_STDLIB_H) && defined (HAVE_STRING_H)
# define IN_CTYPE_DOMAIN(c) 1
# define NON_NEGATIVE(c) 1
#else
# define IN_CTYPE_DOMAIN(c) ((c) >= 0 && (c) <= CHAR_MAX)
# define NON_NEGATIVE(c) ((unsigned char)(c) == (c))
#endif
#if !defined (isxdigit) && !defined (HAVE_ISXDIGIT) && !defined (__cplusplus)
# define isxdigit(c) (isdigit((unsigned char)(c)) || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F'))
#endif
/* Some systems define these; we want our definitions. */
#undef ISPRINT
/* Beware: these only work with single-byte ASCII characters. */
#define ISALNUM(c) (IN_CTYPE_DOMAIN (c) && isalnum ((unsigned char)c))
#define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha ((unsigned char)c))
#define ISDIGIT(c) (IN_CTYPE_DOMAIN (c) && isdigit ((unsigned char)c))
#define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower ((unsigned char)c))
#define ISPRINT(c) (IN_CTYPE_DOMAIN (c) && isprint ((unsigned char)c))
#define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper ((unsigned char)c))
#define ISXDIGIT(c) (IN_CTYPE_DOMAIN (c) && isxdigit ((unsigned char)c))
#define _rl_lowercase_p(c) (NON_NEGATIVE(c) && ISLOWER(c))
#define _rl_uppercase_p(c) (NON_NEGATIVE(c) && ISUPPER(c))
#define _rl_digit_p(c) ((c) >= '0' && (c) <= '9')
#define _rl_alphabetic_p(c) (NON_NEGATIVE(c) && ISALNUM(c))
#define _rl_pure_alphabetic(c) (NON_NEGATIVE(c) && ISALPHA(c))
#ifndef _rl_to_upper
# define _rl_to_upper(c) (_rl_lowercase_p(c) ? toupper((unsigned char)(c)) : (c))
# define _rl_to_lower(c) (_rl_uppercase_p(c) ? tolower((unsigned char)(c)) : (c))
#endif
#ifndef _rl_digit_value
# define _rl_digit_value(x) ((x) - '0')
#endif
#ifndef _rl_isident
# define _rl_isident(c) (ISALNUM(c) || (c) == '_')
#endif
#ifndef ISOCTAL
# define ISOCTAL(c) ((c) >= '0' && (c) <= '7')
#endif
#define OCTVALUE(c) ((c) - '0')
#define HEXVALUE(c) \
(((c) >= 'a' && (c) <= 'f') \
? (c)-'a'+10 \
: (c) >= 'A' && (c) <= 'F' ? (c)-'A'+10 : (c)-'0')
#ifndef NEWLINE
#define NEWLINE '\n'
#endif
#ifndef RETURN
#define RETURN CTRL('M')
#endif
#ifndef RUBOUT
#define RUBOUT 0x7f
#endif
#ifndef TAB
#define TAB '\t'
#endif
#ifdef ABORT_CHAR
#undef ABORT_CHAR
#endif
#define ABORT_CHAR CTRL('G')
#ifdef PAGE
#undef PAGE
#endif
#define PAGE CTRL('L')
#ifdef SPACE
#undef SPACE
#endif
#define SPACE ' ' /* XXX - was 0x20 */
#ifdef ESC
#undef ESC
#endif
#define ESC CTRL('[')
#endif /* _CHARDEFS_H_ */

320
colors.c Normal file
View file

@ -0,0 +1,320 @@
/* `dir', `vdir' and `ls' directory listing programs for GNU.
Modified by Chet Ramey for Readline.
Copyright (C) 1985, 1988, 1990-1991, 1995-2021
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 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* Written by Richard Stallman and David MacKenzie. */
/* Color support by Peter Anvin <Peter.Anvin@linux.org> and Dennis
Flaherty <dennisf@denix.elk.miles.com> based on original patches by
Greg Lee <lee@uhunix.uhcc.hawaii.edu>. */
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include "rlconf.h"
#if defined __TANDEM
# define _XOPEN_SOURCE_EXTENDED 1
# define _TANDEM_SOURCE 1
# include <sys/types.h>
# include <sys/stat.h>
#endif
#include <stdio.h>
#include "posixstat.h" // stat related macros (S_ISREG, ...)
#include <fcntl.h> // S_ISUID
#ifndef S_ISDIR
# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#endif
// strlen()
#if defined (HAVE_STRING_H)
# include <string.h>
#else /* !HAVE_STRING_H */
# include <strings.h>
#endif /* !HAVE_STRING_H */
// abort()
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#include "readline.h"
#include "rldefs.h"
#ifdef COLOR_SUPPORT
#include "xmalloc.h"
#include "colors.h"
static bool is_colored (enum indicator_no type);
static void restore_default_color (void);
#define RL_COLOR_PREFIX_EXTENSION "readline-colored-completion-prefix"
COLOR_EXT_TYPE *_rl_color_ext_list = 0;
/* Output a color indicator (which may contain nulls). */
void
_rl_put_indicator (const struct bin_str *ind)
{
fwrite (ind->string, ind->len, 1, rl_outstream);
}
static bool
is_colored (enum indicator_no colored_filetype)
{
size_t len = _rl_color_indicator[colored_filetype].len;
char const *s = _rl_color_indicator[colored_filetype].string;
return ! (len == 0
|| (len == 1 && strncmp (s, "0", 1) == 0)
|| (len == 2 && strncmp (s, "00", 2) == 0));
}
static void
restore_default_color (void)
{
_rl_put_indicator (&_rl_color_indicator[C_LEFT]);
_rl_put_indicator (&_rl_color_indicator[C_RIGHT]);
}
void
_rl_set_normal_color (void)
{
if (is_colored (C_NORM))
{
_rl_put_indicator (&_rl_color_indicator[C_LEFT]);
_rl_put_indicator (&_rl_color_indicator[C_NORM]);
_rl_put_indicator (&_rl_color_indicator[C_RIGHT]);
}
}
static struct bin_str *
_rl_custom_readline_prefix (void)
{
size_t len;
COLOR_EXT_TYPE *ext;
len = strlen (RL_COLOR_PREFIX_EXTENSION);
for (ext = _rl_color_ext_list; ext; ext = ext->next)
if (ext->ext.len == len && STREQN (ext->ext.string, RL_COLOR_PREFIX_EXTENSION, len))
return (&ext->seq);
return (NULL);
}
bool
_rl_print_prefix_color (void)
{
struct bin_str *s;
/* What do we want to use for the prefix? Let's try cyan first, see colors.h */
s = _rl_custom_readline_prefix ();
if (s == 0)
s = &_rl_color_indicator[C_PREFIX];
if (s->string != NULL)
{
if (is_colored (C_NORM))
restore_default_color ();
_rl_put_indicator (&_rl_color_indicator[C_LEFT]);
_rl_put_indicator (s);
_rl_put_indicator (&_rl_color_indicator[C_RIGHT]);
return 0;
}
else
return 1;
}
/* Returns whether any color sequence was printed. */
bool
_rl_print_color_indicator (const char *f)
{
enum indicator_no colored_filetype;
COLOR_EXT_TYPE *ext; /* Color extension */
size_t len; /* Length of name */
const char* name;
char *filename;
struct stat astat, linkstat;
mode_t mode;
int linkok; /* 1 == ok, 0 == dangling symlink, -1 == missing */
int stat_ok;
name = f;
/* This should already have undergone tilde expansion */
filename = 0;
if (rl_filename_stat_hook)
{
filename = savestring (f);
(*rl_filename_stat_hook) (&filename);
name = filename;
}
#if defined (HAVE_LSTAT)
stat_ok = lstat(name, &astat);
#else
stat_ok = stat(name, &astat);
#endif
if (stat_ok == 0)
{
mode = astat.st_mode;
#if defined (HAVE_LSTAT)
if (S_ISLNK (mode))
{
linkok = stat (name, &linkstat) == 0;
if (linkok && strncmp (_rl_color_indicator[C_LINK].string, "target", 6) == 0)
mode = linkstat.st_mode;
}
else
#endif
linkok = 1;
}
else
linkok = -1;
/* Is this a nonexistent file? If so, linkok == -1. */
if (linkok == -1 && _rl_color_indicator[C_MISSING].string != NULL)
colored_filetype = C_MISSING;
else if (linkok == 0 && _rl_color_indicator[C_ORPHAN].string != NULL)
colored_filetype = C_ORPHAN; /* dangling symlink */
else if(stat_ok != 0)
{
static enum indicator_no filetype_indicator[] = FILETYPE_INDICATORS;
colored_filetype = filetype_indicator[normal]; //f->filetype];
}
else
{
if (S_ISREG (mode))
{
colored_filetype = C_FILE;
#if defined (S_ISUID)
if ((mode & S_ISUID) != 0 && is_colored (C_SETUID))
colored_filetype = C_SETUID;
else
#endif
#if defined (S_ISGID)
if ((mode & S_ISGID) != 0 && is_colored (C_SETGID))
colored_filetype = C_SETGID;
else
#endif
if (is_colored (C_CAP) && 0) //f->has_capability)
colored_filetype = C_CAP;
else if ((mode & S_IXUGO) != 0 && is_colored (C_EXEC))
colored_filetype = C_EXEC;
else if ((1 < astat.st_nlink) && is_colored (C_MULTIHARDLINK))
colored_filetype = C_MULTIHARDLINK;
}
else if (S_ISDIR (mode))
{
colored_filetype = C_DIR;
#if defined (S_ISVTX)
if ((mode & S_ISVTX) && (mode & S_IWOTH)
&& is_colored (C_STICKY_OTHER_WRITABLE))
colored_filetype = C_STICKY_OTHER_WRITABLE;
else
#endif
if ((mode & S_IWOTH) != 0 && is_colored (C_OTHER_WRITABLE))
colored_filetype = C_OTHER_WRITABLE;
#if defined (S_ISVTX)
else if ((mode & S_ISVTX) != 0 && is_colored (C_STICKY))
colored_filetype = C_STICKY;
#endif
}
#if defined (S_ISLNK)
else if (S_ISLNK (mode))
colored_filetype = C_LINK;
#endif
else if (S_ISFIFO (mode))
colored_filetype = C_FIFO;
#if defined (S_ISSOCK)
else if (S_ISSOCK (mode))
colored_filetype = C_SOCK;
#endif
#if defined (S_ISBLK)
else if (S_ISBLK (mode))
colored_filetype = C_BLK;
#endif
else if (S_ISCHR (mode))
colored_filetype = C_CHR;
else
{
/* Classify a file of some other type as C_ORPHAN. */
colored_filetype = C_ORPHAN;
}
}
/* Check the file's suffix only if still classified as C_FILE. */
ext = NULL;
if (colored_filetype == C_FILE)
{
/* Test if NAME has a recognized suffix. */
len = strlen (name);
name += len; /* Pointer to final \0. */
for (ext = _rl_color_ext_list; ext != NULL; ext = ext->next)
{
if (ext->ext.len <= len
&& strncmp (name - ext->ext.len, ext->ext.string,
ext->ext.len) == 0)
break;
}
}
free (filename); /* NULL or savestring return value */
{
const struct bin_str *const s
= ext ? &(ext->seq) : &_rl_color_indicator[colored_filetype];
if (s->string != NULL)
{
/* Need to reset so not dealing with attribute combinations */
if (is_colored (C_NORM))
restore_default_color ();
_rl_put_indicator (&_rl_color_indicator[C_LEFT]);
_rl_put_indicator (s);
_rl_put_indicator (&_rl_color_indicator[C_RIGHT]);
return 0;
}
else
return 1;
}
}
void
_rl_prep_non_filename_text (void)
{
if (_rl_color_indicator[C_END].string != NULL)
_rl_put_indicator (&_rl_color_indicator[C_END]);
else
{
_rl_put_indicator (&_rl_color_indicator[C_LEFT]);
_rl_put_indicator (&_rl_color_indicator[C_RESET]);
_rl_put_indicator (&_rl_color_indicator[C_RIGHT]);
}
}
#endif /* COLOR_SUPPORT */

126
colors.h Normal file
View file

@ -0,0 +1,126 @@
/* `dir', `vdir' and `ls' directory listing programs for GNU.
Modified by Chet Ramey for Readline.
Copyright (C) 1985, 1988, 1990-1991, 1995-2010, 2012, 2015
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 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* Written by Richard Stallman and David MacKenzie. */
/* Color support by Peter Anvin <Peter.Anvin@linux.org> and Dennis
Flaherty <dennisf@denix.elk.miles.com> based on original patches by
Greg Lee <lee@uhunix.uhcc.hawaii.edu>. */
#ifndef _COLORS_H_
#define _COLORS_H_
#include <stdio.h> // size_t
#if defined(__TANDEM) && defined(HAVE_STDBOOL_H) && (__STDC_VERSION__ < 199901L)
typedef int _Bool;
#endif
#if defined (HAVE_STDBOOL_H)
# include <stdbool.h> // bool
#else
typedef int _rl_bool_t;
#ifdef bool
# undef bool
#endif
#define bool _rl_bool_t
#ifndef true
# define true 1
# define false 0
#endif
#endif /* !HAVE_STDBOOL_H */
/* Null is a valid character in a color indicator (think about Epson
printers, for example) so we have to use a length/buffer string
type. */
struct bin_str
{
size_t len;
const char *string;
};
/* file type indicators (dir, sock, fifo, ...)
Default value is initialized in parse-colors.c.
It is then modified from the values of $LS_COLORS. */
extern struct bin_str _rl_color_indicator[];
/* The LS_COLORS variable is in a termcap-like format. */
typedef struct _color_ext_type
{
struct bin_str ext; /* The extension we're looking for */
struct bin_str seq; /* The sequence to output when we do */
struct _color_ext_type *next; /* Next in list */
} COLOR_EXT_TYPE;
/* file extensions indicators (.txt, .log, .jpg, ...)
Values are taken from $LS_COLORS in rl_parse_colors(). */
extern COLOR_EXT_TYPE *_rl_color_ext_list;
#define FILETYPE_INDICATORS \
{ \
C_ORPHAN, C_FIFO, C_CHR, C_DIR, C_BLK, C_FILE, \
C_LINK, C_SOCK, C_FILE, C_DIR \
}
/* Whether we used any colors in the output so far. If so, we will
need to restore the default color later. If not, we will need to
call prep_non_filename_text before using color for the first time. */
enum indicator_no
{
C_LEFT, C_RIGHT, C_END, C_RESET, C_NORM, C_FILE, C_DIR, C_LINK,
C_FIFO, C_SOCK,
C_BLK, C_CHR, C_MISSING, C_ORPHAN, C_EXEC, C_DOOR, C_SETUID, C_SETGID,
C_STICKY, C_OTHER_WRITABLE, C_STICKY_OTHER_WRITABLE, C_CAP, C_MULTIHARDLINK,
C_CLR_TO_EOL
};
#if !S_IXUGO
# define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH)
#endif
enum filetype
{
unknown,
fifo,
chardev,
directory,
blockdev,
normal,
symbolic_link,
sock,
whiteout,
arg_directory
};
/* Prefix color, currently same as socket */
#define C_PREFIX C_SOCK
extern void _rl_put_indicator (const struct bin_str *ind);
extern void _rl_set_normal_color (void);
extern bool _rl_print_prefix_color (void);
extern bool _rl_print_color_indicator (const char *f);
extern void _rl_prep_non_filename_text (void);
#endif /* !_COLORS_H_ */

106
compat.c Normal file
View file

@ -0,0 +1,106 @@
/* compat.c -- backwards compatibility functions. */
/* Copyright (C) 2000-2021 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
Readline 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 3 of the License, or
(at your option) any later version.
Readline 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 Readline. If not, see <http://www.gnu.org/licenses/>.
*/
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <stdio.h>
#include "rlstdc.h"
#include "rltypedefs.h"
extern void rl_free_undo_list (void);
extern int rl_maybe_save_line (void);
extern int rl_maybe_unsave_line (void);
extern int rl_maybe_replace_line (void);
extern int rl_crlf (void);
extern int rl_ding (void);
extern int rl_alphabetic (int);
extern char **rl_completion_matches (const char *, rl_compentry_func_t *);
extern char *rl_username_completion_function (const char *, int);
extern char *rl_filename_completion_function (const char *, int);
/* Provide backwards-compatible entry points for old function names. */
void
free_undo_list (void)
{
rl_free_undo_list ();
}
int
maybe_replace_line (void)
{
return rl_maybe_replace_line ();
}
int
maybe_save_line (void)
{
return rl_maybe_save_line ();
}
int
maybe_unsave_line (void)
{
return rl_maybe_unsave_line ();
}
int
ding (void)
{
return rl_ding ();
}
int
crlf (void)
{
return rl_crlf ();
}
int
alphabetic (int c)
{
return rl_alphabetic (c);
}
char **
completion_matches (const char *s, rl_compentry_func_t *f)
{
return rl_completion_matches (s, f);
}
char *
username_completion_function (const char *s, int i)
{
return rl_username_completion_function (s, i);
}
char *
filename_completion_function (const char *s, int i)
{
return rl_filename_completion_function (s, i);
}

2992
complete.c Normal file

File diff suppressed because it is too large Load diff

311
config.h.in Normal file
View file

@ -0,0 +1,311 @@
/* config.h.in. Maintained by hand. */
/* Template definitions for autoconf */
/* These are set by AC_USE_SYSTEM_EXTENSIONS */
#undef __EXTENSIONS__
#undef _ALL_SOURCE
#undef _GNU_SOURCE
#undef _POSIX_SOURCE
#undef _POSIX_1_SOURCE
#undef _POSIX_PTHREAD_SEMANTICS
#undef _TANDEM_SOURCE
#undef _MINIX
/* Define NO_MULTIBYTE_SUPPORT to not compile in support for multibyte
characters, even if the OS supports them. */
#undef NO_MULTIBYTE_SUPPORT
#undef _FILE_OFFSET_BITS
/* Characteristics of the compiler. */
#undef inline
#undef sig_atomic_t
#undef size_t
#undef ssize_t
#undef const
#undef volatile
#undef PROTOTYPES
#undef __PROTOTYPES
#undef __CHAR_UNSIGNED__
/* Define if the `S_IS*' macros in <sys/stat.h> do not work properly. */
#undef STAT_MACROS_BROKEN
/* Define if you have the chown function. */
#undef HAVE_CHOWN
/* Define if you have the fcntl function. */
#undef HAVE_FCNTL
/* Define if you have the fnmatch function. */
#undef HAVE_FNMATCH
/* Define if you have the getpwent function. */
#undef HAVE_GETPWENT
/* Define if you have the getpwnam function. */
#undef HAVE_GETPWNAM
/* Define if you have the getpwuid function. */
#undef HAVE_GETPWUID
/* Define if you have the gettimeofday function. */
#undef HAVE_GETTIMEOFDAY
/* Define if you have the isascii function. */
#undef HAVE_ISASCII
/* Define if you have the iswctype function. */
#undef HAVE_ISWCTYPE
/* Define if you have the iswlower function. */
#undef HAVE_ISWLOWER
/* Define if you have the iswupper function. */
#undef HAVE_ISWUPPER
/* Define if you have the isxdigit function. */
#undef HAVE_ISXDIGIT
/* Define if you have the kill function. */
#undef HAVE_KILL
/* Define if you have the lstat function. */
#undef HAVE_LSTAT
/* Define if you have the mbrlen function. */
#undef HAVE_MBRLEN
/* Define if you have the mbrtowc function. */
#undef HAVE_MBRTOWC
/* Define if you have the mbsrtowcs function. */
#undef HAVE_MBSRTOWCS
/* Define if you have the memmove function. */
#undef HAVE_MEMMOVE
/* Define if you have the pselect function. */
#undef HAVE_PSELECT
/* Define if you have the putenv function. */
#undef HAVE_PUTENV
/* Define if you have the readlink function. */
#undef HAVE_READLINK
/* Define if you have the select function. */
#undef HAVE_SELECT
/* Define if you have the setenv function. */
#undef HAVE_SETENV
/* Define if you have the setitimer function. */
#undef HAVE_SETITIMER
/* Define if you have the setlocale function. */
#undef HAVE_SETLOCALE
/* Define if you have the strcasecmp function. */
#undef HAVE_STRCASECMP
/* Define if you have the strcoll function. */
#undef HAVE_STRCOLL
#undef STRCOLL_BROKEN
/* Define if you have the strpbrk function. */
#undef HAVE_STRPBRK
/* Define if you have the sysconf function. */
#undef HAVE_SYSCONF
/* Define if you have the tcgetattr function. */
#undef HAVE_TCGETATTR
/* Define if you have the towlower function. */
#undef HAVE_TOWLOWER
/* Define if you have the towupper function. */
#undef HAVE_TOWUPPER
/* Define if you have the vsnprintf function. */
#undef HAVE_VSNPRINTF
/* Define if you have the wcrtomb function. */
#undef HAVE_WCRTOMB
/* Define if you have the wcscoll function. */
#undef HAVE_WCSCOLL
/* Define if you have the wctype function. */
#undef HAVE_WCTYPE
/* Define if you have the wcwidth function. */
#undef HAVE_WCWIDTH
/* and whether it works */
#undef WCWIDTH_BROKEN
/* Define if you have the <dirent.h> header file. */
#undef HAVE_DIRENT_H
/* Define if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
/* Define if you have the <langinfo.h> header file. */
#undef HAVE_LANGINFO_H
/* Define if you have the <libaudit.h> header file. */
#undef HAVE_LIBAUDIT_H
/* Define if you have the <limits.h> header file. */
#undef HAVE_LIMITS_H
/* Define if you have the <locale.h> header file. */
#undef HAVE_LOCALE_H
/* Define if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define if you have the <ndir.h> header file. */
#undef HAVE_NDIR_H
/* Define if you have the <ncurses/termcap.h> header file. */
#undef HAVE_NCURSES_TERMCAP_H
/* Define if you have the <pwd.h> header file. */
#undef HAVE_PWD_H
/* Define if you have the <stdarg.h> header file. */
#undef HAVE_STDARG_H
/* Define if you have the <stdbool.h> header file. */
#undef HAVE_STDBOOL_H
/* Define if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define if you have the <sys/dir.h> header file. */
#undef HAVE_SYS_DIR_H
/* Define if you have the <sys/file.h> header file. */
#undef HAVE_SYS_FILE_H
/* Define if you have the <sys/ioctl.h> header file. */
#undef HAVE_SYS_IOCTL_H
/* Define if you have the <sys/ndir.h> header file. */
#undef HAVE_SYS_NDIR_H
/* Define if you have the <sys/pte.h> header file. */
#undef HAVE_SYS_PTE_H
/* Define if you have the <sys/ptem.h> header file. */
#undef HAVE_SYS_PTEM_H
/* Define if you have the <sys/select.h> header file. */
#undef HAVE_SYS_SELECT_H
/* Define if you have the <sys/stream.h> header file. */
#undef HAVE_SYS_STREAM_H
/* Define if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H
/* Define if you have the <termcap.h> header file. */
#undef HAVE_TERMCAP_H
/* Define if you have the <termio.h> header file. */
#undef HAVE_TERMIO_H
/* Define if you have the <termios.h> header file. */
#undef HAVE_TERMIOS_H
/* Define if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define if you have the <varargs.h> header file. */
#undef HAVE_VARARGS_H
/* Define if you have the <wchar.h> header file. */
#undef HAVE_WCHAR_H
/* Define if you have the <wctype.h> header file. */
#undef HAVE_WCTYPE_H
#undef HAVE_MBSTATE_T
/* Define if you have wchar_t in <wctype.h>. */
#undef HAVE_WCHAR_T
/* Define if you have wctype_t in <wctype.h>. */
#undef HAVE_WCTYPE_T
/* Define if you have wint_t in <wctype.h>. */
#undef HAVE_WINT_T
/* Define if you have <langinfo.h> and nl_langinfo(CODESET). */
#undef HAVE_LANGINFO_CODESET
/* Define if you have <linux/audit.h> and it defines AUDIT_USER_TTY */
#undef HAVE_DECL_AUDIT_USER_TTY
/* Definitions pulled in from aclocal.m4. */
#undef GWINSZ_IN_SYS_IOCTL
#undef STRUCT_WINSIZE_IN_SYS_IOCTL
#undef STRUCT_WINSIZE_IN_TERMIOS
#undef TIOCSTAT_IN_SYS_IOCTL
#undef FIONREAD_IN_SYS_IOCTL
#undef SPEED_T_IN_SYS_TYPES
#undef HAVE_GETPW_DECLS
#undef HAVE_STRUCT_DIRENT_D_INO
#undef HAVE_STRUCT_DIRENT_D_FILENO
#undef HAVE_STRUCT_DIRENT_D_NAMLEN
#undef HAVE_TIMEVAL
#undef HAVE_BSD_SIGNALS
#undef HAVE_POSIX_SIGNALS
#undef HAVE_USG_SIGHOLD
#undef MUST_REINSTALL_SIGHANDLERS
#undef HAVE_POSIX_SIGSETJMP
#undef CTYPE_NON_ASCII
/* modify settings or make new ones based on what autoconf tells us. */
/* Ultrix botches type-ahead when switching from canonical to
non-canonical mode, at least through version 4.3 */
#if !defined (HAVE_TERMIOS_H) || !defined (HAVE_TCGETATTR) || defined (ultrix)
# define TERMIOS_MISSING
#endif
/* VARARGS defines moved to rlstdc.h */

9219
configure vendored Executable file

File diff suppressed because it is too large Load diff

345
configure.ac Normal file
View file

@ -0,0 +1,345 @@
dnl
dnl Configure script for readline library
dnl
dnl report bugs to chet@po.cwru.edu
dnl
dnl Process this file with autoconf to produce a configure script.
# Copyright (C) 1987-2022 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 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
AC_REVISION([for Readline 8.2, version 2.97])
AC_INIT(readline, 8.2, bug-readline@gnu.org)
dnl make sure we are using a recent autoconf version
AC_PREREQ(2.69)
AC_CONFIG_SRCDIR(readline.h)
AC_CONFIG_AUX_DIR(./support)
AC_CONFIG_HEADERS(config.h)
dnl update the value of RL_READLINE_VERSION in readline.h when this changes
LIBVERSION=8.2
AC_CANONICAL_HOST
AC_CANONICAL_BUILD
dnl configure defaults
opt_curses=no
opt_shared_termcap_lib=no
dnl arguments to configure
AC_ARG_WITH(curses, AS_HELP_STRING([--with-curses], [use the curses library instead of the termcap library]), opt_curses=$withval)
AC_ARG_WITH(shared-termcap-library, AS_HELP_STRING([--with-shared-termcap-library], [link the readline shared library against the termcap/curses shared library [[default=NO]]]), opt_shared_termcap_lib=$withval)
if test "$opt_curses" = "yes"; then
prefer_curses=yes
fi
dnl option parsing for optional features
opt_multibyte=yes
opt_static_libs=yes
opt_shared_libs=yes
opt_install_examples=yes
opt_bracketed_paste_default=yes
AC_ARG_ENABLE(multibyte, AS_HELP_STRING([--enable-multibyte], [enable multibyte characters if OS supports them]), opt_multibyte=$enableval)
AC_ARG_ENABLE(shared, AS_HELP_STRING([--enable-shared], [build shared libraries [[default=YES]]]), opt_shared_libs=$enableval)
AC_ARG_ENABLE(static, AS_HELP_STRING([--enable-static], [build static libraries [[default=YES]]]), opt_static_libs=$enableval)
AC_ARG_ENABLE(install-examples, AS_HELP_STRING([--disable-install-examples], [don't install examples [[default=install]]]), opt_install_examples=$enableval)
AC_ARG_ENABLE(bracketed-paste-default, AS_HELP_STRING([--disable-bracketed-paste-default], [disable bracketed paste by default [[default=enable]]]), opt_bracketed_paste_default=$enableval)
if test $opt_multibyte = no; then
AC_DEFINE(NO_MULTIBYTE_SUPPORT)
fi
if test $opt_bracketed_paste_default = yes; then
BRACKETED_PASTE='-DBRACKETED_PASTE_DEFAULT=1'
else
BRACKETED_PASTE='-DBRACKETED_PASTE_DEFAULT=0'
fi
AC_SUBST(BRACKETED_PASTE)
dnl load up the cross-building cache file -- add more cases and cache
dnl files as necessary
dnl Note that host and target machine are the same, and different than the
dnl build machine.
CROSS_COMPILE=
if test "x$cross_compiling" = "xyes"; then
case "${host}" in
*-cygwin*)
cross_cache=${srcdir}/cross-build/cygwin.cache
;;
*-mingw*)
cross_cache=${srcdir}/cross-build/mingw.cache
;;
i[[3456]]86-*-beos*)
cross_cache=${srcdir}/cross-build/x86-beos.cache
;;
*) echo "configure: cross-compiling for $host is not supported" >&2
;;
esac
if test -n "${cross_cache}" && test -r "${cross_cache}"; then
echo "loading cross-build cache file ${cross_cache}"
. ${cross_cache}
fi
unset cross_cache
CROSS_COMPILE='-DCROSS_COMPILING'
AC_SUBST(CROSS_COMPILE)
fi
echo ""
echo "Beginning configuration for readline-$LIBVERSION for ${host_cpu}-${host_vendor}-${host_os}"
echo ""
# We want these before the checks, so the checks can modify their values.
test -z "$CFLAGS" && want_auto_cflags=1
AC_PROG_MAKE_SET
AC_PROG_CC
AC_USE_SYSTEM_EXTENSIONS
# If we're using gcc and the user hasn't specified CFLAGS, add -O2 to CFLAGS
if test -n "$want_auto_cflags" ; then
AUTO_CFLAGS="-g ${GCC:+-O2}"
STYLE_CFLAGS="${GCC:+-Wno-parentheses} ${GCC:+-Wno-format-security} ${GCC:+-Wno-tautological-constant-out-of-range-compare}"
fi
AC_PROG_GCC_TRADITIONAL
AC_PROG_INSTALL
AC_CHECK_TOOL(AR, ar)
dnl Set default for ARFLAGS, since autoconf does not have a macro for it.
dnl This allows people to set it when running configure or make
test -n "$ARFLAGS" || ARFLAGS="cr"
AC_PROG_RANLIB
MAKE_SHELL=/bin/sh
AC_SUBST(MAKE_SHELL)
dnl include files for gettext
m4_include([m4/codeset.m4])
AC_C_CONST
AC_C_INLINE
AC_C_PROTOTYPES
AC_C_CHAR_UNSIGNED
AC_C_VOLATILE
AC_TYPE_SIZE_T
AC_CHECK_TYPE(ssize_t, int)
AC_HEADER_STAT
AC_HEADER_DIRENT
AC_CHECK_FUNCS(fcntl gettimeofday kill lstat pselect readlink select setitimer)
AC_CHECK_FUNCS(fnmatch memmove putenv setenv setlocale \
strcasecmp strpbrk sysconf tcgetattr vsnprintf)
AC_CHECK_FUNCS(isascii isxdigit)
AC_CHECK_FUNCS(getpwent getpwnam getpwuid)
AC_FUNC_CHOWN
AC_FUNC_STRCOLL
AC_CHECK_HEADERS(fcntl.h unistd.h stdlib.h varargs.h stdarg.h stdbool.h \
string.h strings.h \
limits.h locale.h pwd.h memory.h termcap.h termios.h termio.h)
AC_CHECK_HEADERS(sys/ioctl.h sys/pte.h sys/stream.h sys/select.h \
sys/time.h sys/file.h)
AC_CHECK_HEADERS(sys/ptem.h,,,
[[
#if HAVE_SYS_STREAM_H
# include <sys/stream.h>
#endif
]])
AC_SYS_LARGEFILE
BASH_SYS_SIGNAL_VINTAGE
BASH_SYS_REINSTALL_SIGHANDLERS
BASH_FUNC_POSIX_SETJMP
BASH_FUNC_LSTAT
BASH_FUNC_STRCOLL
BASH_CHECK_GETPW_FUNCS
AC_HEADER_TIOCGWINSZ
BASH_TYPE_SIG_ATOMIC_T
BASH_HAVE_TIOCSTAT
BASH_HAVE_FIONREAD
BASH_CHECK_SPEED_T
BASH_STRUCT_WINSIZE
BASH_STRUCT_DIRENT_D_INO
BASH_STRUCT_DIRENT_D_FILENO
BASH_STRUCT_TIMEVAL
AC_CHECK_HEADERS(libaudit.h)
AC_CHECK_DECLS([AUDIT_USER_TTY],,, [[#include <linux/audit.h>]])
dnl yuck
case "$host_os" in
aix*) prefer_curses=yes ;;
esac
BASH_CHECK_LIB_TERMCAP
if test "$TERMCAP_LIB" = "./lib/termcap/libtermcap.a"; then
if test "$prefer_curses" = yes; then
TERMCAP_LIB=-lcurses
else
TERMCAP_LIB=-ltermcap #default
fi
fi
# Windows ncurses installation
if test "$TERMCAP_LIB" = "-lncurses"; then
AC_CHECK_HEADERS(ncurses/termcap.h)
fi
case "$opt_shared_termcap_lib" in
[[Yy]][[Ee]][[Ss]]) SHARED_TERMCAP="$TERMCAP_LIB" ;;
-l*) SHARED_TERMCAP="$opt_shared_termcap_lib" ;;
esac
case "$TERMCAP_LIB" in
-ltinfo) TERMCAP_PKG_CONFIG_LIB=tinfo ;;
-lcurses) TERMCAP_PKG_CONFIG_LIB=ncurses ;;
-lncurses) TERMCAP_PKG_CONFIG_LIB=ncurses ;;
-ltermcap) TERMCAP_PKG_CONFIG_LIB=termcap ;;
*) TERMCAP_PKG_CONFIG_LIB=termcap ;;
esac
BASH_CHECK_MULTIBYTE
case "$host_cpu" in
*cray*) LOCAL_CFLAGS=-DCRAY ;;
*s390*) LOCAL_CFLAGS=-fsigned-char ;;
esac
case "$host_os" in
isc*) LOCAL_CFLAGS=-Disc386 ;;
hpux*) LOCAL_CFLAGS="-DTGETENT_BROKEN -DTGETFLAG_BROKEN" ;;
esac
# shared library configuration section
#
# Shared object configuration section. These values are generated by
# ${srcdir}/support/shobj-conf
#
if test -f ${srcdir}/support/shobj-conf; then
AC_MSG_CHECKING(configuration for building shared libraries)
eval `TERMCAP_LIB=$TERMCAP_LIB ${CONFIG_SHELL-/bin/sh} ${srcdir}/support/shobj-conf -C "${CC}" -c ${host_cpu} -o ${host_os} -v ${host_vendor}`
# SHARED_TERMCAP is set only if opt_shared_termcap_library is set
case "$SHLIB_LIBS" in
*curses*|*tinfo*) ;;
*termcap*|*termlib*) ;; # common aliases
*) SHLIB_LIBS="$SHLIB_LIBS $SHARED_TERMCAP" ;;
esac
AC_SUBST(SHOBJ_CC)
AC_SUBST(SHOBJ_CFLAGS)
AC_SUBST(SHOBJ_LD)
AC_SUBST(SHOBJ_LDFLAGS)
AC_SUBST(SHOBJ_XLDFLAGS)
AC_SUBST(SHOBJ_LIBS)
AC_SUBST(SHOBJ_STATUS)
AC_SUBST(SHLIB_STATUS)
AC_SUBST(SHLIB_XLDFLAGS)
AC_SUBST(SHLIB_DOT)
AC_SUBST(SHLIB_LIBPREF)
AC_SUBST(SHLIB_LIBSUFF)
AC_SUBST(SHLIB_LIBVERSION)
AC_SUBST(SHLIB_DLLVERSION)
AC_SUBST(SHLIB_LIBS)
AC_MSG_RESULT($SHLIB_STATUS)
# SHLIB_STATUS is either `supported' or `unsupported'. If it's
# `unsupported', turn off any default shared library building
if test "$SHLIB_STATUS" = 'unsupported'; then
opt_shared_libs=no
fi
# shared library versioning
# quoted for m4 so I can use character classes
SHLIB_MAJOR=[`expr "$LIBVERSION" : '\([0-9]\)\..*'`]
SHLIB_MINOR=[`expr "$LIBVERSION" : '[0-9]\.\([0-9]\).*'`]
AC_SUBST(SHLIB_MAJOR)
AC_SUBST(SHLIB_MINOR)
fi
if test "$opt_static_libs" = "yes"; then
STATIC_TARGET=static
STATIC_INSTALL_TARGET=install-static
fi
if test "$opt_shared_libs" = "yes"; then
SHARED_TARGET=shared
SHARED_INSTALL_TARGET=install-shared
fi
AC_SUBST(STATIC_TARGET)
AC_SUBST(SHARED_TARGET)
AC_SUBST(STATIC_INSTALL_TARGET)
AC_SUBST(SHARED_INSTALL_TARGET)
if test "$opt_install_examples" = "yes"; then
EXAMPLES_INSTALL_TARGET=install-examples
fi
AC_SUBST(EXAMPLES_INSTALL_TARGET)
case "$build_os" in
msdosdjgpp*) BUILD_DIR=`pwd.exe` ;; # to prevent //d/path/file
*) BUILD_DIR=`pwd` ;;
esac
case "$BUILD_DIR" in
*\ *) BUILD_DIR=`echo "$BUILD_DIR" | sed 's: :\\\\ :g'` ;;
*) ;;
esac
AC_SUBST(BUILD_DIR)
# CFLAGS=${CFLAGS-"$AUTO_CFLAGS"}
if test -n "$want_auto_cflags"; then
CFLAGS="$AUTO_CFLAGS"
fi
CFLAGS="$CFLAGS $STYLE_CFLAGS"
AC_SUBST(CFLAGS)
AC_SUBST(LOCAL_CFLAGS)
AC_SUBST(LOCAL_LDFLAGS)
AC_SUBST(LOCAL_DEFS)
AC_SUBST(AR)
AC_SUBST(ARFLAGS)
AC_SUBST(host_cpu)
AC_SUBST(host_os)
AC_SUBST(LIBVERSION)
AC_SUBST(TERMCAP_LIB)
AC_SUBST(TERMCAP_PKG_CONFIG_LIB)
AC_CONFIG_FILES([Makefile doc/Makefile examples/Makefile shlib/Makefile readline.pc history.pc])
dnl Makefile uses this timestamp file to record whether config.h is up to date.
AC_CONFIG_COMMANDS([stamp-h], [echo > stamp-h])
AC_OUTPUT

3583
display.c Normal file

File diff suppressed because it is too large Load diff

272
doc/Makefile.in Normal file
View file

@ -0,0 +1,272 @@
# This makefile for Readline library documentation is in -*- text -*- mode.
# Emacs likes it that way.
# Copyright (C) 1996-2009 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 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
PACKAGE_TARNAME = @PACKAGE_TARNAME@
topdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
prefix = @prefix@
datarootdir = @datarootdir@
docdir = @docdir@
infodir = @infodir@
mandir = @mandir@
manpfx = man
man1ext = .1
man1dir = $(mandir)/$(manpfx)1
man3ext = .3
man3dir = $(mandir)/$(manpfx)3
# set this to a value to have the HTML documentation installed
htmldir =
# Support an alternate destination root directory for package building
DESTDIR =
SHELL = @MAKE_SHELL@
RM = rm -f
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
BUILD_DIR = @BUILD_DIR@
TEXINPUTDIR = $(srcdir)
MAKEINFO = LANGUAGE= makeinfo
TEXI2DVI = $(srcdir)/texi2dvi
TEXI2HTML = $(srcdir)/texi2html
QUIETPS = #set this to -q to shut up dvips
PAPERSIZE = letter
PSDPI = 600
DVIPS = dvips -D ${PSDPI} $(QUIETPS) -t ${PAPERSIZE} -o $@ # tricky
# experimental; uses external texi2dvi for now; this needs pdftex to be present
TEXI2PDF = texi2dvi --pdf
# These tools might not be available; they're not required
DVIPDF = dvipdfm -o $@ -p ${PAPERSIZE}
PSPDF = gs -sPAPERSIZE=${PAPERSIZE} -sDEVICE=pdfwrite -dNOPAUSE -dBATCH -sOutputFile=$@
RLSRC = $(srcdir)/rlman.texi $(srcdir)/rluser.texi \
$(srcdir)/rltech.texi $(srcdir)/version.texi \
$(srcdir)/rluserman.texi $(srcdir)/fdl.texi
HISTSRC = $(srcdir)/history.texi $(srcdir)/hsuser.texi \
$(srcdir)/hstech.texi $(srcdir)/version.texi $(srcdir)/fdl.texi
# This should be a program that converts troff to an ascii-readable format
NROFF = groff -Tascii
# This should be a program that converts troff to postscript
GROFF = groff
DVIOBJ = readline.dvi history.dvi rluserman.dvi
INFOOBJ = readline.info history.info rluserman.info
PSOBJ = readline.ps history.ps rluserman.ps readline_3.ps history_3.ps
HTMLOBJ = readline.html history.html rluserman.html
TEXTOBJ = readline.0 history.0
PDFOBJ = readline.pdf history.pdf rluserman.pdf
INTERMEDIATE_OBJ = rlman.dvi
DIST_DOCS = $(DVIOBJ) $(PSOBJ) $(HTMLOBJ) $(INFOOBJ) $(TEXTOBJ) $(PDFOBJ)
.SUFFIXES: .0 .3 .ps .txt .dvi .html .pdf
.3.0:
$(RM) $@
-${NROFF} -man $< > $@
.ps.pdf:
$(RM) $@
-${PSPDF} $<
.dvi.pdf:
$(RM) $@
-${DVIPDF} $<
#.texi.pdf:
# $(RM) $@
# -${TEXI2PDF} $<
all: info dvi html ps text pdf
nodvi: info html text
xdist: $(DIST_DOCS)
info: $(INFOOBJ)
dvi: $(DVIOBJ)
ps: $(PSOBJ)
html: $(HTMLOBJ)
text: $(TEXTOBJ)
pdf: $(PDFOBJ)
readline.dvi: $(RLSRC)
TEXINPUTS=.:$(TEXINPUTDIR):$$TEXINPUTS $(TEXI2DVI) $(srcdir)/rlman.texi
mv rlman.dvi readline.dvi
readline.info: $(RLSRC)
$(MAKEINFO) --no-split -I $(TEXINPUTDIR) -o $@ $(srcdir)/rlman.texi
rluserman.dvi: $(RLSRC)
TEXINPUTS=.:$(TEXINPUTDIR):$$TEXINPUTS $(TEXI2DVI) $(srcdir)/rluserman.texi
rluserman.info: $(RLSRC)
$(MAKEINFO) --no-split -I $(TEXINPUTDIR) -o $@ $(srcdir)/rluserman.texi
history.dvi: ${HISTSRC}
TEXINPUTS=.:$(TEXINPUTDIR):$$TEXINPUTS $(TEXI2DVI) $(srcdir)/history.texi
history.info: ${HISTSRC}
$(MAKEINFO) --no-split -I $(TEXINPUTDIR) -o $@ $(srcdir)/history.texi
readline.ps: readline.dvi
$(RM) $@
$(DVIPS) readline.dvi
rluserman.ps: rluserman.dvi
$(RM) $@
$(DVIPS) rluserman.dvi
history.ps: history.dvi
$(RM) $@
$(DVIPS) history.dvi
#
# This leaves readline.html and rlman.html -- rlman.html is for www.gnu.org
#
readline.html: ${RLSRC}
$(MAKEINFO) -o $@ --html --no-split -I$(TEXINPUTDIR) $(srcdir)/rlman.texi
rlman.html: ${RLSRC}
$(MAKEINFO) -o $@ --html --no-split -I$(TEXINPUTDIR) $(srcdir)/rlman.texi
rluserman.html: ${RLSRC}
$(MAKEINFO) --html --no-split -I$(TEXINPUTDIR) $(srcdir)/rluserman.texi
history.html: ${HISTSRC}
$(MAKEINFO) --html --no-split -I$(TEXINPUTDIR) $(srcdir)/history.texi
readline.0: readline.3
readline_3.ps: $(srcdir)/readline.3
${RM} $@
${GROFF} -man < $(srcdir)/readline.3 > $@
history.0: history.3
history_3.ps: $(srcdir)/history.3
${RM} $@
${GROFF} -man < $(srcdir)/history.3 > $@
readline.pdf: $(RLSRC)
TEXINPUTS=.:$(TEXINPUTDIR):$$TEXINPUTS $(TEXI2PDF) $(srcdir)/rlman.texi
mv rlman.pdf $@
history.pdf: $(HISTSRC)
TEXINPUTS=.:$(TEXINPUTDIR):$$TEXINPUTS $(TEXI2PDF) $(srcdir)/history.texi
rluserman.pdf: $(RLSRC)
TEXINPUTS=.:$(TEXINPUTDIR):$$TEXINPUTS $(TEXI2PDF) $(srcdir)/rluserman.texi
clean:
$(RM) *.aux *.bak *.cp *.fn *.ky *.log *.pg *.toc *.tp *.vr *.cps \
*.pgs *.bt *.bts *.rw *.rws *.fns *.kys *.tps *.vrs *.o \
core *.core
mostlyclean: clean
distclean: clean maybe-clean
$(RM) $(INTERMEDIATE_OBJ)
$(RM) Makefile
maybe-clean:
-if test "X$(topdir)" != "X.." && test "X$(topdir)" != "X$(BUILD_DIR)"; then \
$(RM) $(DIST_DOCS); \
fi
maintainer-clean: clean
$(RM) $(DIST_DOCS)
$(RM) $(INTERMEDIATE_OBJ)
$(RM) $(PDFOBJ)
$(RM) Makefile
installdirs: $(topdir)/support/mkdirs
-$(SHELL) $(topdir)/support/mkdirs $(DESTDIR)$(infodir) $(DESTDIR)$(man3dir)
-if test -n "${htmldir}" ; then \
$(SHELL) $(topdir)/support/mkdirs $(DESTDIR)$(htmldir) ; \
fi
install: installdirs
if test -f readline.info; then \
${INSTALL_DATA} readline.info $(DESTDIR)$(infodir)/readline.info; \
else \
${INSTALL_DATA} $(srcdir)/readline.info $(DESTDIR)$(infodir)/readline.info; \
fi
if test -f rluserman.info; then \
${INSTALL_DATA} rluserman.info $(DESTDIR)$(infodir)/rluserman.info; \
else \
${INSTALL_DATA} $(srcdir)/rluserman.info $(DESTDIR)$(infodir)/rluserman.info; \
fi
if test -f history.info; then \
${INSTALL_DATA} history.info $(DESTDIR)$(infodir)/history.info; \
else \
${INSTALL_DATA} $(srcdir)/history.info $(DESTDIR)$(infodir)/history.info; \
fi
-if $(SHELL) -c 'install-info --version' >/dev/null 2>&1; then \
install-info --dir-file=$(DESTDIR)$(infodir)/dir \
$(DESTDIR)$(infodir)/readline.info ; \
install-info --dir-file=$(DESTDIR)$(infodir)/dir \
$(DESTDIR)$(infodir)/history.info ; \
install-info --dir-file=$(DESTDIR)$(infodir)/dir \
$(DESTDIR)$(infodir)/rluserman.info ; \
else true; fi
-${INSTALL_DATA} $(srcdir)/readline.3 $(DESTDIR)$(man3dir)/readline$(man3ext)
-${INSTALL_DATA} $(srcdir)/history.3 $(DESTDIR)$(man3dir)/history$(man3ext)
-if test -n "${htmldir}" ; then \
if test -f readline.html; then \
${INSTALL_DATA} readline.html $(DESTDIR)$(htmldir)/readline.html; \
else \
${INSTALL_DATA} $(srcdir)/readline.html $(DESTDIR)$(htmldir)/readline.html; \
fi ; \
if test -f history.html; then \
${INSTALL_DATA} history.html $(DESTDIR)$(htmldir)/history.html; \
else \
${INSTALL_DATA} $(srcdir)/history.html $(DESTDIR)$(htmldir)/history.html; \
fi ; \
if test -f rluserman.html; then \
${INSTALL_DATA} rluserman.html $(DESTDIR)$(htmldir)/rluserman.html; \
else \
${INSTALL_DATA} $(srcdir)/rluserman.html $(DESTDIR)$(htmldir)/rluserman.html; \
fi ; \
fi
uninstall:
$(RM) $(DESTDIR)$(infodir)/readline.info
$(RM) $(DESTDIR)$(infodir)/rluserman.info
$(RM) $(DESTDIR)$(infodir)/history.info
$(RM) $(DESTDIR)$(man3dir)/readline$(man3ext)
$(RM) $(DESTDIR)$(man3dir)/history$(man3ext)
-if test -n "${htmldir}" ; then \
$(RM) $(DESTDIR)$(htmldir)/readline.html ; \
$(RM) $(DESTDIR)$(htmldir)/rluserman.html ; \
$(RM) $(DESTDIR)$(htmldir)/history.html ; \
fi

506
doc/fdl.texi Normal file
View file

@ -0,0 +1,506 @@
@c The GNU Free Documentation License.
@center Version 1.3, 3 November 2008
@c This file is intended to be included within another document,
@c hence no sectioning command or @node.
@display
Copyright @copyright{} 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
@uref{http://fsf.org/}
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@end display
@enumerate 0
@item
PREAMBLE
The purpose of this License is to make a manual, textbook, or other
functional and useful document @dfn{free} in the sense of freedom: to
assure everyone the effective freedom to copy and redistribute it,
with or without modifying it, either commercially or noncommercially.
Secondarily, this License preserves for the author and publisher a way
to get credit for their work, while not being considered responsible
for modifications made by others.
This License is a kind of ``copyleft'', which means that derivative
works of the document must themselves be free in the same sense. It
complements the GNU General Public License, which is a copyleft
license designed for free software.
We have designed this License in order to use it for manuals for free
software, because free software needs free documentation: a free
program should come with manuals providing the same freedoms that the
software does. But this License is not limited to software manuals;
it can be used for any textual work, regardless of subject matter or
whether it is published as a printed book. We recommend this License
principally for works whose purpose is instruction or reference.
@item
APPLICABILITY AND DEFINITIONS
This License applies to any manual or other work, in any medium, that
contains a notice placed by the copyright holder saying it can be
distributed under the terms of this License. Such a notice grants a
world-wide, royalty-free license, unlimited in duration, to use that
work under the conditions stated herein. The ``Document'', below,
refers to any such manual or work. Any member of the public is a
licensee, and is addressed as ``you''. You accept the license if you
copy, modify or distribute the work in a way requiring permission
under copyright law.
A ``Modified Version'' of the Document means any work containing the
Document or a portion of it, either copied verbatim, or with
modifications and/or translated into another language.
A ``Secondary Section'' is a named appendix or a front-matter section
of the Document that deals exclusively with the relationship of the
publishers or authors of the Document to the Document's overall
subject (or to related matters) and contains nothing that could fall
directly within that overall subject. (Thus, if the Document is in
part a textbook of mathematics, a Secondary Section may not explain
any mathematics.) The relationship could be a matter of historical
connection with the subject or with related matters, or of legal,
commercial, philosophical, ethical or political position regarding
them.
The ``Invariant Sections'' are certain Secondary Sections whose titles
are designated, as being those of Invariant Sections, in the notice
that says that the Document is released under this License. If a
section does not fit the above definition of Secondary then it is not
allowed to be designated as Invariant. The Document may contain zero
Invariant Sections. If the Document does not identify any Invariant
Sections then there are none.
The ``Cover Texts'' are certain short passages of text that are listed,
as Front-Cover Texts or Back-Cover Texts, in the notice that says that
the Document is released under this License. A Front-Cover Text may
be at most 5 words, and a Back-Cover Text may be at most 25 words.
A ``Transparent'' copy of the Document means a machine-readable copy,
represented in a format whose specification is available to the
general public, that is suitable for revising the document
straightforwardly with generic text editors or (for images composed of
pixels) generic paint programs or (for drawings) some widely available
drawing editor, and that is suitable for input to text formatters or
for automatic translation to a variety of formats suitable for input
to text formatters. A copy made in an otherwise Transparent file
format whose markup, or absence of markup, has been arranged to thwart
or discourage subsequent modification by readers is not Transparent.
An image format is not Transparent if used for any substantial amount
of text. A copy that is not ``Transparent'' is called ``Opaque''.
Examples of suitable formats for Transparent copies include plain
@sc{ascii} without markup, Texinfo input format, La@TeX{} input
format, @acronym{SGML} or @acronym{XML} using a publicly available
@acronym{DTD}, and standard-conforming simple @acronym{HTML},
PostScript or @acronym{PDF} designed for human modification. Examples
of transparent image formats include @acronym{PNG}, @acronym{XCF} and
@acronym{JPG}. Opaque formats include proprietary formats that can be
read and edited only by proprietary word processors, @acronym{SGML} or
@acronym{XML} for which the @acronym{DTD} and/or processing tools are
not generally available, and the machine-generated @acronym{HTML},
PostScript or @acronym{PDF} produced by some word processors for
output purposes only.
The ``Title Page'' means, for a printed book, the title page itself,
plus such following pages as are needed to hold, legibly, the material
this License requires to appear in the title page. For works in
formats which do not have any title page as such, ``Title Page'' means
the text near the most prominent appearance of the work's title,
preceding the beginning of the body of the text.
The ``publisher'' means any person or entity that distributes copies
of the Document to the public.
A section ``Entitled XYZ'' means a named subunit of the Document whose
title either is precisely XYZ or contains XYZ in parentheses following
text that translates XYZ in another language. (Here XYZ stands for a
specific section name mentioned below, such as ``Acknowledgements'',
``Dedications'', ``Endorsements'', or ``History''.) To ``Preserve the Title''
of such a section when you modify the Document means that it remains a
section ``Entitled XYZ'' according to this definition.
The Document may include Warranty Disclaimers next to the notice which
states that this License applies to the Document. These Warranty
Disclaimers are considered to be included by reference in this
License, but only as regards disclaiming warranties: any other
implication that these Warranty Disclaimers may have is void and has
no effect on the meaning of this License.
@item
VERBATIM COPYING
You may copy and distribute the Document in any medium, either
commercially or noncommercially, provided that this License, the
copyright notices, and the license notice saying this License applies
to the Document are reproduced in all copies, and that you add no other
conditions whatsoever to those of this License. You may not use
technical measures to obstruct or control the reading or further
copying of the copies you make or distribute. However, you may accept
compensation in exchange for copies. If you distribute a large enough
number of copies you must also follow the conditions in section 3.
You may also lend copies, under the same conditions stated above, and
you may publicly display copies.
@item
COPYING IN QUANTITY
If you publish printed copies (or copies in media that commonly have
printed covers) of the Document, numbering more than 100, and the
Document's license notice requires Cover Texts, you must enclose the
copies in covers that carry, clearly and legibly, all these Cover
Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
the back cover. Both covers must also clearly and legibly identify
you as the publisher of these copies. The front cover must present
the full title with all words of the title equally prominent and
visible. You may add other material on the covers in addition.
Copying with changes limited to the covers, as long as they preserve
the title of the Document and satisfy these conditions, can be treated
as verbatim copying in other respects.
If the required texts for either cover are too voluminous to fit
legibly, you should put the first ones listed (as many as fit
reasonably) on the actual cover, and continue the rest onto adjacent
pages.
If you publish or distribute Opaque copies of the Document numbering
more than 100, you must either include a machine-readable Transparent
copy along with each Opaque copy, or state in or with each Opaque copy
a computer-network location from which the general network-using
public has access to download using public-standard network protocols
a complete Transparent copy of the Document, free of added material.
If you use the latter option, you must take reasonably prudent steps,
when you begin distribution of Opaque copies in quantity, to ensure
that this Transparent copy will remain thus accessible at the stated
location until at least one year after the last time you distribute an
Opaque copy (directly or through your agents or retailers) of that
edition to the public.
It is requested, but not required, that you contact the authors of the
Document well before redistributing any large number of copies, to give
them a chance to provide you with an updated version of the Document.
@item
MODIFICATIONS
You may copy and distribute a Modified Version of the Document under
the conditions of sections 2 and 3 above, provided that you release
the Modified Version under precisely this License, with the Modified
Version filling the role of the Document, thus licensing distribution
and modification of the Modified Version to whoever possesses a copy
of it. In addition, you must do these things in the Modified Version:
@enumerate A
@item
Use in the Title Page (and on the covers, if any) a title distinct
from that of the Document, and from those of previous versions
(which should, if there were any, be listed in the History section
of the Document). You may use the same title as a previous version
if the original publisher of that version gives permission.
@item
List on the Title Page, as authors, one or more persons or entities
responsible for authorship of the modifications in the Modified
Version, together with at least five of the principal authors of the
Document (all of its principal authors, if it has fewer than five),
unless they release you from this requirement.
@item
State on the Title page the name of the publisher of the
Modified Version, as the publisher.
@item
Preserve all the copyright notices of the Document.
@item
Add an appropriate copyright notice for your modifications
adjacent to the other copyright notices.
@item
Include, immediately after the copyright notices, a license notice
giving the public permission to use the Modified Version under the
terms of this License, in the form shown in the Addendum below.
@item
Preserve in that license notice the full lists of Invariant Sections
and required Cover Texts given in the Document's license notice.
@item
Include an unaltered copy of this License.
@item
Preserve the section Entitled ``History'', Preserve its Title, and add
to it an item stating at least the title, year, new authors, and
publisher of the Modified Version as given on the Title Page. If
there is no section Entitled ``History'' in the Document, create one
stating the title, year, authors, and publisher of the Document as
given on its Title Page, then add an item describing the Modified
Version as stated in the previous sentence.
@item
Preserve the network location, if any, given in the Document for
public access to a Transparent copy of the Document, and likewise
the network locations given in the Document for previous versions
it was based on. These may be placed in the ``History'' section.
You may omit a network location for a work that was published at
least four years before the Document itself, or if the original
publisher of the version it refers to gives permission.
@item
For any section Entitled ``Acknowledgements'' or ``Dedications'', Preserve
the Title of the section, and preserve in the section all the
substance and tone of each of the contributor acknowledgements and/or
dedications given therein.
@item
Preserve all the Invariant Sections of the Document,
unaltered in their text and in their titles. Section numbers
or the equivalent are not considered part of the section titles.
@item
Delete any section Entitled ``Endorsements''. Such a section
may not be included in the Modified Version.
@item
Do not retitle any existing section to be Entitled ``Endorsements'' or
to conflict in title with any Invariant Section.
@item
Preserve any Warranty Disclaimers.
@end enumerate
If the Modified Version includes new front-matter sections or
appendices that qualify as Secondary Sections and contain no material
copied from the Document, you may at your option designate some or all
of these sections as invariant. To do this, add their titles to the
list of Invariant Sections in the Modified Version's license notice.
These titles must be distinct from any other section titles.
You may add a section Entitled ``Endorsements'', provided it contains
nothing but endorsements of your Modified Version by various
parties---for example, statements of peer review or that the text has
been approved by an organization as the authoritative definition of a
standard.
You may add a passage of up to five words as a Front-Cover Text, and a
passage of up to 25 words as a Back-Cover Text, to the end of the list
of Cover Texts in the Modified Version. Only one passage of
Front-Cover Text and one of Back-Cover Text may be added by (or
through arrangements made by) any one entity. If the Document already
includes a cover text for the same cover, previously added by you or
by arrangement made by the same entity you are acting on behalf of,
you may not add another; but you may replace the old one, on explicit
permission from the previous publisher that added the old one.
The author(s) and publisher(s) of the Document do not by this License
give permission to use their names for publicity for or to assert or
imply endorsement of any Modified Version.
@item
COMBINING DOCUMENTS
You may combine the Document with other documents released under this
License, under the terms defined in section 4 above for modified
versions, provided that you include in the combination all of the
Invariant Sections of all of the original documents, unmodified, and
list them all as Invariant Sections of your combined work in its
license notice, and that you preserve all their Warranty Disclaimers.
The combined work need only contain one copy of this License, and
multiple identical Invariant Sections may be replaced with a single
copy. If there are multiple Invariant Sections with the same name but
different contents, make the title of each such section unique by
adding at the end of it, in parentheses, the name of the original
author or publisher of that section if known, or else a unique number.
Make the same adjustment to the section titles in the list of
Invariant Sections in the license notice of the combined work.
In the combination, you must combine any sections Entitled ``History''
in the various original documents, forming one section Entitled
``History''; likewise combine any sections Entitled ``Acknowledgements'',
and any sections Entitled ``Dedications''. You must delete all
sections Entitled ``Endorsements.''
@item
COLLECTIONS OF DOCUMENTS
You may make a collection consisting of the Document and other documents
released under this License, and replace the individual copies of this
License in the various documents with a single copy that is included in
the collection, provided that you follow the rules of this License for
verbatim copying of each of the documents in all other respects.
You may extract a single document from such a collection, and distribute
it individually under this License, provided you insert a copy of this
License into the extracted document, and follow this License in all
other respects regarding verbatim copying of that document.
@item
AGGREGATION WITH INDEPENDENT WORKS
A compilation of the Document or its derivatives with other separate
and independent documents or works, in or on a volume of a storage or
distribution medium, is called an ``aggregate'' if the copyright
resulting from the compilation is not used to limit the legal rights
of the compilation's users beyond what the individual works permit.
When the Document is included in an aggregate, this License does not
apply to the other works in the aggregate which are not themselves
derivative works of the Document.
If the Cover Text requirement of section 3 is applicable to these
copies of the Document, then if the Document is less than one half of
the entire aggregate, the Document's Cover Texts may be placed on
covers that bracket the Document within the aggregate, or the
electronic equivalent of covers if the Document is in electronic form.
Otherwise they must appear on printed covers that bracket the whole
aggregate.
@item
TRANSLATION
Translation is considered a kind of modification, so you may
distribute translations of the Document under the terms of section 4.
Replacing Invariant Sections with translations requires special
permission from their copyright holders, but you may include
translations of some or all Invariant Sections in addition to the
original versions of these Invariant Sections. You may include a
translation of this License, and all the license notices in the
Document, and any Warranty Disclaimers, provided that you also include
the original English version of this License and the original versions
of those notices and disclaimers. In case of a disagreement between
the translation and the original version of this License or a notice
or disclaimer, the original version will prevail.
If a section in the Document is Entitled ``Acknowledgements'',
``Dedications'', or ``History'', the requirement (section 4) to Preserve
its Title (section 1) will typically require changing the actual
title.
@item
TERMINATION
You may not copy, modify, sublicense, or distribute the Document
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense, or distribute it is void, and
will automatically terminate your rights under this License.
However, if you cease all violation of this License, then your license
from a particular copyright holder is reinstated (a) provisionally,
unless and until the copyright holder explicitly and finally
terminates your license, and (b) permanently, if the copyright holder
fails to notify you of the violation by some reasonable means prior to
60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, receipt of a copy of some or all of the same material does
not give you any rights to use it.
@item
FUTURE REVISIONS OF THIS LICENSE
The Free Software Foundation may publish new, revised versions
of the GNU Free Documentation License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns. See
@uref{http://www.gnu.org/copyleft/}.
Each version of the License is given a distinguishing version number.
If the Document specifies that a particular numbered version of this
License ``or any later version'' applies to it, you have the option of
following the terms and conditions either of that specified version or
of any later version that has been published (not as a draft) by the
Free Software Foundation. If the Document does not specify a version
number of this License, you may choose any version ever published (not
as a draft) by the Free Software Foundation. If the Document
specifies that a proxy can decide which future versions of this
License can be used, that proxy's public statement of acceptance of a
version permanently authorizes you to choose that version for the
Document.
@item
RELICENSING
``Massive Multiauthor Collaboration Site'' (or ``MMC Site'') means any
World Wide Web server that publishes copyrightable works and also
provides prominent facilities for anybody to edit those works. A
public wiki that anybody can edit is an example of such a server. A
``Massive Multiauthor Collaboration'' (or ``MMC'') contained in the
site means any set of copyrightable works thus published on the MMC
site.
``CC-BY-SA'' means the Creative Commons Attribution-Share Alike 3.0
license published by Creative Commons Corporation, a not-for-profit
corporation with a principal place of business in San Francisco,
California, as well as future copyleft versions of that license
published by that same organization.
``Incorporate'' means to publish or republish a Document, in whole or
in part, as part of another Document.
An MMC is ``eligible for relicensing'' if it is licensed under this
License, and if all works that were first published under this License
somewhere other than this MMC, and subsequently incorporated in whole
or in part into the MMC, (1) had no cover texts or invariant sections,
and (2) were thus incorporated prior to November 1, 2008.
The operator of an MMC Site may republish an MMC contained in the site
under CC-BY-SA on the same site at any time before August 1, 2009,
provided the MMC is eligible for relicensing.
@end enumerate
@page
@heading ADDENDUM: How to use this License for your documents
To use this License in a document you have written, include a copy of
the License in the document and put the following copyright and
license notices just after the title page:
@smallexample
@group
Copyright (C) @var{year} @var{your name}.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
Texts. A copy of the license is included in the section entitled ``GNU
Free Documentation License''.
@end group
@end smallexample
If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
replace the ``with@dots{}Texts.'' line with this:
@smallexample
@group
with the Invariant Sections being @var{list their titles}, with
the Front-Cover Texts being @var{list}, and with the Back-Cover Texts
being @var{list}.
@end group
@end smallexample
If you have Invariant Sections without Cover Texts, or some other
combination of the three, merge those two alternatives to suit the
situation.
If your document contains nontrivial examples of program code, we
recommend releasing these examples in parallel under your choice of
free software license, such as the GNU General Public License,
to permit their use in free software.
@c Local Variables:
@c ispell-local-pdict: "ispell-dict"
@c End:

505
doc/history.0 Normal file
View file

@ -0,0 +1,505 @@
HISTORY(3) Library Functions Manual HISTORY(3)
NAME
history - GNU History Library
COPYRIGHT
The GNU History Library is Copyright (C) 1989-2020 by the Free Software
Foundation, Inc.
DESCRIPTION
Many programs read input from the user a line at a time. The GNU His-
tory library is able to keep track of those lines, associate arbitrary
data with each line, and utilize information from previous lines in
composing new ones.
HISTORY EXPANSION
The history library supports a history expansion feature that is iden-
tical to the history expansion in bash. This section describes what
syntax features are available.
History expansions introduce words from the history list into the input
stream, making it easy to repeat commands, insert the arguments to a
previous command into the current input line, or fix errors in previous
commands quickly.
History expansion is usually performed immediately after a complete
line is read. It takes place in two parts. The first is to determine
which line from the history list to use during substitution. The sec-
ond is to select portions of that line for inclusion into the current
one. The line selected from the history is the event, and the portions
of that line that are acted upon are words. Various modifiers are
available to manipulate the selected words. The line is broken into
words in the same fashion as bash does when reading input, so that sev-
eral words that would otherwise be separated are considered one word
when surrounded by quotes (see the description of history_tokenize()
below). History expansions are introduced by the appearance of the
history expansion character, which is ! by default. Only backslash (\)
and single quotes can quote the history expansion character.
Event Designators
An event designator is a reference to a command line entry in the his-
tory list. Unless the reference is absolute, events are relative to
the current position in the history list.
! Start a history substitution, except when followed by a blank,
newline, = or (.
!n Refer to command line n.
!-n Refer to the current command minus n.
!! Refer to the previous command. This is a synonym for `!-1'.
!string
Refer to the most recent command preceding the current position
in the history list starting with string.
!?string[?]
Refer to the most recent command preceding the current position
in the history list containing string. The trailing ? may be
omitted if string is followed immediately by a newline. If
string is missing, the string from the most recent search is
used; it is an error if there is no previous search string.
^string1^string2^
Quick substitution. Repeat the last command, replacing string1
with string2. Equivalent to ``!!:s^string1^string2^'' (see Mod-
ifiers below).
!# The entire command line typed so far.
Word Designators
Word designators are used to select desired words from the event. A :
separates the event specification from the word designator. It may be
omitted if the word designator begins with a ^, $, *, -, or %. Words
are numbered from the beginning of the line, with the first word being
denoted by 0 (zero). Words are inserted into the current line sepa-
rated by single spaces.
0 (zero)
The zeroth word. For the shell, this is the command word.
n The nth word.
^ The first argument. That is, word 1.
$ The last word. This is usually the last argument, but will ex-
pand to the zeroth word if there is only one word in the line.
% The first word matched by the most recent `?string?' search, if
the search string begins with a character that is part of a
word.
x-y A range of words; `-y' abbreviates `0-y'.
* All of the words but the zeroth. This is a synonym for `1-$'.
It is not an error to use * if there is just one word in the
event; the empty string is returned in that case.
x* Abbreviates x-$.
x- Abbreviates x-$ like x*, but omits the last word. If x is miss-
ing, it defaults to 0.
If a word designator is supplied without an event specification, the
previous command is used as the event.
Modifiers
After the optional word designator, there may appear a sequence of one
or more of the following modifiers, each preceded by a `:'. These mod-
ify, or edit, the word or words selected from the history event.
h Remove a trailing file name component, leaving only the head.
t Remove all leading file name components, leaving the tail.
r Remove a trailing suffix of the form .xxx, leaving the basename.
e Remove all but the trailing suffix.
p Print the new command but do not execute it.
q Quote the substituted words, escaping further substitutions.
x Quote the substituted words as with q, but break into words at
blanks and newlines. The q and x modifiers are mutually exclu-
sive; the last one supplied is used.
s/old/new/
Substitute new for the first occurrence of old in the event
line. Any character may be used as the delimiter in place of /.
The final delimiter is optional if it is the last character of
the event line. The delimiter may be quoted in old and new with
a single backslash. If & appears in new, it is replaced by old.
A single backslash will quote the &. If old is null, it is set
to the last old substituted, or, if no previous history substi-
tutions took place, the last string in a !?string[?] search.
If new is null, each matching old is deleted.
& Repeat the previous substitution.
g Cause changes to be applied over the entire event line. This is
used in conjunction with `:s' (e.g., `:gs/old/new/') or `:&'.
If used with `:s', any delimiter can be used in place of /, and
the final delimiter is optional if it is the last character of
the event line. An a may be used as a synonym for g.
G Apply the following `s' or `&' modifier once to each word in the
event line.
PROGRAMMING WITH HISTORY FUNCTIONS
This section describes how to use the History library in other pro-
grams.
Introduction to History
A programmer using the History library has available functions for re-
membering lines on a history list, associating arbitrary data with a
line, removing lines from the list, searching through the list for a
line containing an arbitrary text string, and referencing any line in
the list directly. In addition, a history expansion function is avail-
able which provides for a consistent user interface across different
programs.
The user using programs written with the History library has the bene-
fit of a consistent user interface with a set of well-known commands
for manipulating the text of previous lines and using that text in new
commands. The basic history manipulation commands are identical to the
history substitution provided by bash.
The programmer can also use the readline library, which includes some
history manipulation by default, and has the added advantage of command
line editing.
Before declaring any functions using any functionality the History li-
brary provides in other code, an application writer should include the
file <readline/history.h> in any file that uses the History library's
features. It supplies extern declarations for all of the library's
public functions and variables, and declares all of the public data
structures.
History Storage
The history list is an array of history entries. A history entry is
declared as follows:
typedef void * histdata_t;
typedef struct _hist_entry {
char *line;
char *timestamp;
histdata_t data;
} HIST_ENTRY;
The history list itself might therefore be declared as
HIST_ENTRY ** the_history_list;
The state of the History library is encapsulated into a single struc-
ture:
/*
* A structure used to pass around the current state of the history.
*/
typedef struct _hist_state {
HIST_ENTRY **entries; /* Pointer to the entries themselves. */
int offset; /* The location pointer within this array. */
int length; /* Number of elements within this array. */
int size; /* Number of slots allocated to this array. */
int flags;
} HISTORY_STATE;
If the flags member includes HS_STIFLED, the history has been stifled.
History Functions
This section describes the calling sequence for the various functions
exported by the GNU History library.
Initializing History and State Management
This section describes functions used to initialize and manage the
state of the History library when you want to use the history functions
in your program.
void using_history (void)
Begin a session in which the history functions might be used. This
initializes the interactive variables.
HISTORY_STATE * history_get_history_state (void)
Return a structure describing the current state of the input history.
void history_set_history_state (HISTORY_STATE *state)
Set the state of the history list according to state.
History List Management
These functions manage individual entries on the history list, or set
parameters managing the list itself.
void add_history (const char *string)
Place string at the end of the history list. The associated data field
(if any) is set to NULL. If the maximum number of history entries has
been set using stifle_history(), and the new number of history entries
would exceed that maximum, the oldest history entry is removed.
void add_history_time (const char *string)
Change the time stamp associated with the most recent history entry to
string.
HIST_ENTRY * remove_history (int which)
Remove history entry at offset which from the history. The removed el-
ement is returned so you can free the line, data, and containing struc-
ture.
histdata_t free_history_entry (HIST_ENTRY *histent)
Free the history entry histent and any history library private data as-
sociated with it. Returns the application-specific data so the caller
can dispose of it.
HIST_ENTRY * replace_history_entry (int which, const char *line, hist-
data_t data)
Make the history entry at offset which have line and data. This re-
turns the old entry so the caller can dispose of any application-spe-
cific data. In the case of an invalid which, a NULL pointer is re-
turned.
void clear_history (void)
Clear the history list by deleting all the entries.
void stifle_history (int max)
Stifle the history list, remembering only the last max entries. The
history list will contain only max entries at a time.
int unstifle_history (void)
Stop stifling the history. This returns the previously-set maximum
number of history entries (as set by stifle_history()). history was
stifled. The value is positive if the history was stifled, negative if
it wasn't.
int history_is_stifled (void)
Returns non-zero if the history is stifled, zero if it is not.
Information About the History List
These functions return information about the entire history list or in-
dividual list entries.
HIST_ENTRY ** history_list (void)
Return a NULL terminated array of HIST_ENTRY * which is the current in-
put history. Element 0 of this list is the beginning of time. If
there is no history, return NULL.
int where_history (void)
Returns the offset of the current history element.
HIST_ENTRY * current_history (void)
Return the history entry at the current position, as determined by
where_history(). If there is no entry there, return a NULL pointer.
HIST_ENTRY * history_get (int offset)
Return the history entry at position offset. The range of valid values
of offset starts at history_base and ends at history_length - 1. If
there is no entry there, or if offset is outside the valid range, re-
turn a NULL pointer.
time_t history_get_time (HIST_ENTRY *)
Return the time stamp associated with the history entry passed as the
argument.
int history_total_bytes (void)
Return the number of bytes that the primary history entries are using.
This function returns the sum of the lengths of all the lines in the
history.
Moving Around the History List
These functions allow the current index into the history list to be set
or changed.
int history_set_pos (int pos)
Set the current history offset to pos, an absolute index into the list.
Returns 1 on success, 0 if pos is less than zero or greater than the
number of history entries.
HIST_ENTRY * previous_history (void)
Back up the current history offset to the previous history entry, and
return a pointer to that entry. If there is no previous entry, return
a NULL pointer.
HIST_ENTRY * next_history (void)
If the current history offset refers to a valid history entry, incre-
ment the current history offset. If the possibly-incremented history
offset refers to a valid history entry, return a pointer to that entry;
otherwise, return a NULL pointer.
Searching the History List
These functions allow searching of the history list for entries con-
taining a specific string. Searching may be performed both forward and
backward from the current history position. The search may be an-
chored, meaning that the string must match at the beginning of the his-
tory entry.
int history_search (const char *string, int direction)
Search the history for string, starting at the current history offset.
If direction is less than 0, then the search is through previous en-
tries, otherwise through subsequent entries. If string is found, then
the current history index is set to that history entry, and the value
returned is the offset in the line of the entry where string was found.
Otherwise, nothing is changed, and a -1 is returned.
int history_search_prefix (const char *string, int direction)
Search the history for string, starting at the current history offset.
The search is anchored: matching lines must begin with string. If di-
rection is less than 0, then the search is through previous entries,
otherwise through subsequent entries. If string is found, then the
current history index is set to that entry, and the return value is 0.
Otherwise, nothing is changed, and a -1 is returned.
int history_search_pos (const char *string, int direction, int pos)
Search for string in the history list, starting at pos, an absolute in-
dex into the list. If direction is negative, the search proceeds back-
ward from pos, otherwise forward. Returns the absolute index of the
history element where string was found, or -1 otherwise.
Managing the History File
The History library can read the history from and write it to a file.
This section documents the functions for managing a history file.
int read_history (const char *filename)
Add the contents of filename to the history list, a line at a time. If
filename is NULL, then read from ~/.history. Returns 0 if successful,
or errno if not.
int read_history_range (const char *filename, int from, int to)
Read a range of lines from filename, adding them to the history list.
Start reading at line from and end at to. If from is zero, start at
the beginning. If to is less than from, then read until the end of the
file. If filename is NULL, then read from ~/.history. Returns 0 if
successful, or errno if not.
int write_history (const char *filename)
Write the current history to filename, overwriting filename if neces-
sary. If filename is NULL, then write the history list to ~/.history.
Returns 0 on success, or errno on a read or write error.
int append_history (int nelements, const char *filename)
Append the last nelements of the history list to filename. If filename
is NULL, then append to ~/.history. Returns 0 on success, or errno on
a read or write error.
int history_truncate_file (const char *filename, int nlines)
Truncate the history file filename, leaving only the last nlines lines.
If filename is NULL, then ~/.history is truncated. Returns 0 on suc-
cess, or errno on failure.
History Expansion
These functions implement history expansion.
int history_expand (char *string, char **output)
Expand string, placing the result into output, a pointer to a string.
Returns:
0 If no expansions took place (or, if the only change in
the text was the removal of escape characters preceding
the history expansion character);
1 if expansions did take place;
-1 if there was an error in expansion;
2 if the returned line should be displayed, but not exe-
cuted, as with the :p modifier.
If an error occurred in expansion, then output contains a descriptive
error message.
char * get_history_event (const char *string, int *cindex, int qchar)
Returns the text of the history event beginning at string + *cindex.
*cindex is modified to point to after the event specifier. At function
entry, cindex points to the index into string where the history event
specification begins. qchar is a character that is allowed to end the
event specification in addition to the ``normal'' terminating charac-
ters.
char ** history_tokenize (const char *string)
Return an array of tokens parsed out of string, much as the shell
might. The tokens are split on the characters in the history_word_de-
limiters variable, and shell quoting conventions are obeyed.
char * history_arg_extract (int first, int last, const char *string)
Extract a string segment consisting of the first through last arguments
present in string. Arguments are split using history_tokenize().
History Variables
This section describes the externally-visible variables exported by the
GNU History Library.
int history_base
The logical offset of the first entry in the history list.
int history_length
The number of entries currently stored in the history list.
int history_max_entries
The maximum number of history entries. This must be changed using sti-
fle_history().
int history_write_timestamps
If non-zero, timestamps are written to the history file, so they can be
preserved between sessions. The default value is 0, meaning that time-
stamps are not saved. The current timestamp format uses the value of
history_comment_char to delimit timestamp entries in the history file.
If that variable does not have a value (the default), timestamps will
not be written.
char history_expansion_char
The character that introduces a history event. The default is !. Set-
ting this to 0 inhibits history expansion.
char history_subst_char
The character that invokes word substitution if found at the start of a
line. The default is ^.
char history_comment_char
During tokenization, if this character is seen as the first character
of a word, then it and all subsequent characters up to a newline are
ignored, suppressing history expansion for the remainder of the line.
This is disabled by default.
char * history_word_delimiters
The characters that separate tokens for history_tokenize(). The de-
fault value is " \t\n()<>;&|".
char * history_no_expand_chars
The list of characters which inhibit history expansion if found immedi-
ately following history_expansion_char. The default is space, tab,
newline, \r, and =.
char * history_search_delimiter_chars
The list of additional characters which can delimit a history search
string, in addition to space, tab, : and ? in the case of a substring
search. The default is empty.
int history_quotes_inhibit_expansion
If non-zero, double-quoted words are not scanned for the history expan-
sion character or the history comment character. The default value is
0.
rl_linebuf_func_t * history_inhibit_expansion_function
This should be set to the address of a function that takes two argu-
ments: a char * (string) and an int index into that string (i). It
should return a non-zero value if the history expansion starting at
string[i] should not be performed; zero if the expansion should be
done. It is intended for use by applications like bash that use the
history expansion character for additional purposes. By default, this
variable is set to NULL.
FILES
~/.history
Default filename for reading and writing saved history
SEE ALSO
The Gnu Readline Library, Brian Fox and Chet Ramey
The Gnu History Library, Brian Fox and Chet Ramey
bash(1)
readline(3)
AUTHORS
Brian Fox, Free Software Foundation
bfox@gnu.org
Chet Ramey, Case Western Reserve University
chet.ramey@case.edu
BUG REPORTS
If you find a bug in the history library, you should report it. But
first, you should make sure that it really is a bug, and that it ap-
pears in the latest version of the history library that you have.
Once you have determined that a bug actually exists, mail a bug report
to bug-readline@gnu.org. If you have a fix, you are welcome to mail
that as well! Suggestions and `philosophical' bug reports may be
mailed to bug-readline@gnu.org or posted to the Usenet newsgroup
gnu.bash.bug.
Comments and bug reports concerning this manual page should be directed
to chet.ramey@case.edu.
GNU History 8.1 2020 July 17 HISTORY(3)

687
doc/history.3 Normal file
View file

@ -0,0 +1,687 @@
.\"
.\" MAN PAGE COMMENTS to
.\"
.\" Chet Ramey
.\" Information Network Services
.\" Case Western Reserve University
.\" chet.ramey@case.edu
.\"
.\" Last Change: Fri Jul 17 09:43:01 EDT 2020
.\"
.TH HISTORY 3 "2020 July 17" "GNU History 8.1"
.\"
.\" File Name macro. This used to be `.PN', for Path Name,
.\" but Sun doesn't seem to like that very much.
.\"
.de FN
\fI\|\\$1\|\fP
..
.ds lp \fR\|(\fP
.ds rp \fR\|)\fP
.\" FnN return-value fun-name N arguments
.de Fn1
\fI\\$1\fP \fB\\$2\fP \\*(lp\fI\\$3\fP\\*(rp
.br
..
.de Fn2
.if t \fI\\$1\fP \fB\\$2\fP \\*(lp\fI\\$3,\|\\$4\fP\\*(rp
.if n \fI\\$1\fP \fB\\$2\fP \\*(lp\fI\\$3, \\$4\fP\\*(rp
.br
..
.de Fn3
.if t \fI\\$1\fP \fB\\$2\fP \\*(lp\fI\\$3,\|\\$4,\|\\$5\fP\|\\*(rp
.if n \fI\\$1\fP \fB\\$2\fP \\*(lp\fI\\$3, \\$4, \\$5\fP\\*(rp
.br
..
.de Vb
\fI\\$1\fP \fB\\$2\fP
.br
..
.SH NAME
history \- GNU History Library
.SH COPYRIGHT
.if t The GNU History Library is Copyright \(co 1989-2020 by the Free Software Foundation, Inc.
.if n The GNU History Library is Copyright (C) 1989-2020 by the Free Software Foundation, Inc.
.SH DESCRIPTION
Many programs read input from the user a line at a time. The GNU
History library is able to keep track of those lines, associate arbitrary
data with each line, and utilize information from previous lines in
composing new ones.
.PP
.SH "HISTORY EXPANSION"
The history library supports a history expansion feature that
is identical to the history expansion in
.BR bash.
This section describes what syntax features are available.
.PP
History expansions introduce words from the history list into
the input stream, making it easy to repeat commands, insert the
arguments to a previous command into the current input line, or
fix errors in previous commands quickly.
.PP
History expansion is usually performed immediately after a complete line
is read.
It takes place in two parts.
The first is to determine which line from the history list
to use during substitution.
The second is to select portions of that line for inclusion into
the current one.
The line selected from the history is the \fIevent\fP,
and the portions of that line that are acted upon are \fIwords\fP.
Various \fImodifiers\fP are available to manipulate the selected words.
The line is broken into words in the same fashion as \fBbash\fP
does when reading input,
so that several words that would otherwise be separated
are considered one word when surrounded by quotes (see the
description of \fBhistory_tokenize()\fP below).
History expansions are introduced by the appearance of the
history expansion character, which is \^\fB!\fP\^ by default.
Only backslash (\^\fB\e\fP\^) and single quotes can quote
the history expansion character.
.SS Event Designators
An event designator is a reference to a command line entry in the
history list.
Unless the reference is absolute, events are relative to the current
position in the history list.
.PP
.PD 0
.TP
.B !
Start a history substitution, except when followed by a
.BR blank ,
newline, = or (.
.TP
.B !\fIn\fR
Refer to command line
.IR n .
.TP
.B !\-\fIn\fR
Refer to the current command minus
.IR n .
.TP
.B !!
Refer to the previous command. This is a synonym for `!\-1'.
.TP
.B !\fIstring\fR
Refer to the most recent command
preceding the current position in the history list
starting with
.IR string .
.TP
.B !?\fIstring\fR\fB[?]\fR
Refer to the most recent command
preceding the current position in the history list
containing
.IR string .
The trailing \fB?\fP may be omitted if
.I string
is followed immediately by a newline.
If \fIstring\fP is missing, the string from the most recent search is used;
it is an error if there is no previous search string.
.TP
.B \d\s+2^\s-2\u\fIstring1\fP\d\s+2^\s-2\u\fIstring2\fP\d\s+2^\s-2\u
Quick substitution. Repeat the last command, replacing
.I string1
with
.IR string2 .
Equivalent to
``!!:s\d\s+2^\s-2\u\fIstring1\fP\d\s+2^\s-2\u\fIstring2\fP\d\s+2^\s-2\u''
(see \fBModifiers\fP below).
.TP
.B !#
The entire command line typed so far.
.PD
.SS Word Designators
Word designators are used to select desired words from the event.
A
.B :
separates the event specification from the word designator.
It may be omitted if the word designator begins with a
.BR ^ ,
.BR $ ,
.BR * ,
.BR \- ,
or
.BR % .
Words are numbered from the beginning of the line,
with the first word being denoted by 0 (zero).
Words are inserted into the current line separated by single spaces.
.PP
.PD 0
.TP
.B 0 (zero)
The zeroth word. For the shell, this is the command
word.
.TP
.I n
The \fIn\fRth word.
.TP
.B ^
The first argument. That is, word 1.
.TP
.B $
The last word. This is usually the last argument, but will expand to the
zeroth word if there is only one word in the line.
.TP
.B %
The first word matched by the most recent `?\fIstring\fR?' search,
if the search string begins with a character that is part of a word.
.TP
.I x\fB\-\fPy
A range of words; `\-\fIy\fR' abbreviates `0\-\fIy\fR'.
.TP
.B *
All of the words but the zeroth. This is a synonym
for `\fI1\-$\fP'. It is not an error to use
.B *
if there is just one
word in the event; the empty string is returned in that case.
.TP
.B x*
Abbreviates \fIx\-$\fP.
.TP
.B x\-
Abbreviates \fIx\-$\fP like \fBx*\fP, but omits the last word.
If \fBx\fP is missing, it defaults to 0.
.PD
.PP
If a word designator is supplied without an event specification, the
previous command is used as the event.
.SS Modifiers
After the optional word designator, there may appear a sequence of
one or more of the following modifiers, each preceded by a `:'.
These modify, or edit, the word or words selected from the history event.
.PP
.PD 0
.PP
.TP
.B h
Remove a trailing file name component, leaving only the head.
.TP
.B t
Remove all leading file name components, leaving the tail.
.TP
.B r
Remove a trailing suffix of the form \fI.xxx\fP, leaving the
basename.
.TP
.B e
Remove all but the trailing suffix.
.TP
.B p
Print the new command but do not execute it.
.TP
.B q
Quote the substituted words, escaping further substitutions.
.TP
.B x
Quote the substituted words as with
.BR q ,
but break into words at
.B blanks
and newlines.
The \fBq\fP and \fBx\fP modifiers are mutually exclusive; the last one
supplied is used.
.TP
.B s/\fIold\fP/\fInew\fP/
Substitute
.I new
for the first occurrence of
.I old
in the event line.
Any character may be used as the delimiter in place of /.
The final delimiter is optional if it is the last character of the
event line.
The delimiter may be quoted in
.I old
and
.I new
with a single backslash. If & appears in
.IR new ,
it is replaced by
.IR old .
A single backslash will quote the &.
If
.I old
is null, it is set to the last
.I old
substituted, or, if no previous history substitutions took place,
the last
.I string
in a
.B !?\fIstring\fR\fB[?]\fR
search.
If
.I new
is null, each matching
.I old
is deleted.
.TP
.B &
Repeat the previous substitution.
.TP
.B g
Cause changes to be applied over the entire event line. This is
used in conjunction with `\fB:s\fP' (e.g., `\fB:gs/\fIold\fP/\fInew\fP/\fR')
or `\fB:&\fP'. If used with
`\fB:s\fP', any delimiter can be used
in place of /, and the final delimiter is optional
if it is the last character of the event line.
An \fBa\fP may be used as a synonym for \fBg\fP.
.TP
.B G
Apply the following `\fBs\fP' or `\fB&\fP' modifier once to each word
in the event line.
.PD
.SH "PROGRAMMING WITH HISTORY FUNCTIONS"
This section describes how to use the History library in other programs.
.SS Introduction to History
A programmer using the History library has available functions
for remembering lines on a history list, associating arbitrary data
with a line, removing lines from the list, searching through the list
for a line containing an arbitrary text string, and referencing any line
in the list directly. In addition, a history \fIexpansion\fP function
is available which provides for a consistent user interface across
different programs.
.PP
The user using programs written with the History library has the
benefit of a consistent user interface with a set of well-known
commands for manipulating the text of previous lines and using that text
in new commands. The basic history manipulation commands are
identical to
the history substitution provided by \fBbash\fP.
.PP
The programmer can also use the readline library, which
includes some history manipulation by default, and has the added
advantage of command line editing.
.PP
Before declaring any functions using any functionality the History
library provides in other code, an application writer should include
the file
.FN <readline/history.h>
in any file that uses the
History library's features. It supplies extern declarations for all
of the library's public functions and variables, and declares all of
the public data structures.
.SS History Storage
The history list is an array of history entries. A history entry is
declared as follows:
.PP
.Vb "typedef void *" histdata_t;
.PP
.nf
typedef struct _hist_entry {
char *line;
char *timestamp;
histdata_t data;
} HIST_ENTRY;
.fi
.PP
The history list itself might therefore be declared as
.PP
.Vb "HIST_ENTRY **" the_history_list;
.PP
The state of the History library is encapsulated into a single structure:
.PP
.nf
/*
* A structure used to pass around the current state of the history.
*/
typedef struct _hist_state {
HIST_ENTRY **entries; /* Pointer to the entries themselves. */
int offset; /* The location pointer within this array. */
int length; /* Number of elements within this array. */
int size; /* Number of slots allocated to this array. */
int flags;
} HISTORY_STATE;
.fi
.PP
If the flags member includes \fBHS_STIFLED\fP, the history has been
stifled.
.SH "History Functions"
This section describes the calling sequence for the various functions
exported by the GNU History library.
.SS Initializing History and State Management
This section describes functions used to initialize and manage
the state of the History library when you want to use the history
functions in your program.
.Fn1 void using_history void
Begin a session in which the history functions might be used. This
initializes the interactive variables.
.Fn1 "HISTORY_STATE *" history_get_history_state void
Return a structure describing the current state of the input history.
.Fn1 void history_set_history_state "HISTORY_STATE *state"
Set the state of the history list according to \fIstate\fP.
.SS History List Management
These functions manage individual entries on the history list, or set
parameters managing the list itself.
.Fn1 void add_history "const char *string"
Place \fIstring\fP at the end of the history list. The associated data
field (if any) is set to \fBNULL\fP.
If the maximum number of history entries has been set using
\fBstifle_history()\fP, and the new number of history entries would exceed
that maximum, the oldest history entry is removed.
.Fn1 void add_history_time "const char *string"
Change the time stamp associated with the most recent history entry to
\fIstring\fP.
.Fn1 "HIST_ENTRY *" remove_history "int which"
Remove history entry at offset \fIwhich\fP from the history. The
removed element is returned so you can free the line, data,
and containing structure.
.Fn1 "histdata_t" free_history_entry "HIST_ENTRY *histent"
Free the history entry \fIhistent\fP and any history library private
data associated with it. Returns the application-specific data
so the caller can dispose of it.
.Fn3 "HIST_ENTRY *" replace_history_entry "int which" "const char *line" "histdata_t data"
Make the history entry at offset \fIwhich\fP have \fIline\fP and \fIdata\fP.
This returns the old entry so the caller can dispose of any
application-specific data. In the case
of an invalid \fIwhich\fP, a \fBNULL\fP pointer is returned.
.Fn1 void clear_history "void"
Clear the history list by deleting all the entries.
.Fn1 void stifle_history "int max"
Stifle the history list, remembering only the last \fImax\fP entries.
The history list will contain only \fImax\fP entries at a time.
.Fn1 int unstifle_history "void"
Stop stifling the history. This returns the previously-set
maximum number of history entries (as set by \fBstifle_history()\fP).
history was stifled. The value is positive if the history was
stifled, negative if it wasn't.
.Fn1 int history_is_stifled "void"
Returns non-zero if the history is stifled, zero if it is not.
.SS Information About the History List
These functions return information about the entire history list or
individual list entries.
.Fn1 "HIST_ENTRY **" history_list "void"
Return a \fBNULL\fP terminated array of \fIHIST_ENTRY *\fP which is the
current input history. Element 0 of this list is the beginning of time.
If there is no history, return \fBNULL\fP.
.Fn1 int where_history "void"
Returns the offset of the current history element.
.Fn1 "HIST_ENTRY *" current_history "void"
Return the history entry at the current position, as determined by
\fBwhere_history()\fP. If there is no entry there, return a \fBNULL\fP
pointer.
.Fn1 "HIST_ENTRY *" history_get "int offset"
Return the history entry at position \fIoffset\fP.
The range of valid values of \fIoffset\fP starts at \fBhistory_base\fP
and ends at \fBhistory_length\fP \- 1.
If there is no entry there, or if \fIoffset\fP is outside the valid
range, return a \fBNULL\fP pointer.
.Fn1 "time_t" history_get_time "HIST_ENTRY *"
Return the time stamp associated with the history entry passed as the argument.
.Fn1 int history_total_bytes "void"
Return the number of bytes that the primary history entries are using.
This function returns the sum of the lengths of all the lines in the
history.
.SS Moving Around the History List
These functions allow the current index into the history list to be
set or changed.
.Fn1 int history_set_pos "int pos"
Set the current history offset to \fIpos\fP, an absolute index
into the list.
Returns 1 on success, 0 if \fIpos\fP is less than zero or greater
than the number of history entries.
.Fn1 "HIST_ENTRY *" previous_history "void"
Back up the current history offset to the previous history entry, and
return a pointer to that entry. If there is no previous entry, return
a \fBNULL\fP pointer.
.Fn1 "HIST_ENTRY *" next_history "void"
If the current history offset refers to a valid history entry,
increment the current history offset.
If the possibly-incremented history offset refers to a valid history
entry, return a pointer to that entry;
otherwise, return a \fBNULL\fP pointer.
.SS Searching the History List
These functions allow searching of the history list for entries containing
a specific string. Searching may be performed both forward and backward
from the current history position. The search may be \fIanchored\fP,
meaning that the string must match at the beginning of the history entry.
.Fn2 int history_search "const char *string" "int direction"
Search the history for \fIstring\fP, starting at the current history offset.
If \fIdirection\fP is less than 0, then the search is through
previous entries, otherwise through subsequent entries.
If \fIstring\fP is found, then
the current history index is set to that history entry, and the value
returned is the offset in the line of the entry where
\fIstring\fP was found. Otherwise, nothing is changed, and a -1 is
returned.
.Fn2 int history_search_prefix "const char *string" "int direction"
Search the history for \fIstring\fP, starting at the current history
offset. The search is anchored: matching lines must begin with
\fIstring\fP. If \fIdirection\fP is less than 0, then the search is
through previous entries, otherwise through subsequent entries.
If \fIstring\fP is found, then the
current history index is set to that entry, and the return value is 0.
Otherwise, nothing is changed, and a -1 is returned.
.Fn3 int history_search_pos "const char *string" "int direction" "int pos"
Search for \fIstring\fP in the history list, starting at \fIpos\fP, an
absolute index into the list. If \fIdirection\fP is negative, the search
proceeds backward from \fIpos\fP, otherwise forward. Returns the absolute
index of the history element where \fIstring\fP was found, or -1 otherwise.
.SS Managing the History File
The History library can read the history from and write it to a file.
This section documents the functions for managing a history file.
.Fn1 int read_history "const char *filename"
Add the contents of \fIfilename\fP to the history list, a line at a time.
If \fIfilename\fP is \fBNULL\fP, then read from \fI~/.history\fP.
Returns 0 if successful, or \fBerrno\fP if not.
.Fn3 int read_history_range "const char *filename" "int from" "int to"
Read a range of lines from \fIfilename\fP, adding them to the history list.
Start reading at line \fIfrom\fP and end at \fIto\fP.
If \fIfrom\fP is zero, start at the beginning. If \fIto\fP is less than
\fIfrom\fP, then read until the end of the file. If \fIfilename\fP is
\fBNULL\fP, then read from \fI~/.history\fP. Returns 0 if successful,
or \fBerrno\fP if not.
.Fn1 int write_history "const char *filename"
Write the current history to \fIfilename\fP, overwriting \fIfilename\fP
if necessary.
If \fIfilename\fP is \fBNULL\fP, then write the history list to \fI~/.history\fP.
Returns 0 on success, or \fBerrno\fP on a read or write error.
.Fn2 int append_history "int nelements" "const char *filename"
Append the last \fInelements\fP of the history list to \fIfilename\fP.
If \fIfilename\fP is \fBNULL\fP, then append to \fI~/.history\fP.
Returns 0 on success, or \fBerrno\fP on a read or write error.
.Fn2 int history_truncate_file "const char *filename" "int nlines"
Truncate the history file \fIfilename\fP, leaving only the last
\fInlines\fP lines.
If \fIfilename\fP is \fBNULL\fP, then \fI~/.history\fP is truncated.
Returns 0 on success, or \fBerrno\fP on failure.
.SS History Expansion
These functions implement history expansion.
.Fn2 int history_expand "char *string" "char **output"
Expand \fIstring\fP, placing the result into \fIoutput\fP, a pointer
to a string. Returns:
.RS
.PD 0
.TP
0
If no expansions took place (or, if the only change in
the text was the removal of escape characters preceding the history expansion
character);
.TP
1
if expansions did take place;
.TP
-1
if there was an error in expansion;
.TP
2
if the returned line should be displayed, but not executed,
as with the \fB:p\fP modifier.
.PD
.RE
If an error occurred in expansion, then \fIoutput\fP contains a descriptive
error message.
.Fn3 "char *" get_history_event "const char *string" "int *cindex" "int qchar"
Returns the text of the history event beginning at \fIstring\fP +
\fI*cindex\fP. \fI*cindex\fP is modified to point to after the event
specifier. At function entry, \fIcindex\fP points to the index into
\fIstring\fP where the history event specification begins. \fIqchar\fP
is a character that is allowed to end the event specification in addition
to the ``normal'' terminating characters.
.Fn1 "char **" history_tokenize "const char *string"
Return an array of tokens parsed out of \fIstring\fP, much as the
shell might.
The tokens are split on the characters in the
\fBhistory_word_delimiters\fP variable,
and shell quoting conventions are obeyed.
.Fn3 "char *" history_arg_extract "int first" "int last" "const char *string"
Extract a string segment consisting of the \fIfirst\fP through \fIlast\fP
arguments present in \fIstring\fP. Arguments are split using
\fBhistory_tokenize()\fP.
.SS History Variables
This section describes the externally-visible variables exported by
the GNU History Library.
.Vb int history_base
The logical offset of the first entry in the history list.
.Vb int history_length
The number of entries currently stored in the history list.
.Vb int history_max_entries
The maximum number of history entries. This must be changed using
\fBstifle_history()\fP.
.Vb int history_write_timestamps
If non-zero, timestamps are written to the history file, so they can be
preserved between sessions. The default value is 0, meaning that
timestamps are not saved.
The current timestamp format uses the value of \fIhistory_comment_char\fP
to delimit timestamp entries in the history file. If that variable does
not have a value (the default), timestamps will not be written.
.Vb char history_expansion_char
The character that introduces a history event. The default is \fB!\fP.
Setting this to 0 inhibits history expansion.
.Vb char history_subst_char
The character that invokes word substitution if found at the start of
a line. The default is \fB^\fP.
.Vb char history_comment_char
During tokenization, if this character is seen as the first character
of a word, then it and all subsequent characters up to a newline are
ignored, suppressing history expansion for the remainder of the line.
This is disabled by default.
.Vb "char *" history_word_delimiters
The characters that separate tokens for \fBhistory_tokenize()\fP.
The default value is \fB"\ \et\en()<>;&|"\fP.
.Vb "char *" history_no_expand_chars
The list of characters which inhibit history expansion if found immediately
following \fBhistory_expansion_char\fP. The default is space, tab, newline,
\fB\er\fP, and \fB=\fP.
.Vb "char *" history_search_delimiter_chars
The list of additional characters which can delimit a history search
string, in addition to space, tab, \fI:\fP and \fI?\fP in the case of
a substring search. The default is empty.
.Vb int history_quotes_inhibit_expansion
If non-zero, double-quoted words are not scanned for the history expansion
character or the history comment character. The default value is 0.
.Vb "rl_linebuf_func_t *" history_inhibit_expansion_function
This should be set to the address of a function that takes two arguments:
a \fBchar *\fP (\fIstring\fP)
and an \fBint\fP index into that string (\fIi\fP).
It should return a non-zero value if the history expansion starting at
\fIstring[i]\fP should not be performed; zero if the expansion should
be done.
It is intended for use by applications like \fBbash\fP that use the history
expansion character for additional purposes.
By default, this variable is set to \fBNULL\fP.
.SH FILES
.PD 0
.TP
.FN ~/.history
Default filename for reading and writing saved history
.PD
.SH "SEE ALSO"
.PD 0
.TP
\fIThe Gnu Readline Library\fP, Brian Fox and Chet Ramey
.TP
\fIThe Gnu History Library\fP, Brian Fox and Chet Ramey
.TP
\fIbash\fP(1)
.TP
\fIreadline\fP(3)
.PD
.SH AUTHORS
Brian Fox, Free Software Foundation
.br
bfox@gnu.org
.PP
Chet Ramey, Case Western Reserve University
.br
chet.ramey@case.edu
.SH BUG REPORTS
If you find a bug in the
.B history
library, you should report it. But first, you should
make sure that it really is a bug, and that it appears in the latest
version of the
.B history
library that you have.
.PP
Once you have determined that a bug actually exists, mail a
bug report to \fIbug\-readline\fP@\fIgnu.org\fP.
If you have a fix, you are welcome to mail that
as well! Suggestions and `philosophical' bug reports may be mailed
to \fPbug-readline\fP@\fIgnu.org\fP or posted to the Usenet
newsgroup
.BR gnu.bash.bug .
.PP
Comments and bug reports concerning
this manual page should be directed to
.IR chet.ramey@case.edu .

BIN
doc/history.dvi Normal file

Binary file not shown.

1751
doc/history.html Normal file

File diff suppressed because it is too large Load diff

1426
doc/history.info Normal file

File diff suppressed because it is too large Load diff

BIN
doc/history.pdf Normal file

Binary file not shown.

6666
doc/history.ps Normal file

File diff suppressed because it is too large Load diff

85
doc/history.texi Normal file
View file

@ -0,0 +1,85 @@
\input texinfo @c -*-texinfo-*-
@c %**start of header (This is for running Texinfo on a region.)
@setfilename history.info
@settitle GNU History Library
@include version.texi
@c %**end of header (This is for running Texinfo on a region.)
@copying
This document describes the GNU History library
(version @value{VERSION}, @value{UPDATED}),
a programming tool that provides a consistent user interface for
recalling lines of previously typed input.
Copyright @copyright{} 1988--2022 Free Software Foundation, Inc.
@quotation
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation; with no
Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
A copy of the license is included in the section entitled
``GNU Free Documentation License''.
@end quotation
@end copying
@dircategory Libraries
@direntry
* History: (history). The GNU history library API.
@end direntry
@titlepage
@title GNU History Library
@subtitle Edition @value{EDITION}, for @code{History Library} Version @value{VERSION}.
@subtitle @value{UPDATED-MONTH}
@author Chet Ramey, Case Western Reserve University
@author Brian Fox, Free Software Foundation
@page
@vskip 0pt plus 1filll
@insertcopying
@end titlepage
@contents
@ifnottex
@node Top
@top GNU History Library
This document describes the GNU History library, a programming tool that
provides a consistent user interface for recalling lines of previously
typed input.
@menu
* Using History Interactively:: GNU History User's Manual.
* Programming with GNU History:: GNU History Programmer's Manual.
* GNU Free Documentation License:: License for copying this manual.
* Concept Index:: Index of concepts described in this manual.
* Function and Variable Index:: Index of externally visible functions
and variables.
@end menu
@end ifnottex
@syncodeindex fn vr
@include hsuser.texi
@include hstech.texi
@node GNU Free Documentation License
@appendix GNU Free Documentation License
@include fdl.texi
@node Concept Index
@appendix Concept Index
@printindex cp
@node Function and Variable Index
@appendix Function and Variable Index
@printindex vr
@bye

896
doc/history_3.ps Normal file
View file

@ -0,0 +1,896 @@
%!PS-Adobe-3.0
%%Creator: groff version 1.22.4
%%CreationDate: Fri Sep 23 09:52:37 2022
%%DocumentNeededResources: font Times-Roman
%%+ font Times-Bold
%%+ font Times-Italic
%%DocumentSuppliedResources: procset grops 1.22 4
%%Pages: 7
%%PageOrder: Ascend
%%DocumentMedia: Default 612 792 0 () ()
%%Orientation: Portrait
%%EndComments
%%BeginDefaults
%%PageMedia: Default
%%EndDefaults
%%BeginProlog
%%BeginResource: procset grops 1.22 4
%!PS-Adobe-3.0 Resource-ProcSet
/setpacking where{
pop
currentpacking
true setpacking
}if
/grops 120 dict dup begin
/SC 32 def
/A/show load def
/B{0 SC 3 -1 roll widthshow}bind def
/C{0 exch ashow}bind def
/D{0 exch 0 SC 5 2 roll awidthshow}bind def
/E{0 rmoveto show}bind def
/F{0 rmoveto 0 SC 3 -1 roll widthshow}bind def
/G{0 rmoveto 0 exch ashow}bind def
/H{0 rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
/I{0 exch rmoveto show}bind def
/J{0 exch rmoveto 0 SC 3 -1 roll widthshow}bind def
/K{0 exch rmoveto 0 exch ashow}bind def
/L{0 exch rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
/M{rmoveto show}bind def
/N{rmoveto 0 SC 3 -1 roll widthshow}bind def
/O{rmoveto 0 exch ashow}bind def
/P{rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
/Q{moveto show}bind def
/R{moveto 0 SC 3 -1 roll widthshow}bind def
/S{moveto 0 exch ashow}bind def
/T{moveto 0 exch 0 SC 5 2 roll awidthshow}bind def
/SF{
findfont exch
[exch dup 0 exch 0 exch neg 0 0]makefont
dup setfont
[exch/setfont cvx]cvx bind def
}bind def
/MF{
findfont
[5 2 roll
0 3 1 roll
neg 0 0]makefont
dup setfont
[exch/setfont cvx]cvx bind def
}bind def
/level0 0 def
/RES 0 def
/PL 0 def
/LS 0 def
/MANUAL{
statusdict begin/manualfeed true store end
}bind def
/PLG{
gsave newpath clippath pathbbox grestore
exch pop add exch pop
}bind def
/BP{
/level0 save def
1 setlinecap
1 setlinejoin
DEFS/BPhook known{DEFS begin BPhook end}if
72 RES div dup scale
LS{
90 rotate
}{
0 PL translate
}ifelse
1 -1 scale
}bind def
/EP{
level0 restore
showpage
}def
/DA{
newpath arcn stroke
}bind def
/SN{
transform
.25 sub exch .25 sub exch
round .25 add exch round .25 add exch
itransform
}bind def
/DL{
SN
moveto
SN
lineto stroke
}bind def
/DC{
newpath 0 360 arc closepath
}bind def
/TM matrix def
/DE{
TM currentmatrix pop
translate scale newpath 0 0 .5 0 360 arc closepath
TM setmatrix
}bind def
/RC/rcurveto load def
/RL/rlineto load def
/ST/stroke load def
/MT/moveto load def
/CL/closepath load def
/Fr{
setrgbcolor fill
}bind def
/setcmykcolor where{
pop
/Fk{
setcmykcolor fill
}bind def
}if
/Fg{
setgray fill
}bind def
/FL/fill load def
/LW/setlinewidth load def
/Cr/setrgbcolor load def
/setcmykcolor where{
pop
/Ck/setcmykcolor load def
}if
/Cg/setgray load def
/RE{
findfont
dup maxlength 1 index/FontName known not{1 add}if dict begin
{
1 index/FID ne
2 index/UniqueID ne
and
{def}{pop pop}ifelse
}forall
/Encoding exch def
dup/FontName exch def
currentdict end definefont pop
}bind def
/DEFS 0 def
/EBEGIN{
moveto
DEFS begin
}bind def
/EEND/end load def
/CNT 0 def
/level1 0 def
/PBEGIN{
/level1 save def
translate
div 3 1 roll div exch scale
neg exch neg exch translate
0 setgray
0 setlinecap
1 setlinewidth
0 setlinejoin
10 setmiterlimit
[]0 setdash
/setstrokeadjust where{
pop
false setstrokeadjust
}if
/setoverprint where{
pop
false setoverprint
}if
newpath
/CNT countdictstack def
userdict begin
/showpage{}def
/setpagedevice{}def
mark
}bind def
/PEND{
cleartomark
countdictstack CNT sub{end}repeat
level1 restore
}bind def
end def
/setpacking where{
pop
setpacking
}if
%%EndResource
%%EndProlog
%%BeginSetup
%%BeginFeature: *PageSize Default
<< /PageSize [ 612 792 ] /ImagingBBox null >> setpagedevice
%%EndFeature
%%IncludeResource: font Times-Roman
%%IncludeResource: font Times-Bold
%%IncludeResource: font Times-Italic
grops begin/DEFS 1 dict def DEFS begin/u{.001 mul}bind def end/RES 72
def/PL 792 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron/Zcaron
/scaron/zcaron/Ydieresis/trademark/quotesingle/Euro/.notdef/.notdef
/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
/.notdef/.notdef/space/exclam/quotedbl/numbersign/dollar/percent
/ampersand/quoteright/parenleft/parenright/asterisk/plus/comma/hyphen
/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon
/semicolon/less/equal/greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O
/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright/circumflex
/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y
/z/braceleft/bar/braceright/tilde/.notdef/quotesinglbase/guillemotleft
/guillemotright/bullet/florin/fraction/perthousand/dagger/daggerdbl
/endash/emdash/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/hungarumlaut
/dotaccent/breve/caron/ring/ogonek/quotedblleft/quotedblright/oe/lslash
/quotedblbase/OE/Lslash/.notdef/exclamdown/cent/sterling/currency/yen
/brokenbar/section/dieresis/copyright/ordfeminine/guilsinglleft
/logicalnot/minus/registered/macron/degree/plusminus/twosuperior
/threesuperior/acute/mu/paragraph/periodcentered/cedilla/onesuperior
/ordmasculine/guilsinglright/onequarter/onehalf/threequarters
/questiondown/Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE
/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex
/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis
/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn
/germandbls/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla
/egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis
/eth/ntilde/ograve/oacute/ocircumflex/otilde/odieresis/divide/oslash
/ugrave/uacute/ucircumflex/udieresis/yacute/thorn/ydieresis]def
/Times-Italic@0 ENC0/Times-Italic RE/Times-Bold@0 ENC0/Times-Bold RE
/Times-Roman@0 ENC0/Times-Roman RE
%%EndSetup
%%Page: 1 1
%%BeginPageSetup
BP
%%EndPageSetup
/F0 10/Times-Roman@0 SF(HIST)72 48 Q(OR)-.18 E 124.845(Y\(3\) Library)
-.65 F(Functions Manual)2.5 E(HIST)127.345 E(OR)-.18 E(Y\(3\))-.65 E/F1
10.95/Times-Bold@0 SF -.219(NA)72 84 S(ME).219 E F0
(history \255 GNU History Library)108 96 Q F1(COPYRIGHT)72 112.8 Q F0
(The GNU History Library is Cop)108 124.8 Q
(yright \251 1989-2020 by the Free Softw)-.1 E(are F)-.1 E
(oundation, Inc.)-.15 E F1(DESCRIPTION)72 141.6 Q F0(Man)108 153.6 Q
2.81(yp)-.15 G .31(rograms read input from the user a line at a time.)
-2.81 F .309(The GNU History library is able to k)5.309 F .309
(eep track of)-.1 F .024(those lines, associate arbitrary data with eac\
h line, and utilize information from pre)108 165.6 R .024
(vious lines in composing)-.25 F(ne)108 177.6 Q 2.5(wo)-.25 G(nes.)-2.5
E F1(HIST)72 194.4 Q(OR)-.197 E 2.738(YE)-.383 G(XP)-2.738 E(ANSION)-.81
E F0 .823(The history library supports a history e)108 206.4 R .822
(xpansion feature that is identical to the history e)-.15 F .822
(xpansion in)-.15 F/F2 10/Times-Bold@0 SF(bash.)3.322 E F0
(This section describes what syntax features are a)108 218.4 Q -.25(va)
-.2 G(ilable.).25 E 1.305(History e)108 235.2 R 1.305
(xpansions introduce w)-.15 F 1.306(ords from the history list into the\
input stream, making it easy to repeat)-.1 F .21
(commands, insert the ar)108 247.2 R .21(guments to a pre)-.18 F .209
(vious command into the current input line, or \214x errors in pre)-.25
F(vious)-.25 E(commands quickly)108 259.2 Q(.)-.65 E 1.296(History e)108
276 R 1.297(xpansion is usually performed immediately after a complete \
line is read.)-.15 F 1.297(It tak)6.297 F 1.297(es place in tw)-.1 F(o)
-.1 E 2.855(parts. The)108 288 R .354(\214rst is to determine which lin\
e from the history list to use during substitution.)2.855 F .354
(The second is to)5.354 F .116
(select portions of that line for inclusion into the current one.)108
300 R .117(The line selected from the history is the)5.116 F/F3 10
/Times-Italic@0 SF -.15(ev)2.617 G(ent).15 E F0(,)A .846
(and the portions of that line that are acted upon are)108 312 R F3(wor)
3.346 E(ds)-.37 E F0 5.846(.V)C(arious)-6.956 E F3(modi\214er)3.346 E(s)
-.1 E F0 .846(are a)3.346 F -.25(va)-.2 G .845(ilable to manipulate).25
F .304(the selected w)108 324 R 2.804(ords. The)-.1 F .304(line is brok)
2.804 F .304(en into w)-.1 F .304(ords in the same f)-.1 F .304
(ashion as)-.1 F F2(bash)2.804 E F0 .305(does when reading input, so)
2.804 F .539(that se)108 336 R -.15(ve)-.25 G .539(ral w).15 F .539
(ords that w)-.1 F .539
(ould otherwise be separated are considered one w)-.1 F .538
(ord when surrounded by quotes)-.1 F .307(\(see the description of)108
348 R F2(history_tok)2.807 E(enize\(\))-.1 E F0(belo)2.807 E 2.807
(w\). History)-.25 F -.15(ex)2.807 G .307
(pansions are introduced by the appearance of).15 F .52(the history e)
108 360 R .52(xpansion character)-.15 F 3.02(,w)-.4 G .52(hich is)-3.02
F F2(!)3.853 E F0 .52(by def)3.853 F 3.02(ault. Only)-.1 F .52
(backslash \()3.02 F F2(\\).833 E F0 3.02(\)a).833 G .52
(nd single quotes can quote the)-3.02 F(history e)108 372 Q
(xpansion character)-.15 E(.)-.55 E F2(Ev)87 388.8 Q(ent Designators)-.1
E F0 .204(An e)108 400.8 R -.15(ve)-.25 G .204(nt designator is a refer\
ence to a command line entry in the history list.).15 F .205
(Unless the reference is abso-)5.204 F(lute, e)108 412.8 Q -.15(ve)-.25
G(nts are relati).15 E .3 -.15(ve t)-.25 H 2.5(ot).15 G
(he current position in the history list.)-2.5 E F2(!)108 429.6 Q F0
(Start a history substitution, e)144 429.6 Q(xcept when follo)-.15 E
(wed by a)-.25 E F2(blank)2.5 E F0 2.5(,n)C -.25(ew)-2.5 G
(line, = or \(.).25 E F2(!)108 441.6 Q F3(n)A F0(Refer to command line)
144 441.6 Q F3(n)2.86 E F0(.).24 E F2<21ad>108 453.6 Q F3(n)A F0
(Refer to the current command minus)144 453.6 Q F3(n)2.86 E F0(.).24 E
F2(!!)108 465.6 Q F0(Refer to the pre)144 465.6 Q(vious command.)-.25 E
(This is a synon)5 E(ym for `!\2551'.)-.15 E F2(!)108 477.6 Q F3(string)
A F0 .865(Refer to the most recent command preceding the current positi\
on in the history list starting with)144 477.6 R F3(string)144.34 489.6
Q F0(.).22 E F2(!?)108 501.6 Q F3(string)A F2([?])A F0 1.503(Refer to t\
he most recent command preceding the current position in the history li\
st containing)144 513.6 R F3(string)144.34 525.6 Q F0 5.497(.T).22 G
.497(he trailing)-5.497 F F2(?)2.997 E F0 .497(may be omitted if)2.997 F
F3(string)3.337 E F0 .496(is follo)3.216 F .496(wed immediately by a ne)
-.25 F 2.996(wline. If)-.25 F F3(string)2.996 E F0(is)2.996 E .39(missi\
ng, the string from the most recent search is used; it is an error if t\
here is no pre)144 537.6 R .391(vious search)-.25 F(string.)144 549.6 Q
/F4 12/Times-Bold@0 SF(^)108 566.6 Q F3(string1)-5 I F4(^)5 I F3
(string2)-5 I F4(^)5 I F0 2.599(Quick substitution.)144 573.6 R 2.598
(Repeat the last command, replacing)7.599 F F3(string1)5.438 E F0(with)
5.098 E F3(string2)5.438 E F0 7.598(.E).02 G(qui)-7.598 E -.25(va)-.25 G
2.598(lent to).25 F -.74(``)144 585.6 S(!!:s).74 E/F5 12/Times-Roman@0
SF(^)5 I F3(string1)-5 I F5(^)5 I F3(string2)-5 I F5(^)5 I F0 1.48 -.74
('' \()-5 L(see).74 E F2(Modi\214ers)2.5 E F0(belo)2.5 E(w\).)-.25 E F2
(!#)108 597.6 Q F0(The entire command line typed so f)144 597.6 Q(ar)-.1
E(.)-.55 E F2 -.75(Wo)87 614.4 S(rd Designators).75 E F0 -.8(Wo)108
626.4 S 1.313(rd designators are used to select desired w).8 F 1.314
(ords from the e)-.1 F -.15(ve)-.25 G 3.814(nt. A).15 F F2(:)3.814 E F0
1.314(separates the e)3.814 F -.15(ve)-.25 G 1.314(nt speci\214cation)
.15 F .53(from the w)108 638.4 R .529(ord designator)-.1 F 5.529(.I)-.55
G 3.029(tm)-5.529 G .529(ay be omitted if the w)-3.029 F .529
(ord designator be)-.1 F .529(gins with a)-.15 F F2(^)3.029 E F0(,)A F2
($)3.029 E F0(,)A F2(*)3.029 E F0(,)A F2<ad>3.029 E F0 3.029(,o)C(r)
-3.029 E F2(%)3.029 E F0 5.529(.W)C(ords)-6.329 E .515
(are numbered from the be)108 650.4 R .516
(ginning of the line, with the \214rst w)-.15 F .516
(ord being denoted by 0 \(zero\).)-.1 F -.8(Wo)5.516 G .516(rds are in-)
.8 F(serted into the current line separated by single spaces.)108 662.4
Q F2 2.5(0\()108 679.2 S(zer)-2.5 E(o\))-.18 E F0(The zeroth w)144 691.2
Q 2.5(ord. F)-.1 F(or the shell, this is the command w)-.15 E(ord.)-.1 E
F3(n)108.36 703.2 Q F0(The)144 703.2 Q F3(n)2.5 E F0(th w)A(ord.)-.1 E
F2(^)108 715.2 Q F0(The \214rst ar)144 715.2 Q 2.5(gument. That)-.18 F
(is, w)2.5 E(ord 1.)-.1 E(GNU History 8.1)72 768 Q(2020 July 17)139.005
E(1)203.165 E 0 Cg EP
%%Page: 2 2
%%BeginPageSetup
BP
%%EndPageSetup
/F0 10/Times-Roman@0 SF(HIST)72 48 Q(OR)-.18 E 124.845(Y\(3\) Library)
-.65 F(Functions Manual)2.5 E(HIST)127.345 E(OR)-.18 E(Y\(3\))-.65 E/F1
10/Times-Bold@0 SF($)108 84 Q F0 .064(The last w)144 84 R 2.564
(ord. This)-.1 F .064(is usually the last ar)2.564 F .064(gument, b)-.18
F .064(ut will e)-.2 F .064(xpand to the zeroth w)-.15 F .063
(ord if there is only)-.1 F(one w)144 96 Q(ord in the line.)-.1 E F1(%)
108 108 Q F0 1.419(The \214rst w)144 108 R 1.419
(ord matched by the most recent `?)-.1 F/F2 10/Times-Italic@0 SF(string)
A F0 1.42(?' search, if the search string be)B 1.42(gins with a)-.15 F
(character that is part of a w)144 120 Q(ord.)-.1 E F2(x)108.77 132 Q F1
<ad>A F2(y)A F0 2.5(Ar)144 132 S(ange of w)-2.5 E(ords; `\255)-.1 E F2
(y)A F0 2.5('a)C(bbre)-2.5 E(viates `0\255)-.25 E F2(y)A F0('.)A F1(*)
108 144 Q F0 .316(All of the w)144 144 R .316(ords b)-.1 F .316
(ut the zeroth.)-.2 F .315(This is a synon)5.315 F .315(ym for `)-.15 F
F2(1\255$)A F0 2.815('. It)B .315(is not an error to use)2.815 F F1(*)
2.815 E F0 .315(if there is)2.815 F(just one w)144 156 Q(ord in the e)
-.1 E -.15(ve)-.25 G(nt; the empty string is returned in that case.).15
E F1(x*)108 168 Q F0(Abbre)144 168 Q(viates)-.25 E F2(x\255$)2.5 E F0(.)
A F1<78ad>108 180 Q F0(Abbre)144 180 Q(viates)-.25 E F2(x\255$)2.5 E F0
(lik)2.5 E(e)-.1 E F1(x*)2.5 E F0 2.5(,b)C(ut omits the last w)-2.7 E
2.5(ord. If)-.1 F F1(x)2.5 E F0(is missing, it def)2.5 E(aults to 0.)-.1
E(If a w)108 196.8 Q(ord designator is supplied without an e)-.1 E -.15
(ve)-.25 G(nt speci\214cation, the pre).15 E
(vious command is used as the e)-.25 E -.15(ve)-.25 G(nt.).15 E F1
(Modi\214ers)87 213.6 Q F0 .183(After the optional w)108 225.6 R .183
(ord designator)-.1 F 2.683(,t)-.4 G .184
(here may appear a sequence of one or more of the follo)-2.683 F .184
(wing modi\214ers,)-.25 F(each preceded by a `:'.)108 237.6 Q
(These modify)5 E 2.5(,o)-.65 G 2.5(re)-2.5 G(dit, the w)-2.5 E
(ord or w)-.1 E(ords selected from the history e)-.1 E -.15(ve)-.25 G
(nt.).15 E F1(h)108 254.4 Q F0(Remo)144 254.4 Q .3 -.15(ve a t)-.15 H
(railing \214le name component, lea).15 E(ving only the head.)-.2 E F1
(t)108 266.4 Q F0(Remo)144 266.4 Q .3 -.15(ve a)-.15 H
(ll leading \214le name components, lea).15 E(ving the tail.)-.2 E F1(r)
108 278.4 Q F0(Remo)144 278.4 Q .3 -.15(ve a t)-.15 H(railing suf).15 E
(\214x of the form)-.25 E F2(.xxx)2.5 E F0 2.5(,l)C(ea)-2.5 E
(ving the basename.)-.2 E F1(e)108 290.4 Q F0(Remo)144 290.4 Q .3 -.15
(ve a)-.15 H(ll b).15 E(ut the trailing suf)-.2 E(\214x.)-.25 E F1(p)108
302.4 Q F0(Print the ne)144 302.4 Q 2.5(wc)-.25 G(ommand b)-2.5 E
(ut do not e)-.2 E -.15(xe)-.15 G(cute it.).15 E F1(q)108 314.4 Q F0
(Quote the substituted w)144 314.4 Q
(ords, escaping further substitutions.)-.1 E F1(x)108 326.4 Q F0 .386
(Quote the substituted w)144 326.4 R .386(ords as with)-.1 F F1(q)2.886
E F0 2.886(,b)C .386(ut break into w)-3.086 F .385(ords at)-.1 F F1
(blanks)2.885 E F0 .385(and ne)2.885 F 2.885(wlines. The)-.25 F F1(q)
2.885 E F0(and)2.885 E F1(x)2.885 E F0(modi\214ers are mutually e)144
338.4 Q(xclusi)-.15 E -.15(ve)-.25 G 2.5(;t).15 G
(he last one supplied is used.)-2.5 E F1(s/)108 350.4 Q F2(old)A F1(/)A
F2(ne)A(w)-.15 E F1(/)A F0(Substitute)144 362.4 Q F2(ne)3.328 E(w)-.15 E
F0 .469(for the \214rst occurrence of)3.278 F F2(old)3.199 E F0 .469
(in the e)3.739 F -.15(ve)-.25 G .469(nt line.).15 F(An)5.469 E 2.969
(yc)-.15 G .469(haracter may be used as the)-2.969 F .954
(delimiter in place of /.)144 374.4 R .953
(The \214nal delimiter is optional if it is the last character of the e)
5.953 F -.15(ve)-.25 G .953(nt line.).15 F .131
(The delimiter may be quoted in)144 386.4 R F2(old)2.861 E F0(and)3.401
E F2(ne)2.991 E(w)-.15 E F0 .131(with a single backslash.)2.941 F .131
(If & appears in)5.131 F F2(ne)2.991 E(w)-.15 E F0 2.631(,i).31 G 2.631
(ti)-2.631 G 2.631(sr)-2.631 G(e-)-2.631 E .62(placed by)144 398.4 R F2
(old)3.349 E F0 5.619(.A).77 G .619(single backslash will quote the &.)
-2.5 F(If)5.619 E F2(old)3.349 E F0 .619(is null, it is set to the last)
3.889 F F2(old)3.349 E F0(substi-)3.889 E .486(tuted, or)144 410.4 R
2.986(,i)-.4 G 2.986(fn)-2.986 G 2.986(op)-2.986 G(re)-2.986 E .486
(vious history substitutions took place, the last)-.25 F F2(string)3.326
E F0 .487(in a)3.206 F F1(!?)2.987 E F2(string)A F1([?])A F0 2.987
(search. If)5.487 F F2(ne)144.36 422.4 Q(w)-.15 E F0
(is null, each matching)2.81 E F2(old)2.73 E F0(is deleted.)3.27 E F1(&)
108 434.4 Q F0(Repeat the pre)144 434.4 Q(vious substitution.)-.25 E F1
(g)108 446.4 Q F0 .398(Cause changes to be applied o)144 446.4 R -.15
(ve)-.15 G 2.898(rt).15 G .398(he entire e)-2.898 F -.15(ve)-.25 G .398
(nt line.).15 F .397(This is used in conjunction with `)5.398 F F1(:s)A
F0 2.897('\()C(e.g.,)-2.897 E(`)144 458.4 Q F1(:gs/)A F2(old)A F1(/)A F2
(ne)A(w)-.15 E F1(/)A F0 .35('\) or `)B F1(:&)A F0 2.85('. If)B .35
(used with `)2.85 F F1(:s)A F0 .35(', an)B 2.85(yd)-.15 G .351
(elimiter can be used in place of /, and the \214nal de-)-2.85 F
(limiter is optional if it is the last character of the e)144 470.4 Q
-.15(ve)-.25 G(nt line.).15 E(An)5 E F1(a)2.5 E F0
(may be used as a synon)2.5 E(ym for)-.15 E F1(g)2.5 E F0(.)A F1(G)108
482.4 Q F0(Apply the follo)144 482.4 Q(wing `)-.25 E F1(s)A F0 2.5('o)C
2.5(r`)-2.5 G F1(&)-2.5 E F0 2.5('m)C(odi\214er once to each w)-2.5 E
(ord in the e)-.1 E -.15(ve)-.25 G(nt line.).15 E/F3 10.95/Times-Bold@0
SF(PR)72 499.2 Q(OGRAMMING WITH HIST)-.329 E(OR)-.197 E 2.738(YF)-.383 G
(UNCTIONS)-2.738 E F0(This section describes ho)108 511.2 Q 2.5(wt)-.25
G 2.5(ou)-2.5 G(se the History library in other programs.)-2.5 E F1
(Intr)87 528 Q(oduction to History)-.18 E F0 2.883(Ap)108 540 S .383
(rogrammer using the History library has a)-2.883 F -.25(va)-.2 G .382
(ilable functions for remembering lines on a history list, as-).25 F .77
(sociating arbitrary data with a line, remo)108 552 R .771
(ving lines from the list, searching through the list for a line con-)
-.15 F .303(taining an arbitrary te)108 564 R .303
(xt string, and referencing an)-.15 F 2.803(yl)-.15 G .303
(ine in the list directly)-2.803 F 5.303(.I)-.65 G 2.803(na)-5.303 G
.303(ddition, a history)-2.803 F F2 -.2(ex)2.802 G(pansion).2 E F0
(function is a)108 576 Q -.25(va)-.2 G(ilable which pro).25 E
(vides for a consistent user interf)-.15 E(ace across dif)-.1 E
(ferent programs.)-.25 E .059(The user using programs written with the \
History library has the bene\214t of a consistent user interf)108 592.8
R .059(ace with a)-.1 F .918(set of well-kno)108 604.8 R .917
(wn commands for manipulating the te)-.25 F .917(xt of pre)-.15 F .917
(vious lines and using that te)-.25 F .917(xt in ne)-.15 F 3.417(wc)-.25
G(om-)-3.417 E 4.183(mands. The)108 616.8 R 1.684(basic history manipul\
ation commands are identical to the history substitution pro)4.183 F
1.684(vided by)-.15 F F1(bash)108 628.8 Q F0(.)A 1.154
(The programmer can also use the readline library)108 645.6 R 3.654(,w)
-.65 G 1.153(hich includes some history manipulation by def)-3.654 F
(ault,)-.1 E(and has the added adv)108 657.6 Q
(antage of command line editing.)-.25 E .39(Before declaring an)108
674.4 R 2.89(yf)-.15 G .39(unctions using an)-2.89 F 2.89(yf)-.15 G .39
(unctionality the History library pro)-2.89 F .39
(vides in other code, an appli-)-.15 F .067
(cation writer should include the \214le)108 686.4 R F2(<r)4.233 E
(eadline/history)-.37 E(.h>)-.55 E F0 .067(in an)4.233 F 2.566<798c>-.15
G .066(le that uses the History library')-2.566 F 2.566(sf)-.55 G
(eatures.)-2.566 E .538(It supplies e)108 698.4 R .538
(xtern declarations for all of the library')-.15 F 3.038(sp)-.55 G .538
(ublic functions and v)-3.038 F .539(ariables, and declares all of the)
-.25 F(public data structures.)108 710.4 Q(GNU History 8.1)72 768 Q
(2020 July 17)139.005 E(2)203.165 E 0 Cg EP
%%Page: 3 3
%%BeginPageSetup
BP
%%EndPageSetup
/F0 10/Times-Roman@0 SF(HIST)72 48 Q(OR)-.18 E 124.845(Y\(3\) Library)
-.65 F(Functions Manual)2.5 E(HIST)127.345 E(OR)-.18 E(Y\(3\))-.65 E/F1
10/Times-Bold@0 SF(History Storage)87 84 Q F0
(The history list is an array of history entries.)108 96 Q 2.5(Ah)5 G
(istory entry is declared as follo)-2.5 E(ws:)-.25 E/F2 10
/Times-Italic@0 SF(typedef void *)108 112.8 Q F1(histdata_t;)2.5 E F0
(typedef struct _hist_entry {)108 129.6 Q(char *line;)113 141.6 Q
(char *timestamp;)113 153.6 Q(histdata_t data;)113 165.6 Q 2.5(}H)108
177.6 S(IST_ENTR)-2.5 E -.92(Y;)-.65 G
(The history list itself might therefore be declared as)108 194.4 Q F2
(HIST_ENTR)108 211.2 Q 2.5(Y*)-.18 G(*)-2.5 E F1(the_history_list;)2.5 E
F0(The state of the History library is encapsulated into a single struc\
ture:)108 228 Q(/*)108 244.8 Q 2.5(*As)110.5 256.8 S
(tructure used to pass around the current state of the history)-2.5 E(.)
-.65 E(*/)110.5 268.8 Q(typedef struct _hist_state {)108 280.8 Q
(HIST_ENTR)113 292.8 Q 2.5(Y*)-.65 G
(*entries; /* Pointer to the entries themselv)-2.5 E(es. */)-.15 E
(int of)113 304.8 Q 25(fset; /*)-.25 F
(The location pointer within this array)2.5 E 2.5(.*)-.65 G(/)-2.5 E
(int length;)113 316.8 Q(/* Number of elements within this array)27.5 E
2.5(.*)-.65 G(/)-2.5 E(int size;)113 328.8 Q
(/* Number of slots allocated to this array)32.5 E 2.5(.*)-.65 G(/)-2.5
E(int \215ags;)113 340.8 Q 2.5(}H)108 352.8 S(IST)-2.5 E(OR)-.18 E(Y_ST)
-.65 E -1.11(AT)-.93 G(E;)1.11 E(If the \215ags member includes)108
369.6 Q F1(HS_STIFLED)2.5 E F0 2.5(,t)C(he history has been sti\215ed.)
-2.5 E/F3 10.95/Times-Bold@0 SF(History Functions)72 386.4 Q F0
(This section describes the calling sequence for the v)108 398.4 Q
(arious functions e)-.25 E(xported by the GNU History library)-.15 E(.)
-.65 E F1(Initializing History and State Management)87 415.2 Q F0 1.274
(This section describes functions used to initialize and manage the sta\
te of the History library when you)108 427.2 R -.1(wa)108 439.2 S
(nt to use the history functions in your program.).1 E F2(void)108 463.2
Q F1(using_history)2.5 E F0(\()4.166 E F2(void)A F0(\))1.666 E(Be)108
475.2 Q(gin a session in which the history functions might be used.)-.15
E(This initializes the interacti)5 E .3 -.15(ve v)-.25 H(ariables.)-.1 E
F2(HIST)108 499.2 Q(OR)-.18 E(Y_ST)-.18 E -.37(AT)-.5 G 2.5(E*).37 G F1
(history_get_history_state)A F0(\()4.166 E F2(void)A F0(\))1.666 E
(Return a structure describing the current state of the input history)
108 511.2 Q(.)-.65 E F2(void)108 535.2 Q F1(history_set_history_state)
2.5 E F0(\()4.166 E F2(HIST)A(OR)-.18 E(Y_ST)-.18 E -.37(AT)-.5 G 2.5
(E*).37 G(state)-2.5 E F0(\))1.666 E
(Set the state of the history list according to)108 547.2 Q F2(state)2.5
E F0(.)A F1(History List Management)87 576 Q F0
(These functions manage indi)108 588 Q(vidual entries on the history li\
st, or set parameters managing the list itself.)-.25 E F2(void)108 612 Q
F1(add_history)2.5 E F0(\()4.166 E F2(const c)A(har *string)-.15 E F0
(\))1.666 E(Place)108 624 Q F2(string)3.279 E F0 .779
(at the end of the history list.)3.279 F .779
(The associated data \214eld \(if an)5.779 F .779(y\) is set to)-.15 F
F1(NULL)3.279 E F0 5.779(.I)C 3.279(ft)-5.779 G .78(he maxi-)-3.279 F
.787(mum number of history entries has been set using)108 636 R F1
(sti\215e_history\(\))3.286 E F0 3.286(,a)C .786(nd the ne)-3.286 F
3.286(wn)-.25 G .786(umber of history entries)-3.286 F -.1(wo)108 648 S
(uld e).1 E(xceed that maximum, the oldest history entry is remo)-.15 E
-.15(ve)-.15 G(d.).15 E F2(void)108 672 Q F1(add_history_time)2.5 E F0
(\()4.166 E F2(const c)A(har *string)-.15 E F0(\))1.666 E
(Change the time stamp associated with the most recent history entry to)
108 684 Q F2(string)2.5 E F0(.)A F2(HIST_ENTR)108 708 Q 2.5(Y*)-.18 G F1
-.18(re)C(mo).18 E -.1(ve)-.1 G(_history).1 E F0(\()4.166 E F2(int whic)
A(h)-.15 E F0(\))1.666 E(Remo)108 720 Q .352 -.15(ve h)-.15 H .052
(istory entry at of).15 F(fset)-.25 E F2(whic)2.553 E(h)-.15 E F0 .053
(from the history)2.553 F 5.053(.T)-.65 G .053(he remo)-5.053 F -.15(ve)
-.15 G 2.553(de).15 G .053(lement is returned so you can free the)-2.553
F(GNU History 8.1)72 768 Q(2020 July 17)139.005 E(3)203.165 E 0 Cg EP
%%Page: 4 4
%%BeginPageSetup
BP
%%EndPageSetup
/F0 10/Times-Roman@0 SF(HIST)72 48 Q(OR)-.18 E 124.845(Y\(3\) Library)
-.65 F(Functions Manual)2.5 E(HIST)127.345 E(OR)-.18 E(Y\(3\))-.65 E
(line, data, and containing structure.)108 84 Q/F1 10/Times-Italic@0 SF
(histdata_t)108 108 Q/F2 10/Times-Bold@0 SF(fr)2.5 E(ee_history_entry)
-.18 E F0(\()4.166 E F1(HIST_ENTR)A 2.5(Y*)-.18 G(histent)-2.5 E F0(\))
1.666 E .934(Free the history entry)108 120 R F1(histent)3.433 E F0 .933
(and an)3.433 F 3.433(yh)-.15 G .933(istory library pri)-3.433 F -.25
(va)-.25 G .933(te data associated with it.).25 F .933
(Returns the applica-)5.933 F
(tion-speci\214c data so the caller can dispose of it.)108 132 Q F1
(HIST_ENTR)108 156 Q 2.5(Y*)-.18 G F2 -.18(re)C(place_history_entry).18
E F0(\()4.166 E F1(int whic)A -.834(h, const)-.15 F -.15(ch)2.5 G
(ar *line).15 E 1.666(,h)-.1 G(istdata_t data)-1.666 E F0(\))3.332 E
(Mak)108 168 Q 3.062(et)-.1 G .562(he history entry at of)-3.062 F(fset)
-.25 E F1(whic)3.062 E(h)-.15 E F0(ha)3.062 E -.15(ve)-.2 G F1(line)
3.212 E F0(and)3.062 E F1(data)3.062 E F0 5.563(.T)C .563
(his returns the old entry so the caller can dis-)-5.563 F(pose of an)
108 180 Q 2.5(ya)-.15 G(pplication-speci\214c data.)-2.5 E
(In the case of an in)5 E -.25(va)-.4 G(lid).25 E F1(whic)2.5 E(h)-.15 E
F0 2.5(,a)C F2(NULL)A F0(pointer is returned.)2.5 E F1(void)108 204 Q F2
(clear_history)2.5 E F0(\()4.166 E F1(void)A F0(\))1.666 E
(Clear the history list by deleting all the entries.)108 216 Q F1(void)
108 240 Q F2(sti\215e_history)2.5 E F0(\()4.166 E F1(int max)A F0(\))
1.666 E .38(Sti\215e the history list, remembering only the last)108 252
R F1(max)2.88 E F0 2.88(entries. The)2.88 F .38
(history list will contain only)2.88 F F1(max)2.88 E F0(entries)2.88 E
(at a time.)108 264 Q F1(int)108 288 Q F2(unsti\215e_history)2.5 E F0
(\()4.166 E F1(void)A F0(\))1.666 E .46(Stop sti\215ing the history)108
300 R 5.46(.T)-.65 G .46(his returns the pre)-5.46 F .46
(viously-set maximum number of history entries \(as set by)-.25 F F2
(sti-)2.96 E(\215e_history\(\))108 312 Q F0 2.5(\). history)B -.1(wa)2.5
G 2.5(ss).1 G 2.5(ti\215ed. The)-2.5 F -.25(va)2.5 G(lue is positi).25 E
.3 -.15(ve i)-.25 H 2.5(ft).15 G(he history w)-2.5 E(as sti\215ed, ne)
-.1 E -.05(ga)-.15 G(ti).05 E .3 -.15(ve i)-.25 H 2.5(fi).15 G 2.5(tw)
-2.5 G(asn')-2.6 E(t.)-.18 E F1(int)108 336 Q F2(history_is_sti\215ed)
2.5 E F0(\()4.166 E F1(void)A F0(\))1.666 E
(Returns non-zero if the history is sti\215ed, zero if it is not.)108
348 Q F2(Inf)87 376.8 Q(ormation About the History List)-.25 E F0(These\
functions return information about the entire history list or indi)108
388.8 Q(vidual list entries.)-.25 E F1(HIST_ENTR)108 412.8 Q 2.5(Y*)-.18
G(*)-2.5 E F2(history_list)2.5 E F0(\()4.166 E F1(void)A F0(\))1.666 E
.708(Return a)108 424.8 R F2(NULL)3.208 E F0 .708(terminated array of)
3.208 F F1(HIST_ENTR)3.208 E 3.208(Y*)-.18 G F0 .708
(which is the current input history)B 5.707(.E)-.65 G .707
(lement 0 of this)-5.707 F(list is the be)108 436.8 Q(ginning of time.)
-.15 E(If there is no history)5 E 2.5(,r)-.65 G(eturn)-2.5 E F2(NULL)2.5
E F0(.)A F1(int)108 460.8 Q F2(wher)2.5 E(e_history)-.18 E F0(\()4.166 E
F1(void)A F0(\))1.666 E(Returns the of)108 472.8 Q
(fset of the current history element.)-.25 E F1(HIST_ENTR)108 496.8 Q
2.5(Y*)-.18 G F2(curr)A(ent_history)-.18 E F0(\()4.166 E F1(void)A F0
(\))1.666 E 1.373
(Return the history entry at the current position, as determined by)108
508.8 R F2(wher)3.873 E(e_history\(\))-.18 E F0 6.373(.I)C 3.873(ft)
-6.373 G 1.374(here is no entry)-3.873 F(there, return a)108 520.8 Q F2
(NULL)2.5 E F0(pointer)2.5 E(.)-.55 E F1(HIST_ENTR)108 544.8 Q 2.5(Y*)
-.18 G F2(history_get)A F0(\()4.166 E F1(int of)A(fset)-.18 E F0(\))
1.666 E 1.069(Return the history entry at position)108 556.8 R F1(of)
3.569 E(fset)-.18 E F0 6.069(.T)C 1.069(he range of v)-6.069 F 1.069
(alid v)-.25 F 1.069(alues of)-.25 F F1(of)3.569 E(fset)-.18 E F0 1.068
(starts at)3.569 F F2(history_base)3.568 E F0(and)3.568 E .286(ends at)
108 568.8 R F2(history_length)2.786 E F0 2.786<ad31>2.786 G 5.286(.I)
-2.786 G 2.786(ft)-5.286 G .286(here is no entry there, or if)-2.786 F
F1(of)2.786 E(fset)-.18 E F0 .286(is outside the v)2.786 F .287
(alid range, return a)-.25 F F2(NULL)2.787 E F0(pointer)108 580.8 Q(.)
-.55 E F1(time_t)108 604.8 Q F2(history_get_time)2.5 E F0(\()4.166 E F1
(HIST_ENTR)A 2.5(Y*)-.18 G F0(\))-.834 E(Return the time stamp associat\
ed with the history entry passed as the ar)108 616.8 Q(gument.)-.18 E F1
(int)108 640.8 Q F2(history_total_bytes)2.5 E F0(\()4.166 E F1(void)A F0
(\))1.666 E .392
(Return the number of bytes that the primary history entries are using.)
108 652.8 R .391(This function returns the sum of the)5.392 F
(lengths of all the lines in the history)108 664.8 Q(.)-.65 E F2(Mo)87
693.6 Q(ving Ar)-.1 E(ound the History List)-.18 E F0
(These functions allo)108 705.6 Q 2.5(wt)-.25 G(he current inde)-2.5 E
2.5(xi)-.15 G(nto the history list to be set or changed.)-2.5 E F1(int)
108 729.6 Q F2(history_set_pos)2.5 E F0(\()4.166 E F1(int pos)A F0(\))
1.666 E(GNU History 8.1)72 768 Q(2020 July 17)139.005 E(4)203.165 E 0 Cg
EP
%%Page: 5 5
%%BeginPageSetup
BP
%%EndPageSetup
/F0 10/Times-Roman@0 SF(HIST)72 48 Q(OR)-.18 E 124.845(Y\(3\) Library)
-.65 F(Functions Manual)2.5 E(HIST)127.345 E(OR)-.18 E(Y\(3\))-.65 E .79
(Set the current history of)108 84 R .79(fset to)-.25 F/F1 10
/Times-Italic@0 SF(pos)3.29 E F0 3.29(,a)C 3.29(na)-3.29 G .79
(bsolute inde)-3.29 F 3.29(xi)-.15 G .79(nto the list.)-3.29 F .79
(Returns 1 on success, 0 if)5.79 F F1(pos)3.29 E F0 .79(is less)3.29 F
(than zero or greater than the number of history entries.)108 96 Q F1
(HIST_ENTR)108 120 Q 2.5(Y*)-.18 G/F2 10/Times-Bold@0 SF(pr)A -.15(ev)
-.18 G(ious_history).15 E F0(\()4.166 E F1(void)A F0(\))1.666 E .208
(Back up the current history of)108 132 R .208(fset to the pre)-.25 F
.208(vious history entry)-.25 F 2.707(,a)-.65 G .207
(nd return a pointer to that entry)-2.707 F 5.207(.I)-.65 G 2.707(ft)
-5.207 G .207(here is)-2.707 F(no pre)108 144 Q(vious entry)-.25 E 2.5
(,r)-.65 G(eturn a)-2.5 E F2(NULL)2.5 E F0(pointer)2.5 E(.)-.55 E F1
(HIST_ENTR)108 168 Q 2.5(Y*)-.18 G F2(next_history)A F0(\()4.166 E F1
(void)A F0(\))1.666 E .332(If the current history of)108 180 R .333
(fset refers to a v)-.25 F .333(alid history entry)-.25 F 2.833(,i)-.65
G .333(ncrement the current history of)-2.833 F 2.833(fset. If)-.25 F
.333(the possi-)2.833 F .202(bly-incremented history of)108 192 R .202
(fset refers to a v)-.25 F .202(alid history entry)-.25 F 2.702(,r)-.65
G .202(eturn a pointer to that entry; otherwise, return)-2.702 F(a)108
204 Q F2(NULL)2.5 E F0(pointer)2.5 E(.)-.55 E F2(Sear)87 232.8 Q
(ching the History List)-.18 E F0 .005(These functions allo)108 244.8 R
2.505(ws)-.25 G .006(earching of the history list for entries containin\
g a speci\214c string.)-2.505 F .006(Searching may be)5.006 F 1.452
(performed both forw)108 256.8 R 1.452(ard and backw)-.1 F 1.451
(ard from the current history position.)-.1 F 1.451(The search may be)
6.451 F F1(anc)3.951 E(hor)-.15 E(ed)-.37 E F0(,)A
(meaning that the string must match at the be)108 268.8 Q
(ginning of the history entry)-.15 E(.)-.65 E F1(int)108 292.8 Q F2
(history_sear)2.5 E(ch)-.18 E F0(\()4.166 E F1(const c)A(har *string)
-.15 E 1.666(,i)-.1 G(nt dir)-1.666 E(ection)-.37 E F0(\))1.666 E .155
(Search the history for)108 304.8 R F1(string)2.655 E F0 2.656(,s)C .156
(tarting at the current history of)-2.656 F 2.656(fset. If)-.25 F F1
(dir)2.656 E(ection)-.37 E F0 .156(is less than 0, then the search)2.656
F .802(is through pre)108 316.8 R .802
(vious entries, otherwise through subsequent entries.)-.25 F(If)5.801 E
F1(string)3.301 E F0 .801(is found, then the current his-)3.301 F .064
(tory inde)108 328.8 R 2.564(xi)-.15 G 2.564(ss)-2.564 G .064
(et to that history entry)-2.564 F 2.564(,a)-.65 G .064(nd the v)-2.564
F .064(alue returned is the of)-.25 F .064
(fset in the line of the entry where)-.25 F F1(string)2.565 E F0 -.1(wa)
108 340.8 S 2.5(sf).1 G 2.5(ound. Otherwise,)-2.5 F
(nothing is changed, and a -1 is returned.)2.5 E F1(int)108 364.8 Q F2
(history_sear)2.5 E(ch_pr)-.18 E(e\214x)-.18 E F0(\()4.166 E F1(const c)
A(har *string)-.15 E 1.666(,i)-.1 G(nt dir)-1.666 E(ection)-.37 E F0(\))
1.666 E .684(Search the history for)108 376.8 R F1(string)3.183 E F0
3.183(,s)C .683(tarting at the current history of)-3.183 F 3.183
(fset. The)-.25 F .683(search is anchored: matching lines)3.183 F 1.063
(must be)108 388.8 R 1.063(gin with)-.15 F F1(string)3.563 E F0 6.063
(.I)C(f)-6.063 E F1(dir)3.563 E(ection)-.37 E F0 1.064
(is less than 0, then the search is through pre)3.563 F 1.064
(vious entries, otherwise)-.25 F .34(through subsequent entries.)108
400.8 R(If)5.34 E F1(string)2.84 E F0 .34
(is found, then the current history inde)2.84 F 2.84(xi)-.15 G 2.84(ss)
-2.84 G .34(et to that entry)-2.84 F 2.84(,a)-.65 G .34(nd the re-)-2.84
F(turn v)108 412.8 Q(alue is 0.)-.25 E
(Otherwise, nothing is changed, and a -1 is returned.)5 E F1(int)108
436.8 Q F2(history_sear)2.5 E(ch_pos)-.18 E F0(\()4.166 E F1(const c)A
(har *string)-.15 E 1.666(,i)-.1 G(nt dir)-1.666 E -.834(ection, int)
-.37 F(pos)2.5 E F0(\))3.332 E .603(Search for)108 448.8 R F1(string)
3.103 E F0 .603(in the history list, starting at)3.103 F F1(pos)3.104 E
F0 3.104(,a)C 3.104(na)-3.104 G .604(bsolute inde)-3.104 F 3.104(xi)-.15
G .604(nto the list.)-3.104 F(If)5.604 E F1(dir)3.104 E(ection)-.37 E F0
.604(is ne)3.104 F -.05(ga)-.15 G(ti).05 E -.15(ve)-.25 G(,).15 E .608
(the search proceeds backw)108 460.8 R .608(ard from)-.1 F F1(pos)3.108
E F0 3.108(,o)C .608(therwise forw)-3.108 F 3.108(ard. Returns)-.1 F
.608(the absolute inde)3.108 F 3.108(xo)-.15 G 3.108(ft)-3.108 G .608
(he history ele-)-3.108 F(ment where)108 472.8 Q F1(string)2.5 E F0 -.1
(wa)2.5 G 2.5(sf).1 G(ound, or -1 otherwise.)-2.5 E F2
(Managing the History File)87 501.6 Q F0 .035(The History library can r\
ead the history from and write it to a \214le.)108 513.6 R .036
(This section documents the functions for)5.035 F
(managing a history \214le.)108 525.6 Q F1(int)108 549.6 Q F2 -.18(re)
2.5 G(ad_history).18 E F0(\()4.166 E F1(const c)A(har *\214lename)-.15 E
F0(\))1.666 E .151(Add the contents of)108 561.6 R F1(\214lename)2.651 E
F0 .151(to the history list, a line at a time.)2.651 F(If)5.15 E F1
(\214lename)2.65 E F0(is)2.65 E F2(NULL)2.65 E F0 2.65(,t)C .15
(hen read from)-2.65 F F1(~/.his-)2.65 E(tory)108 573.6 Q F0 5(.R)C
(eturns 0 if successful, or)-5 E F2(err)2.5 E(no)-.15 E F0(if not.)2.5 E
F1(int)108 597.6 Q F2 -.18(re)2.5 G(ad_history_range).18 E F0(\()4.166 E
F1(const c)A(har *\214lename)-.15 E 1.666(,i)-.1 G(nt fr)-1.666 E -.834
(om, int)-.45 F(to)2.5 E F0(\))3.332 E .052(Read a range of lines from)
108 609.6 R F1(\214lename)2.553 E F0 2.553(,a)C .053
(dding them to the history list.)-2.553 F .053(Start reading at line)
5.053 F F1(fr)2.553 E(om)-.45 E F0 .053(and end at)2.553 F F1(to)2.553 E
F0(.)A(If)108 621.6 Q F1(fr)2.889 E(om)-.45 E F0 .389
(is zero, start at the be)2.889 F 2.889(ginning. If)-.15 F F1(to)2.889 E
F0 .389(is less than)2.889 F F1(fr)2.889 E(om)-.45 E F0 2.889(,t)C .388
(hen read until the end of the \214le.)-2.889 F(If)5.388 E F1
(\214lename)2.888 E F0(is)108 633.6 Q F2(NULL)2.5 E F0 2.5(,t)C
(hen read from)-2.5 E F1(~/.history)2.5 E F0 5(.R)C
(eturns 0 if successful, or)-5 E F2(err)2.5 E(no)-.15 E F0(if not.)2.5 E
F1(int)108 657.6 Q F2(write_history)2.5 E F0(\()4.166 E F1(const c)A
(har *\214lename)-.15 E F0(\))1.666 E .961(Write the current history to)
108 669.6 R F1(\214lename)3.461 E F0 3.461(,o)C -.15(ve)-3.611 G
(rwriting).15 E F1(\214lename)3.461 E F0 .961(if necessary)3.461 F 5.961
(.I)-.65 G(f)-5.961 E F1(\214lename)3.462 E F0(is)3.462 E F2(NULL)3.462
E F0 3.462(,t)C .962(hen write)-3.462 F(the history list to)108 681.6 Q
F1(~/.history)2.5 E F0 5(.R)C(eturns 0 on success, or)-5 E F2(err)2.5 E
(no)-.15 E F0(on a read or write error)2.5 E(.)-.55 E F1(int)108 717.6 Q
F2(append_history)2.5 E F0(\()4.166 E F1(int nelements,)A(const c)1.666
E(har *\214lename)-.15 E F0(\))1.666 E .839(Append the last)108 729.6 R
F1(nelements)3.339 E F0 .839(of the history list to)3.339 F F1
(\214lename)3.339 E F0 5.839(.I)C(f)-5.839 E F1(\214lename)3.339 E F0
(is)3.339 E F2(NULL)3.339 E F0 3.339(,t)C .838(hen append to)-3.339 F F1
(~/.history)3.338 E F0(.)A(GNU History 8.1)72 768 Q(2020 July 17)139.005
E(5)203.165 E 0 Cg EP
%%Page: 6 6
%%BeginPageSetup
BP
%%EndPageSetup
/F0 10/Times-Roman@0 SF(HIST)72 48 Q(OR)-.18 E 124.845(Y\(3\) Library)
-.65 F(Functions Manual)2.5 E(HIST)127.345 E(OR)-.18 E(Y\(3\))-.65 E
(Returns 0 on success, or)108 84 Q/F1 10/Times-Bold@0 SF(err)2.5 E(no)
-.15 E F0(on a read or write error)2.5 E(.)-.55 E/F2 10/Times-Italic@0
SF(int)108 108 Q F1(history_truncate_\214le)2.5 E F0(\()4.166 E F2
(const c)A(har *\214lename)-.15 E 1.666(,i)-.1 G(nt nlines)-1.666 E F0
(\))1.666 E -.35(Tr)108 120 S .38(uncate the history \214le).35 F F2
(\214lename)2.88 E F0 2.88(,l)C(ea)-2.88 E .38(ving only the last)-.2 F
F2(nlines)2.881 E F0 2.881(lines. If)2.881 F F2(\214lename)2.881 E F0
(is)2.881 E F1(NULL)2.881 E F0 2.881(,t)C(hen)-2.881 E F2(~/.history)
2.881 E F0(is)2.881 E 2.5(truncated. Returns)108 132 R 2.5(0o)2.5 G 2.5
(ns)-2.5 G(uccess, or)-2.5 E F1(err)2.5 E(no)-.15 E F0(on f)2.5 E
(ailure.)-.1 E F1(History Expansion)87 160.8 Q F0
(These functions implement history e)108 172.8 Q(xpansion.)-.15 E F2
(int)108 196.8 Q F1(history_expand)2.5 E F0(\()4.166 E F2 -.15(ch)C
(ar *string).15 E 1.666(,c)-.1 G(har **output)-1.816 E F0(\))1.666 E
(Expand)108 208.8 Q F2(string)2.5 E F0 2.5(,p)C(lacing the result into)
-2.5 E F2(output)2.5 E F0 2.5(,ap)C(ointer to a string.)-2.5 E(Returns:)
5 E(0)144 220.8 Q .566(If no e)180 220.8 R .566
(xpansions took place \(or)-.15 F 3.065(,i)-.4 G 3.065(ft)-3.065 G .565
(he only change in the te)-3.065 F .565(xt w)-.15 F .565(as the remo)-.1
F -.25(va)-.15 G 3.065(lo).25 G 3.065(fe)-3.065 G(scape)-3.065 E
(characters preceding the history e)180 232.8 Q(xpansion character\);)
-.15 E(1)144 244.8 Q(if e)180 244.8 Q(xpansions did tak)-.15 E 2.5(ep)
-.1 G(lace;)-2.5 E(-1)144 256.8 Q(if there w)180 256.8 Q
(as an error in e)-.1 E(xpansion;)-.15 E(2)144 268.8 Q
(if the returned line should be displayed, b)180 268.8 Q(ut not e)-.2 E
-.15(xe)-.15 G(cuted, as with the).15 E F1(:p)2.5 E F0(modi\214er)2.5 E
(.)-.55 E(If an error occurred in e)108 280.8 Q(xpansion, then)-.15 E F2
(output)2.5 E F0(contains a descripti)2.5 E .3 -.15(ve e)-.25 H
(rror message.).15 E F2 -.15(ch)108 304.8 S(ar *).15 E F1(get_history_e)
2.5 E -.1(ve)-.15 G(nt).1 E F0(\()4.166 E F2(const c)A(har *string)-.15
E 1.666(,i)-.1 G(nt *cinde)-1.666 E -.834(x, int)-.2 F(qc)2.5 E(har)-.15
E F0(\))3.332 E .262(Returns the te)108 316.8 R .262
(xt of the history e)-.15 F -.15(ve)-.25 G .262(nt be).15 F .263
(ginning at)-.15 F F2(string)2.763 E F0(+)2.763 E F2(*cinde)2.763 E(x)
-.2 E F0(.)A F2(*cinde)5.263 E(x)-.2 E F0 .263
(is modi\214ed to point to after the)2.763 F -2.15 -.25(ev e)108 328.8 T
.71(nt speci\214er).25 F 5.71(.A)-.55 G 3.21(tf)-5.71 G .71
(unction entry)-3.21 F(,)-.65 E F2(cinde)3.21 E(x)-.2 E F0 .709
(points to the inde)3.21 F 3.209(xi)-.15 G(nto)-3.209 E F2(string)3.209
E F0 .709(where the history e)3.209 F -.15(ve)-.25 G .709
(nt speci\214ca-).15 F .527(tion be)108 340.8 R(gins.)-.15 E F2(qc)5.527
E(har)-.15 E F0 .527(is a character that is allo)3.027 F .527
(wed to end the e)-.25 F -.15(ve)-.25 G .528
(nt speci\214cation in addition to the `).15 F(`normal')-.74 E(')-.74 E
(terminating characters.)108 352.8 Q F2 -.15(ch)108 376.8 S(ar **).15 E
F1(history_tok)2.5 E(enize)-.1 E F0(\()4.166 E F2(const c)A(har *string)
-.15 E F0(\))1.666 E .239(Return an array of tok)108 388.8 R .239
(ens parsed out of)-.1 F F2(string)2.739 E F0 2.739(,m)C .238
(uch as the shell might.)-2.739 F .238(The tok)5.238 F .238
(ens are split on the charac-)-.1 F(ters in the)108 400.8 Q F1
(history_w)2.5 E(ord_delimiters)-.1 E F0 -.25(va)2.5 G
(riable, and shell quoting con).25 E -.15(ve)-.4 G(ntions are obe).15 E
(yed.)-.15 E F2 -.15(ch)108 424.8 S(ar *).15 E F1(history_ar)2.5 E
(g_extract)-.1 E F0(\()4.166 E F2(int \214r)A -.834(st, int)-.1 F -.834
(last, const)2.5 F -.15(ch)2.5 G(ar *string).15 E F0(\))3.332 E .025
(Extract a string se)108 436.8 R .025(gment consisting of the)-.15 F F2
<8c72>2.526 E(st)-.1 E F0(through)2.526 E F2(last)2.526 E F0(ar)2.526 E
.026(guments present in)-.18 F F2(string)2.526 E F0 5.026(.A)C -.18(rg)
-5.026 G .026(uments are split).18 F(using)108 448.8 Q F1(history_tok)
2.5 E(enize\(\))-.1 E F0(.)A F1(History V)87 477.6 Q(ariables)-.92 E F0
(This section describes the e)108 489.6 Q(xternally-visible v)-.15 E
(ariables e)-.25 E(xported by the GNU History Library)-.15 E(.)-.65 E F2
(int)108 513.6 Q F1(history_base)2.5 E F0(The logical of)108 525.6 Q
(fset of the \214rst entry in the history list.)-.25 E F2(int)108 549.6
Q F1(history_length)2.5 E F0
(The number of entries currently stored in the history list.)108 561.6 Q
F2(int)108 585.6 Q F1(history_max_entries)2.5 E F0
(The maximum number of history entries.)108 597.6 Q
(This must be changed using)5 E F1(sti\215e_history\(\))2.5 E F0(.)A F2
(int)108 621.6 Q F1(history_write_timestamps)2.5 E F0 .484
(If non-zero, timestamps are written to the history \214le, so the)108
633.6 R 2.983(yc)-.15 G .483(an be preserv)-2.983 F .483
(ed between sessions.)-.15 F .483(The de-)5.483 F -.1(fa)108 645.6 S
.994(ult v).1 F .994(alue is 0, meaning that timestamps are not sa)-.25
F -.15(ve)-.2 G 3.494(d. The).15 F .994
(current timestamp format uses the v)3.494 F .995(alue of)-.25 F F2
(history_comment_c)108 657.6 Q(har)-.15 E F0 .051
(to delimit timestamp entries in the history \214le.)2.552 F .051
(If that v)5.051 F .051(ariable does not ha)-.25 F .351 -.15(ve a v)-.2
H(alue)-.1 E(\(the def)108 669.6 Q
(ault\), timestamps will not be written.)-.1 E F2 -.15(ch)108 693.6 S
(ar).15 E F1(history_expansion_char)2.5 E F0
(The character that introduces a history e)108 705.6 Q -.15(ve)-.25 G
2.5(nt. The).15 F(def)2.5 E(ault is)-.1 E F1(!)2.5 E F0 5(.S)C
(etting this to 0 inhibits history e)-5 E(xpansion.)-.15 E F2 -.15(ch)
108 729.6 S(ar).15 E F1(history_subst_char)2.5 E F0(GNU History 8.1)72
768 Q(2020 July 17)139.005 E(6)203.165 E 0 Cg EP
%%Page: 7 7
%%BeginPageSetup
BP
%%EndPageSetup
/F0 10/Times-Roman@0 SF(HIST)72 48 Q(OR)-.18 E 124.845(Y\(3\) Library)
-.65 F(Functions Manual)2.5 E(HIST)127.345 E(OR)-.18 E(Y\(3\))-.65 E
(The character that in)108 84 Q -.2(vo)-.4 G -.1(ke).2 G 2.5(sw).1 G
(ord substitution if found at the start of a line.)-2.6 E(The def)5 E
(ault is)-.1 E/F1 10/Times-Bold@0 SF(^)2.5 E F0(.)A/F2 10/Times-Italic@0
SF -.15(ch)108 108 S(ar).15 E F1(history_comment_char)2.5 E F0 .116
(During tok)108 120 R .117
(enization, if this character is seen as the \214rst character of a w)
-.1 F .117(ord, then it and all subsequent char)-.1 F(-)-.2 E .277
(acters up to a ne)108 132 R .276
(wline are ignored, suppressing history e)-.25 F .276
(xpansion for the remainder of the line.)-.15 F .276(This is dis-)5.276
F(abled by def)108 144 Q(ault.)-.1 E F2 -.15(ch)108 168 S(ar *).15 E F1
(history_w)2.5 E(ord_delimiters)-.1 E F0
(The characters that separate tok)108 180 Q(ens for)-.1 E F1
(history_tok)2.5 E(enize\(\))-.1 E F0 5(.T)C(he def)-5 E(ault v)-.1 E
(alue is)-.25 E F1 2.5("\\)2.5 G(t\\n\(\)<>;&|")-2.5 E F0(.)A F2 -.15
(ch)108 204 S(ar *).15 E F1(history_no_expand_chars)2.5 E F0 2.054
(The list of characters which inhibit history e)108 216 R 2.054
(xpansion if found immediately follo)-.15 F(wing)-.25 E F1
(history_expan-)4.555 E(sion_char)108 228 Q F0 5(.T)C(he def)-5 E
(ault is space, tab, ne)-.1 E(wline,)-.25 E F1(\\r)2.5 E F0 2.5(,a)C(nd)
-2.5 E F1(=)2.5 E F0(.)A F2 -.15(ch)108 252 S(ar *).15 E F1
(history_sear)2.5 E(ch_delimiter_chars)-.18 E F0 .401(The list of addit\
ional characters which can delimit a history search string, in addition\
to space, tab,)108 264 R F2(:)2.901 E F0(and)2.901 E F2(?)2.901 E F0
(in the case of a substring search.)108 276 Q(The def)5 E(ault is empty)
-.1 E(.)-.65 E F2(int)108 300 Q F1(history_quotes_inhibit_expansion)2.5
E F0 .86(If non-zero, double-quoted w)108 312 R .861
(ords are not scanned for the history e)-.1 F .861
(xpansion character or the history com-)-.15 F(ment character)108 324 Q
5(.T)-.55 G(he def)-5 E(ault v)-.1 E(alue is 0.)-.25 E F2(rl_lineb)108
348 Q(uf_func_t *)-.2 E F1(history_inhibit_expansion_function)2.5 E F0
.348(This should be set to the address of a function that tak)108 360 R
.348(es tw)-.1 F 2.848(oa)-.1 G -.18(rg)-2.848 G .347(uments: a).18 F F1
.347(char *)2.847 F F0(\()2.847 E F2(string)A F0 2.847(\)a)C .347(nd an)
-2.847 F F1(int)2.847 E F0(inde)2.847 E(x)-.15 E .227
(into that string \()108 372 R F2(i)A F0 2.727(\). It)B .227
(should return a non-zero v)2.727 F .227(alue if the history e)-.25 F
.227(xpansion starting at)-.15 F F2(string[i])2.728 E F0 .228
(should not)2.728 F .019(be performed; zero if the e)108 384 R .019
(xpansion should be done.)-.15 F .019
(It is intended for use by applications lik)5.019 F(e)-.1 E F1(bash)
2.519 E F0 .018(that use)2.519 F(the history e)108 396 Q
(xpansion character for additional purposes.)-.15 E(By def)5 E
(ault, this v)-.1 E(ariable is set to)-.25 E F1(NULL)2.5 E F0(.)A/F3
10.95/Times-Bold@0 SF(FILES)72 412.8 Q F2(~/.history)109.666 424.8 Q F0
(Def)144 436.8 Q(ault \214lename for reading and writing sa)-.1 E -.15
(ve)-.2 G 2.5(dh).15 G(istory)-2.5 E F3(SEE ALSO)72 453.6 Q F2
(The Gnu Readline Libr)108 465.6 Q(ary)-.15 E F0 2.5(,B)C(rian F)-2.5 E
(ox and Chet Rame)-.15 E(y)-.15 E F2(The Gnu History Libr)108 477.6 Q
(ary)-.15 E F0 2.5(,B)C(rian F)-2.5 E(ox and Chet Rame)-.15 E(y)-.15 E
F2(bash)108 489.6 Q F0(\(1\))A F2 -.37(re)108 501.6 S(adline).37 E F0
(\(3\))A F3 -.548(AU)72 518.4 S(THORS).548 E F0(Brian F)108 530.4 Q
(ox, Free Softw)-.15 E(are F)-.1 E(oundation)-.15 E(bfox@gnu.or)108
542.4 Q(g)-.18 E(Chet Rame)108 559.2 Q 1.3 -.65(y, C)-.15 H(ase W).65 E
(estern Reserv)-.8 E 2.5(eU)-.15 G(ni)-2.5 E -.15(ve)-.25 G(rsity).15 E
(chet.rame)108 571.2 Q(y@case.edu)-.15 E F3 -.11(BU)72 588 S 2.738(GR)
.11 G(EPOR)-2.738 E(TS)-.438 E F0 .16(If you \214nd a b)108 600 R .16
(ug in the)-.2 F F1(history)2.66 E F0(library)2.66 E 2.66(,y)-.65 G .16
(ou should report it.)-2.66 F .16(But \214rst, you should mak)5.16 F
2.66(es)-.1 G .16(ure that it really is)-2.66 F 2.5(ab)108 612 S
(ug, and that it appears in the latest v)-2.7 E(ersion of the)-.15 E F1
(history)2.5 E F0(library that you ha)2.5 E -.15(ve)-.2 G(.).15 E .705
(Once you ha)108 628.8 R 1.005 -.15(ve d)-.2 H .705(etermined that a b)
.15 F .704(ug actually e)-.2 F .704(xists, mail a b)-.15 F .704
(ug report to)-.2 F F2 -.2(bu)3.204 G(g\255r).2 E(eadline)-.37 E F0(@)A
F2(gnu.or)A(g)-.37 E F0 5.704(.I)C 3.204(fy)-5.704 G(ou)-3.204 E(ha)108
640.8 Q 1.809 -.15(ve a \214)-.2 H 1.509
(x, you are welcome to mail that as well!).15 F 1.51
(Suggestions and `philosophical' b)6.51 F 1.51(ug reports may be)-.2 F
(mailed to)108 652.8 Q F2 -.2(bu)2.5 G(g-r).2 E(eadline)-.37 E F0(@)A F2
(gnu.or)A(g)-.37 E F0(or posted to the Usenet ne)2.5 E(wsgroup)-.25 E F1
(gnu.bash.b)2.5 E(ug)-.2 E F0(.)A(Comments and b)108 669.6 Q
(ug reports concerning this manual page should be directed to)-.2 E F2
-.15(ch)2.5 G(et.r).15 E(ame)-.15 E(y@case)-.3 E(.edu)-.15 E F0(.).25 E
(GNU History 8.1)72 768 Q(2020 July 17)139.005 E(7)203.165 E 0 Cg EP
%%Trailer
end
%%EOF

602
doc/hstech.texi Normal file
View file

@ -0,0 +1,602 @@
@ignore
This file documents the user interface to the GNU History library.
Copyright (C) 1988-2022 Free Software Foundation, Inc.
Authored by Brian Fox and Chet Ramey.
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 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).
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided also that the
GNU Copyright statement is available to the distributee, and provided that
the entire resulting derived work is distributed under the terms of a
permission notice identical to this one.
Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions.
@end ignore
@node Programming with GNU History
@chapter Programming with GNU History
This chapter describes how to interface programs that you write
with the @sc{gnu} History Library.
It should be considered a technical guide.
For information on the interactive use of @sc{gnu} History, @pxref{Using
History Interactively}.
@menu
* Introduction to History:: What is the GNU History library for?
* History Storage:: How information is stored.
* History Functions:: Functions that you can use.
* History Variables:: Variables that control behaviour.
* History Programming Example:: Example of using the GNU History Library.
@end menu
@node Introduction to History
@section Introduction to History
Many programs read input from the user a line at a time. The @sc{gnu}
History library is able to keep track of those lines, associate arbitrary
data with each line, and utilize information from previous lines in
composing new ones.
A programmer using the History library has available functions
for remembering lines on a history list, associating arbitrary data
with a line, removing lines from the list, searching through the list
for a line containing an arbitrary text string, and referencing any line
in the list directly. In addition, a history @dfn{expansion} function
is available which provides for a consistent user interface across
different programs.
The user using programs written with the History library has the
benefit of a consistent user interface with a set of well-known
commands for manipulating the text of previous lines and using that text
in new commands. The basic history manipulation commands are similar to
the history substitution provided by @code{csh}.
The programmer can also use the Readline library, which
includes some history manipulation by default, and has the added
advantage of command line editing.
Before declaring any functions using any functionality the History
library provides in other code, an application writer should include
the file @code{<readline/history.h>} in any file that uses the
History library's features. It supplies extern declarations for all
of the library's public functions and variables, and declares all of
the public data structures.
@node History Storage
@section History Storage
The history list is an array of history entries. A history entry is
declared as follows:
@example
typedef void *histdata_t;
typedef struct _hist_entry @{
char *line;
char *timestamp;
histdata_t data;
@} HIST_ENTRY;
@end example
The history list itself might therefore be declared as
@example
HIST_ENTRY **the_history_list;
@end example
The state of the History library is encapsulated into a single structure:
@example
/*
* A structure used to pass around the current state of the history.
*/
typedef struct _hist_state @{
HIST_ENTRY **entries; /* Pointer to the entries themselves. */
int offset; /* The location pointer within this array. */
int length; /* Number of elements within this array. */
int size; /* Number of slots allocated to this array. */
int flags;
@} HISTORY_STATE;
@end example
If the flags member includes @code{HS_STIFLED}, the history has been
stifled.
@node History Functions
@section History Functions
This section describes the calling sequence for the various functions
exported by the @sc{gnu} History library.
@menu
* Initializing History and State Management:: Functions to call when you
want to use history in a
program.
* History List Management:: Functions used to manage the list
of history entries.
* Information About the History List:: Functions returning information about
the history list.
* Moving Around the History List:: Functions used to change the position
in the history list.
* Searching the History List:: Functions to search the history list
for entries containing a string.
* Managing the History File:: Functions that read and write a file
containing the history list.
* History Expansion:: Functions to perform csh-like history
expansion.
@end menu
@node Initializing History and State Management
@subsection Initializing History and State Management
This section describes functions used to initialize and manage
the state of the History library when you want to use the history
functions in your program.
@deftypefun void using_history (void)
Begin a session in which the history functions might be used. This
initializes the interactive variables.
@end deftypefun
@deftypefun {HISTORY_STATE *} history_get_history_state (void)
Return a structure describing the current state of the input history.
@end deftypefun
@deftypefun void history_set_history_state (HISTORY_STATE *state)
Set the state of the history list according to @var{state}.
@end deftypefun
@node History List Management
@subsection History List Management
These functions manage individual entries on the history list, or set
parameters managing the list itself.
@deftypefun void add_history (const char *string)
Place @var{string} at the end of the history list. The associated data
field (if any) is set to @code{NULL}.
If the maximum number of history entries has been set using
@code{stifle_history()}, and the new number of history entries would exceed
that maximum, the oldest history entry is removed.
@end deftypefun
@deftypefun void add_history_time (const char *string)
Change the time stamp associated with the most recent history entry to
@var{string}.
@end deftypefun
@deftypefun {HIST_ENTRY *} remove_history (int which)
Remove history entry at offset @var{which} from the history. The
removed element is returned so you can free the line, data,
and containing structure.
@end deftypefun
@deftypefun {histdata_t} free_history_entry (HIST_ENTRY *histent)
Free the history entry @var{histent} and any history library private
data associated with it. Returns the application-specific data
so the caller can dispose of it.
@end deftypefun
@deftypefun {HIST_ENTRY *} replace_history_entry (int which, const char *line, histdata_t data)
Make the history entry at offset @var{which} have @var{line} and @var{data}.
This returns the old entry so the caller can dispose of any
application-specific data. In the case
of an invalid @var{which}, a @code{NULL} pointer is returned.
@end deftypefun
@deftypefun void clear_history (void)
Clear the history list by deleting all the entries.
@end deftypefun
@deftypefun void stifle_history (int max)
Stifle the history list, remembering only the last @var{max} entries.
The history list will contain only @var{max} entries at a time.
@end deftypefun
@deftypefun int unstifle_history (void)
Stop stifling the history. This returns the previously-set
maximum number of history entries (as set by @code{stifle_history()}).
The value is positive if the history was
stifled, negative if it wasn't.
@end deftypefun
@deftypefun int history_is_stifled (void)
Returns non-zero if the history is stifled, zero if it is not.
@end deftypefun
@node Information About the History List
@subsection Information About the History List
These functions return information about the entire history list or
individual list entries.
@deftypefun {HIST_ENTRY **} history_list (void)
Return a @code{NULL} terminated array of @code{HIST_ENTRY *} which is the
current input history. Element 0 of this list is the beginning of time.
If there is no history, return @code{NULL}.
@end deftypefun
@deftypefun int where_history (void)
Returns the offset of the current history element.
@end deftypefun
@deftypefun {HIST_ENTRY *} current_history (void)
Return the history entry at the current position, as determined by
@code{where_history()}. If there is no entry there, return a @code{NULL}
pointer.
@end deftypefun
@deftypefun {HIST_ENTRY *} history_get (int offset)
Return the history entry at position @var{offset}.
The range of valid
values of @var{offset} starts at @code{history_base} and ends at
@var{history_length} - 1 (@pxref{History Variables}).
If there is no entry there, or if @var{offset} is outside the valid
range, return a @code{NULL} pointer.
@end deftypefun
@deftypefun time_t history_get_time (HIST_ENTRY *entry)
Return the time stamp associated with the history entry @var{entry}.
If the timestamp is missing or invalid, return 0.
@end deftypefun
@deftypefun int history_total_bytes (void)
Return the number of bytes that the primary history entries are using.
This function returns the sum of the lengths of all the lines in the
history.
@end deftypefun
@node Moving Around the History List
@subsection Moving Around the History List
These functions allow the current index into the history list to be
set or changed.
@deftypefun int history_set_pos (int pos)
Set the current history offset to @var{pos}, an absolute index
into the list.
Returns 1 on success, 0 if @var{pos} is less than zero or greater
than the number of history entries.
@end deftypefun
@deftypefun {HIST_ENTRY *} previous_history (void)
Back up the current history offset to the previous history entry, and
return a pointer to that entry. If there is no previous entry, return
a @code{NULL} pointer.
@end deftypefun
@deftypefun {HIST_ENTRY *} next_history (void)
If the current history offset refers to a valid history entry,
increment the current history offset.
If the possibly-incremented history offset refers to a valid history
entry, return a pointer to that entry;
otherwise, return a @code{BNULL} pointer.
@end deftypefun
@node Searching the History List
@subsection Searching the History List
@cindex History Searching
These functions allow searching of the history list for entries containing
a specific string. Searching may be performed both forward and backward
from the current history position. The search may be @dfn{anchored},
meaning that the string must match at the beginning of the history entry.
@cindex anchored search
@deftypefun int history_search (const char *string, int direction)
Search the history for @var{string}, starting at the current history offset.
If @var{direction} is less than 0, then the search is through
previous entries, otherwise through subsequent entries.
If @var{string} is found, then
the current history index is set to that history entry, and the value
returned is the offset in the line of the entry where
@var{string} was found. Otherwise, nothing is changed, and a -1 is
returned.
@end deftypefun
@deftypefun int history_search_prefix (const char *string, int direction)
Search the history for @var{string}, starting at the current history
offset. The search is anchored: matching lines must begin with
@var{string}. If @var{direction} is less than 0, then the search is
through previous entries, otherwise through subsequent entries.
If @var{string} is found, then the
current history index is set to that entry, and the return value is 0.
Otherwise, nothing is changed, and a -1 is returned.
@end deftypefun
@deftypefun int history_search_pos (const char *string, int direction, int pos)
Search for @var{string} in the history list, starting at @var{pos}, an
absolute index into the list. If @var{direction} is negative, the search
proceeds backward from @var{pos}, otherwise forward. Returns the absolute
index of the history element where @var{string} was found, or -1 otherwise.
@end deftypefun
@node Managing the History File
@subsection Managing the History File
The History library can read the history from and write it to a file.
This section documents the functions for managing a history file.
@deftypefun int read_history (const char *filename)
Add the contents of @var{filename} to the history list, a line at a time.
If @var{filename} is @code{NULL}, then read from @file{~/.history}.
Returns 0 if successful, or @code{errno} if not.
@end deftypefun
@deftypefun int read_history_range (const char *filename, int from, int to)
Read a range of lines from @var{filename}, adding them to the history list.
Start reading at line @var{from} and end at @var{to}.
If @var{from} is zero, start at the beginning. If @var{to} is less than
@var{from}, then read until the end of the file. If @var{filename} is
@code{NULL}, then read from @file{~/.history}. Returns 0 if successful,
or @code{errno} if not.
@end deftypefun
@deftypefun int write_history (const char *filename)
Write the current history to @var{filename}, overwriting @var{filename}
if necessary.
If @var{filename} is @code{NULL}, then write the history list to
@file{~/.history}.
Returns 0 on success, or @code{errno} on a read or write error.
@end deftypefun
@deftypefun int append_history (int nelements, const char *filename)
Append the last @var{nelements} of the history list to @var{filename}.
If @var{filename} is @code{NULL}, then append to @file{~/.history}.
Returns 0 on success, or @code{errno} on a read or write error.
@end deftypefun
@deftypefun int history_truncate_file (const char *filename, int nlines)
Truncate the history file @var{filename}, leaving only the last
@var{nlines} lines.
If @var{filename} is @code{NULL}, then @file{~/.history} is truncated.
Returns 0 on success, or @code{errno} on failure.
@end deftypefun
@node History Expansion
@subsection History Expansion
These functions implement history expansion.
@deftypefun int history_expand (char *string, char **output)
Expand @var{string}, placing the result into @var{output}, a pointer
to a string (@pxref{History Interaction}). Returns:
@table @code
@item 0
If no expansions took place (or, if the only change in
the text was the removal of escape characters preceding the history expansion
character);
@item 1
if expansions did take place;
@item -1
if there was an error in expansion;
@item 2
if the returned line should be displayed, but not executed,
as with the @code{:p} modifier (@pxref{Modifiers}).
@end table
If an error occurred in expansion, then @var{output} contains a descriptive
error message.
@end deftypefun
@deftypefun {char *} get_history_event (const char *string, int *cindex, int qchar)
Returns the text of the history event beginning at @var{string} +
@var{*cindex}. @var{*cindex} is modified to point to after the event
specifier. At function entry, @var{cindex} points to the index into
@var{string} where the history event specification begins. @var{qchar}
is a character that is allowed to end the event specification in addition
to the ``normal'' terminating characters.
@end deftypefun
@deftypefun {char **} history_tokenize (const char *string)
Return an array of tokens parsed out of @var{string}, much as the
shell might. The tokens are split on the characters in the
@var{history_word_delimiters} variable,
and shell quoting conventions are obeyed as described below.
@end deftypefun
@deftypefun {char *} history_arg_extract (int first, int last, const char *string)
Extract a string segment consisting of the @var{first} through @var{last}
arguments present in @var{string}. Arguments are split using
@code{history_tokenize}.
@end deftypefun
@node History Variables
@section History Variables
This section describes the externally-visible variables exported by
the @sc{gnu} History Library.
@deftypevar int history_base
The logical offset of the first entry in the history list.
@end deftypevar
@deftypevar int history_length
The number of entries currently stored in the history list.
@end deftypevar
@deftypevar int history_max_entries
The maximum number of history entries. This must be changed using
@code{stifle_history()}.
@end deftypevar
@deftypevar int history_write_timestamps
If non-zero, timestamps are written to the history file, so they can be
preserved between sessions. The default value is 0, meaning that
timestamps are not saved.
The current timestamp format uses the value of @var{history_comment_char}
to delimit timestamp entries in the history file. If that variable does
not have a value (the default), timestamps will not be written.
@end deftypevar
@deftypevar char history_expansion_char
The character that introduces a history event. The default is @samp{!}.
Setting this to 0 inhibits history expansion.
@end deftypevar
@deftypevar char history_subst_char
The character that invokes word substitution if found at the start of
a line. The default is @samp{^}.
@end deftypevar
@deftypevar char history_comment_char
During tokenization, if this character is seen as the first character
of a word, then it and all subsequent characters up to a newline are
ignored, suppressing history expansion for the remainder of the line.
This is disabled by default.
@end deftypevar
@deftypevar {char *} history_word_delimiters
The characters that separate tokens for @code{history_tokenize()}.
The default value is @code{" \t\n()<>;&|"}.
@end deftypevar
@deftypevar {char *} history_search_delimiter_chars
The list of additional characters which can delimit a history search
string, in addition to space, TAB, @samp{:} and @samp{?} in the case of
a substring search. The default is empty.
@end deftypevar
@deftypevar {char *} history_no_expand_chars
The list of characters which inhibit history expansion if found immediately
following @var{history_expansion_char}. The default is space, tab, newline,
carriage return, and @samp{=}.
@end deftypevar
@deftypevar int history_quotes_inhibit_expansion
If non-zero, the history expansion code implements shell-like quoting:
single-quoted words are not scanned for the history expansion
character or the history comment character, and double-quoted words may
have history expansion performed, since single quotes are not special
within double quotes.
The default value is 0.
@end deftypevar
@deftypevar int history_quoting_state
An application may set this variable to indicate that the current line
being expanded is subject to existing quoting. If set to @samp{'}, the
history expansion function will assume that the line is single-quoted and
inhibit expansion until it reads an unquoted closing single quote; if set
to @samp{"}, history expansion will assume the line is double quoted until
it reads an unquoted closing double quote. If set to zero, the default,
the history expansion function will assume the line is not quoted and
treat quote characters within the line as described above.
This is only effective if @var{history_quotes_inhibit_expansion} is set.
@end deftypevar
@deftypevar {rl_linebuf_func_t *} history_inhibit_expansion_function
This should be set to the address of a function that takes two arguments:
a @code{char *} (@var{string})
and an @code{int} index into that string (@var{i}).
It should return a non-zero value if the history expansion starting at
@var{string[i]} should not be performed; zero if the expansion should
be done.
It is intended for use by applications like Bash that use the history
expansion character for additional purposes.
By default, this variable is set to @code{NULL}.
@end deftypevar
@node History Programming Example
@section History Programming Example
The following program demonstrates simple use of the @sc{gnu} History Library.
@smallexample
#include <stdio.h>
#include <readline/history.h>
main (argc, argv)
int argc;
char **argv;
@{
char line[1024], *t;
int len, done = 0;
line[0] = 0;
using_history ();
while (!done)
@{
printf ("history$ ");
fflush (stdout);
t = fgets (line, sizeof (line) - 1, stdin);
if (t && *t)
@{
len = strlen (t);
if (t[len - 1] == '\n')
t[len - 1] = '\0';
@}
if (!t)
strcpy (line, "quit");
if (line[0])
@{
char *expansion;
int result;
result = history_expand (line, &expansion);
if (result)
fprintf (stderr, "%s\n", expansion);
if (result < 0 || result == 2)
@{
free (expansion);
continue;
@}
add_history (expansion);
strncpy (line, expansion, sizeof (line) - 1);
free (expansion);
@}
if (strcmp (line, "quit") == 0)
done = 1;
else if (strcmp (line, "save") == 0)
write_history ("history_file");
else if (strcmp (line, "read") == 0)
read_history ("history_file");
else if (strcmp (line, "list") == 0)
@{
register HIST_ENTRY **the_list;
register int i;
the_list = history_list ();
if (the_list)
for (i = 0; the_list[i]; i++)
printf ("%d: %s\n", i + history_base, the_list[i]->line);
@}
else if (strncmp (line, "delete", 6) == 0)
@{
int which;
if ((sscanf (line + 6, "%d", &which)) == 1)
@{
HIST_ENTRY *entry = remove_history (which);
if (!entry)
fprintf (stderr, "No such entry %d\n", which);
else
@{
free (entry->line);
free (entry);
@}
@}
else
@{
fprintf (stderr, "non-numeric arg given to `delete'\n");
@}
@}
@}
@}
@end smallexample

533
doc/hsuser.texi Normal file
View file

@ -0,0 +1,533 @@
@ignore
This file documents the user interface to the GNU History library.
Copyright (C) 1988--2022 Free Software Foundation, Inc.
Authored by Brian Fox and Chet Ramey.
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 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).
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided also that the
GNU Copyright statement is available to the distributee, and provided that
the entire resulting derived work is distributed under the terms of a
permission notice identical to this one.
Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions.
@end ignore
@node Using History Interactively
@chapter Using History Interactively
@ifclear BashFeatures
@defcodeindex bt
@end ifclear
@ifset BashFeatures
This chapter describes how to use the @sc{gnu} History Library
interactively, from a user's standpoint.
It should be considered a user's guide.
For information on using the @sc{gnu} History Library in other programs,
see the @sc{gnu} Readline Library Manual.
@end ifset
@ifclear BashFeatures
This chapter describes how to use the @sc{gnu} History Library interactively,
from a user's standpoint. It should be considered a user's guide. For
information on using the @sc{gnu} History Library in your own programs,
@pxref{Programming with GNU History}.
@end ifclear
@ifset BashFeatures
@menu
* Bash History Facilities:: How Bash lets you manipulate your command
history.
* Bash History Builtins:: The Bash builtin commands that manipulate
the command history.
* History Interaction:: What it feels like using History as a user.
@end menu
@end ifset
@ifclear BashFeatures
@menu
* History Interaction:: What it feels like using History as a user.
@end menu
@end ifclear
@ifset BashFeatures
@node Bash History Facilities
@section Bash History Facilities
@cindex command history
@cindex history list
When the @option{-o history} option to the @code{set} builtin
is enabled (@pxref{The Set Builtin}),
the shell provides access to the @dfn{command history},
the list of commands previously typed.
The value of the @env{HISTSIZE} shell variable is used as the
number of commands to save in a history list.
The text of the last @env{$HISTSIZE}
commands (default 500) is saved.
The shell stores each command in the history list prior to
parameter and variable expansion
but after history expansion is performed, subject to the
values of the shell variables
@env{HISTIGNORE} and @env{HISTCONTROL}.
When the shell starts up, the history is initialized from the
file named by the @env{HISTFILE} variable (default @file{~/.bash_history}).
The file named by the value of @env{HISTFILE} is truncated, if
necessary, to contain no more than the number of lines specified by
the value of the @env{HISTFILESIZE} variable.
When a shell with history enabled exits, the last
@env{$HISTSIZE} lines are copied from the history list to the file
named by @env{$HISTFILE}.
If the @code{histappend} shell option is set (@pxref{Bash Builtins}),
the lines are appended to the history file,
otherwise the history file is overwritten.
If @env{HISTFILE}
is unset, or if the history file is unwritable, the history is not saved.
After saving the history, the history file is truncated
to contain no more than @env{$HISTFILESIZE} lines.
If @env{HISTFILESIZE} is unset, or set to null, a non-numeric value, or
a numeric value less than zero, the history file is not truncated.
If the @env{HISTTIMEFORMAT} is set, the time stamp information
associated with each history entry is written to the history file,
marked with the history comment character.
When the history file is read, lines beginning with the history
comment character followed immediately by a digit are interpreted
as timestamps for the following history entry.
The builtin command @code{fc} may be used to list or edit and re-execute
a portion of the history list.
The @code{history} builtin may be used to display or modify the history
list and manipulate the history file.
When using command-line editing, search commands
are available in each editing mode that provide access to the
history list (@pxref{Commands For History}).
The shell allows control over which commands are saved on the history
list. The @env{HISTCONTROL} and @env{HISTIGNORE}
variables may be set to cause the shell to save only a subset of the
commands entered.
The @code{cmdhist}
shell option, if enabled, causes the shell to attempt to save each
line of a multi-line command in the same history entry, adding
semicolons where necessary to preserve syntactic correctness.
The @code{lithist}
shell option causes the shell to save the command with embedded newlines
instead of semicolons.
The @code{shopt} builtin is used to set these options.
@xref{The Shopt Builtin}, for a description of @code{shopt}.
@node Bash History Builtins
@section Bash History Builtins
@cindex history builtins
Bash provides two builtin commands which manipulate the
history list and history file.
@table @code
@item fc
@btindex fc
@example
@code{fc [-e @var{ename}] [-lnr] [@var{first}] [@var{last}]}
@code{fc -s [@var{pat}=@var{rep}] [@var{command}]}
@end example
The first form selects a range of commands from @var{first} to
@var{last} from the history list and displays or edits and re-executes
them.
Both @var{first} and
@var{last} may be specified as a string (to locate the most recent
command beginning with that string) or as a number (an index into the
history list, where a negative number is used as an offset from the
current command number).
When listing, a @var{first} or @var{last} of 0 is equivalent to -1
and -0 is equivalent to the current command (usually the @code{fc}
command);
otherwise 0 is equivalent to -1 and -0 is invalid.
If @var{last} is not specified, it is set to
@var{first}. If @var{first} is not specified, it is set to the previous
command for editing and @minus{}16 for listing. If the @option{-l} flag is
given, the commands are listed on standard output. The @option{-n} flag
suppresses the command numbers when listing. The @option{-r} flag
reverses the order of the listing. Otherwise, the editor given by
@var{ename} is invoked on a file containing those commands. If
@var{ename} is not given, the value of the following variable expansion
is used: @code{$@{FCEDIT:-$@{EDITOR:-vi@}@}}. This says to use the
value of the @env{FCEDIT} variable if set, or the value of the
@env{EDITOR} variable if that is set, or @code{vi} if neither is set.
When editing is complete, the edited commands are echoed and executed.
In the second form, @var{command} is re-executed after each instance
of @var{pat} in the selected command is replaced by @var{rep}.
@var{command} is interpreted the same as @var{first} above.
A useful alias to use with the @code{fc} command is @code{r='fc -s'}, so
that typing @samp{r cc} runs the last command beginning with @code{cc}
and typing @samp{r} re-executes the last command (@pxref{Aliases}).
@item history
@btindex history
@example
history [@var{n}]
history -c
history -d @var{offset}
history -d @var{start}-@var{end}
history [-anrw] [@var{filename}]
history -ps @var{arg}
@end example
With no options, display the history list with line numbers.
Lines prefixed with a @samp{*} have been modified.
An argument of @var{n} lists only the last @var{n} lines.
If the shell variable @env{HISTTIMEFORMAT} is set and not null,
it is used as a format string for @var{strftime} to display
the time stamp associated with each displayed history entry.
No intervening blank is printed between the formatted time stamp
and the history line.
Options, if supplied, have the following meanings:
@table @code
@item -c
Clear the history list. This may be combined
with the other options to replace the history list completely.
@item -d @var{offset}
Delete the history entry at position @var{offset}.
If @var{offset} is positive, it should be specified as it appears when
the history is displayed.
If @var{offset} is negative, it is interpreted as relative to one greater
than the last history position, so negative indices count back from the
end of the history, and an index of @samp{-1} refers to the current
@code{history -d} command.
@item -d @var{start}-@var{end}
Delete the range of history entries between positions @var{start} and
@var{end}, inclusive.
Positive and negative values for @var{start} and @var{end}
are interpreted as described above.
@item -a
Append the new history lines to the history file.
These are history lines entered since the beginning of the current
Bash session, but not already appended to the history file.
@item -n
Append the history lines not already read from the history file
to the current history list. These are lines appended to the history
file since the beginning of the current Bash session.
@item -r
Read the history file and append its contents to
the history list.
@item -w
Write out the current history list to the history file.
@item -p
Perform history substitution on the @var{arg}s and display the result
on the standard output, without storing the results in the history list.
@item -s
The @var{arg}s are added to the end of
the history list as a single entry.
@end table
If a @var{filename} argument is supplied
when any of the @option{-w}, @option{-r}, @option{-a}, or @option{-n} options
is used, Bash uses @var{filename} as the history file.
If not, then the value of the @env{HISTFILE} variable is used.
The return value is 0 unless an invalid option is encountered, an
error occurs while reading or writing the history file, an invalid
@var{offset} or range is supplied as an argument to @option{-d}, or the
history expansion supplied as an argument to @option{-p} fails.
@end table
@end ifset
@node History Interaction
@section History Expansion
@cindex history expansion
The History library provides a history expansion feature that is similar
to the history expansion provided by @code{csh}. This section
describes the syntax used to manipulate the history information.
History expansions introduce words from the history list into
the input stream, making it easy to repeat commands, insert the
arguments to a previous command into the current input line, or
fix errors in previous commands quickly.
@ifset BashFeatures
History expansion is performed immediately after a complete line
is read, before the shell breaks it into words, and is performed
on each line individually. Bash attempts to inform the history
expansion functions about quoting still in effect from previous lines.
@end ifset
History expansion takes place in two parts. The first is to determine
which line from the history list should be used during substitution.
The second is to select portions of that line for inclusion into the
current one. The line selected from the history is called the
@dfn{event}, and the portions of that line that are acted upon are
called @dfn{words}. Various @dfn{modifiers} are available to manipulate
the selected words. The line is broken into words in the same fashion
that Bash does, so that several words
surrounded by quotes are considered one word.
History expansions are introduced by the appearance of the
history expansion character, which is @samp{!} by default.
History expansion implements shell-like quoting conventions:
a backslash can be used to remove the special handling for the next character;
single quotes enclose verbatim sequences of characters, and can be used to
inhibit history expansion;
and characters enclosed within double quotes may be subject to history
expansion, since backslash can escape the history expansion character,
but single quotes may not, since they are not treated specially within
double quotes.
@ifset BashFeatures
When using the shell, only @samp{\} and @samp{'} may be used to escape the
history expansion character, but the history expansion character is
also treated as quoted if it immediately precedes the closing double quote
in a double-quoted string.
@end ifset
@ifset BashFeatures
Several shell options settable with the @code{shopt}
builtin (@pxref{The Shopt Builtin}) may be used to tailor
the behavior of history expansion. If the
@code{histverify} shell option is enabled, and Readline
is being used, history substitutions are not immediately passed to
the shell parser.
Instead, the expanded line is reloaded into the Readline
editing buffer for further modification.
If Readline is being used, and the @code{histreedit}
shell option is enabled, a failed history expansion will be
reloaded into the Readline editing buffer for correction.
The @option{-p} option to the @code{history} builtin command
may be used to see what a history expansion will do before using it.
The @option{-s} option to the @code{history} builtin may be used to
add commands to the end of the history list without actually executing
them, so that they are available for subsequent recall.
This is most useful in conjunction with Readline.
The shell allows control of the various characters used by the
history expansion mechanism with the @code{histchars} variable,
as explained above (@pxref{Bash Variables}). The shell uses
the history comment character to mark history timestamps when
writing the history file.
@end ifset
@menu
* Event Designators:: How to specify which history line to use.
* Word Designators:: Specifying which words are of interest.
* Modifiers:: Modifying the results of substitution.
@end menu
@node Event Designators
@subsection Event Designators
@cindex event designators
An event designator is a reference to a command line entry in the
history list.
Unless the reference is absolute, events are relative to the current
position in the history list.
@cindex history events
@table @asis
@item @code{!}
@ifset BashFeatures
Start a history substitution, except when followed by a space, tab,
the end of the line, @samp{=} or @samp{(} (when the
@code{extglob} shell option is enabled using the @code{shopt} builtin).
@end ifset
@ifclear BashFeatures
Start a history substitution, except when followed by a space, tab,
the end of the line, or @samp{=}.
@end ifclear
@item @code{!@var{n}}
Refer to command line @var{n}.
@item @code{!-@var{n}}
Refer to the command @var{n} lines back.
@item @code{!!}
Refer to the previous command. This is a synonym for @samp{!-1}.
@item @code{!@var{string}}
Refer to the most recent command
preceding the current position in the history list
starting with @var{string}.
@item @code{!?@var{string}[?]}
Refer to the most recent command
preceding the current position in the history list
containing @var{string}.
The trailing
@samp{?} may be omitted if the @var{string} is followed immediately by
a newline.
If @var{string} is missing, the string from the most recent search is used;
it is an error if there is no previous search string.
@item @code{^@var{string1}^@var{string2}^}
Quick Substitution. Repeat the last command, replacing @var{string1}
with @var{string2}. Equivalent to
@code{!!:s^@var{string1}^@var{string2}^}.
@item @code{!#}
The entire command line typed so far.
@end table
@node Word Designators
@subsection Word Designators
Word designators are used to select desired words from the event.
A @samp{:} separates the event specification from the word designator. It
may be omitted if the word designator begins with a @samp{^}, @samp{$},
@samp{*}, @samp{-}, or @samp{%}. Words are numbered from the beginning
of the line, with the first word being denoted by 0 (zero). Words are
inserted into the current line separated by single spaces.
@need 0.75
For example,
@table @code
@item !!
designates the preceding command. When you type this, the preceding
command is repeated in toto.
@item !!:$
designates the last argument of the preceding command. This may be
shortened to @code{!$}.
@item !fi:2
designates the second argument of the most recent command starting with
the letters @code{fi}.
@end table
@need 0.75
Here are the word designators:
@table @code
@item 0 (zero)
The @code{0}th word. For many applications, this is the command word.
@item @var{n}
The @var{n}th word.
@item ^
The first argument; that is, word 1.
@item $
The last argument.
@item %
The first word matched by the most recent @samp{?@var{string}?} search,
if the search string begins with a character that is part of a word.
@item @var{x}-@var{y}
A range of words; @samp{-@var{y}} abbreviates @samp{0-@var{y}}.
@item *
All of the words, except the @code{0}th. This is a synonym for @samp{1-$}.
It is not an error to use @samp{*} if there is just one word in the event;
the empty string is returned in that case.
@item @var{x}*
Abbreviates @samp{@var{x}-$}
@item @var{x}-
Abbreviates @samp{@var{x}-$} like @samp{@var{x}*}, but omits the last word.
If @samp{x} is missing, it defaults to 0.
@end table
If a word designator is supplied without an event specification, the
previous command is used as the event.
@node Modifiers
@subsection Modifiers
After the optional word designator, you can add a sequence of one or more
of the following modifiers, each preceded by a @samp{:}.
These modify, or edit, the word or words selected from the history event.
@table @code
@item h
Remove a trailing pathname component, leaving only the head.
@item t
Remove all leading pathname components, leaving the tail.
@item r
Remove a trailing suffix of the form @samp{.@var{suffix}}, leaving
the basename.
@item e
Remove all but the trailing suffix.
@item p
Print the new command but do not execute it.
@ifset BashFeatures
@item q
Quote the substituted words, escaping further substitutions.
@item x
Quote the substituted words as with @samp{q},
but break into words at spaces, tabs, and newlines.
The @samp{q} and @samp{x} modifiers are mutually exclusive; the last one
supplied is used.
@end ifset
@item s/@var{old}/@var{new}/
Substitute @var{new} for the first occurrence of @var{old} in the
event line.
Any character may be used as the delimiter in place of @samp{/}.
The delimiter may be quoted in @var{old} and @var{new}
with a single backslash. If @samp{&} appears in @var{new},
it is replaced by @var{old}. A single backslash will quote
the @samp{&}.
If @var{old} is null, it is set to the last @var{old}
substituted, or, if no previous history substitutions took place,
the last @var{string}
in a !?@var{string}@code{[?]}
search.
If @var{new} is null, each matching @var{old} is deleted.
The final delimiter is optional if it is the last
character on the input line.
@item &
Repeat the previous substitution.
@item g
@itemx a
Cause changes to be applied over the entire event line. Used in
conjunction with @samp{s}, as in @code{gs/@var{old}/@var{new}/},
or with @samp{&}.
@item G
Apply the following @samp{s} or @samp{&} modifier once to each word
in the event.
@end table

1175
doc/readline.0 Normal file

File diff suppressed because it is too large Load diff

1597
doc/readline.3 Normal file

File diff suppressed because it is too large Load diff

BIN
doc/readline.dvi Normal file

Binary file not shown.

6286
doc/readline.html Normal file

File diff suppressed because it is too large Load diff

5320
doc/readline.info Normal file

File diff suppressed because it is too large Load diff

BIN
doc/readline.pdf Normal file

Binary file not shown.

12656
doc/readline.ps Normal file

File diff suppressed because it is too large Load diff

1782
doc/readline_3.ps Normal file

File diff suppressed because it is too large Load diff

84
doc/rlman.texi Normal file
View file

@ -0,0 +1,84 @@
\input texinfo @c -*-texinfo-*-
@comment %**start of header (This is for running Texinfo on a region.)
@setfilename readline.info
@settitle GNU Readline Library
@include version.texi
@comment %**end of header (This is for running Texinfo on a region.)
@synindex vr fn
@copying
This manual describes the GNU Readline Library
(version @value{VERSION}, @value{UPDATED}), a library which aids in the
consistency of user interface across discrete programs which provide
a command line interface.
Copyright @copyright{} 1988--2022 Free Software Foundation, Inc.
@quotation
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation; with no
Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
A copy of the license is included in the section entitled
``GNU Free Documentation License''.
@end quotation
@end copying
@dircategory Libraries
@direntry
* Readline: (readline). The GNU readline library API.
@end direntry
@titlepage
@title GNU Readline Library
@subtitle Edition @value{EDITION}, for @code{Readline Library} Version @value{VERSION}.
@subtitle @value{UPDATED-MONTH}
@author Chet Ramey, Case Western Reserve University
@author Brian Fox, Free Software Foundation
@page
@vskip 0pt plus 1filll
@insertcopying
@end titlepage
@contents
@ifnottex
@node Top
@top GNU Readline Library
This document describes the GNU Readline Library, a utility which aids
in the consistency of user interface across discrete programs which
provide a command line interface.
The Readline home page is @url{http://www.gnu.org/software/readline/}.
@menu
* Command Line Editing:: GNU Readline User's Manual.
* Programming with GNU Readline:: GNU Readline Programmer's Manual.
* GNU Free Documentation License:: License for copying this manual.
* Concept Index:: Index of concepts described in this manual.
* Function and Variable Index:: Index of externally visible functions
and variables.
@end menu
@end ifnottex
@include rluser.texi
@include rltech.texi
@node GNU Free Documentation License
@appendix GNU Free Documentation License
@include fdl.texi
@node Concept Index
@unnumbered Concept Index
@printindex cp
@node Function and Variable Index
@unnumbered Function and Variable Index
@printindex fn
@bye

2815
doc/rltech.texi Normal file

File diff suppressed because it is too large Load diff

2488
doc/rluser.texi Normal file

File diff suppressed because it is too large Load diff

BIN
doc/rluserman.dvi Normal file

Binary file not shown.

2529
doc/rluserman.html Normal file

File diff suppressed because it is too large Load diff

2087
doc/rluserman.info Normal file

File diff suppressed because it is too large Load diff

BIN
doc/rluserman.pdf Normal file

Binary file not shown.

7574
doc/rluserman.ps Normal file

File diff suppressed because it is too large Load diff

70
doc/rluserman.texi Normal file
View file

@ -0,0 +1,70 @@
\input texinfo @c -*-texinfo-*-
@comment %**start of header (This is for running Texinfo on a region.)
@setfilename rluserman.info
@settitle GNU Readline Library
@include version.texi
@comment %**end of header (This is for running Texinfo on a region.)
@copying
This manual describes the end user interface of the GNU Readline Library
(version @value{VERSION}, @value{UPDATED}), a library which aids in the
consistency of user interface across discrete programs which provide
a command line interface.
Copyright @copyright{} 1988--2022 Free Software Foundation, Inc.
@quotation
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation; with no
Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
A copy of the license is included in the section entitled
``GNU Free Documentation License''.
@end quotation
@end copying
@dircategory Libraries
@direntry
* RLuserman: (rluserman). The GNU readline library User's Manual.
@end direntry
@titlepage
@title GNU Readline Library User Interface
@subtitle Edition @value{EDITION}, for @code{Readline Library} Version @value{VERSION}.
@subtitle @value{UPDATED-MONTH}
@author Chet Ramey, Case Western Reserve University
@author Brian Fox, Free Software Foundation
@page
@vskip 0pt plus 1filll
@insertcopying
@end titlepage
@contents
@ifnottex
@node Top
@top GNU Readline Library
This document describes the end user interface of the GNU Readline Library,
a utility which aids in the consistency of user interface across discrete
programs which provide a command line interface.
The Readline home page is @url{http://www.gnu.org/software/readline/}.
@menu
* Command Line Editing:: GNU Readline User's Manual.
* GNU Free Documentation License:: License for copying this manual.
@end menu
@end ifnottex
@include rluser.texi
@node GNU Free Documentation License
@appendix GNU Free Documentation License
@include fdl.texi
@bye

1996
doc/texi2dvi Normal file

File diff suppressed because it is too large Load diff

5428
doc/texi2html Normal file

File diff suppressed because it is too large Load diff

11045
doc/texinfo.tex Normal file

File diff suppressed because it is too large Load diff

11
doc/version.texi Normal file
View file

@ -0,0 +1,11 @@
@ignore
Copyright (C) 1988-2022 Free Software Foundation, Inc.
@end ignore
@set EDITION 8.2
@set VERSION 8.2
@set UPDATED 19 September 2022
@set UPDATED-MONTH September 2022
@set LASTCHANGE Mon Sep 19 11:15:16 EDT 2022

872
emacs_keymap.c Normal file
View file

@ -0,0 +1,872 @@
/* emacs_keymap.c -- the keymap for emacs_mode in readline (). */
/* Copyright (C) 1987-2017 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
Readline 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 3 of the License, or
(at your option) any later version.
Readline 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 Readline. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined (BUFSIZ)
#include <stdio.h>
#endif /* !BUFSIZ */
#include "readline.h"
/* An array of function pointers, one for each possible key.
If the type byte is ISKMAP, then the pointer is the address of
a keymap. */
KEYMAP_ENTRY_ARRAY emacs_standard_keymap = {
/* Control keys. */
{ ISFUNC, rl_set_mark }, /* Control-@ */
{ ISFUNC, rl_beg_of_line }, /* Control-a */
{ ISFUNC, rl_backward_char }, /* Control-b */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-c */
{ ISFUNC, rl_delete }, /* Control-d */
{ ISFUNC, rl_end_of_line }, /* Control-e */
{ ISFUNC, rl_forward_char }, /* Control-f */
{ ISFUNC, rl_abort }, /* Control-g */
{ ISFUNC, rl_rubout }, /* Control-h */
{ ISFUNC, rl_complete }, /* Control-i */
{ ISFUNC, rl_newline }, /* Control-j */
{ ISFUNC, rl_kill_line }, /* Control-k */
{ ISFUNC, rl_clear_screen }, /* Control-l */
{ ISFUNC, rl_newline }, /* Control-m */
{ ISFUNC, rl_get_next_history }, /* Control-n */
{ ISFUNC, rl_operate_and_get_next }, /* Control-o */
{ ISFUNC, rl_get_previous_history }, /* Control-p */
{ ISFUNC, rl_quoted_insert }, /* Control-q */
{ ISFUNC, rl_reverse_search_history }, /* Control-r */
{ ISFUNC, rl_forward_search_history }, /* Control-s */
{ ISFUNC, rl_transpose_chars }, /* Control-t */
{ ISFUNC, rl_unix_line_discard }, /* Control-u */
{ ISFUNC, rl_quoted_insert }, /* Control-v */
{ ISFUNC, rl_unix_word_rubout }, /* Control-w */
{ ISKMAP, (rl_command_func_t *)emacs_ctlx_keymap }, /* Control-x */
{ ISFUNC, rl_yank }, /* Control-y */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-z */
{ ISKMAP, (rl_command_func_t *)emacs_meta_keymap }, /* Control-[ */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-\ */
{ ISFUNC, rl_char_search }, /* Control-] */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-^ */
{ ISFUNC, rl_undo_command }, /* Control-_ */
/* The start of printing characters. */
{ ISFUNC, rl_insert }, /* SPACE */
{ ISFUNC, rl_insert }, /* ! */
{ ISFUNC, rl_insert }, /* " */
{ ISFUNC, rl_insert }, /* # */
{ ISFUNC, rl_insert }, /* $ */
{ ISFUNC, rl_insert }, /* % */
{ ISFUNC, rl_insert }, /* & */
{ ISFUNC, rl_insert }, /* ' */
{ ISFUNC, rl_insert }, /* ( */
{ ISFUNC, rl_insert }, /* ) */
{ ISFUNC, rl_insert }, /* * */
{ ISFUNC, rl_insert }, /* + */
{ ISFUNC, rl_insert }, /* , */
{ ISFUNC, rl_insert }, /* - */
{ ISFUNC, rl_insert }, /* . */
{ ISFUNC, rl_insert }, /* / */
/* Regular digits. */
{ ISFUNC, rl_insert }, /* 0 */
{ ISFUNC, rl_insert }, /* 1 */
{ ISFUNC, rl_insert }, /* 2 */
{ ISFUNC, rl_insert }, /* 3 */
{ ISFUNC, rl_insert }, /* 4 */
{ ISFUNC, rl_insert }, /* 5 */
{ ISFUNC, rl_insert }, /* 6 */
{ ISFUNC, rl_insert }, /* 7 */
{ ISFUNC, rl_insert }, /* 8 */
{ ISFUNC, rl_insert }, /* 9 */
/* A little more punctuation. */
{ ISFUNC, rl_insert }, /* : */
{ ISFUNC, rl_insert }, /* ; */
{ ISFUNC, rl_insert }, /* < */
{ ISFUNC, rl_insert }, /* = */
{ ISFUNC, rl_insert }, /* > */
{ ISFUNC, rl_insert }, /* ? */
{ ISFUNC, rl_insert }, /* @ */
/* Uppercase alphabet. */
{ ISFUNC, rl_insert }, /* A */
{ ISFUNC, rl_insert }, /* B */
{ ISFUNC, rl_insert }, /* C */
{ ISFUNC, rl_insert }, /* D */
{ ISFUNC, rl_insert }, /* E */
{ ISFUNC, rl_insert }, /* F */
{ ISFUNC, rl_insert }, /* G */
{ ISFUNC, rl_insert }, /* H */
{ ISFUNC, rl_insert }, /* I */
{ ISFUNC, rl_insert }, /* J */
{ ISFUNC, rl_insert }, /* K */
{ ISFUNC, rl_insert }, /* L */
{ ISFUNC, rl_insert }, /* M */
{ ISFUNC, rl_insert }, /* N */
{ ISFUNC, rl_insert }, /* O */
{ ISFUNC, rl_insert }, /* P */
{ ISFUNC, rl_insert }, /* Q */
{ ISFUNC, rl_insert }, /* R */
{ ISFUNC, rl_insert }, /* S */
{ ISFUNC, rl_insert }, /* T */
{ ISFUNC, rl_insert }, /* U */
{ ISFUNC, rl_insert }, /* V */
{ ISFUNC, rl_insert }, /* W */
{ ISFUNC, rl_insert }, /* X */
{ ISFUNC, rl_insert }, /* Y */
{ ISFUNC, rl_insert }, /* Z */
/* Some more punctuation. */
{ ISFUNC, rl_insert }, /* [ */
{ ISFUNC, rl_insert }, /* \ */
{ ISFUNC, rl_insert }, /* ] */
{ ISFUNC, rl_insert }, /* ^ */
{ ISFUNC, rl_insert }, /* _ */
{ ISFUNC, rl_insert }, /* ` */
/* Lowercase alphabet. */
{ ISFUNC, rl_insert }, /* a */
{ ISFUNC, rl_insert }, /* b */
{ ISFUNC, rl_insert }, /* c */
{ ISFUNC, rl_insert }, /* d */
{ ISFUNC, rl_insert }, /* e */
{ ISFUNC, rl_insert }, /* f */
{ ISFUNC, rl_insert }, /* g */
{ ISFUNC, rl_insert }, /* h */
{ ISFUNC, rl_insert }, /* i */
{ ISFUNC, rl_insert }, /* j */
{ ISFUNC, rl_insert }, /* k */
{ ISFUNC, rl_insert }, /* l */
{ ISFUNC, rl_insert }, /* m */
{ ISFUNC, rl_insert }, /* n */
{ ISFUNC, rl_insert }, /* o */
{ ISFUNC, rl_insert }, /* p */
{ ISFUNC, rl_insert }, /* q */
{ ISFUNC, rl_insert }, /* r */
{ ISFUNC, rl_insert }, /* s */
{ ISFUNC, rl_insert }, /* t */
{ ISFUNC, rl_insert }, /* u */
{ ISFUNC, rl_insert }, /* v */
{ ISFUNC, rl_insert }, /* w */
{ ISFUNC, rl_insert }, /* x */
{ ISFUNC, rl_insert }, /* y */
{ ISFUNC, rl_insert }, /* z */
/* Final punctuation. */
{ ISFUNC, rl_insert }, /* { */
{ ISFUNC, rl_insert }, /* | */
{ ISFUNC, rl_insert }, /* } */
{ ISFUNC, rl_insert }, /* ~ */
{ ISFUNC, rl_rubout }, /* RUBOUT */
#if KEYMAP_SIZE > 128
/* Pure 8-bit characters (128 - 159).
These might be used in some
character sets. */
{ ISFUNC, rl_insert }, /* ? */
{ ISFUNC, rl_insert }, /* ? */
{ ISFUNC, rl_insert }, /* ? */
{ ISFUNC, rl_insert }, /* ? */
{ ISFUNC, rl_insert }, /* ? */
{ ISFUNC, rl_insert }, /* ? */
{ ISFUNC, rl_insert }, /* ? */
{ ISFUNC, rl_insert }, /* ? */
{ ISFUNC, rl_insert }, /* ? */
{ ISFUNC, rl_insert }, /* ? */
{ ISFUNC, rl_insert }, /* ? */
{ ISFUNC, rl_insert }, /* ? */
{ ISFUNC, rl_insert }, /* ? */
{ ISFUNC, rl_insert }, /* ? */
{ ISFUNC, rl_insert }, /* ? */
{ ISFUNC, rl_insert }, /* ? */
{ ISFUNC, rl_insert }, /* ? */
{ ISFUNC, rl_insert }, /* ? */
{ ISFUNC, rl_insert }, /* ? */
{ ISFUNC, rl_insert }, /* ? */
{ ISFUNC, rl_insert }, /* ? */
{ ISFUNC, rl_insert }, /* ? */
{ ISFUNC, rl_insert }, /* ? */
{ ISFUNC, rl_insert }, /* ? */
{ ISFUNC, rl_insert }, /* ? */
{ ISFUNC, rl_insert }, /* ? */
{ ISFUNC, rl_insert }, /* ? */
{ ISFUNC, rl_insert }, /* ? */
{ ISFUNC, rl_insert }, /* ? */
{ ISFUNC, rl_insert }, /* ? */
{ ISFUNC, rl_insert }, /* ? */
{ ISFUNC, rl_insert }, /* ? */
/* ISO Latin-1 characters (160 - 255) */
{ ISFUNC, rl_insert }, /* No-break space */
{ ISFUNC, rl_insert }, /* Inverted exclamation mark */
{ ISFUNC, rl_insert }, /* Cent sign */
{ ISFUNC, rl_insert }, /* Pound sign */
{ ISFUNC, rl_insert }, /* Currency sign */
{ ISFUNC, rl_insert }, /* Yen sign */
{ ISFUNC, rl_insert }, /* Broken bar */
{ ISFUNC, rl_insert }, /* Section sign */
{ ISFUNC, rl_insert }, /* Diaeresis */
{ ISFUNC, rl_insert }, /* Copyright sign */
{ ISFUNC, rl_insert }, /* Feminine ordinal indicator */
{ ISFUNC, rl_insert }, /* Left pointing double angle quotation mark */
{ ISFUNC, rl_insert }, /* Not sign */
{ ISFUNC, rl_insert }, /* Soft hyphen */
{ ISFUNC, rl_insert }, /* Registered sign */
{ ISFUNC, rl_insert }, /* Macron */
{ ISFUNC, rl_insert }, /* Degree sign */
{ ISFUNC, rl_insert }, /* Plus-minus sign */
{ ISFUNC, rl_insert }, /* Superscript two */
{ ISFUNC, rl_insert }, /* Superscript three */
{ ISFUNC, rl_insert }, /* Acute accent */
{ ISFUNC, rl_insert }, /* Micro sign */
{ ISFUNC, rl_insert }, /* Pilcrow sign */
{ ISFUNC, rl_insert }, /* Middle dot */
{ ISFUNC, rl_insert }, /* Cedilla */
{ ISFUNC, rl_insert }, /* Superscript one */
{ ISFUNC, rl_insert }, /* Masculine ordinal indicator */
{ ISFUNC, rl_insert }, /* Right pointing double angle quotation mark */
{ ISFUNC, rl_insert }, /* Vulgar fraction one quarter */
{ ISFUNC, rl_insert }, /* Vulgar fraction one half */
{ ISFUNC, rl_insert }, /* Vulgar fraction three quarters */
{ ISFUNC, rl_insert }, /* Inverted questionk mark */
{ ISFUNC, rl_insert }, /* Latin capital letter a with grave */
{ ISFUNC, rl_insert }, /* Latin capital letter a with acute */
{ ISFUNC, rl_insert }, /* Latin capital letter a with circumflex */
{ ISFUNC, rl_insert }, /* Latin capital letter a with tilde */
{ ISFUNC, rl_insert }, /* Latin capital letter a with diaeresis */
{ ISFUNC, rl_insert }, /* Latin capital letter a with ring above */
{ ISFUNC, rl_insert }, /* Latin capital letter ae */
{ ISFUNC, rl_insert }, /* Latin capital letter c with cedilla */
{ ISFUNC, rl_insert }, /* Latin capital letter e with grave */
{ ISFUNC, rl_insert }, /* Latin capital letter e with acute */
{ ISFUNC, rl_insert }, /* Latin capital letter e with circumflex */
{ ISFUNC, rl_insert }, /* Latin capital letter e with diaeresis */
{ ISFUNC, rl_insert }, /* Latin capital letter i with grave */
{ ISFUNC, rl_insert }, /* Latin capital letter i with acute */
{ ISFUNC, rl_insert }, /* Latin capital letter i with circumflex */
{ ISFUNC, rl_insert }, /* Latin capital letter i with diaeresis */
{ ISFUNC, rl_insert }, /* Latin capital letter eth (Icelandic) */
{ ISFUNC, rl_insert }, /* Latin capital letter n with tilde */
{ ISFUNC, rl_insert }, /* Latin capital letter o with grave */
{ ISFUNC, rl_insert }, /* Latin capital letter o with acute */
{ ISFUNC, rl_insert }, /* Latin capital letter o with circumflex */
{ ISFUNC, rl_insert }, /* Latin capital letter o with tilde */
{ ISFUNC, rl_insert }, /* Latin capital letter o with diaeresis */
{ ISFUNC, rl_insert }, /* Multiplication sign */
{ ISFUNC, rl_insert }, /* Latin capital letter o with stroke */
{ ISFUNC, rl_insert }, /* Latin capital letter u with grave */
{ ISFUNC, rl_insert }, /* Latin capital letter u with acute */
{ ISFUNC, rl_insert }, /* Latin capital letter u with circumflex */
{ ISFUNC, rl_insert }, /* Latin capital letter u with diaeresis */
{ ISFUNC, rl_insert }, /* Latin capital letter Y with acute */
{ ISFUNC, rl_insert }, /* Latin capital letter thorn (Icelandic) */
{ ISFUNC, rl_insert }, /* Latin small letter sharp s (German) */
{ ISFUNC, rl_insert }, /* Latin small letter a with grave */
{ ISFUNC, rl_insert }, /* Latin small letter a with acute */
{ ISFUNC, rl_insert }, /* Latin small letter a with circumflex */
{ ISFUNC, rl_insert }, /* Latin small letter a with tilde */
{ ISFUNC, rl_insert }, /* Latin small letter a with diaeresis */
{ ISFUNC, rl_insert }, /* Latin small letter a with ring above */
{ ISFUNC, rl_insert }, /* Latin small letter ae */
{ ISFUNC, rl_insert }, /* Latin small letter c with cedilla */
{ ISFUNC, rl_insert }, /* Latin small letter e with grave */
{ ISFUNC, rl_insert }, /* Latin small letter e with acute */
{ ISFUNC, rl_insert }, /* Latin small letter e with circumflex */
{ ISFUNC, rl_insert }, /* Latin small letter e with diaeresis */
{ ISFUNC, rl_insert }, /* Latin small letter i with grave */
{ ISFUNC, rl_insert }, /* Latin small letter i with acute */
{ ISFUNC, rl_insert }, /* Latin small letter i with circumflex */
{ ISFUNC, rl_insert }, /* Latin small letter i with diaeresis */
{ ISFUNC, rl_insert }, /* Latin small letter eth (Icelandic) */
{ ISFUNC, rl_insert }, /* Latin small letter n with tilde */
{ ISFUNC, rl_insert }, /* Latin small letter o with grave */
{ ISFUNC, rl_insert }, /* Latin small letter o with acute */
{ ISFUNC, rl_insert }, /* Latin small letter o with circumflex */
{ ISFUNC, rl_insert }, /* Latin small letter o with tilde */
{ ISFUNC, rl_insert }, /* Latin small letter o with diaeresis */
{ ISFUNC, rl_insert }, /* Division sign */
{ ISFUNC, rl_insert }, /* Latin small letter o with stroke */
{ ISFUNC, rl_insert }, /* Latin small letter u with grave */
{ ISFUNC, rl_insert }, /* Latin small letter u with acute */
{ ISFUNC, rl_insert }, /* Latin small letter u with circumflex */
{ ISFUNC, rl_insert }, /* Latin small letter u with diaeresis */
{ ISFUNC, rl_insert }, /* Latin small letter y with acute */
{ ISFUNC, rl_insert }, /* Latin small letter thorn (Icelandic) */
{ ISFUNC, rl_insert } /* Latin small letter y with diaeresis */
#endif /* KEYMAP_SIZE > 128 */
};
KEYMAP_ENTRY_ARRAY emacs_meta_keymap = {
/* Meta keys. Just like above, but the high bit is set. */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-@ */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-a */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-b */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-c */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-d */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-e */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-f */
{ ISFUNC, rl_abort }, /* Meta-Control-g */
{ ISFUNC, rl_backward_kill_word }, /* Meta-Control-h */
{ ISFUNC, rl_tab_insert }, /* Meta-Control-i */
{ ISFUNC, rl_vi_editing_mode }, /* Meta-Control-j */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-k */
{ ISFUNC, rl_clear_display }, /* Meta-Control-l */
{ ISFUNC, rl_vi_editing_mode }, /* Meta-Control-m */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-n */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-o */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-p */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-q */
{ ISFUNC, rl_revert_line }, /* Meta-Control-r */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-s */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-t */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-u */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-v */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-w */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-x */
{ ISFUNC, rl_yank_nth_arg }, /* Meta-Control-y */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-z */
{ ISFUNC, rl_complete }, /* Meta-Control-[ */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-\ */
{ ISFUNC, rl_backward_char_search }, /* Meta-Control-] */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-^ */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-Control-_ */
/* The start of printing characters. */
{ ISFUNC, rl_set_mark }, /* Meta-SPACE */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-! */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-" */
{ ISFUNC, rl_insert_comment }, /* Meta-# */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-$ */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-% */
{ ISFUNC, rl_tilde_expand }, /* Meta-& */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-' */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-( */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-) */
{ ISFUNC, rl_insert_completions }, /* Meta-* */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-+ */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-, */
{ ISFUNC, rl_digit_argument }, /* Meta-- */
{ ISFUNC, rl_yank_last_arg}, /* Meta-. */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-/ */
/* Regular digits. */
{ ISFUNC, rl_digit_argument }, /* Meta-0 */
{ ISFUNC, rl_digit_argument }, /* Meta-1 */
{ ISFUNC, rl_digit_argument }, /* Meta-2 */
{ ISFUNC, rl_digit_argument }, /* Meta-3 */
{ ISFUNC, rl_digit_argument }, /* Meta-4 */
{ ISFUNC, rl_digit_argument }, /* Meta-5 */
{ ISFUNC, rl_digit_argument }, /* Meta-6 */
{ ISFUNC, rl_digit_argument }, /* Meta-7 */
{ ISFUNC, rl_digit_argument }, /* Meta-8 */
{ ISFUNC, rl_digit_argument }, /* Meta-9 */
/* A little more punctuation. */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-: */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-; */
{ ISFUNC, rl_beginning_of_history }, /* Meta-< */
{ ISFUNC, rl_possible_completions }, /* Meta-= */
{ ISFUNC, rl_end_of_history }, /* Meta-> */
{ ISFUNC, rl_possible_completions }, /* Meta-? */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-@ */
/* Uppercase alphabet. */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-A */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-B */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-C */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-D */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-E */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-F */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-G */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-H */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-I */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-J */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-K */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-L */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-M */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-N */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-O */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-P */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-Q */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-R */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-S */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-T */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-U */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-V */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-W */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-X */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-Y */
{ ISFUNC, rl_do_lowercase_version }, /* Meta-Z */
/* Some more punctuation. */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-[ */ /* was rl_arrow_keys */
{ ISFUNC, rl_delete_horizontal_space }, /* Meta-\ */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-] */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-^ */
{ ISFUNC, rl_yank_last_arg }, /* Meta-_ */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-` */
/* Lowercase alphabet. */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-a */
{ ISFUNC, rl_backward_word }, /* Meta-b */
{ ISFUNC, rl_capitalize_word }, /* Meta-c */
{ ISFUNC, rl_kill_word }, /* Meta-d */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-e */
{ ISFUNC, rl_forward_word }, /* Meta-f */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-g */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-h */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-i */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-j */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-k */
{ ISFUNC, rl_downcase_word }, /* Meta-l */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-m */
{ ISFUNC, rl_noninc_forward_search }, /* Meta-n */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-o */ /* was rl_arrow_keys */
{ ISFUNC, rl_noninc_reverse_search }, /* Meta-p */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-q */
{ ISFUNC, rl_revert_line }, /* Meta-r */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-s */
{ ISFUNC, rl_transpose_words }, /* Meta-t */
{ ISFUNC, rl_upcase_word }, /* Meta-u */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-v */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-w */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-x */
{ ISFUNC, rl_yank_pop }, /* Meta-y */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-z */
/* Final punctuation. */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-{ */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-| */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Meta-} */
{ ISFUNC, rl_tilde_expand }, /* Meta-~ */
{ ISFUNC, rl_backward_kill_word }, /* Meta-rubout */
#if KEYMAP_SIZE > 128
/* Undefined keys. */
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 }
#endif /* KEYMAP_SIZE > 128 */
};
KEYMAP_ENTRY_ARRAY emacs_ctlx_keymap = {
/* Control keys. */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-@ */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-a */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-b */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-c */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-d */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-e */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-f */
{ ISFUNC, rl_abort }, /* Control-g */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-h */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-i */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-j */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-k */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-l */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-m */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-n */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-o */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-p */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-q */
{ ISFUNC, rl_re_read_init_file }, /* Control-r */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-s */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-t */
{ ISFUNC, rl_undo_command }, /* Control-u */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-v */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-w */
{ ISFUNC, rl_exchange_point_and_mark }, /* Control-x */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-y */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-z */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-[ */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-\ */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-] */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-^ */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-_ */
/* The start of printing characters. */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* SPACE */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* ! */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* " */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* # */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* $ */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* % */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* & */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* ' */
{ ISFUNC, rl_start_kbd_macro }, /* ( */
{ ISFUNC, rl_end_kbd_macro }, /* ) */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* * */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* + */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* , */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* - */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* . */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* / */
/* Regular digits. */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* 0 */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* 1 */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* 2 */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* 3 */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* 4 */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* 5 */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* 6 */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* 7 */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* 8 */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* 9 */
/* A little more punctuation. */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* : */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* ; */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* < */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* = */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* > */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* ? */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* @ */
/* Uppercase alphabet. */
{ ISFUNC, rl_do_lowercase_version }, /* A */
{ ISFUNC, rl_do_lowercase_version }, /* B */
{ ISFUNC, rl_do_lowercase_version }, /* C */
{ ISFUNC, rl_do_lowercase_version }, /* D */
{ ISFUNC, rl_do_lowercase_version }, /* E */
{ ISFUNC, rl_do_lowercase_version }, /* F */
{ ISFUNC, rl_do_lowercase_version }, /* G */
{ ISFUNC, rl_do_lowercase_version }, /* H */
{ ISFUNC, rl_do_lowercase_version }, /* I */
{ ISFUNC, rl_do_lowercase_version }, /* J */
{ ISFUNC, rl_do_lowercase_version }, /* K */
{ ISFUNC, rl_do_lowercase_version }, /* L */
{ ISFUNC, rl_do_lowercase_version }, /* M */
{ ISFUNC, rl_do_lowercase_version }, /* N */
{ ISFUNC, rl_do_lowercase_version }, /* O */
{ ISFUNC, rl_do_lowercase_version }, /* P */
{ ISFUNC, rl_do_lowercase_version }, /* Q */
{ ISFUNC, rl_do_lowercase_version }, /* R */
{ ISFUNC, rl_do_lowercase_version }, /* S */
{ ISFUNC, rl_do_lowercase_version }, /* T */
{ ISFUNC, rl_do_lowercase_version }, /* U */
{ ISFUNC, rl_do_lowercase_version }, /* V */
{ ISFUNC, rl_do_lowercase_version }, /* W */
{ ISFUNC, rl_do_lowercase_version }, /* X */
{ ISFUNC, rl_do_lowercase_version }, /* Y */
{ ISFUNC, rl_do_lowercase_version }, /* Z */
/* Some more punctuation. */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* [ */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* \ */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* ] */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* ^ */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* _ */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* ` */
/* Lowercase alphabet. */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* a */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* b */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* c */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* d */
{ ISFUNC, rl_call_last_kbd_macro }, /* e */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* f */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* g */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* h */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* i */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* j */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* k */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* l */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* m */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* n */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* o */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* p */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* q */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* r */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* s */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* t */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* u */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* v */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* w */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* x */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* y */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* z */
/* Final punctuation. */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* { */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* | */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* } */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* ~ */
{ ISFUNC, rl_backward_kill_line }, /* RUBOUT */
#if KEYMAP_SIZE > 128
/* Undefined keys. */
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 },
{ ISFUNC, (rl_command_func_t *)0x0 }
#endif /* KEYMAP_SIZE > 128 */
};

81
examples/Inputrc Normal file
View file

@ -0,0 +1,81 @@
# My ~/.inputrc file is in -*- text -*- for easy editing with Emacs.
#
# Notice the various bindings which are conditionalized depending
# on which program is running, or what terminal is active.
#
# Copyright (C) 1989-2009 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 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# In all programs, all terminals, make sure this is bound.
"\C-x\C-r": re-read-init-file
# Hp terminals (and some others) have ugly default behaviour for C-h.
"\C-h": backward-delete-char
"\e\C-h": backward-kill-word
"\C-xd": dump-functions
# In xterm windows, make the arrow keys do the right thing.
$if TERM=xterm
"\e[A": previous-history
"\e[B": next-history
"\e[C": forward-char
"\e[D": backward-char
# alternate arrow key prefix
"\eOA": previous-history
"\eOB": next-history
"\eOC": forward-char
"\eOD": backward-char
# Under Xterm in Bash, we bind local Function keys to do something useful.
$if Bash
"\e[11~": "Function Key 1"
"\e[12~": "Function Key 2"
"\e[13~": "Function Key 3"
"\e[14~": "Function Key 4"
"\e[15~": "Function Key 5"
# I know the following escape sequence numbers are 1 greater than
# the function key. Don't ask me why, I didn't design the xterm terminal.
"\e[17~": "Function Key 6"
"\e[18~": "Function Key 7"
"\e[19~": "Function Key 8"
"\e[20~": "Function Key 9"
"\e[21~": "Function Key 10"
$endif
$endif
# For Bash, all terminals, add some Bash specific hacks.
$if Bash
"\C-xv": show-bash-version
"\C-x\C-e": shell-expand-line
# Here is one for editing my path.
"\C-xp": "$PATH\C-x\C-e\C-e\"\C-aPATH=\":\C-b"
# Make C-x r read my mail in emacs.
# "\C-xr": "emacs -f rmail\C-j"
$endif
# For FTP, different hacks:
$if Ftp
"\C-xg": "get \M-?"
"\C-xt": "put \M-?"
"\M-.": yank-last-arg
$endif
" ": self-insert

193
examples/Makefile.in Normal file
View file

@ -0,0 +1,193 @@
#
# This is the Makefile for the readline examples subdirectory.
#
# Copyright (C) 1994,2008,2009 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 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
RL_LIBRARY_VERSION = @LIBVERSION@
SHELL = @MAKE_SHELL@
RM = rm -f
prefix = @prefix@
exec_prefix = @exec_prefix@
datarootdir = @datarootdir@
bindir = @bindir@
srcdir = @srcdir@
datadir = @datadir@
VPATH = @srcdir@
top_srcdir = @top_srcdir@
#BUILD_DIR = .
BUILD_DIR = @BUILD_DIR@
installdir = $(datadir)/readline
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
EXEEXT = @EXEEXT@
OBJEXT = @OBJEXT@
# Support an alternate destination root directory for package building
DESTDIR =
DEFS = @DEFS@
CC = @CC@
CFLAGS = @CFLAGS@
LOCAL_CFLAGS = @LOCAL_CFLAGS@ -DREADLINE_LIBRARY -DRL_LIBRARY_VERSION='"$(RL_LIBRARY_VERSION)"'
CPPFLAGS = @CPPFLAGS@
INCLUDES = -I$(srcdir) -I$(top_srcdir) -I..
CCFLAGS = $(ASAN_CFLAGS) $(DEFS) $(LOCAL_CFLAGS) $(INCLUDES) $(CPPFLAGS) \
$(CFLAGS)
LDFLAGS = -g -L.. @LDFLAGS@ $(ASAN_LDFLAGS)
ASAN_XCFLAGS = -fsanitize=address -fno-omit-frame-pointer
ASAN_XLDFLAGS = -fsanitize=address
READLINE_LIB = ../libreadline.a
HISTORY_LIB = ../libhistory.a
TERMCAP_LIB = @TERMCAP_LIB@
.c.o:
${RM} $@
$(CC) $(CCFLAGS) -c $<
SOURCES = excallback.c fileman.c histexamp.c manexamp.c rl-fgets.c rl.c \
rlbasic.c rlcat.c rlevent.c rlptytest.c rltest.c rlversion.c \
rltest2.c rl-callbacktest.c hist_erasedups.c hist_purgecmd.c \
rlkeymaps.c rl-timeout.c
EXECUTABLES = fileman$(EXEEXT) rltest$(EXEEXT) rl$(EXEEXT) rlcat$(EXEEXT) \
rlevent$(EXEEXT) rlversion$(EXEEXT) histexamp$(EXEEXT) \
rl-callbacktest$(EXEEXT) rlbasic$(EXEEXT) \
hist_erasedups$(EXEEXT) hist_purgecmd$(EXEEXT) \
rlkeymaps$(EXEEXT) rl-timeout$(EXEEXT)
OBJECTS = fileman.o rltest.o rl.o rlevent.o rlcat.o rlversion.o histexamp.o \
rltest2.o rl-callbacktest.o rlbasic.o hist_erasedups.o hist_purgecmd.o \
rlkeymaps.o rl-timeout.o
OTHEREXE = rlptytest$(EXEEXT)
OTHEROBJ = rlptytest.o
all: $(EXECUTABLES)
everything: all
asan:
${MAKE} ${MFLAGS} ASAN_CFLAGS='${ASAN_XCFLAGS}' ASAN_LDFLAGS='${ASAN_XLDFLAGS}' all
check: rlversion$(EXEEXT)
@echo Readline version: `rlversion$(EXEEXT)`
installdirs:
-$(SHELL) $(top_srcdir)/support/mkdirs $(DESTDIR)$(installdir)
install: installdirs
@for f in $(SOURCES); do \
$(RM) $(DESTDIR)$(installdir)/$$f ; \
$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(installdir) ; \
done
uninstall:
@for f in $(SOURCES); do \
$(RM) $(DESTDIR)$(installdir)/$$f ; \
done
-rmdir $(DESTDIR)$(installdir)
rl$(EXEEXT): rl.o $(READLINE_LIB)
$(CC) $(LDFLAGS) -o $@ rl.o $(READLINE_LIB) $(TERMCAP_LIB)
rlbasic$(EXEEXT): rlbasic.o $(READLINE_LIB)
$(CC) $(LDFLAGS) -o $@ rlbasic.o $(READLINE_LIB) $(TERMCAP_LIB)
rlcat$(EXEEXT): rlcat.o $(READLINE_LIB)
$(CC) $(LDFLAGS) -o $@ rlcat.o $(READLINE_LIB) $(TERMCAP_LIB)
rlevent$(EXEEXT): rlevent.o $(READLINE_LIB)
$(CC) $(LDFLAGS) -o $@ rlevent.o $(READLINE_LIB) $(TERMCAP_LIB)
rlkeymaps$(EXEEXT): rlkeymaps.o $(READLINE_LIB)
$(CC) $(LDFLAGS) -o $@ rlkeymaps.o $(READLINE_LIB) $(TERMCAP_LIB)
fileman$(EXEEXT): fileman.o $(READLINE_LIB)
$(CC) $(LDFLAGS) -o $@ fileman.o $(READLINE_LIB) $(TERMCAP_LIB)
rltest$(EXEEXT): rltest.o $(READLINE_LIB)
$(CC) $(LDFLAGS) -o $@ rltest.o $(READLINE_LIB) $(TERMCAP_LIB)
rltest2$(EXEEXT): rltest2.o $(READLINE_LIB)
$(CC) $(LDFLAGS) -o $@ rltest2.o $(READLINE_LIB) $(TERMCAP_LIB)
rl-callbacktest$(EXEEXT): rl-callbacktest.o $(READLINE_LIB)
$(CC) $(LDFLAGS) -o $@ rl-callbacktest.o $(READLINE_LIB) $(TERMCAP_LIB)
rlptytest$(EXEEXT): rlptytest.o $(READLINE_LIB)
$(CC) $(LDFLAGS) -o $@ rlptytest.o $(READLINE_LIB) $(TERMCAP_LIB) $(LIBUTIL)
rl-timeout$(EXEEXT): rl-timeout.o $(READLINE_LIB)
$(CC) $(LDFLAGS) -o $@ rl-timeout.o $(READLINE_LIB) $(TERMCAP_LIB)
rlversion$(EXEEXT): rlversion.o $(READLINE_LIB)
$(CC) $(LDFLAGS) -o $@ rlversion.o $(READLINE_LIB) $(TERMCAP_LIB)
histexamp$(EXEEXT): histexamp.o $(HISTORY_LIB)
$(CC) $(LDFLAGS) -o $@ histexamp.o -lhistory $(TERMCAP_LIB)
hist_erasedups$(EXEEXT): hist_erasedups.o $(HISTORY_LIB)
$(CC) $(LDFLAGS) -o $@ hist_erasedups.o -lhistory $(TERMCAP_LIB)
hist_purgecmd$(EXEEXT): hist_purgecmd.o $(HISTORY_LIB)
$(CC) $(LDFLAGS) -o $@ hist_purgecmd.o -lhistory $(TERMCAP_LIB)
clean mostlyclean:
$(RM) $(OBJECTS) $(OTHEROBJ)
$(RM) $(EXECUTABLES) $(OTHEREXE) *.exe
distclean maintainer-clean: clean
$(RM) Makefile
fileman.o: fileman.c
rltest.o: rltest.c
rltest2.o: rltest2.c
rl.o: rl.c
rlversion.o: rlversion.c
histexamp.o: histexamp.c
hist_erasedups.o: hist_erasedups.c
hist_purgecmd.o: hist_purgecmd.c
rlbasic.o: rlbasic.c
rlkeymaps.o: rlkeymaps.c
rlcat.o: rlcat.c
rlptytest.o: rlptytest.c
rl-callbacktest.o: rl-callbacktest.c
rl-timeout.o: rl-timeout.c
fileman.o: $(top_srcdir)/readline.h
rltest.o: $(top_srcdir)/readline.h
rltest2.o: $(top_srcdir)/readline.h $(top_srcdir)/history.h
rl.o: $(top_srcdir)/readline.h
rlversion.o: $(top_srcdir)/readline.h
histexamp.o: $(top_srcdir)/history.h
hist_erasedups.o: $(top_srcdir)/history.h
hist_purgecmd.o: $(top_srcdir)/history.h
rlbasic.o: $(top_srcdir)/readline.h $(top_srcdir)/history.h
rlcat.o: $(top_srcdir)/readline.h $(top_srcdir)/history.h
rlptytest.o: $(top_srcdir)/readline.h $(top_srcdir)/history.h
rl-callbacktest.o: $(top_srcdir)/readline.h $(top_srcdir)/history.h
rl-timeout.o: $(top_srcdir)/readline.h $(top_srcdir)/history.h

View file

@ -0,0 +1,41 @@
AC_DEFUN([BASH_CHECK_LIB_TERMCAP],
[
if test "X$bash_cv_termcap_lib" = "X"; then
_bash_needmsg=yes
else
AC_MSG_CHECKING(which library has the termcap functions)
_bash_needmsg=
fi
AC_CACHE_VAL(bash_cv_termcap_lib,
[AC_CHECK_FUNC(tgetent, bash_cv_termcap_lib=libc,
[AC_CHECK_LIB(termcap, tgetent, bash_cv_termcap_lib=libtermcap,
[AC_CHECK_LIB(tinfo, tgetent, bash_cv_termcap_lib=libtinfo,
[AC_CHECK_LIB(curses, tgetent, bash_cv_termcap_lib=libcurses,
[AC_CHECK_LIB(ncurses, tgetent, bash_cv_termcap_lib=libncurses,
[AC_CHECK_LIB(ncursesw, tgetent, bash_cv_termcap_lib=libncursesw,
bash_cv_termcap_lib=gnutermcap)])])])])])])
if test "X$_bash_needmsg" = "Xyes"; then
AC_MSG_CHECKING(which library has the termcap functions)
fi
AC_MSG_RESULT(using $bash_cv_termcap_lib)
if test $bash_cv_termcap_lib = gnutermcap && test -z "$prefer_curses"; then
LDFLAGS="$LDFLAGS -L./lib/termcap"
TERMCAP_LIB="./lib/termcap/libtermcap.a"
TERMCAP_DEP="./lib/termcap/libtermcap.a"
elif test $bash_cv_termcap_lib = libtermcap && test -z "$prefer_curses"; then
TERMCAP_LIB=-ltermcap
TERMCAP_DEP=
elif test $bash_cv_termcap_lib = libtinfo; then
TERMCAP_LIB=-ltinfo
TERMCAP_DEP=
elif test $bash_cv_termcap_lib = libncurses; then
TERMCAP_LIB=-lncurses
TERMCAP_DEP=
elif test $bash_cv_termcap_lib = libc; then
TERMCAP_LIB=
TERMCAP_DEP=
else
TERMCAP_LIB=-lcurses
TERMCAP_DEP=
fi
])

View file

@ -0,0 +1,119 @@
dnl need: prefix exec_prefix libdir includedir CC TERMCAP_LIB
dnl require:
dnl AC_PROG_CC
dnl BASH_CHECK_LIB_TERMCAP
AC_DEFUN([RL_LIB_READLINE_VERSION],
[
AC_REQUIRE([BASH_CHECK_LIB_TERMCAP])
AC_MSG_CHECKING([version of installed readline library])
# What a pain in the ass this is.
# save cpp and ld options
_save_CFLAGS="$CFLAGS"
_save_LDFLAGS="$LDFLAGS"
_save_LIBS="$LIBS"
# Don't set ac_cv_rl_prefix if the caller has already assigned a value. This
# allows the caller to do something like $_rl_prefix=$withval if the user
# specifies --with-installed-readline=PREFIX as an argument to configure
if test -z "$ac_cv_rl_prefix"; then
test "x$prefix" = xNONE && ac_cv_rl_prefix=$ac_default_prefix || ac_cv_rl_prefix=${prefix}
fi
eval ac_cv_rl_includedir=${ac_cv_rl_prefix}/include
eval ac_cv_rl_libdir=${ac_cv_rl_prefix}/lib
LIBS="$LIBS -lreadline ${TERMCAP_LIB}"
CFLAGS="$CFLAGS -I${ac_cv_rl_includedir}"
LDFLAGS="$LDFLAGS -L${ac_cv_rl_libdir}"
AC_CACHE_VAL(ac_cv_rl_version,
[AC_TRY_RUN([
#include <stdio.h>
#include <readline/readline.h>
#include <stdlib.h>
extern int rl_gnu_readline_p;
main()
{
FILE *fp;
fp = fopen("conftest.rlv", "w");
if (fp == 0)
exit(1);
if (rl_gnu_readline_p != 1)
fprintf(fp, "0.0\n");
else
fprintf(fp, "%s\n", rl_library_version ? rl_library_version : "0.0");
fclose(fp);
exit(0);
}
],
ac_cv_rl_version=`cat conftest.rlv`,
ac_cv_rl_version='0.0',
ac_cv_rl_version='4.2')])
CFLAGS="$_save_CFLAGS"
LDFLAGS="$_save_LDFLAGS"
LIBS="$_save_LIBS"
RL_MAJOR=0
RL_MINOR=0
# (
case "$ac_cv_rl_version" in
2*|3*|4*|5*|6*|7*|8*|9*)
RL_MAJOR=`echo $ac_cv_rl_version | sed 's:\..*$::'`
RL_MINOR=`echo $ac_cv_rl_version | sed -e 's:^.*\.::' -e 's:[[a-zA-Z]]*$::'`
;;
esac
# (((
case $RL_MAJOR in
[[0-9][0-9]]) _RL_MAJOR=$RL_MAJOR ;;
[[0-9]]) _RL_MAJOR=0$RL_MAJOR ;;
*) _RL_MAJOR=00 ;;
esac
# (((
case $RL_MINOR in
[[0-9][0-9]]) _RL_MINOR=$RL_MINOR ;;
[[0-9]]) _RL_MINOR=0$RL_MINOR ;;
*) _RL_MINOR=00 ;;
esac
RL_VERSION="0x${_RL_MAJOR}${_RL_MINOR}"
# Readline versions greater than 4.2 have these defines in readline.h
if test $ac_cv_rl_version = '0.0' ; then
AC_MSG_WARN([Could not test version of installed readline library.])
elif test $RL_MAJOR -gt 4 || { test $RL_MAJOR = 4 && test $RL_MINOR -gt 2 ; } ; then
# set these for use by the caller
RL_PREFIX=$ac_cv_rl_prefix
RL_LIBDIR=$ac_cv_rl_libdir
RL_INCLUDEDIR=$ac_cv_rl_includedir
AC_MSG_RESULT($ac_cv_rl_version)
else
AC_DEFINE_UNQUOTED(RL_READLINE_VERSION, $RL_VERSION, [encoded version of the installed readline library])
AC_DEFINE_UNQUOTED(RL_VERSION_MAJOR, $RL_MAJOR, [major version of installed readline library])
AC_DEFINE_UNQUOTED(RL_VERSION_MINOR, $RL_MINOR, [minor version of installed readline library])
AC_SUBST(RL_VERSION)
AC_SUBST(RL_MAJOR)
AC_SUBST(RL_MINOR)
# set these for use by the caller
RL_PREFIX=$ac_cv_rl_prefix
RL_LIBDIR=$ac_cv_rl_libdir
RL_INCLUDEDIR=$ac_cv_rl_includedir
AC_MSG_RESULT($ac_cv_rl_version)
fi
])

View file

@ -0,0 +1,76 @@
dnl Borut Razem
dnl
dnl This macro checks for the presence of the readline library.
dnl It works also in cross-compilation environment.
dnl
dnl To get it into the aclocal.m4 dnl file, do this:
dnl aclocal -I . --verbose
dnl
dnl The --verbose will show all of the files that are searched
dnl for .m4 macros.
AC_DEFUN([wi_LIB_READLINE], [
dnl check for the readline.h header file
AC_CHECK_HEADER(readline/readline.h)
if test "$ac_cv_header_readline_readline_h" = yes; then
dnl check the readline version
cat > conftest.$ac_ext <<EOF
#include <stdio.h>
#include <readline/readline.h>
wi_LIB_READLINE_VERSION RL_VERSION_MAJOR RL_VERSION_MINOR
EOF
wi_READLINE_VERSION=$($CPP $CPPFLAGS conftest.$ac_ext | sed -n -e "s/^wi_LIB_READLINE_VERSION *\([[0-9\]][[0-9\]]*\) *\([[0-9\]][[0-9\]]*\)$/\1.\2/p")
rm -rf conftest*
if test -n "$wi_READLINE_VERSION"; then
wi_MAJOR=$(expr $wi_READLINE_VERSION : '\([[0-9]][[0-9]]*\)\.')
wi_MINOR=$(expr $wi_READLINE_VERSION : '[[0-9]][[0-9]]*\.\([[0-9]][[0-9]]*$\)')
if test $wi_MINOR -lt 10; then
wi_MINOR=$(expr $wi_MINOR \* 10)
fi
wi_READLINE_VERSION=$(expr $wi_MAJOR \* 100 + $wi_MINOR)
else
wi_READLINE_VERSION=-1
fi
dnl check for the readline library
ac_save_LIBS="$LIBS"
# Note: $LIBCURSES is permitted to be empty.
for LIBREADLINE in "-lreadline.dll" "-lreadline" "-lreadline $LIBCURSES" "-lreadline -ltermcap" "-lreadline -lncurses" "-lreadline -lcurses"
do
AC_MSG_CHECKING([for GNU Readline library $LIBREADLINE])
LIBS="$ac_save_LIBS $LIBREADLINE"
AC_TRY_LINK([
/* includes */
#include <stdio.h>
#include <readline/readline.h>
],[
/* function-body */
int dummy = rl_completion_append_character; /* rl_completion_append_character appeared in version 2.1 */
readline(NULL);
],[
wi_cv_lib_readline=yes
AC_MSG_RESULT(yes)
],[
wi_cv_lib_readline=no
AC_MSG_RESULT(no)
])
if test "$wi_cv_lib_readline" = yes; then
AC_SUBST(LIBREADLINE)
AC_DEFINE_UNQUOTED(HAVE_LIBREADLINE, $wi_READLINE_VERSION, [Readline])
break
fi
done
LIBS="$ac_save_LIBS"
fi
])

200
examples/excallback.c Normal file
View file

@ -0,0 +1,200 @@
/*
From: Jeff Solomon <jsolomon@stanford.edu>
Date: Fri, 9 Apr 1999 10:13:27 -0700 (PDT)
To: chet@po.cwru.edu
Subject: new readline example
Message-ID: <14094.12094.527305.199695@mrclean.Stanford.EDU>
Chet,
I've been using readline 4.0. Specifically, I've been using the perl
version Term::ReadLine::Gnu. It works great.
Anyway, I've been playing around the alternate interface and I wanted
to contribute a little C program, callback.c, to you that you could
use as an example of the alternate interface in the /examples
directory of the readline distribution.
My example shows how, using the alternate interface, you can
interactively change the prompt (which is very nice imo). Also, I
point out that you must roll your own terminal setting when using the
alternate interface because readline depreps (using your parlance) the
terminal while in the user callback. I try to demostrate what I mean
with an example. I've included the program below.
To compile, I just put the program in the examples directory and made
the appropriate changes to the EXECUTABLES and OBJECTS line and added
an additional target 'callback'.
I compiled on my Sun Solaris2.6 box using Sun's cc.
Let me know what you think.
Jeff
*/
/*
Copyright (C) 1999 Jeff Solomon
*/
#if defined (HAVE_CONFIG_H)
#include <config.h>
#endif
#include <sys/types.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <termios.h> /* xxx - should make this more general */
#include <locale.h>
#ifdef READLINE_LIBRARY
# include "readline.h"
#else
# include <readline/readline.h>
#endif
#ifndef STDIN_FILENO
# define STDIN_FILENO 0
#endif
/* This little examples demonstrates the alternate interface to using readline.
* In the alternate interface, the user maintains control over program flow and
* only calls readline when STDIN is readable. Using the alternate interface,
* you can do anything else while still using readline (like talking to a
* network or another program) without blocking.
*
* Specifically, this program highlights two importants features of the
* alternate interface. The first is the ability to interactively change the
* prompt, which can't be done using the regular interface since rl_prompt is
* read-only.
*
* The second feature really highlights a subtle point when using the alternate
* interface. That is, readline will not alter the terminal when inside your
* callback handler. So let's so, your callback executes a user command that
* takes a non-trivial amount of time to complete (seconds). While your
* executing the command, the user continues to type keystrokes and expects them
* to be re-echoed on the new prompt when it returns. Unfortunately, the default
* terminal configuration doesn't do this. After the prompt returns, the user
* must hit one additional keystroke and then will see all of his previous
* keystrokes. To illustrate this, compile and run this program. Type "sleep" at
* the prompt and then type "bar" before the prompt returns (you have 3
* seconds). Notice how "bar" is re-echoed on the prompt after the prompt
* returns? This is what you expect to happen. Now comment out the 4 lines below
* the line that says COMMENT LINE BELOW. Recompile and rerun the program and do
* the same thing. When the prompt returns, you should not see "bar". Now type
* "f", see how "barf" magically appears? This behavior is un-expected and not
* desired.
*/
void process_line(char *line);
int change_prompt(void);
char *get_prompt(void);
int prompt = 1;
char prompt_buf[40], line_buf[256];
tcflag_t old_lflag;
cc_t old_vtime;
struct termios term;
int
main()
{
fd_set fds;
setlocale (LC_ALL, "");
/* Adjust the terminal slightly before the handler is installed. Disable
* canonical mode processing and set the input character time flag to be
* non-blocking.
*/
if( tcgetattr(STDIN_FILENO, &term) < 0 ) {
perror("tcgetattr");
exit(1);
}
old_lflag = term.c_lflag;
old_vtime = term.c_cc[VTIME];
term.c_lflag &= ~ICANON;
term.c_cc[VTIME] = 1;
/* COMMENT LINE BELOW - see above */
if( tcsetattr(STDIN_FILENO, TCSANOW, &term) < 0 ) {
perror("tcsetattr");
exit(1);
}
rl_add_defun("change-prompt", change_prompt, CTRL('t'));
rl_callback_handler_install(get_prompt(), process_line);
while(1) {
FD_ZERO(&fds);
FD_SET(fileno(stdin), &fds);
if( select(FD_SETSIZE, &fds, NULL, NULL, NULL) < 0) {
perror("select");
exit(1);
}
if( FD_ISSET(fileno(stdin), &fds) ) {
rl_callback_read_char();
}
}
}
void
process_line(char *line)
{
if( line == NULL ) {
fprintf(stderr, "\n", line);
/* reset the old terminal setting before exiting */
term.c_lflag = old_lflag;
term.c_cc[VTIME] = old_vtime;
if( tcsetattr(STDIN_FILENO, TCSANOW, &term) < 0 ) {
perror("tcsetattr");
exit(1);
}
exit(0);
}
if( strcmp(line, "sleep") == 0 ) {
sleep(3);
} else {
fprintf(stderr, "|%s|\n", line);
}
free (line);
}
int
change_prompt(void)
{
/* toggle the prompt variable */
prompt = !prompt;
/* save away the current contents of the line */
strcpy(line_buf, rl_line_buffer);
/* install a new handler which will change the prompt and erase the current line */
rl_callback_handler_install(get_prompt(), process_line);
/* insert the old text on the new line */
rl_insert_text(line_buf);
/* redraw the current line - this is an undocumented function. It invokes the
* redraw-current-line command.
*/
rl_refresh_line(0, 0);
}
char *
get_prompt(void)
{
/* The prompts can even be different lengths! */
sprintf(prompt_buf, "%s",
prompt ? "Hit ctrl-t to toggle prompt> " : "Pretty cool huh?> ");
return prompt_buf;
}

506
examples/fileman.c Normal file
View file

@ -0,0 +1,506 @@
/* fileman.c - file manager example for readline library. */
/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library for
reading lines of text with interactive input and history editing.
Readline 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 3 of the License, or
(at your option) any later version.
Readline 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 Readline. If not, see <http://www.gnu.org/licenses/>.
*/
/* fileman.c -- A tiny application which demonstrates how to use the
GNU Readline library. This application interactively allows users
to manipulate files and their modes. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <sys/types.h>
#ifdef HAVE_SYS_FILE_H
# include <sys/file.h>
#endif
#include <sys/stat.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#if defined (HAVE_STRING_H)
# include <string.h>
#else /* !HAVE_STRING_H */
# include <strings.h>
#endif /* !HAVE_STRING_H */
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif
#include <time.h>
#ifdef READLINE_LIBRARY
# include "readline.h"
# include "history.h"
#else
# include <readline/readline.h>
# include <readline/history.h>
#endif
extern char *xmalloc PARAMS((size_t));
void initialize_readline PARAMS((void));
void too_dangerous PARAMS((char *));
int execute_line PARAMS((char *));
int valid_argument PARAMS((char *, char *));
/* The names of functions that actually do the manipulation. */
int com_list PARAMS((char *));
int com_view PARAMS((char *));
int com_rename PARAMS((char *));
int com_stat PARAMS((char *));
int com_pwd PARAMS((char *));
int com_delete PARAMS((char *));
int com_help PARAMS((char *));
int com_cd PARAMS((char *));
int com_quit PARAMS((char *));
/* A structure which contains information on the commands this program
can understand. */
typedef struct {
char *name; /* User printable name of the function. */
rl_icpfunc_t *func; /* Function to call to do the job. */
char *doc; /* Documentation for this function. */
} COMMAND;
COMMAND commands[] = {
{ "cd", com_cd, "Change to directory DIR" },
{ "delete", com_delete, "Delete FILE" },
{ "help", com_help, "Display this text" },
{ "?", com_help, "Synonym for `help'" },
{ "list", com_list, "List files in DIR" },
{ "ls", com_list, "Synonym for `list'" },
{ "pwd", com_pwd, "Print the current working directory" },
{ "quit", com_quit, "Quit using Fileman" },
{ "rename", com_rename, "Rename FILE to NEWNAME" },
{ "stat", com_stat, "Print out statistics on FILE" },
{ "view", com_view, "View the contents of FILE" },
{ (char *)NULL, (rl_icpfunc_t *)NULL, (char *)NULL }
};
/* Forward declarations. */
char *stripwhite ();
COMMAND *find_command ();
/* The name of this program, as taken from argv[0]. */
char *progname;
/* When non-zero, this global means the user is done using this program. */
int done;
char *
dupstr (s)
char *s;
{
char *r;
r = xmalloc (strlen (s) + 1);
strcpy (r, s);
return (r);
}
int
main (argc, argv)
int argc;
char **argv;
{
char *line, *s;
progname = argv[0];
initialize_readline (); /* Bind our completer. */
/* Loop reading and executing lines until the user quits. */
for ( ; done == 0; )
{
line = readline ("FileMan: ");
if (!line)
break;
/* Remove leading and trailing whitespace from the line.
Then, if there is anything left, add it to the history list
and execute it. */
s = stripwhite (line);
if (*s)
{
add_history (s);
execute_line (s);
}
free (line);
}
exit (0);
}
/* Execute a command line. */
int
execute_line (line)
char *line;
{
register int i;
COMMAND *command;
char *word;
/* Isolate the command word. */
i = 0;
while (line[i] && whitespace (line[i]))
i++;
word = line + i;
while (line[i] && !whitespace (line[i]))
i++;
if (line[i])
line[i++] = '\0';
command = find_command (word);
if (!command)
{
fprintf (stderr, "%s: No such command for FileMan.\n", word);
return (-1);
}
/* Get argument to command, if any. */
while (whitespace (line[i]))
i++;
word = line + i;
/* Call the function. */
return ((*(command->func)) (word));
}
/* Look up NAME as the name of a command, and return a pointer to that
command. Return a NULL pointer if NAME isn't a command name. */
COMMAND *
find_command (name)
char *name;
{
register int i;
for (i = 0; commands[i].name; i++)
if (strcmp (name, commands[i].name) == 0)
return (&commands[i]);
return ((COMMAND *)NULL);
}
/* Strip whitespace from the start and end of STRING. Return a pointer
into STRING. */
char *
stripwhite (string)
char *string;
{
register char *s, *t;
for (s = string; whitespace (*s); s++)
;
if (*s == 0)
return (s);
t = s + strlen (s) - 1;
while (t > s && whitespace (*t))
t--;
*++t = '\0';
return s;
}
/* **************************************************************** */
/* */
/* Interface to Readline Completion */
/* */
/* **************************************************************** */
char *command_generator PARAMS((const char *, int));
char **fileman_completion PARAMS((const char *, int, int));
/* Tell the GNU Readline library how to complete. We want to try to complete
on command names if this is the first word in the line, or on filenames
if not. */
void
initialize_readline ()
{
/* Allow conditional parsing of the ~/.inputrc file. */
rl_readline_name = "FileMan";
/* Tell the completer that we want a crack first. */
rl_attempted_completion_function = fileman_completion;
}
/* Attempt to complete on the contents of TEXT. START and END bound the
region of rl_line_buffer that contains the word to complete. TEXT is
the word to complete. We can use the entire contents of rl_line_buffer
in case we want to do some simple parsing. Return the array of matches,
or NULL if there aren't any. */
char **
fileman_completion (text, start, end)
const char *text;
int start, end;
{
char **matches;
matches = (char **)NULL;
/* If this word is at the start of the line, then it is a command
to complete. Otherwise it is the name of a file in the current
directory. */
if (start == 0)
matches = rl_completion_matches (text, command_generator);
return (matches);
}
/* Generator function for command completion. STATE lets us know whether
to start from scratch; without any state (i.e. STATE == 0), then we
start at the top of the list. */
char *
command_generator (text, state)
const char *text;
int state;
{
static int list_index, len;
char *name;
/* If this is a new word to complete, initialize now. This includes
saving the length of TEXT for efficiency, and initializing the index
variable to 0. */
if (!state)
{
list_index = 0;
len = strlen (text);
}
/* Return the next name which partially matches from the command list. */
while (name = commands[list_index].name)
{
list_index++;
if (strncmp (name, text, len) == 0)
return (dupstr(name));
}
/* If no names matched, then return NULL. */
return ((char *)NULL);
}
/* **************************************************************** */
/* */
/* FileMan Commands */
/* */
/* **************************************************************** */
/* String to pass to system (). This is for the LIST, VIEW and RENAME
commands. */
static char syscom[1024];
/* List the file(s) named in arg. */
int
com_list (arg)
char *arg;
{
if (!arg)
arg = "";
sprintf (syscom, "ls -FClg %s", arg);
return (system (syscom));
}
int
com_view (arg)
char *arg;
{
if (!valid_argument ("view", arg))
return 1;
#if defined (__MSDOS__)
/* more.com doesn't grok slashes in pathnames */
sprintf (syscom, "less %s", arg);
#else
sprintf (syscom, "more %s", arg);
#endif
return (system (syscom));
}
int
com_rename (arg)
char *arg;
{
too_dangerous ("rename");
return (1);
}
int
com_stat (arg)
char *arg;
{
struct stat finfo;
if (!valid_argument ("stat", arg))
return (1);
if (stat (arg, &finfo) == -1)
{
perror (arg);
return (1);
}
printf ("Statistics for `%s':\n", arg);
printf ("%s has %d link%s, and is %lu byte%s in length.\n",
arg,
finfo.st_nlink,
(finfo.st_nlink == 1) ? "" : "s",
(unsigned long)finfo.st_size,
(finfo.st_size == 1) ? "" : "s");
printf ("Inode Last Change at: %s", ctime (&finfo.st_ctime));
printf (" Last access at: %s", ctime (&finfo.st_atime));
printf (" Last modified at: %s", ctime (&finfo.st_mtime));
return (0);
}
int
com_delete (arg)
char *arg;
{
too_dangerous ("delete");
return (1);
}
/* Print out help for ARG, or for all of the commands if ARG is
not present. */
int
com_help (arg)
char *arg;
{
register int i;
int printed = 0;
for (i = 0; commands[i].name; i++)
{
if (!*arg || (strcmp (arg, commands[i].name) == 0))
{
printf ("%s\t\t%s.\n", commands[i].name, commands[i].doc);
printed++;
}
}
if (!printed)
{
printf ("No commands match `%s'. Possibilities are:\n", arg);
for (i = 0; commands[i].name; i++)
{
/* Print in six columns. */
if (printed == 6)
{
printed = 0;
printf ("\n");
}
printf ("%s\t", commands[i].name);
printed++;
}
if (printed)
printf ("\n");
}
return (0);
}
/* Change to the directory ARG. */
int
com_cd (arg)
char *arg;
{
if (chdir (arg) == -1)
{
perror (arg);
return 1;
}
com_pwd ("");
return (0);
}
/* Print out the current working directory. */
int
com_pwd (ignore)
char *ignore;
{
char dir[1024], *s;
s = getcwd (dir, sizeof(dir) - 1);
if (s == 0)
{
printf ("Error getting pwd: %s\n", dir);
return 1;
}
printf ("Current directory is %s\n", dir);
return 0;
}
/* The user wishes to quit using this program. Just set DONE non-zero. */
int
com_quit (arg)
char *arg;
{
done = 1;
return (0);
}
/* Function which tells you that you can't do this. */
void
too_dangerous (caller)
char *caller;
{
fprintf (stderr,
"%s: Too dangerous for me to distribute. Write it yourself.\n",
caller);
}
/* Return non-zero if ARG is a valid argument for CALLER, else print
an error message and return zero. */
int
valid_argument (caller, arg)
char *caller, *arg;
{
if (!arg || !*arg)
{
fprintf (stderr, "%s: Argument required.\n", caller);
return (0);
}
return (1);
}

121
examples/hist_erasedups.c Normal file
View file

@ -0,0 +1,121 @@
/* hist_erasedups -- remove all duplicate entries from history file */
/* Copyright (C) 2011 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library for
reading lines of text with interactive input and history editing.
Readline 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 3 of the License, or
(at your option) any later version.
Readline 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 Readline. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef READLINE_LIBRARY
#define READLINE_LIBRARY 1
#endif
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#ifdef READLINE_LIBRARY
# include "history.h"
#else
# include <readline/history.h>
#endif
#include <string.h>
#define STREQ(a, b) ((a)[0] == (b)[0] && strcmp(a, b) == 0)
#define STREQN(a, b, n) ((n == 0) ? (1) \
: ((a)[0] == (b)[0] && strncmp(a, b, n) == 0))
int hist_erasedups (void);
static void
usage()
{
fprintf (stderr, "hist_erasedups: usage: hist_erasedups [-t] [filename]\n");
exit (2);
}
int
main (argc, argv)
int argc;
char **argv;
{
char *fn;
int r;
while ((r = getopt (argc, argv, "t")) != -1)
{
switch (r)
{
case 't':
history_write_timestamps = 1;
break;
default:
usage ();
}
}
argv += optind;
argc -= optind;
fn = argc ? argv[0] : getenv ("HISTFILE");
if (fn == 0)
{
fprintf (stderr, "hist_erasedups: no history file\n");
usage ();
}
if ((r = read_history (fn)) != 0)
{
fprintf (stderr, "hist_erasedups: read_history: %s: %s\n", fn, strerror (r));
exit (1);
}
hist_erasedups ();
if ((r = write_history (fn)) != 0)
{
fprintf (stderr, "hist_erasedups: write_history: %s: %s\n", fn, strerror (r));
exit (1);
}
exit (0);
}
int
hist_erasedups ()
{
int r, n;
HIST_ENTRY *h, *temp;
using_history ();
while (h = previous_history ())
{
r = where_history ();
for (n = 0; n < r; n++)
{
temp = history_get (n+history_base);
if (STREQ (h->line, temp->line))
{
remove_history (n);
r--; /* have to get one fewer now */
n--; /* compensate for above increment */
history_offset--; /* moving backwards in history list */
}
}
}
using_history ();
return r;
}

151
examples/hist_purgecmd.c Normal file
View file

@ -0,0 +1,151 @@
/* hist_purgecmd -- remove all instances of command or pattern from history
file */
/* Copyright (C) 2011 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library for
reading lines of text with interactive input and history editing.
Readline 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 3 of the License, or
(at your option) any later version.
Readline 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 Readline. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef READLINE_LIBRARY
#define READLINE_LIBRARY 1
#endif
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <regex.h>
#ifdef READLINE_LIBRARY
# include "history.h"
#else
# include <readline/history.h>
#endif
#include <string.h>
#define STREQ(a, b) ((a)[0] == (b)[0] && strcmp(a, b) == 0)
#define STREQN(a, b, n) ((n == 0) ? (1) \
: ((a)[0] == (b)[0] && strncmp(a, b, n) == 0))
#define PURGE_REGEXP 0x01
int hist_purgecmd (char *, int);
static void
usage()
{
fprintf (stderr, "hist_purgecmd: usage: hist_purgecmd [-r] [-t] [-f filename] command-spec\n");
exit (2);
}
int
main (argc, argv)
int argc;
char **argv;
{
char *fn;
int r, flags;
flags = 0;
fn = 0;
while ((r = getopt (argc, argv, "f:rt")) != -1)
{
switch (r)
{
case 'f':
fn = optarg;
break;
case 'r':
flags |= PURGE_REGEXP;
break;
case 't':
history_write_timestamps = 1;
break;
default:
usage ();
}
}
argv += optind;
argc -= optind;
if (fn == 0)
fn = getenv ("HISTFILE");
if (fn == 0)
{
fprintf (stderr, "hist_purgecmd: no history file\n");
usage ();
}
if ((r = read_history (fn)) != 0)
{
fprintf (stderr, "hist_purgecmd: read_history: %s: %s\n", fn, strerror (r));
exit (1);
}
for (r = 0; r < argc; r++)
hist_purgecmd (argv[r], flags);
if ((r = write_history (fn)) != 0)
{
fprintf (stderr, "hist_purgecmd: write_history: %s: %s\n", fn, strerror (r));
exit (1);
}
exit (0);
}
int
hist_purgecmd (cmd, flags)
char *cmd;
int flags;
{
int r, n, rflags;
HIST_ENTRY *temp;
regex_t regex = { 0 };
if (flags & PURGE_REGEXP)
{
rflags = REG_EXTENDED|REG_NOSUB;
if (regcomp (&regex, cmd, rflags))
{
fprintf (stderr, "hist_purgecmd: %s: invalid regular expression\n", cmd);
return -1;
}
}
r = 0;
using_history ();
r = where_history ();
for (n = 0; n < r; n++)
{
temp = history_get (n+history_base);
if (((flags & PURGE_REGEXP) && (regexec (&regex, temp->line, 0, 0, 0) == 0)) ||
((flags & PURGE_REGEXP) == 0 && STREQ (temp->line, cmd)))
{
remove_history (n);
r--; /* have to get one fewer now */
n--; /* compensate for above increment */
history_offset--; /* moving backwards in history list */
}
}
using_history ();
if (flags & PURGE_REGEXP)
regfree (&regex);
return r;
}

128
examples/histexamp.c Normal file
View file

@ -0,0 +1,128 @@
/* histexamp.c - history library example program. */
/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library for
reading lines of text with interactive input and history editing.
Readline 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 3 of the License, or
(at your option) any later version.
Readline 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 Readline. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#ifdef READLINE_LIBRARY
# include "history.h"
#else
# include <readline/history.h>
#endif
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
int
main (argc, argv)
int argc;
char **argv;
{
char line[1024], *t;
int len, done;
line[0] = 0;
done = 0;
using_history ();
while (!done)
{
printf ("history$ ");
fflush (stdout);
t = fgets (line, sizeof (line) - 1, stdin);
if (t && *t)
{
len = strlen (t);
if (t[len - 1] == '\n')
t[len - 1] = '\0';
}
if (!t)
strcpy (line, "quit");
if (line[0])
{
char *expansion;
int result;
using_history ();
result = history_expand (line, &expansion);
if (result)
fprintf (stderr, "%s\n", expansion);
if (result < 0 || result == 2)
{
free (expansion);
continue;
}
add_history (expansion);
strncpy (line, expansion, sizeof (line) - 1);
free (expansion);
}
if (strcmp (line, "quit") == 0)
done = 1;
else if (strcmp (line, "save") == 0)
write_history ("history_file");
else if (strcmp (line, "read") == 0)
read_history ("history_file");
else if (strcmp (line, "list") == 0)
{
register HIST_ENTRY **the_list;
register int i;
time_t tt;
char timestr[128];
the_list = history_list ();
if (the_list)
for (i = 0; the_list[i]; i++)
{
tt = history_get_time (the_list[i]);
if (tt)
strftime (timestr, sizeof (timestr), "%a %R", localtime(&tt));
else
strcpy (timestr, "??");
printf ("%d: %s: %s\n", i + history_base, timestr, the_list[i]->line);
}
}
else if (strncmp (line, "delete", 6) == 0)
{
int which;
if ((sscanf (line + 6, "%d", &which)) == 1)
{
HIST_ENTRY *entry = remove_history (which);
if (!entry)
fprintf (stderr, "No such entry %d\n", which);
else
{
free (entry->line);
free (entry);
}
}
else
{
fprintf (stderr, "non-numeric arg given to `delete'\n");
}
}
}
}

111
examples/manexamp.c Normal file
View file

@ -0,0 +1,111 @@
/* manexamp.c -- The examples which appear in the documentation are here. */
/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library for
reading lines of text with interactive input and history editing.
Readline 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 3 of the License, or
(at your option) any later version.
Readline 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 Readline. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <readline/readline.h>
/* **************************************************************** */
/* */
/* How to Emulate gets () */
/* */
/* **************************************************************** */
/* A static variable for holding the line. */
static char *line_read = (char *)NULL;
/* Read a string, and return a pointer to it. Returns NULL on EOF. */
char *
rl_gets ()
{
/* If the buffer has already been allocated, return the memory
to the free pool. */
if (line_read)
{
free (line_read);
line_read = (char *)NULL;
}
/* Get a line from the user. */
line_read = readline ("");
/* If the line has any text in it, save it on the history. */
if (line_read && *line_read)
add_history (line_read);
return (line_read);
}
/* **************************************************************** */
/* */
/* Writing a Function to be Called by Readline. */
/* */
/* **************************************************************** */
/* Invert the case of the COUNT following characters. */
invert_case_line (count, key)
int count, key;
{
register int start, end;
start = rl_point;
if (count < 0)
{
direction = -1;
count = -count;
}
else
direction = 1;
/* Find the end of the range to modify. */
end = start + (count * direction);
/* Force it to be within range. */
if (end > rl_end)
end = rl_end;
else if (end < 0)
end = -1;
if (start > end)
{
int temp = start;
start = end;
end = temp;
}
if (start == end)
return;
/* Tell readline that we are modifying the line, so save the undo
information. */
rl_modifying (start, end);
for (; start != end; start += direction)
{
if (_rl_uppercase_p (rl_line_buffer[start]))
rl_line_buffer[start] = _rl_to_lower (rl_line_buffer[start]);
else if (_rl_lowercase_p (rl_line_buffer[start]))
rl_line_buffer[start] = _rl_to_upper (rl_line_buffer[start]);
}
/* Move point to on top of the last character changed. */
rl_point = end - direction;
}

139
examples/readlinebuf.h Normal file
View file

@ -0,0 +1,139 @@
/*******************************************************************************
* $Revision: 1.2 $
* $Date: 2001/09/11 06:19:36 $
* $Author: vyzo $
*
* Contents: A streambuf which uses the GNU readline library for line I/O
* (c) 2001 by Dimitris Vyzovitis [vyzo@media.mit.edu]
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the Free
* Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
******************************************************************************/
#ifndef _READLINEBUF_H_
#define _READLINEBUF_H_
#include <iostream>
#include <cstring>
#include <cassert>
#include <cstdlib>
#include <cstdio>
#include <readline/readline.h>
#include <readline/history.h>
#if (defined __GNUC__) && (__GNUC__ < 3)
#include <streambuf.h>
#else
#include <streambuf>
using std::streamsize;
using std::streambuf;
#endif
class readlinebuf : public streambuf {
public:
#if (defined __GNUC__) && (__GNUC__ < 3)
typedef char char_type;
typedef int int_type;
typedef streampos pos_type;
typedef streamoff off_type;
#endif
static const int_type eof = EOF; // this is -1
static const int_type not_eof = 0;
private:
const char* prompt_;
bool history_;
char* line_;
int low_;
int high_;
protected:
virtual int_type showmanyc() const { return high_ - low_; }
virtual streamsize xsgetn( char_type* buf, streamsize n ) {
int rd = n > (high_ - low_)? (high_ - low_) : n;
memcpy( buf, line_, rd );
low_ += rd;
if ( rd < n ) {
low_ = high_ = 0;
free( line_ ); // free( NULL ) is a noop
line_ = readline( prompt_ );
if ( line_ ) {
high_ = strlen( line_ );
if ( history_ && high_ ) add_history( line_ );
rd += xsgetn( buf + rd, n - rd );
}
}
return rd;
}
virtual int_type underflow() {
if ( high_ == low_ ) {
low_ = high_ = 0;
free( line_ ); // free( NULL ) is a noop
line_ = readline( prompt_ );
if ( line_ ) {
high_ = strlen( line_ );
if ( history_ && high_ ) add_history( line_ );
}
}
if ( low_ < high_ ) return line_[low_];
else return eof;
}
virtual int_type uflow() {
int_type c = underflow();
if ( c != eof ) ++low_;
return c;
}
virtual int_type pbackfail( int_type c = eof ) {
if ( low_ > 0 ) --low_;
else if ( c != eof ) {
if ( high_ > 0 ) {
char* nl = (char*)realloc( line_, high_ + 1 );
if ( nl ) {
line_ = (char*)memcpy( nl + 1, line_, high_ );
high_ += 1;
line_[0] = char( c );
} else return eof;
} else {
assert( !line_ );
line_ = (char*)malloc( sizeof( char ) );
*line_ = char( c );
high_ = 1;
}
} else return eof;
return not_eof;
}
public:
readlinebuf( const char* prompt = NULL, bool history = true )
: prompt_( prompt ), history_( history ),
line_( NULL ), low_( 0 ), high_( 0 ) {
setbuf( 0, 0 );
}
};
#endif

115
examples/rl-callbacktest.c Normal file
View file

@ -0,0 +1,115 @@
/* Standard include files. stdio.h is required. */
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
/* Used for select(2) */
#include <sys/types.h>
#include <sys/select.h>
#include <signal.h>
#include <errno.h>
#include <stdio.h>
#include <locale.h>
/* Standard readline include files. */
#if defined (READLINE_LIBRARY)
# include "readline.h"
# include "history.h"
#else
# include <readline/readline.h>
# include <readline/history.h>
#endif
extern int errno;
static void cb_linehandler (char *);
static void signandler (int);
int running, sigwinch_received;
const char *prompt = "rltest$ ";
/* Handle SIGWINCH and window size changes when readline is not active and
reading a character. */
static void
sighandler (int sig)
{
sigwinch_received = 1;
}
/* Callback function called for each line when accept-line executed, EOF
seen, or EOF character read. This sets a flag and returns; it could
also call exit(3). */
static void
cb_linehandler (char *line)
{
/* Can use ^D (stty eof) or `exit' to exit. */
if (line == NULL || strcmp (line, "exit") == 0)
{
if (line == 0)
printf ("\n");
printf ("exit\n");
/* This function needs to be called to reset the terminal settings,
and calling it from the line handler keeps one extra prompt from
being displayed. */
rl_callback_handler_remove ();
running = 0;
}
else
{
if (*line)
add_history (line);
printf ("input line: %s\n", line);
free (line);
}
}
int
main (int c, char **v)
{
fd_set fds;
int r;
setlocale (LC_ALL, "");
/* Handle SIGWINCH */
signal (SIGWINCH, sighandler);
/* Install the line handler. */
rl_callback_handler_install (prompt, cb_linehandler);
/* Enter a simple event loop. This waits until something is available
to read on readline's input stream (defaults to standard input) and
calls the builtin character read callback to read it. It does not
have to modify the user's terminal settings. */
running = 1;
while (running)
{
FD_ZERO (&fds);
FD_SET (fileno (rl_instream), &fds);
r = select (FD_SETSIZE, &fds, NULL, NULL, NULL);
if (r < 0 && errno != EINTR)
{
perror ("rltest: select");
rl_callback_handler_remove ();
break;
}
if (sigwinch_received)
{
rl_resize_terminal ();
sigwinch_received = 0;
}
if (r < 0)
continue;
if (FD_ISSET (fileno (rl_instream), &fds))
rl_callback_read_char ();
}
printf ("rltest: Event loop has exited\n");
return 0;
}

374
examples/rl-fgets.c Normal file
View file

@ -0,0 +1,374 @@
/*
Date: Tue, 16 Mar 2004 19:38:40 -0800
From: Harold Levy <Harold.Levy@synopsys.com>
Subject: fgets(stdin) --> readline() redirector
To: chet@po.cwru.edu
Hi Chet,
Here is something you may find useful enough to include in the readline
distribution. It is a shared library that redirects calls to fgets(stdin)
to readline() via LD_PRELOAD, and it supports a custom prompt and list of
command names. Many people have asked me for this file, so I thought I'd
pass it your way in hope of just including it with readline to begin with.
Best Regards,
-Harold
*/
/******************************************************************************
*******************************************************************************
FILE NAME: fgets.c TARGET: libfgets.so
AUTHOR: Harold Levy VERSION: 1.0
hlevy@synopsys.com
ABSTRACT: Customize fgets() behavior via LD_PRELOAD in the following ways:
-- If fgets(stdin) is called, redirect to GNU readline() to obtain
command-line editing, file-name completion, history, etc.
-- A list of commands for command-name completion can be configured by
setting the environment-variable FGETS_COMMAND_FILE to a file containing
the list of commands to be used.
-- Command-line editing with readline() works best when the prompt string
is known; you can set this with the FGETS_PROMPT environment variable.
-- There special strings that libfgets will interpret as internal commands:
_fgets_reset_ reset the command list
_fgets_dump_ dump status
_fgets_debug_ toggle debug messages
HOW TO BUILD: Here are examples of how to build libfgets.so on various
platforms; you will have to add -I and -L flags to configure access to
the readline header and library files.
(32-bit builds with gcc)
AIX: gcc -fPIC fgets.c -shared -o libfgets.so -lc -ldl -lreadline -ltermcap
HP-UX: gcc -fPIC fgets.c -shared -o libfgets.so -lc -ldld -lreadline
Linux: gcc -fPIC fgets.c -shared -o libfgets.so -lc -ldl -lreadline
SunOS: gcc -fPIC fgets.c -shared -o libfgets.so -lc -ldl -lgen -lreadline
(64-bit builds without gcc)
SunOS: SUNWspro/bin/cc -D_LARGEFILE64_SOURCE=1 -xtarget=ultra -xarch=v9 \
-KPIC fgets.c -Bdynamic -lc -ldl -lgen -ltermcap -lreadline
HOW TO USE: Different operating systems have different levels of support
for the LD_PRELOAD concept. The generic method for 32-bit platforms is to
put libtermcap.so, libfgets.so, and libreadline.so (with absolute paths)
in the LD_PRELOAD environment variable, and to put their parent directories
in the LD_LIBRARY_PATH environment variable. Unfortunately there is no
generic method for 64-bit platforms; e.g. for 64-bit SunOS, you would have
to build both 32-bit and 64-bit libfgets and libreadline libraries, and
use the LD_FLAGS_32 and LD_FLAGS_64 environment variables with preload and
library_path configurations (a mix of 32-bit and 64-bit calls are made under
64-bit SunOS).
EXAMPLE WRAPPER: Here is an example shell script wrapper around the
program "foo" that uses fgets() for command-line input:
#!/bin/csh
#### replace this with the libtermcap.so directory:
set dir1 = "/usr/lib"
#### replace this with the libfgets.so directory:
set dir2 = "/usr/fgets"
#### replace this with the libreadline.so directory:
set dir3 = "/usr/local/lib"
set lib1 = "${dir1}/libtermcap.so"
set lib2 = "${dir2}/libfgets.so"
set lib3 = "${dir3}/libreadline.so"
if ( "${?LD_PRELOAD}" ) then
setenv LD_PRELOAD "${lib1}:${lib2}:${lib3}:${LD_PRELOAD}"
else
setenv LD_PRELOAD "${lib1}:${lib2}:${lib3}"
endif
if ( "${?LD_LIBRARY_PATH}" ) then
setenv LD_LIBRARY_PATH "${dir1}:${dir2}:${dir3}:${LD_LIBRARY_PATH}"
else
setenv LD_LIBRARY_PATH "${dir1}:${dir2}:${dir3}"
endif
setenv FGETS_COMMAND_FILE "${dir2}/foo.commands"
setenv FGETS_PROMPT "foo> "
exec "foo" $*
Copyright (C)©2003-2004 Harold Levy.
This code links to the GNU readline library, and as such is bound by 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.
The GNU General Public License is often shipped with GNU software, and is
generally kept in a file called COPYING or LICENSE. If you do not have a
copy of the license, write to the Free Software Foundation, 59 Temple Place,
Suite 330, Boston, MA 02111 USA.
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.
*******************************************************************************
******************************************************************************/
#include <dlfcn.h>
#include <stdio.h>
#include <strings.h>
#include <stdlib.h>
#include <unistd.h>
#include <readline/readline.h>
#include <readline/history.h>
/* for dynamically connecting to the native fgets() */
#if defined(RTLD_NEXT)
#define REAL_LIBC RTLD_NEXT
#else
#define REAL_LIBC ((void *) -1L)
#endif
typedef char * ( * fgets_t ) ( char * s, int n, FILE * stream ) ;
/* private data */
/* -- writeable data is stored in the shared library's data segment
-- every process that uses the shared library gets a private memory copy of
its entire data segment
-- static data in the shared library is not copied to the application
-- only read-only (i.e. 'const') data is stored in the shared library's
text segment
*/
static char ** my_fgets_names = NULL ;
static int my_fgets_number_of_names = 0 ;
static int my_fgets_debug_flag = 0 ;
/* invoked with _fgets_reset_ */
static void
my_fgets_reset (
void
) {
if ( my_fgets_names && (my_fgets_number_of_names > 0) ) {
int i ;
if ( my_fgets_debug_flag ) {
printf ( "libfgets: removing command list\n" ) ;
}
for ( i = 0 ; i < my_fgets_number_of_names ; i ++ ) {
if ( my_fgets_names[i] ) free ( my_fgets_names[i] ) ;
}
free ( my_fgets_names ) ;
}
my_fgets_names = NULL ;
my_fgets_number_of_names = 0 ;
}
/* invoked with _fgets_dump_ */
static void
my_fgets_dump (
void
) {
char * s ;
printf ( "\n" ) ;
s = getenv ( "FGETS_PROMPT" ) ;
printf ( "FGETS_PROMPT = %s\n", s ? s : "" ) ;
s = getenv ( "FGETS_COMMAND_FILE" ) ;
printf ( "FGETS_COMMAND_FILE = %s\n", s ? s : "" ) ;
printf ( "debug flag = %d\n", my_fgets_debug_flag ) ;
printf ( "#commands = %d\n", my_fgets_number_of_names ) ;
if ( my_fgets_debug_flag ) {
if ( my_fgets_names && (my_fgets_number_of_names > 0) ) {
int i ;
for ( i = 0 ; i < my_fgets_number_of_names ; i ++ ) {
printf ( "%s\n", my_fgets_names[i] ) ;
}
}
}
printf ( "\n" ) ;
}
/* invoked with _fgets_debug_ */
static void
my_fgets_debug_toggle (
void
) {
my_fgets_debug_flag = my_fgets_debug_flag ? 0 : 1 ;
if ( my_fgets_debug_flag ) {
printf ( "libfgets: debug flag = %d\n", my_fgets_debug_flag ) ;
}
}
/* read the command list if needed, return the i-th name */
static char *
my_fgets_lookup (
int index
) {
if ( (! my_fgets_names) || (! my_fgets_number_of_names) ) {
char * fname ;
FILE * fp ;
fgets_t _fgets ;
int i ;
char buf1[256], buf2[256] ;
fname = getenv ( "FGETS_COMMAND_FILE" ) ;
if ( ! fname ) {
if ( my_fgets_debug_flag ) {
printf ( "libfgets: empty or unset FGETS_COMMAND_FILE\n" ) ;
}
return NULL ;
}
fp = fopen ( fname, "r" ) ;
if ( ! fp ) {
if ( my_fgets_debug_flag ) {
printf ( "libfgets: cannot open '%s' for reading\n", fname ) ;
}
return NULL ;
}
_fgets = (fgets_t) dlsym ( REAL_LIBC, "fgets" ) ;
if ( ! _fgets ) {
fprintf ( stderr,
"libfgets: failed to dynamically link to native fgets()\n"
) ;
return NULL ;
}
for ( i = 0 ; _fgets(buf1,255,fp) ; i ++ ) ;
if ( ! i ) { fclose(fp) ; return NULL ; }
my_fgets_names = (char**) calloc ( i, sizeof(char*) ) ;
rewind ( fp ) ;
i = 0 ;
while ( _fgets(buf1,255,fp) ) {
buf1[255] = 0 ;
if ( 1 == sscanf(buf1,"%s",buf2) ) {
my_fgets_names[i] = strdup(buf2) ;
i ++ ;
}
}
fclose ( fp ) ;
my_fgets_number_of_names = i ;
if ( my_fgets_debug_flag ) {
printf ( "libfgets: successfully read %d commands\n", i ) ;
}
}
if ( index < my_fgets_number_of_names ) {
return my_fgets_names[index] ;
} else {
return NULL ;
}
}
/* generate a list of partial name matches for readline() */
static char *
my_fgets_generator (
const char * text,
int state
)
{
static int list_index, len ;
char * name ;
if ( ! state ) {
list_index = 0 ;
len = strlen ( text ) ;
}
while ( ( name = my_fgets_lookup(list_index) ) ) {
list_index ++ ;
if ( ! strncmp ( name, text, len ) ) {
return ( strdup ( name ) ) ;
}
}
return ( NULL ) ;
}
/* partial name completion callback for readline() */
static char **
my_fgets_completion (
const char * text,
int start,
int end
)
{
char ** matches ;
matches = NULL ;
if ( ! start ) {
matches = rl_completion_matches ( text, my_fgets_generator ) ;
}
return ( matches ) ;
}
/* fgets() intercept */
char *
fgets (
char * s,
int n,
FILE * stream
)
{
if ( ! s ) return NULL ;
if ( stream == stdin ) {
char * prompt ;
char * my_fgets_line ;
rl_already_prompted = 1 ;
rl_attempted_completion_function = my_fgets_completion ;
rl_catch_signals = 1 ;
rl_catch_sigwinch = 1 ;
rl_set_signals () ;
prompt = getenv ( "FGETS_PROMPT" ) ;
for (
my_fgets_line = 0 ; ! my_fgets_line ; my_fgets_line=readline(prompt)
) ;
if ( ! strncmp(my_fgets_line, "_fgets_reset_", 13) ) {
my_fgets_reset () ;
free ( my_fgets_line ) ;
strcpy ( s, "\n" ) ;
return ( s ) ;
}
if ( ! strncmp(my_fgets_line, "_fgets_dump_", 12) ) {
my_fgets_dump () ;
free ( my_fgets_line ) ;
strcpy ( s, "\n" ) ;
return ( s ) ;
}
if ( ! strncmp(my_fgets_line, "_fgets_debug_", 13) ) {
my_fgets_debug_toggle () ;
free ( my_fgets_line ) ;
strcpy ( s, "\n" ) ;
return ( s ) ;
}
(void) strncpy ( s, my_fgets_line, n-1 ) ;
(void) strcat ( s, "\n" ) ;
if ( *my_fgets_line ) add_history ( my_fgets_line ) ;
free ( my_fgets_line ) ;
return ( s ) ;
} else {
static fgets_t _fgets ;
_fgets = (fgets_t) dlsym ( REAL_LIBC, "fgets" ) ;
if ( ! _fgets ) {
fprintf ( stderr,
"libfgets: failed to dynamically link to native fgets()\n"
) ;
strcpy ( s, "\n" ) ;
return ( s ) ;
}
return (
_fgets ( s, n, stream )
) ;
}
}

6
examples/rl-test-timeout Normal file
View file

@ -0,0 +1,6 @@
./rl-timeout readline1 0.5
./rl-timeout readline2 0.25
./rl-timeout callback1 0.5
./rl-timeout callback2 0.5

245
examples/rl-timeout.c Normal file
View file

@ -0,0 +1,245 @@
/* rl-timeout: test various readline builtin timeouts. */
/* Copyright (C) 2021 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library for
reading lines of text with interactive input and history editing.
Readline 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 3 of the License, or
(at your option) any later version.
Readline 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 readline. If not, see <http://www.gnu.org/licenses/>.
*/
/* Standard include files. stdio.h is required. */
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <limits.h>
/* Used for select(2) */
#include <sys/types.h>
#include <sys/select.h>
#include <errno.h>
#include <stdio.h>
/* Standard readline include files. */
#if defined (READLINE_LIBRARY)
# include "readline.h"
# include "history.h"
#else
# include <readline/readline.h>
# include <readline/history.h>
#endif
extern int errno;
static void cb_linehandler (char *);
int timeout_secs = 1, timeout_usecs = 0;
int running;
const char *prompt = "rl-timeout$ ";
/* **************************************************************** */
/* */
/* Example 1: readline () with rl_readline_state */
/* */
/* **************************************************************** */
void
rltest_timeout_readline1 ()
{
const char *temp;
rl_set_timeout (timeout_secs, timeout_usecs);
temp = readline (prompt);
if (RL_ISSTATE (RL_STATE_TIMEOUT))
printf ("timeout\n");
else if (temp == NULL)
printf ("no input line\n");
else
printf ("input line: %s\n", temp);
free ((void *) temp);
}
/* **************************************************************** */
/* */
/* Example 2: readline () with rl_timeout_event_hook */
/* */
/* **************************************************************** */
static int
timeout_handler ()
{
printf ("timeout\n");
return READERR;
}
void
rltest_timeout_readline2 ()
{
const char *temp;
rl_set_timeout (timeout_secs, timeout_usecs);
rl_timeout_event_hook = timeout_handler;
temp = readline (prompt);
if (temp == NULL)
printf ("no input line\n");
else
printf ("input line: %s\n", temp);
free ((void *)temp);
}
/* **************************************************************** */
/* */
/* Example 3: rl_callback_* () with rl_timeout_remaining */
/* */
/* **************************************************************** */
/* Callback function called for each line when accept-line executed, EOF
seen, or EOF character read. This sets a flag and returns; it could
also call exit(3). */
static void
cb_linehandler (char *line)
{
/* Can use ^D (stty eof) or `exit' to exit. */
if (line == NULL || strcmp (line, "exit") == 0)
{
if (line == 0)
printf ("\n");
printf ("exit\n");
/* This function needs to be called to reset the terminal settings,
and calling it from the line handler keeps one extra prompt from
being displayed. */
rl_callback_handler_remove ();
running = 0;
}
else
{
if (*line)
add_history (line);
printf ("input line: %s\n", line);
free (line);
}
}
void
rltest_timeout_callback1 ()
{
fd_set fds;
int r;
unsigned sec, usec;
rl_set_timeout (timeout_secs, timeout_usecs);
rl_callback_handler_install (prompt, cb_linehandler);
running = 1;
while (running)
{
FD_ZERO (&fds);
FD_SET (fileno (rl_instream), &fds);
r = rl_timeout_remaining (&sec, &usec);
if (r == 1)
{
struct timeval timeout = {sec, usec};
r = select (FD_SETSIZE, &fds, NULL, NULL, &timeout);
}
if (r < 0 && errno != EINTR)
{
perror ("rl-timeout: select");
rl_callback_handler_remove ();
break;
}
else if (r == 0)
{
printf ("rl-timeout: timeout\n");
rl_callback_handler_remove ();
break;
}
if (FD_ISSET (fileno (rl_instream), &fds))
rl_callback_read_char ();
}
printf ("rl-timeout: Event loop has exited\n");
}
/* **************************************************************** */
/* */
/* Example 4: rl_callback_* () with rl_timeout_event_hook */
/* */
/* **************************************************************** */
static int
cb_timeouthandler ()
{
printf ("timeout\n");
rl_callback_handler_remove ();
running = 0;
return READERR;
}
void
rltest_timeout_callback2 ()
{
int r;
rl_set_timeout (timeout_secs, timeout_usecs);
rl_timeout_event_hook = cb_timeouthandler;
rl_callback_handler_install (prompt, cb_linehandler);
running = 1;
while (running)
rl_callback_read_char ();
printf ("rl-timeout: Event loop has exited\n");
}
int
main (int argc, char **argv)
{
if (argc >= 2)
{
if (argc >= 3)
{
double timeout = atof (argv[2]);
if (timeout <= 0.0)
{
fprintf (stderr, "rl-timeout: specify a positive number for timeout.\n");
return 2;
}
else if (timeout > UINT_MAX)
{
fprintf (stderr, "rl-timeout: timeout too large.\n");
return 2;
}
timeout_secs = (unsigned) timeout;
timeout_usecs = (unsigned) ((timeout - timeout_secs) * 1000000 + 0.5);
}
if (strcmp (argv[1], "readline1") == 0)
rltest_timeout_readline1 ();
else if (strcmp (argv[1], "readline2") == 0)
rltest_timeout_readline2 ();
else if (strcmp (argv[1], "callback1") == 0)
rltest_timeout_callback1 ();
else if (strcmp (argv[1], "callback2") == 0)
rltest_timeout_callback2 ();
else
return 2;
}
else
{
fprintf (stderr, "usage: rl-timeout [readline1 | readline2 | callback1 | callback2] [timeout]\n");
return 2;
}
return 0;
}

166
examples/rl.c Normal file
View file

@ -0,0 +1,166 @@
/*
* rl - command-line interface to read a line from the standard input
* (or another fd) using readline.
*
* usage: rl [-p prompt] [-u unit] [-d default] [-n nchars]
*/
/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library for
reading lines of text with interactive input and history editing.
Readline 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 3 of the License, or
(at your option) any later version.
Readline 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 Readline. If not, see <http://www.gnu.org/licenses/>.
*/
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#else
extern void exit();
#endif
#ifdef HAVE_LOCALE_H
# include <locale.h>
#endif
#if defined (READLINE_LIBRARY)
# include "posixstat.h"
# include "readline.h"
# include "history.h"
#else
# include <sys/stat.h>
# include <readline/readline.h>
# include <readline/history.h>
#endif
extern int optind;
extern char *optarg;
#if !defined (strchr) && !defined (__STDC__)
extern char *strrchr();
#endif
static char *progname;
static char *deftext;
static int
set_deftext ()
{
if (deftext)
{
rl_insert_text (deftext);
deftext = (char *)NULL;
rl_startup_hook = (rl_hook_func_t *)NULL;
}
return 0;
}
static void
usage()
{
fprintf (stderr, "%s: usage: %s [-p prompt] [-u unit] [-d default] [-n nchars]\n",
progname, progname);
}
int
main (argc, argv)
int argc;
char **argv;
{
char *temp, *prompt;
struct stat sb;
int opt, fd, nch;
FILE *ifp;
progname = strrchr(argv[0], '/');
if (progname == 0)
progname = argv[0];
else
progname++;
#ifdef HAVE_SETLOCALE
setlocale (LC_ALL, "");
#endif
/* defaults */
prompt = "readline$ ";
fd = nch = 0;
deftext = (char *)0;
while ((opt = getopt(argc, argv, "p:u:d:n:")) != EOF)
{
switch (opt)
{
case 'p':
prompt = optarg;
break;
case 'u':
fd = atoi(optarg);
if (fd < 0)
{
fprintf (stderr, "%s: bad file descriptor `%s'\n", progname, optarg);
exit (2);
}
break;
case 'd':
deftext = optarg;
break;
case 'n':
nch = atoi(optarg);
if (nch < 0)
{
fprintf (stderr, "%s: bad value for -n: `%s'\n", progname, optarg);
exit (2);
}
break;
default:
usage ();
exit (2);
}
}
if (fd != 0)
{
if (fstat (fd, &sb) < 0)
{
fprintf (stderr, "%s: %d: bad file descriptor\n", progname, fd);
exit (1);
}
ifp = fdopen (fd, "r");
rl_instream = ifp;
}
if (deftext && *deftext)
rl_startup_hook = set_deftext;
if (nch > 0)
rl_num_chars_to_read = nch;
temp = readline (prompt);
/* Test for EOF. */
if (temp == 0)
exit (1);
printf ("%s\n", temp);
exit (0);
}

37
examples/rlbasic.c Normal file
View file

@ -0,0 +1,37 @@
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#ifdef HAVE_LOCALE_H
# include <locale.h>
#endif
#if defined (READLINE_LIBRARY)
# include "readline.h"
# include "history.h"
#else
# include <readline/readline.h>
# include <readline/history.h>
#endif
int
main (int c, char **v)
{
char *input;
#ifdef HAVE_SETLOCALE
setlocale (LC_ALL, "");
#endif
for (;;) {
input = readline ((char *)NULL);
if (input == 0)
break;
printf ("%s\n", input);
if (strcmp (input, "exit") == 0)
break;
free (input);
}
exit (0);
}

187
examples/rlcat.c Normal file
View file

@ -0,0 +1,187 @@
/*
* rlcat - cat(1) using readline
*
* usage: rlcat
*/
/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library for
reading lines of text with interactive input and history editing.
Readline 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 3 of the License, or
(at your option) any later version.
Readline 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 Readline. If not, see <http://www.gnu.org/licenses/>.
*/
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <sys/types.h>
#include "posixstat.h"
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <errno.h>
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#else
extern void exit();
#endif
#ifdef HAVE_LOCALE_H
# include <locale.h>
#endif
#ifndef errno
extern int errno;
#endif
#if defined (READLINE_LIBRARY)
# include "readline.h"
# include "history.h"
#else
# include <readline/readline.h>
# include <readline/history.h>
#endif
extern int optind;
extern char *optarg;
static int stdcat();
static char *progname;
static int vflag;
static void
usage()
{
fprintf (stderr, "%s: usage: %s [-vEVN] [filename]\n", progname, progname);
}
int
main (argc, argv)
int argc;
char **argv;
{
char *temp;
int opt, Vflag, Nflag;
#ifdef HAVE_SETLOCALE
setlocale (LC_ALL, "");
#endif
progname = strrchr(argv[0], '/');
if (progname == 0)
progname = argv[0];
else
progname++;
vflag = Vflag = Nflag = 0;
while ((opt = getopt(argc, argv, "vEVN")) != EOF)
{
switch (opt)
{
case 'v':
vflag = 1;
break;
case 'V':
Vflag = 1;
break;
case 'E':
Vflag = 0;
break;
case 'N':
Nflag = 1;
break;
default:
usage ();
exit (2);
}
}
argc -= optind;
argv += optind;
if (isatty(0) == 0 || argc || Nflag)
return stdcat(argc, argv);
rl_variable_bind ("editing-mode", Vflag ? "vi" : "emacs");
while (temp = readline (""))
{
if (*temp)
add_history (temp);
printf ("%s\n", temp);
}
return (ferror (stdout));
}
static int
fcopy(fp)
FILE *fp;
{
int c;
char *x;
while ((c = getc(fp)) != EOF)
{
if (vflag && isascii ((unsigned char)c) && isprint((unsigned char)c) == 0)
{
x = rl_untranslate_keyseq (c);
if (fputs (x, stdout) == EOF)
return 1;
}
else if (putchar (c) == EOF)
return 1;
}
return (ferror (stdout));
}
int
stdcat (argc, argv)
int argc;
char **argv;
{
int i, fd, r;
char *s;
FILE *fp;
if (argc == 0)
return (fcopy(stdin));
for (i = 0, r = 1; i < argc; i++)
{
if (*argv[i] == '-' && argv[i][1] == 0)
fp = stdin;
else
{
fp = fopen (argv[i], "r");
if (fp == 0)
{
fprintf (stderr, "%s: %s: cannot open: %s\n", progname, argv[i], strerror(errno));
continue;
}
}
r = fcopy (fp);
if (fp != stdin)
fclose(fp);
}
return r;
}

181
examples/rlevent.c Normal file
View file

@ -0,0 +1,181 @@
/*
* rl - command-line interface to read a line from the standard input
* (or another fd) using readline.
*
* usage: rl [-p prompt] [-u unit] [-d default] [-n nchars]
*/
/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library for
reading lines of text with interactive input and history editing.
Readline 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 3 of the License, or
(at your option) any later version.
Readline 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 Readline. If not, see <http://www.gnu.org/licenses/>.
*/
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#else
extern int getopt();
extern int sleep();
#endif
#include <stdio.h>
#include <sys/types.h>
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#else
extern void exit();
#endif
#ifdef HAVE_LOCALE_H
# include <locale.h>
#endif
#if defined (READLINE_LIBRARY)
# include "posixstat.h"
# include "readline.h"
# include "history.h"
#else
# include <sys/stat.h>
# include <readline/readline.h>
# include <readline/history.h>
#endif
extern int optind;
extern char *optarg;
#if !defined (strchr) && !defined (__STDC__)
extern char *strrchr();
#endif
static char *progname;
static char *deftext;
static int
event_hook ()
{
fprintf (stderr, "ding!\n");
sleep (1);
return 0;
}
static int
set_deftext ()
{
if (deftext)
{
rl_insert_text (deftext);
deftext = (char *)NULL;
rl_startup_hook = (rl_hook_func_t *)NULL;
}
return 0;
}
static void
usage()
{
fprintf (stderr, "%s: usage: %s [-p prompt] [-u unit] [-d default] [-n nchars]\n",
progname, progname);
}
int
main (argc, argv)
int argc;
char **argv;
{
char *temp, *prompt;
struct stat sb;
int opt, fd, nch;
FILE *ifp;
#ifdef HAVE_SETLOCALE
setlocale (LC_ALL, "");
#endif
progname = strrchr(argv[0], '/');
if (progname == 0)
progname = argv[0];
else
progname++;
/* defaults */
prompt = "readline$ ";
fd = nch = 0;
deftext = (char *)0;
while ((opt = getopt(argc, argv, "p:u:d:n:")) != EOF)
{
switch (opt)
{
case 'p':
prompt = optarg;
break;
case 'u':
fd = atoi(optarg);
if (fd < 0)
{
fprintf (stderr, "%s: bad file descriptor `%s'\n", progname, optarg);
exit (2);
}
break;
case 'd':
deftext = optarg;
break;
case 'n':
nch = atoi(optarg);
if (nch < 0)
{
fprintf (stderr, "%s: bad value for -n: `%s'\n", progname, optarg);
exit (2);
}
break;
default:
usage ();
exit (2);
}
}
if (fd != 0)
{
if (fstat (fd, &sb) < 0)
{
fprintf (stderr, "%s: %d: bad file descriptor\n", progname, fd);
exit (1);
}
ifp = fdopen (fd, "r");
rl_instream = ifp;
}
if (deftext && *deftext)
rl_startup_hook = set_deftext;
if (nch > 0)
rl_num_chars_to_read = nch;
rl_event_hook = event_hook;
temp = readline (prompt);
/* Test for EOF. */
if (temp == 0)
exit (1);
printf ("%s\n", temp);
exit (0);
}

37
examples/rlfe/ChangeLog Normal file
View file

@ -0,0 +1,37 @@
2004-11-04 Per Bothner <per@bothner.com>
* pty.c: Import from screen-4.0.2.
* configure.in, Makefile.in, config.h.in: Set up autoconf handling,
copying a bunk of stuff over from screen.
* rlfe.c: Use OpenPTY from pty.c instead of get_master_pty.
2004-11-03 Per Bothner <per@bothner.com>
* rlfe.c: Get input emphasis (boldening) more robust.
* rlfe.c: Various cleanups on comments and names.
2003-11-07 Wolfgang Taeuber <wolfgang_taeuber@agilent.com>
* Specify a history file and the size of the history file with command
* line options; use EDITOR/VISUAL to set vi/emacs preference.
1999-09-03 Chet Ramey <chet@nike.ins.cwru.edu>
* fep.c: Memmove is not universally available. This patch assumes
that an autoconf test has been performed, and that memcpy is
available without checking.
* fep.c: VDISCARD is not universally available, even when termios is.
* fep.c: If a system doesn't have TIOCSCTTY, the first `open'
performed after setsid allocates a controlling terminal. The
original code would leave the child process running on the slave pty
without a controlling tty if TIOCSCTTY was not available.
* fep.c: Most versions of SVR4, including solaris, don't allow
terminal ioctl calls on the master side of the pty.
1999-08-28 Per Bothner <per@bothner.com>
* fep.c: Initial release.

184
examples/rlfe/Makefile.in Normal file
View file

@ -0,0 +1,184 @@
#
# Makefile template for rlfe
#
# See machine dependant config.h for more configuration options.
#
srcdir = @srcdir@
VPATH = @srcdir@
DESTDIR =
# Where to install screen.
prefix = @prefix@
exec_prefix = @exec_prefix@
# don't forget to change mandir and infodir in doc/Makefile.
bindir = $(exec_prefix)/bin
VERSION = @VERSION@
SCREEN = screen-$(VERSION)
CC = @CC@
CFLAGS = @CFLAGS@
CPPFLAGS = @CPPFLAGS@
#LDFLAGS = -L$(READLINE_DIR)
LDFLAGS = @LDFLAGS@
LIBS = -lreadline -lhistory @LIBS@
CPP=@CPP@
CPP_DEPEND=$(CC) -MM
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
AWK = @AWK@
OPTIONS=
#OPTIONS= -DDEBUG
SHELL=/bin/sh
CFILES= rlfe.c pty.c
HFILES= extern.h os.h screen.h
EXTRA_DIST=configure.in configure Makefile.in config.h.in ChangeLog README
OFILES= rlfe.o pty.o
all: rlfe
rlfe: $(OFILES)
$(CC) $(LDFLAGS) -o $@ $(OFILES) $(LIBS)
rlfe-$(VERSION).tar.gz:
tar czf $@ $(CFILES) $(HFILES) $(EXTRA_DIST)
.c.o:
$(CC) -c -I. -I$(srcdir) $(CPPFLAGS) $(M_CFLAGS) $(DEFS) $(OPTIONS) $(CFLAGS) $<
install_bin: .version screen
-if [ -f $(DESTDIR)$(bindir)/$(SCREEN) ] && [ ! -f $(DESTDIR)$(bindir)/$(SCREEN).old ]; \
then mv $(DESTDIR)$(bindir)/$(SCREEN) $(DESTDIR)$(bindir)/$(SCREEN).old; fi
$(INSTALL_PROGRAM) screen $(DESTDIR)$(bindir)/$(SCREEN)
-chown root $(DESTDIR)$(bindir)/$(SCREEN) && chmod 4755 $(DESTDIR)$(bindir)/$(SCREEN)
# This doesn't work if $(bindir)/screen is a symlink
-if [ -f $(DESTDIR)$(bindir)/screen ] && [ ! -f $(DESTDIR)$(bindir)/screen.old ]; then mv $(DESTDIR)$(bindir)/screen $(DESTDIR)$(bindir)/screen.old; fi
rm -f $(DESTDIR)$(bindir)/screen
(cd $(DESTDIR)$(bindir) && ln -sf $(SCREEN) screen)
cp $(srcdir)/utf8encodings/?? $(DESTDIR)$(SCREENENCODINGS)
uninstall: .version
rm -f $(DESTDIR)$(bindir)/$(SCREEN)
rm -f $(DESTDIR)$(bindir)/screen
-mv $(DESTDIR)$(bindir)/screen.old $(DESTDIR)$(bindir)/screen
rm -f $(DESTDIR)$(ETCSCREENRC)
cd doc; $(MAKE) uninstall
shadow:
mkdir shadow;
cd shadow; ln -s ../*.[ch] ../*.in ../*.sh ../configure ../doc ../terminfo ../etc .
rm -f shadow/term.h shadow/tty.c shadow/comm.h shadow/osdef.h
echo "install all Makefiles and config:" > shadow/Makefile
echo " rm -f config.cache" >> shadow/Makefile
echo " sh ./configure" >> shadow/Makefile
term.h: term.c term.sh
AWK=$(AWK) srcdir=$(srcdir) sh $(srcdir)/term.sh
kmapdef.c: term.h
tty.c: tty.sh
sh $(srcdir)/tty.sh tty.c
mostlyclean:
rm -f $(OFILES) rlfe *.o
clean celan: mostlyclean
rm -f tty.c term.h comm.h osdef.h kmapdef.c core
# Delete all files from the current directory that are created by
# configuring or building the program.
# building of term.h/comm.h requires awk. Keep it in the distribution
# we keep config.h, as this file knows where 'make dist' finds the ETCSCREENRC.
#distclean: mostlyclean
# rm -f $(SCREEN).tar $(SCREEN).tar.gz
# rm -f config.status Makefile
# rm -f osdef.h doc/Makefile
maintainer-clean:
@echo "This command is not even intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
# Delete everything from the current directory that can be
# reconstructed with this Makefile.
realclean: .version mostlyclean
rm -f $(SCREEN).tar $(SCREEN).tar.gz
rm -f config.status Makefile doc/Makefile
rm -f tty.c term.h comm.h osdef.h kmapdef.c
rm -f config.h
echo "install all Makefiles and config:" > Makefile
echo " sh ./configure" >> Makefile
tags TAGS: $(CFILES)
-ctags *.sh $(CFILES) *.h
-ctags -e *.sh $(CFILES) *.h
dist: .version $(SCREEN).tar.gz
# Perform self-tests (if any).
check:
config:
rm -f config.cache
sh ./configure
###############################################################################
.version:
@rev=`sed < $(srcdir)/patchlevel.h -n -e '/#define REV/s/#define REV *//p'`; \
vers=`sed < $(srcdir)/patchlevel.h -n -e '/#define VERS/s/#define VERS *//p'`; \
pat=`sed < $(srcdir)/patchlevel.h -n -e '/#define PATCHLEVEL/s/#define PATCHLEVEL *//p'`; \
if [ "$${rev}.$${vers}.$${pat}" != "$(VERSION)" ]; then \
echo "This distribution is screen-$${rev}.$${vers}.$${pat}, but"; \
echo "the Makefile is from $(VERSION). Please update!"; exit 1; fi
###############################################################################
mdepend: $(CFILES) term.h
@rm -f DEPEND ; \
for i in ${CFILES} ; do \
echo "$$i" ; \
echo `echo "$$i" | sed -e 's/.c$$/.o/'`": $$i" `\
cc -E $$i |\
grep '^# .*"\./.*\.h"' |\
(sort -t'"' -u -k 2,2 2>/dev/null || sort -t'"' -u +1 -2) |\
sed -e 's/.*"\.\/\(.*\)".*/\1/'\
` >> DEPEND ; \
done
depend: depend.in
./config.status || ./configure
depend.in: $(CFILES) term.h
cp Makefile.in Makefile.in~
sed -e '/\#\#\# Dependencies/q' < Makefile.in > tmp_make
for i in $(CFILES); do echo $$i; $(CPP_DEPEND) $$i >> tmp_make; done
mv tmp_make Makefile.in
Makefile makefile: config.status $(srcdir)/Makefile.in
CONFIG_FILES=Makefile CONFIG_HEADERS= $(SHELL) ./config.status
config.status: $(srcdir)/configure
$(SHELL) ./config.status --recheck
$(srcdir)/configure: $(srcdir)/configure.in
cd $(srcdir) && autoconf
###############################################################################
### Dependencies:
pty.o: pty.c config.h

78
examples/rlfe/README Normal file
View file

@ -0,0 +1,78 @@
rlfe (ReadLine Front-End) is a "universal wrapper" around readline.
You specify an interactive program to run (typically a shell), and
readline is used to edit input lines.
There are other such front-ends; what distinguishes this one is that
it monitors the state of the inferior pty, and if the inferior program
switches its terminal to raw mode, then rlfe passes your characters
through directly. This basically means you can run your entire
session (including bash and terminal-mode emacs) under rlfe.
FEATURES
* Can use all readline commands (and history) in commands that
read input lines in "canonical mode" - even 'cat'!
* Automatically switches between "readline-editing mode" and "raw mode"
depending on the terminal mode. If the inferior program invokes
readline itself, it will do its own line editing. (The inferior
readline will not know about rlfe, and it will have its own history.)
You can even run programs like 'emavs -nw' and 'vi' under rlfe.
The goal is you could leave rlfe always on without even knowing
about it. (We're not quite there, but it works tolerably well.)
* The input line (after any prompt) is changed to bold-face.
INSTALL
The usual: ./configure && make && make install
Note so far rlfe has only been tested on GNU Linux (Fedora Core 2)
and Mac OS X (10.3).
This assumes readline header files and libraries are in the default
places. If not, you can create a link named readline pointing to the
readline sources. To link with libreadline.a and libhistory.a
you can copy or link them, or add LDFLAGS='-/path/to/readline' to
the make command-line.
USAGE
Just run it. That by default runs bash. You can run some other
command by giving it as command-line arguments.
There are a few tweaks: -h allows you to name the history file,
and -s allows you to specify its size. It default to "emacs" mode,
but if the the environment variable EDITOR is set to "vi" that
mode is chosen.
ISSUES
* The mode switching depends on the terminal mode set by the inferior
program. Thus ssh/telnet/screen-type programs will typically be in
raw mode, so rlfe won't be much use, even if remote programs run in
canonical mode. The work-around is to run rlfe on the remote end.
* Echo supression and prompt recognition are somewhat fragile.
(A protocol so that the o/s tty code can reliably communicate its
state to rlfe could solve this problem, and the previous one.)
* See the intro to rlfe.c for more notes.
* Assumes a VT100-compatible terminal, though that could be generalized
if anybody cares.
* Requires ncurses.
* It would be useful to integrate rlfe's logic in a terminal emulator.
That would make it easier to reposition the edit position with a mouse,
integrate cut-and-paste with the system clipboard, and more robustly
handle escape sequence and multi-byte characters more robustly.
AUTHOR
Per Bothner <per@bothner.com>
LICENSE
GPL.

383
examples/rlfe/config.h.in Normal file
View file

@ -0,0 +1,383 @@
/* Copyright 2004 Per Bothner <per@bothner.com>
* Based on config.h from screen-4.0.2.
* Copyright (c) 1993-2000
* Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
* Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
* Copyright (c) 1987 Oliver Laumann
*
* 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 (see the file COPYING); if not, write to the
* Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
****************************************************************
* $Id: config.h.in,v 1.12 1994/05/31 12:31:36 mlschroe Exp $ FAU
*/
/**********************************************************************
*
* User Configuration Section
*/
/*
* define PTYMODE if you do not like the default of 0622, which allows
* public write to your pty.
* define PTYGROUP to some numerical group-id if you do not want the
* tty to be in "your" group.
* Note, screen is unable to change mode or group of the pty if it
* is not installed with sufficient privilege. (e.g. set-uid-root)
* define PTYROFS if the /dev/pty devices are mounted on a read-only
* filesystem so screen should not even attempt to set mode or group
* even if running as root (e.g. on TiVo).
*/
#undef PTYMODE
#undef PTYGROUP
#undef PTYROFS
/*
* If screen is NOT installed set-uid root, screen can provide tty
* security by exclusively locking the ptys. While this keeps other
* users from opening your ptys, it also keeps your own subprocesses
* from being able to open /dev/tty. Define LOCKPTY to add this
* exclusive locking.
*/
#undef LOCKPTY
/**********************************************************************
*
* End of User Configuration Section
*
* Rest of this file is modified by 'configure'
* Change at your own risk!
*
*/
/*
* Some defines to identify special unix variants
*/
#ifndef SVR4
#undef SVR4
#endif
#ifndef _POSIX_SOURCE
#undef _POSIX_SOURCE
#endif
/*
* Define POSIX if your system supports IEEE Std 1003.1-1988 (POSIX).
*/
#undef POSIX
/*
* Define TERMIO if you have struct termio instead of struct sgttyb.
* This is usually the case for SVID systems, where BSD uses sgttyb.
* POSIX systems should define this anyway, even though they use
* struct termios.
*/
#undef TERMIO
/*
* Define CYTERMIO if you have cyrillic termio modes.
*/
#undef CYTERMIO
/*
* Define TERMINFO if your machine emulates the termcap routines
* with the terminfo database.
* Thus the .screenrc file is parsed for
* the command 'terminfo' and not 'termcap'.
*/
#undef TERMINFO
/*
* If your library does not define ospeed, define this.
*/
#undef NEED_OSPEED
/*
* Define SYSV if your machine is SYSV complient (Sys V, HPUX, A/UX)
*/
#ifndef SYSV
#undef SYSV
#endif
/*
* Define SIGVOID if your signal handlers return void. On older
* systems, signal returns int, but on newer ones, it returns void.
*/
#undef SIGVOID
/*
* Define USESIGSET if you have sigset for BSD 4.1 reliable signals.
*/
#undef USESIGSET
/*
* Define SYSVSIGS if signal handlers must be reinstalled after
* they have been called.
*/
#undef SYSVSIGS
/*
* Define BSDWAIT if your system defines a 'union wait' in <sys/wait.h>
*
* Only allow BSDWAIT i.e. wait3 on nonposix systems, since
* posix implies wait(3) and waitpid(3). vdlinden@fwi.uva.nl
*
*/
#ifndef POSIX
#undef BSDWAIT
#endif
/*
* On RISCOS we prefer wait2() over wait3(). rouilj@sni-usa.com
*/
#ifdef BSDWAIT
#undef USE_WAIT2
#endif
/*
* Define if you have the utempter utmp helper program
*/
#undef HAVE_UTEMPTER
/*
* If ttyslot() breaks getlogin() by returning indexes to utmp entries
* of type DEAD_PROCESS, then our getlogin() replacement should be
* selected by defining BUGGYGETLOGIN.
*/
#undef BUGGYGETLOGIN
/*
* If your system has the calls setreuid() and setregid(),
* define HAVE_SETREUID. Otherwise screen will use a forked process to
* safely create output files without retaining any special privileges.
*/
#undef HAVE_SETREUID
/*
* If your system supports BSD4.4's seteuid() and setegid(), define
* HAVE_SETEUID.
*/
#undef HAVE_SETEUID
/*
* If you want the "time" command to display the current load average
* define LOADAV. Maybe you must install screen with the needed
* privileges to read /dev/kmem.
* Note that NLIST_ stuff is only checked, when getloadavg() is not available.
*/
#undef LOADAV
#undef LOADAV_NUM
#undef LOADAV_TYPE
#undef LOADAV_SCALE
#undef LOADAV_GETLOADAVG
#undef LOADAV_UNIX
#undef LOADAV_AVENRUN
#undef LOADAV_USE_NLIST64
#undef NLIST_DECLARED
#undef NLIST_STRUCT
#undef NLIST_NAME_UNION
/*
* If your system has the new format /etc/ttys (like 4.3 BSD) and the
* getttyent(3) library functions, define GETTTYENT.
*/
#undef GETTTYENT
/*
* Define USEBCOPY if the bcopy/memcpy from your system's C library
* supports the overlapping of source and destination blocks. When
* undefined, screen uses its own (probably slower) version of bcopy().
*
* SYSV machines may have a working memcpy() -- Oh, this is
* quite unlikely. Tell me if you see one.
* "But then, memmove() should work, if at all available" he thought...
* Boing, never say "works everywhere" unless you checked SCO UNIX.
* Their memove fails the test in the configure script. Sigh. (Juergen)
*/
#undef USEBCOPY
#undef USEMEMCPY
#undef USEMEMMOVE
/*
* If your system has vsprintf() and requires the use of the macros in
* "varargs.h" to use functions with variable arguments,
* define USEVARARGS.
*/
#undef USEVARARGS
/*
* If your system has strerror() define this.
*/
#undef HAVE_STRERROR
/*
* If the select return value doesn't treat a descriptor that is
* usable for reading and writing as two hits, define SELECT_BROKEN.
*/
#undef SELECT_BROKEN
/*
* Define this if your system supports named pipes.
*/
#undef NAMEDPIPE
/*
* Define this if your system exits select() immediatly if a pipe is
* opened read-only and no writer has opened it.
*/
#undef BROKEN_PIPE
/*
* Define this if the unix-domain socket implementation doesn't
* create a socket in the filesystem.
*/
#undef SOCK_NOT_IN_FS
/*
* If your system has setenv() and unsetenv() define USESETENV
*/
#undef USESETENV
/*
* If your system does not come with a setenv()/putenv()/getenv()
* functions, you may bring in our own code by defining NEEDPUTENV.
*/
#undef NEEDPUTENV
/*
* If the passwords are stored in a shadow file and you want the
* builtin lock to work properly, define SHADOWPW.
*/
#undef SHADOWPW
/*
* If you are on a SYS V machine that restricts filename length to 14
* characters, you may need to enforce that by setting NAME_MAX to 14
*/
#undef NAME_MAX /* KEEP_UNDEF_HERE override system value */
#undef NAME_MAX
/*
* define HAVE_RENAME if your system has a rename() function
*/
#undef HAVE_RENAME
/*
* define HAVE__EXIT if your system has the _exit() call.
*/
#undef HAVE__EXIT
/*
* define HAVE_LSTAT if your system has symlinks and the lstat() call.
*/
#undef HAVE_LSTAT
/*
* define HAVE_UTIMES if your system has the utimes() call.
*/
#undef HAVE_UTIMES
/*
* define HAVE_FCHOWN if your system has the fchown() call.
*/
#undef HAVE_FCHOWN
/*
* define HAVE_FCHMOD if your system has the fchmod() call.
*/
#undef HAVE_FCHMOD
/*
* define HAVE_VSNPRINTF if your system has vsnprintf() (GNU lib).
*/
#undef HAVE_VSNPRINTF
/*
* define HAVE_GETCWD if your system has the getcwd() call.
*/
#undef HAVE_GETCWD
/*
* define HAVE_SETLOCALE if your system has the setlocale() call.
*/
#undef HAVE_SETLOCALE
/*
* define HAVE_STRFTIME if your system has the strftime() call.
*/
#undef HAVE_STRFTIME
/*
* define HAVE_NL_LANGINFO if your system has the nl_langinfo() call
* and <langinfo.h> defines CODESET.
*/
#undef HAVE_NL_LANGINFO
/*
* Newer versions of Solaris include fdwalk, which can greatly improve
* the startup time of screen; otherwise screen spends a lot of time
* closing file descriptors.
*/
#undef HAVE_FDWALK
/*
* define HAVE_DEV_PTC if you have a /dev/ptc character special
* device.
*/
#undef HAVE_DEV_PTC
/*
* define HAVE_SVR4_PTYS if you have a /dev/ptmx character special
* device and support the ptsname(), grantpt(), unlockpt() functions.
*/
#undef HAVE_SVR4_PTYS
/*
* define HAVE_GETPT if you have the getpt() function.
*/
#undef HAVE_GETPT
/*
* define HAVE_OPENPTY if your system has the openpty() call.
*/
#undef HAVE_OPENPTY
/*
* define PTYRANGE0 and or PTYRANGE1 if you want to adapt screen
* to unusual environments. E.g. For SunOs the defaults are "qpr" and
* "0123456789abcdef". For SunOs 4.1.2
* #define PTYRANGE0 "pqrstuvwxyzPQRST"
* is recommended by Dan Jacobson.
*/
#undef PTYRANGE0
#undef PTYRANGE1
#define USEVARARGS
#undef HAVE_SYS_STROPTS_H
#undef HAVE_SYS_WAIT_H
#undef HAVE_SGTTY_H
#undef HAVE_SYS_SELECT_H

5637
examples/rlfe/configure vendored Executable file

File diff suppressed because it is too large Load diff

442
examples/rlfe/configure.in Normal file
View file

@ -0,0 +1,442 @@
dnl Process this file with autoconf to produce a configure script.
AC_INIT(rlfe.c)
AC_CONFIG_HEADER(config.h)
VERSION=0.4
AC_SUBST(VERSION)
dnl
dnl Define some useful macros
dnl
AC_DEFUN([AC_PROGRAM_SOURCE],
[AC_REQUIRE([AC_PROG_CPP])AC_PROVIDE([$0])cat > conftest.c <<EOF
#include "confdefs.h"
[$1]
_CUT_HERE_
[$2]
EOF
eval "$ac_cpp conftest.c 2>&5 | sed -e '1,/_CUT_HERE_/d' -e 's/ //g' > conftest.out"
. ./conftest.out
rm -f conftest*
])dnl
dnl
define(AC_NOTE,
[echo "$1" 1>&AC_FD_MSG
])dnl
old_CFLAGS="$CFLAGS"
AC_PROG_CC
AC_PROG_CPP
AC_PROG_GCC_TRADITIONAL
AC_ISC_POSIX
AC_TRY_RUN(main(){exit(0);},,[
if test $CC != cc ; then
AC_NOTE(Your $CC failed - restarting with CC=cc)
AC_NOTE()
CC=cc
export CC
exec $0 $configure_args
fi
])
AC_TRY_RUN(main(){exit(0);},,
exec 5>&2
eval $ac_link
AC_NOTE(CC=$CC; CFLAGS=$CFLAGS; LIBS=$LIBS;)
AC_NOTE($ac_compile)
AC_MSG_ERROR(Can't run the compiler - sorry))
AC_TRY_RUN([
main()
{
int __something_strange_();
__something_strange_(0);
}
],AC_MSG_ERROR(Your compiler does not set the exit status - sorry))
AC_PROG_AWK
if test -f etc/toolcheck; then
AC_CHECKING(for buggy tools)
sh etc/toolcheck 1>&AC_FD_MSG
fi
dnl
dnl **** special unix variants ****
dnl
AC_CHECKING(for System V)
AC_TRY_COMPILE(
[#include <sys/types.h>
#include <signal.h>
#include <fcntl.h>], [int x = SIGCHLD | FNDELAY;], , AC_DEFINE(SYSV))
AC_CHECKING(for Solaris 2.x)
AC_EGREP_CPP(yes,
[#if defined(SVR4) && defined(sun)
yes
#endif
], LIBS="$LIBS -lsocket -lnsl -lkstat")
dnl
dnl **** select() ****
dnl
AC_CHECKING(select)
AC_TRY_LINK(,[select(0, 0, 0, 0, 0);],,
LIBS="$LIBS -lnet -lnsl"
AC_CHECKING(select with $LIBS)
AC_TRY_LINK(,[select(0, 0, 0, 0, 0);],,
AC_MSG_ERROR(!!! no select - no screen))
)
dnl
dnl **** check the select implementation ****
dnl
AC_CHECKING(select return value)
AC_TRY_RUN([
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
char *nam = "/tmp/conftest$$";
#ifdef NAMEDPIPE
#ifndef O_NONBLOCK
#define O_NONBLOCK O_NDELAY
#endif
#ifndef S_IFIFO
#define S_IFIFO 0010000
#endif
main()
{
#ifdef FD_SET
fd_set f;
#else
int f;
#endif
#ifdef __FreeBSD__
/* From Andrew A. Chernov (ache@astral.msk.su):
* opening RDWR fifo fails in BSD 4.4, but select return values are
* right.
*/
exit(0);
#endif
(void)alarm(5);
#ifdef POSIX
if (mkfifo(nam, 0777))
#else
if (mknod(nam, S_IFIFO|0777, 0))
#endif
exit(1);
close(0);
if (open(nam, O_RDWR | O_NONBLOCK))
exit(1);
if (write(0, "TEST", 4) == -1)
exit(1);
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
main()
{
int s1, s2, l;
struct sockaddr_un a;
#ifdef FD_SET
fd_set f;
#else
int f;
#endif
(void)alarm(5);
if ((s1 = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
exit(1);
a.sun_family = AF_UNIX;
strcpy(a.sun_path, nam);
(void) unlink(nam);
if (bind(s1, (struct sockaddr *) &a, strlen(nam)+2) == -1)
exit(1);
if (listen(s1, 2))
exit(1);
if (fork() == 0)
{
if ((s2 = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
kill(getppid(), 3);
(void)connect(s2, (struct sockaddr *)&a, strlen(nam) + 2);
if (write(s2, "HELLO", 5) == -1)
kill(getppid(), 3);
exit(0);
}
l = sizeof(a);
close(0);
if (accept(s1, (struct sockaddr *)&a, &l))
exit(1);
#endif
#ifdef FD_SET
FD_SET(0, &f);
#else
f = 1;
#endif
if (select(1, &f, 0, 0, 0) == -1)
exit(1);
if (select(1, &f, &f, 0, 0) != 2)
exit(1);
exit(0);
}
],AC_NOTE(- select is ok),
AC_NOTE(- select can't count) AC_DEFINE(SELECT_BROKEN))
dnl
dnl **** termcap or terminfo ****
dnl
AC_CHECKING(for tgetent)
AC_TRY_LINK(,tgetent((char *)0, (char *)0);,,
olibs="$LIBS"
LIBS="-lcurses $olibs"
AC_CHECKING(libcurses)
AC_TRY_LINK(,[
#ifdef __hpux
__sorry_hpux_libcurses_is_totally_broken_in_10_10();
#else
tgetent((char *)0, (char *)0);
#endif
],,
LIBS="-ltermcap $olibs"
AC_CHECKING(libtermcap)
AC_TRY_LINK(,tgetent((char *)0, (char *)0);,,
LIBS="-ltermlib $olibs"
AC_CHECKING(libtermlib)
AC_TRY_LINK(,tgetent((char *)0, (char *)0);,,
LIBS="-lncurses $olibs"
AC_CHECKING(libncurses)
AC_TRY_LINK(,tgetent((char *)0, (char *)0);,,
AC_MSG_ERROR(!!! no tgetent - no screen))))))
AC_TRY_RUN([
extern char *tgoto();
main()
{
exit(strcmp(tgoto("%p1%d", 0, 1), "1") ? 0 : 1);
}], AC_NOTE(- you use the termcap database),
AC_NOTE(- you use the terminfo database) AC_DEFINE(TERMINFO))
AC_CHECKING(ospeed)
AC_TRY_LINK(extern short ospeed;,ospeed=5;,,AC_DEFINE(NEED_OSPEED))
dnl
dnl **** PTY specific things ****
dnl
AC_CHECKING(for /dev/ptc)
if test -r /dev/ptc; then
AC_DEFINE(HAVE_DEV_PTC)
fi
AC_CHECKING(for SVR4 ptys)
sysvr4ptys=
if test -c /dev/ptmx ; then
AC_TRY_LINK([],[ptsname(0);grantpt(0);unlockpt(0);],[AC_DEFINE(HAVE_SVR4_PTYS)
sysvr4ptys=1])
fi
AC_CHECK_FUNCS(getpt)
dnl check for openpty()
if test -z "$sysvr4ptys"; then
AC_CHECK_FUNCS(openpty,,
[AC_CHECK_LIB(util,openpty, [AC_DEFINE(HAVE_OPENPTY)] [LIBS="$LIBS -lutil"])])
fi
AC_CHECKING(for ptyranges)
if test -d /dev/ptym ; then
pdir='/dev/ptym'
else
pdir='/dev'
fi
dnl SCO uses ptyp%d
AC_EGREP_CPP(yes,
[#ifdef M_UNIX
yes;
#endif
], ptys=`echo /dev/ptyp??`, ptys=`echo $pdir/pty??`)
dnl if test -c /dev/ptyp19; then
dnl ptys=`echo /dev/ptyp??`
dnl else
dnl ptys=`echo $pdir/pty??`
dnl fi
if test "$ptys" != "$pdir/pty??" ; then
p0=`echo $ptys | tr ' ' '\012' | sed -e 's/^.*\(.\).$/\1/g' | sort -u | tr -d '\012'`
p1=`echo $ptys | tr ' ' '\012' | sed -e 's/^.*\(.\)$/\1/g' | sort -u | tr -d '\012'`
AC_DEFINE_UNQUOTED(PTYRANGE0,"$p0")
AC_DEFINE_UNQUOTED(PTYRANGE1,"$p1")
fi
dnl **** pty mode/group handling ****
dnl
dnl support provided by Luke Mewburn <lm@rmit.edu.au>, 931222
AC_ARG_WITH(pty-mode, [ --with-pty-mode=mode default mode for ptys], [ ptymode="${withval}" ])
AC_ARG_WITH(pty-group, [ --with-pty-group=group default group for ptys], [ ptygrp="${withval}" ])
test -n "$ptymode" || ptymode=0620
if test -n "$ptygrp" ; then
AC_DEFINE_UNQUOTED(PTYMODE, $ptymode)
AC_DEFINE_UNQUOTED(PTYGROUP,$ptygrp)
else
AC_CHECKING(default tty permissions/group)
rm -f conftest_grp
AC_TRY_RUN([
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
main()
{
struct stat sb;
char *x,*ttyname();
int om, m;
FILE *fp;
if (!(x = ttyname(0))) exit(1);
if (stat(x, &sb)) exit(1);
om = sb.st_mode;
if (om & 002) exit(0);
m = system("mesg y");
if (m == -1 || m == 127) exit(1);
if (stat(x, &sb)) exit(1);
m = sb.st_mode;
if (chmod(x, om)) exit(1);
if (m & 002) exit(0);
if (sb.st_gid == getgid()) exit(1);
if (!(fp=fopen("conftest_grp", "w")))
exit(1);
fprintf(fp, "%d\n", sb.st_gid);
fclose(fp);
exit(0);
}
],[
if test -f conftest_grp; then
ptygrp=`cat conftest_grp`
AC_NOTE([- pty mode: $ptymode, group: $ptygrp])
AC_DEFINE_UNQUOTED(PTYMODE, $ptymode)
AC_DEFINE_UNQUOTED(PTYGROUP,$ptygrp)
else
AC_NOTE(- ptys are world accessable)
fi
],[
WRITEPATH=''
XTERMPATH=''
AC_PATH_PROG(WRITEPATH, write)
AC_PATH_PROG(XTERMPATH, xterm)
found=
if test -n "$WRITEPATH$XTERMPATH"; then
findfollow=
lsfollow=
found=`find $WRITEPATH $XTERMPATH -follow -print 2>/dev/null`
if test -n "$found"; then
findfollow=-follow
lsfollow=L
fi
if test -n "$XTERMPATH"; then
ptygrpn=`ls -l$lsfollow $XTERMPATH | sed -n -e 1p | $AWK '{print $4}'`
if test tty != "$ptygrpn"; then
XTERMPATH=
fi
fi
fi
if test -n "$WRITEPATH$XTERMPATH"; then
found=`find $WRITEPATH $XTERMPATH $findfollow -perm -2000 -print`
if test -n "$found"; then
ptygrp=`ls -ln$lsfollow $found | sed -n -e 1p | $AWK '{print $4}'`
AC_NOTE([- pty mode: $ptymode, group: $ptygrp])
AC_DEFINE_UNQUOTED(PTYMODE, $ptymode)
AC_DEFINE_UNQUOTED(PTYGROUP,$ptygrp)
else
AC_NOTE(- ptys are world accessable)
fi
else
AC_NOTE(- can't determine - assume ptys are world accessable)
fi
]
)
rm -f conftest_grp
fi
dnl
dnl **** signal handling ****
dnl
if test -n "$posix" ; then
dnl POSIX has reliable signals with void return type.
AC_NOTE(assuming posix signal definition)
AC_DEFINE(SIGVOID)
else
AC_CHECKING(return type of signal handlers)
AC_TRY_COMPILE(
[#include <sys/types.h>
#include <signal.h>
#ifdef signal
#undef signal
#endif
extern void (*signal ()) ();], [int i;], AC_DEFINE(SIGVOID))
AC_CHECKING(sigset)
AC_TRY_LINK([
#include <sys/types.h>
#include <signal.h>
],[
#ifdef SIGVOID
sigset(0, (void (*)())0);
#else
sigset(0, (int (*)())0);
#endif
], AC_DEFINE(USESIGSET))
AC_CHECKING(signal implementation)
AC_TRY_RUN([
#include <sys/types.h>
#include <signal.h>
#ifndef SIGCLD
#define SIGCLD SIGCHLD
#endif
#ifdef USESIGSET
#define signal sigset
#endif
int got;
#ifdef SIGVOID
void
#endif
hand()
{
got++;
}
main()
{
/* on hpux we use sigvec to get bsd signals */
#ifdef __hpux
(void)signal(SIGCLD, hand);
kill(getpid(), SIGCLD);
kill(getpid(), SIGCLD);
if (got < 2)
exit(1);
#endif
exit(0);
}
],,AC_DEFINE(SYSVSIGS))
fi
AC_CHECK_HEADERS(sys/stropts.h sys/wait.h sgtty.h sys/select.h)
AC_CHECK_HEADERS(term.h)
AC_OUTPUT(Makefile)

40
examples/rlfe/extern.h Normal file
View file

@ -0,0 +1,40 @@
/* Copyright (c) 1993-2002
* Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
* Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
* Copyright (c) 1987 Oliver Laumann
*
* 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 (see the file COPYING); if not, write to the
* Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
****************************************************************
* $Id: extern.h,v 1.18 1994/05/31 12:31:57 mlschroe Exp $ FAU
*/
#if !defined(__GNUC__) || __GNUC__ < 2
#undef __attribute__
#define __attribute__(x)
#endif
#if !defined (__P)
# if defined (__STDC__) || defined (__GNUC__) || defined (__cplusplus)
# define __P(protos) protos
# else
# define __P(protos) ()
# endif
#endif
/* pty.c */
extern int OpenPTY __P((char **));
extern void InitPTY __P((int));

531
examples/rlfe/os.h Normal file
View file

@ -0,0 +1,531 @@
/* Copyright (c) 1993-2002
* Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
* Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
* Copyright (c) 1987 Oliver Laumann
*
* 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 (see the file COPYING); if not, write to the
* Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
****************************************************************
* $Id: os.h,v 1.10 1994/05/31 12:32:22 mlschroe Exp $ FAU
*/
#include <stdio.h>
#include <errno.h>
#include <sys/param.h>
/* In strict ANSI mode, HP-UX machines define __hpux but not hpux */
#if defined(__hpux) && !defined(hpux)
# define hpux
#endif
#if defined(__bsdi__) || defined(__386BSD__) || defined(_CX_UX) || defined(hpux) || defined(_IBMR2) || defined(linux)
# include <signal.h>
#endif /* __bsdi__ || __386BSD__ || _CX_UX || hpux || _IBMR2 || linux */
#ifdef ISC
# ifdef ENAMETOOLONG
# undef ENAMETOOLONG
# endif
# ifdef ENOTEMPTY
# undef ENOTEMPTY
# endif
# include <sys/bsdtypes.h>
# include <net/errno.h>
#endif
#ifdef sun
# define getpgrp __getpgrp
# define exit __exit
#endif
#ifdef POSIX
# include <unistd.h>
# if defined(__STDC__)
# include <stdlib.h>
# endif /* __STDC__ */
#endif /* POSIX */
#ifdef sun
# undef getpgrp
# undef exit
#endif /* sun */
#ifndef linux /* all done in <errno.h> */
extern int errno;
#endif /* linux */
#ifndef HAVE_STRERROR
/* No macros, please */
#undef strerror
#endif
#if !defined(SYSV) && !defined(linux)
# ifdef NEWSOS
# define strlen ___strlen___
# include <strings.h>
# undef strlen
# else /* NEWSOS */
# include <strings.h>
# endif /* NEWSOS */
#else /* SYSV */
# if defined(SVR4) || defined(NEWSOS)
# define strlen ___strlen___
# include <string.h>
# undef strlen
# if !defined(NEWSOS) && !defined(__hpux)
extern size_t strlen(const char *);
# endif
# else /* SVR4 */
# include <string.h>
# endif /* SVR4 */
#endif /* SYSV */
#ifdef USEVARARGS
# if defined(__STDC__)
# include <stdarg.h>
# define VA_LIST(var) va_list var;
# define VA_DOTS ...
# define VA_DECL
# define VA_START(ap, fmt) va_start(ap, fmt)
# define VA_ARGS(ap) ap
# define VA_END(ap) va_end(ap)
# else
# include <varargs.h>
# define VA_LIST(var) va_list var;
# define VA_DOTS va_alist
# define VA_DECL va_dcl
# define VA_START(ap, fmt) va_start(ap)
# define VA_ARGS(ap) ap
# define VA_END(ap) va_end(ap)
# endif
#else
# define VA_LIST(var)
# define VA_DOTS p1, p2, p3, p4, p5, p6
# define VA_DECL unsigned long VA_DOTS;
# define VA_START(ap, fmt)
# define VA_ARGS(ap) VA_DOTS
# define VA_END(ap)
# undef vsnprintf
# define vsnprintf xsnprintf
#endif
#if !defined(sun) && !defined(B43) && !defined(ISC) && !defined(pyr) && !defined(_CX_UX)
# include <time.h>
#endif
#include <sys/time.h>
#ifdef M_UNIX /* SCO */
# include <sys/stream.h>
# include <sys/ptem.h>
# define ftruncate(fd, s) chsize(fd, s)
#endif
#ifdef SYSV
# define index strchr
# define rindex strrchr
# define bzero(poi,len) memset(poi,0,len)
# define bcmp memcmp
# define killpg(pgrp,sig) kill( -(pgrp), sig)
#endif
#ifndef HAVE_GETCWD
# define getcwd(b,l) getwd(b)
#endif
#ifndef USEBCOPY
# ifdef USEMEMMOVE
# define bcopy(s,d,len) memmove(d,s,len)
# else
# ifdef USEMEMCPY
# define bcopy(s,d,len) memcpy(d,s,len)
# else
# define NEED_OWN_BCOPY
# define bcopy xbcopy
# endif
# endif
#endif
#ifdef hpux
# define setreuid(ruid, euid) setresuid(ruid, euid, -1)
# define setregid(rgid, egid) setresgid(rgid, egid, -1)
#endif
#if defined(HAVE_SETEUID) || defined(HAVE_SETREUID)
# define USE_SETEUID
#endif
#if !defined(HAVE__EXIT) && !defined(_exit)
#define _exit(x) exit(x)
#endif
#ifndef HAVE_UTIMES
# define utimes utime
#endif
#ifdef BUILTIN_TELNET
# include <netinet/in.h>
# include <arpa/inet.h>
#endif
#if defined(USE_LOCALE) && (!defined(HAVE_SETLOCALE) || !defined(HAVE_STRFTIME))
# undef USE_LOCALE
#endif
/*****************************************************************
* terminal handling
*/
#if defined (POSIX) || defined (__FreeBSD__)
# include <termios.h>
# ifdef hpux
# include <bsdtty.h>
# endif /* hpux */
# ifdef NCCS
# define MAXCC NCCS
# else
# define MAXCC 256
# endif
#else /* POSIX */
# ifdef TERMIO
# include <termio.h>
# ifdef NCC
# define MAXCC NCC
# else
# define MAXCC 256
# endif
# ifdef CYTERMIO
# include <cytermio.h>
# endif
# else /* TERMIO */
# if defined (HAVE_SGTTY_H)
# include <sgtty.h>
# endif
# endif /* TERMIO */
#endif /* POSIX */
#ifndef VDISABLE
# ifdef _POSIX_VDISABLE
# define VDISABLE _POSIX_VDISABLE
# else
# define VDISABLE 0377
# endif /* _POSIX_VDISABLE */
#endif /* !VDISABLE */
/* on sgi, regardless of the stream head's read mode (RNORM/RMSGN/RMSGD)
* TIOCPKT mode causes data loss if our buffer is too small (IOSIZE)
* to hold the whole packet at first read().
* (Marc Boucher)
*
* matthew green:
* TIOCPKT is broken on dgux 5.4.1 generic AViiON mc88100
*
* Joe Traister: On AIX4, programs like irc won't work if screen
* uses TIOCPKT (select fails to return on pty read).
*/
#if defined(sgi) || defined(DGUX) || defined(_IBMR2)
# undef TIOCPKT
#endif
/* linux ncurses is broken, we have to use our own tputs */
#if defined(linux) && defined(TERMINFO)
# define tputs xtputs
#endif
/* Alexandre Oliva: SVR4 style ptys don't work with osf */
#ifdef __osf__
# undef HAVE_SVR4_PTYS
#endif
/*****************************************************************
* utmp handling
*/
#ifdef GETUTENT
typedef char *slot_t;
#else
typedef int slot_t;
#endif
#if defined(UTMPOK) || defined(BUGGYGETLOGIN)
# if defined(SVR4) && !defined(DGUX) && !defined(__hpux) && !defined(linux)
# include <utmpx.h>
# define UTMPFILE UTMPX_FILE
# define utmp utmpx
# define getutent getutxent
# define getutid getutxid
# define getutline getutxline
# define pututline pututxline
# define setutent setutxent
# define endutent endutxent
# define ut_time ut_xtime
# else /* SVR4 */
# include <utmp.h>
# endif /* SVR4 */
# ifdef apollo
/*
* We don't have GETUTENT, so we dig into utmp ourselves.
* But we save the permanent filedescriptor and
* open utmp just when we need to.
* This code supports an unsorted utmp. jw.
*/
# define UTNOKEEP
# endif /* apollo */
# ifndef UTMPFILE
# ifdef UTMP_FILE
# define UTMPFILE UTMP_FILE
# else
# ifdef _PATH_UTMP
# define UTMPFILE _PATH_UTMP
# else
# define UTMPFILE "/etc/utmp"
# endif /* _PATH_UTMP */
# endif
# endif
#endif /* UTMPOK || BUGGYGETLOGIN */
#if !defined(UTMPOK) && defined(USRLIMIT)
# undef USRLIMIT
#endif
#ifdef LOGOUTOK
# ifndef LOGINDEFAULT
# define LOGINDEFAULT 0
# endif
#else
# ifdef LOGINDEFAULT
# undef LOGINDEFAULT
# endif
# define LOGINDEFAULT 1
#endif
/*****************************************************************
* file stuff
*/
#ifndef F_OK
#define F_OK 0
#endif
#ifndef X_OK
#define X_OK 1
#endif
#ifndef W_OK
#define W_OK 2
#endif
#ifndef R_OK
#define R_OK 4
#endif
#ifndef S_IFIFO
#define S_IFIFO 0010000
#endif
#ifndef S_IREAD
#define S_IREAD 0000400
#endif
#ifndef S_IWRITE
#define S_IWRITE 0000200
#endif
#ifndef S_IEXEC
#define S_IEXEC 0000100
#endif
#if defined(S_IFIFO) && defined(S_IFMT) && !defined(S_ISFIFO)
#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
#endif
#if defined(S_IFSOCK) && defined(S_IFMT) && !defined(S_ISSOCK)
#define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
#endif
#if defined(S_IFCHR) && defined(S_IFMT) && !defined(S_ISCHR)
#define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
#endif
#if defined(S_IFDIR) && defined(S_IFMT) && !defined(S_ISDIR)
#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
#endif
#if defined(S_IFLNK) && defined(S_IFMT) && !defined(S_ISLNK)
#define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
#endif
/*
* SunOS 4.1.3: `man 2V open' has only one line that mentions O_NOBLOCK:
*
* O_NONBLOCK Same as O_NDELAY above.
*
* on the very same SunOS 4.1.3, I traced the open system call and found
* that an open("/dev/ttyy08", O_RDWR|O_NONBLOCK|O_NOCTTY) was blocked,
* whereas open("/dev/ttyy08", O_RDWR|O_NDELAY |O_NOCTTY) went through.
*
* For this simple reason I now favour O_NDELAY. jw. 4.5.95
*/
#if defined(sun) && !defined(SVR4)
# undef O_NONBLOCK
#endif
#if !defined(O_NONBLOCK) && defined(O_NDELAY)
# define O_NONBLOCK O_NDELAY
#endif
#if !defined(FNBLOCK) && defined(FNONBLOCK)
# define FNBLOCK FNONBLOCK
#endif
#if !defined(FNBLOCK) && defined(FNDELAY)
# define FNBLOCK FNDELAY
#endif
#if !defined(FNBLOCK) && defined(O_NONBLOCK)
# define FNBLOCK O_NONBLOCK
#endif
#ifndef POSIX
#undef mkfifo
#define mkfifo(n,m) mknod(n,S_IFIFO|(m),0)
#endif
#if !defined(HAVE_LSTAT) && !defined(lstat)
# define lstat stat
#endif
/*****************************************************************
* signal handling
*/
#ifdef SIGVOID
# define SIGRETURN
# define sigret_t void
#else
# define SIGRETURN return 0;
# define sigret_t int
#endif
/* Geeeee, reverse it? */
#if defined(SVR4) || (defined(SYSV) && defined(ISC)) || defined(_AIX) || defined(linux) || defined(ultrix) || defined(__386BSD__) || defined(__bsdi__) || defined(POSIX) || defined(NeXT)
# define SIGHASARG
#endif
#ifdef SIGHASARG
# define SIGPROTOARG (int)
# define SIGDEFARG (sigsig) int sigsig;
# define SIGARG 0
#else
# define SIGPROTOARG (void)
# define SIGDEFARG ()
# define SIGARG
#endif
#ifndef SIGCHLD
#define SIGCHLD SIGCLD
#endif
#if defined(POSIX) || defined(hpux)
# define signal xsignal
#else
# ifdef USESIGSET
# define signal sigset
# endif /* USESIGSET */
#endif
/* used in screen.c and attacher.c */
#ifndef NSIG /* kbeal needs these w/o SYSV */
# define NSIG 32
#endif /* !NSIG */
/*****************************************************************
* Wait stuff
*/
#if (!defined(sysV68) && !defined(M_XENIX)) || defined(NeXT) || defined(M_UNIX)
# include <sys/wait.h>
#endif
#ifndef WTERMSIG
# ifndef BSDWAIT /* if wait is NOT a union: */
# define WTERMSIG(status) (status & 0177)
# else
# define WTERMSIG(status) status.w_T.w_Termsig
# endif
#endif
#ifndef WSTOPSIG
# ifndef BSDWAIT /* if wait is NOT a union: */
# define WSTOPSIG(status) ((status >> 8) & 0377)
# else
# define WSTOPSIG(status) status.w_S.w_Stopsig
# endif
#endif
/* NET-2 uses WCOREDUMP */
#if defined(WCOREDUMP) && !defined(WIFCORESIG)
# define WIFCORESIG(status) WCOREDUMP(status)
#endif
#ifndef WIFCORESIG
# ifndef BSDWAIT /* if wait is NOT a union: */
# define WIFCORESIG(status) (status & 0200)
# else
# define WIFCORESIG(status) status.w_T.w_Coredump
# endif
#endif
#ifndef WEXITSTATUS
# ifndef BSDWAIT /* if wait is NOT a union: */
# define WEXITSTATUS(status) ((status >> 8) & 0377)
# else
# define WEXITSTATUS(status) status.w_T.w_Retcode
# endif
#endif
/*****************************************************************
* select stuff
*/
#if defined(M_XENIX) || defined(M_UNIX) || defined(_SEQUENT_) || defined (__INTERIX)
#include <sys/select.h> /* for timeval + FD... */
#endif
/*
* SunOS 3.5 - Tom Schmidt - Micron Semiconductor, Inc - 27-Jul-93
* tschmidt@vax.micron.com
*/
#ifndef FD_SET
# ifndef SUNOS3
typedef struct fd_set { int fds_bits[1]; } fd_set;
# endif
# define FD_ZERO(fd) ((fd)->fds_bits[0] = 0)
# define FD_SET(b, fd) ((fd)->fds_bits[0] |= 1 << (b))
# define FD_ISSET(b, fd) ((fd)->fds_bits[0] & 1 << (b))
# define FD_SETSIZE 32
#endif
/*****************************************************************
* user defineable stuff
*/
#ifndef TERMCAP_BUFSIZE
# define TERMCAP_BUFSIZE 2048
#endif
#ifndef MAXPATHLEN
# define MAXPATHLEN 1024
#endif
/*
* you may try to vary this value. Use low values if your (VMS) system
* tends to choke when pasting. Use high values if you want to test
* how many characters your pty's can buffer.
*/
#define IOSIZE 4096

388
examples/rlfe/pty.c Normal file
View file

@ -0,0 +1,388 @@
/* Copyright (c) 1993-2002
* Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
* Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
* Copyright (c) 1987 Oliver Laumann
*
* 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 (see the file COPYING); if not, write to the
* Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
****************************************************************
*/
#include "config.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include "screen.h"
#ifndef sun
# include <sys/ioctl.h>
#endif
/* for solaris 2.1, Unixware (SVR4.2) and possibly others */
#if defined (HAVE_SVR4_PTYS) && defined (HAVE_SYS_STROPTS_H)
# include <sys/stropts.h>
#endif
#if defined(sun) && defined(LOCKPTY) && !defined(TIOCEXCL)
# include <sys/ttold.h>
#endif
#ifdef ISC
# include <sys/tty.h>
# include <sys/sioctl.h>
# include <sys/pty.h>
#endif
#ifdef sgi
# include <sys/sysmacros.h>
#endif /* sgi */
#include "extern.h"
/*
* if no PTYRANGE[01] is in the config file, we pick a default
*/
#ifndef PTYRANGE0
# define PTYRANGE0 "qpr"
#endif
#ifndef PTYRANGE1
# define PTYRANGE1 "0123456789abcdef"
#endif
/* SVR4 pseudo ttys don't seem to work with SCO-5 */
#ifdef M_UNIX
# undef HAVE_SVR4_PTYS
#endif
extern int eff_uid;
/* used for opening a new pty-pair: */
static char PtyName[32], TtyName[32];
#if !(defined(sequent) || defined(_SEQUENT_) || defined(HAVE_SVR4_PTYS))
# ifdef hpux
static char PtyProto[] = "/dev/ptym/ptyXY";
static char TtyProto[] = "/dev/pty/ttyXY";
# else
# ifdef M_UNIX
static char PtyProto[] = "/dev/ptypXY";
static char TtyProto[] = "/dev/ttypXY";
# else
static char PtyProto[] = "/dev/ptyXY";
static char TtyProto[] = "/dev/ttyXY";
# endif
# endif /* hpux */
#endif
static void initmaster __P((int));
#if defined(sun)
/* sun's utmp_update program opens the salve side, thus corrupting
*/
int pty_preopen = 1;
#else
int pty_preopen = 0;
#endif
/*
* Open all ptys with O_NOCTTY, just to be on the safe side
* (RISCos mips breaks otherwise)
*/
#ifndef O_NOCTTY
# define O_NOCTTY 0
#endif
/***************************************************************/
static void
initmaster(f)
int f;
{
#ifdef POSIX
tcflush(f, TCIOFLUSH);
#else
# ifdef TIOCFLUSH
(void) ioctl(f, TIOCFLUSH, (char *) 0);
# endif
#endif
#ifdef LOCKPTY
(void) ioctl(f, TIOCEXCL, (char *) 0);
#endif
}
void
InitPTY(f)
int f;
{
if (f < 0)
return;
#if defined(I_PUSH) && defined(HAVE_SVR4_PTYS) && !defined(sgi) && !defined(linux) && !defined(__osf__) && !defined(M_UNIX)
if (ioctl(f, I_PUSH, "ptem"))
Panic(errno, "InitPTY: cannot I_PUSH ptem");
if (ioctl(f, I_PUSH, "ldterm"))
Panic(errno, "InitPTY: cannot I_PUSH ldterm");
# ifdef sun
if (ioctl(f, I_PUSH, "ttcompat"))
Panic(errno, "InitPTY: cannot I_PUSH ttcompat");
# endif
#endif
}
/***************************************************************/
#if defined(OSX) && !defined(PTY_DONE)
#define PTY_DONE
int
OpenPTY(ttyn)
char **ttyn;
{
register int f;
if ((f = open_controlling_pty(TtyName)) < 0)
return -1;
initmaster(f);
*ttyn = TtyName;
return f;
}
#endif
/***************************************************************/
#if (defined(sequent) || defined(_SEQUENT_)) && !defined(PTY_DONE)
#define PTY_DONE
int
OpenPTY(ttyn)
char **ttyn;
{
char *m, *s;
register int f;
if ((f = getpseudotty(&s, &m)) < 0)
return -1;
#ifdef _SEQUENT_
fvhangup(s);
#endif
strncpy(PtyName, m, sizeof(PtyName));
strncpy(TtyName, s, sizeof(TtyName));
initmaster(f);
*ttyn = TtyName;
return f;
}
#endif
/***************************************************************/
#if defined(__sgi) && !defined(PTY_DONE)
#define PTY_DONE
int
OpenPTY(ttyn)
char **ttyn;
{
int f;
char *name, *_getpty();
sigret_t (*sigcld)__P(SIGPROTOARG);
/*
* SIGCHLD set to SIG_DFL for _getpty() because it may fork() and
* exec() /usr/adm/mkpts
*/
sigcld = signal(SIGCHLD, SIG_DFL);
name = _getpty(&f, O_RDWR | O_NONBLOCK, 0600, 0);
signal(SIGCHLD, sigcld);
if (name == 0)
return -1;
initmaster(f);
*ttyn = name;
return f;
}
#endif
/***************************************************************/
#if defined(MIPS) && defined(HAVE_DEV_PTC) && !defined(PTY_DONE)
#define PTY_DONE
int
OpenPTY(ttyn)
char **ttyn;
{
register int f;
struct stat buf;
strcpy(PtyName, "/dev/ptc");
if ((f = open(PtyName, O_RDWR | O_NOCTTY | O_NONBLOCK)) < 0)
return -1;
if (fstat(f, &buf) < 0)
{
close(f);
return -1;
}
sprintf(TtyName, "/dev/ttyq%d", minor(buf.st_rdev));
initmaster(f);
*ttyn = TtyName;
return f;
}
#endif
/***************************************************************/
#if defined(HAVE_SVR4_PTYS) && !defined(PTY_DONE)
#define PTY_DONE
int
OpenPTY(ttyn)
char **ttyn;
{
register int f;
char *m, *ptsname();
int unlockpt __P((int)), grantpt __P((int));
#if defined(HAVE_GETPT) && defined(linux)
int getpt __P((void));
#endif
sigret_t (*sigcld)__P(SIGPROTOARG);
strcpy(PtyName, "/dev/ptmx");
#if defined(HAVE_GETPT) && defined(linux)
if ((f = getpt()) == -1)
#else
if ((f = open(PtyName, O_RDWR | O_NOCTTY)) == -1)
#endif
return -1;
/*
* SIGCHLD set to SIG_DFL for grantpt() because it fork()s and
* exec()s pt_chmod
*/
sigcld = signal(SIGCHLD, SIG_DFL);
if ((m = ptsname(f)) == NULL || grantpt(f) || unlockpt(f))
{
signal(SIGCHLD, sigcld);
close(f);
return -1;
}
signal(SIGCHLD, sigcld);
strncpy(TtyName, m, sizeof(TtyName));
initmaster(f);
*ttyn = TtyName;
return f;
}
#endif
/***************************************************************/
#if defined(_AIX) && defined(HAVE_DEV_PTC) && !defined(PTY_DONE)
#define PTY_DONE
int
OpenPTY(ttyn)
char **ttyn;
{
register int f;
/* a dumb looking loop replaced by mycrofts code: */
strcpy (PtyName, "/dev/ptc");
if ((f = open (PtyName, O_RDWR | O_NOCTTY)) < 0)
return -1;
strncpy(TtyName, ttyname(f), sizeof(TtyName));
if (eff_uid && access(TtyName, R_OK | W_OK))
{
close(f);
return -1;
}
initmaster(f);
# ifdef _IBMR2
pty_preopen = 1;
# endif
*ttyn = TtyName;
return f;
}
#endif
/***************************************************************/
#if defined(HAVE_OPENPTY) && !defined(PTY_DONE)
#define PTY_DONE
int
OpenPTY(ttyn)
char **ttyn;
{
int f, s;
if (openpty(&f, &s, TtyName, NULL, NULL) != 0)
return -1;
close(s);
initmaster(f);
pty_preopen = 1;
*ttyn = TtyName;
return f;
}
#endif
/***************************************************************/
#ifndef PTY_DONE
int
OpenPTY(ttyn)
char **ttyn;
{
register char *p, *q, *l, *d;
register int f;
debug("OpenPTY: Using BSD style ptys.\n");
strcpy(PtyName, PtyProto);
strcpy(TtyName, TtyProto);
for (p = PtyName; *p != 'X'; p++)
;
for (q = TtyName; *q != 'X'; q++)
;
for (l = PTYRANGE0; (*p = *l) != '\0'; l++)
{
for (d = PTYRANGE1; (p[1] = *d) != '\0'; d++)
{
debug1("OpenPTY tries '%s'\n", PtyName);
if ((f = open(PtyName, O_RDWR | O_NOCTTY)) == -1)
continue;
q[0] = *l;
q[1] = *d;
if (eff_uid && access(TtyName, R_OK | W_OK))
{
close(f);
continue;
}
#if defined(sun) && defined(TIOCGPGRP) && !defined(SUNOS3)
/* Hack to ensure that the slave side of the pty is
* unused. May not work in anything other than SunOS4.1
*/
{
int pgrp;
/* tcgetpgrp does not work (uses TIOCGETPGRP)! */
if (ioctl(f, TIOCGPGRP, (char *)&pgrp) != -1 || errno != EIO)
{
close(f);
continue;
}
}
#endif
initmaster(f);
*ttyn = TtyName;
return f;
}
}
return -1;
}
#endif

792
examples/rlfe/rlfe.c Normal file
View file

@ -0,0 +1,792 @@
/* A front-end using readline to "cook" input lines.
*
* Copyright (C) 2004, 1999 Per Bothner
*
* This front-end 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.
*
* Some code from Johnson & Troan: "Linux Application Development"
* (Addison-Wesley, 1998) was used directly or for inspiration.
*
* 2003-11-07 Wolfgang Taeuber <wolfgang_taeuber@agilent.com>
* Specify a history file and the size of the history file with command
* line options; use EDITOR/VISUAL to set vi/emacs preference.
*/
/* PROBLEMS/TODO:
*
* Only tested under GNU/Linux and Mac OS 10.x; needs to be ported.
*
* Switching between line-editing-mode vs raw-char-mode depending on
* what tcgetattr returns is inherently not robust, plus it doesn't
* work when ssh/telnetting in. A better solution is possible if the
* tty system can send in-line escape sequences indicating the current
* mode, echo'd input, etc. That would also allow a user preference
* to set different colors for prompt, input, stdout, and stderr.
*
* When running mc -c under the Linux console, mc does not recognize
* mouse clicks, which mc does when not running under rlfe.
*
* Pasting selected text containing tabs is like hitting the tab character,
* which invokes readline completion. We don't want this. I don't know
* if this is fixable without integrating rlfe into a terminal emulator.
*
* Echo suppression is a kludge, but can only be avoided with better kernel
* support: We need a tty mode to disable "real" echoing, while still
* letting the inferior think its tty driver to doing echoing.
* Stevens's book claims SCR$ and BSD4.3+ have TIOCREMOTE.
*
* The latest readline may have some hooks we can use to avoid having
* to back up the prompt. (See HAVE_ALREADY_PROMPTED.)
*
* Desirable readline feature: When in cooked no-echo mode (e.g. password),
* echo characters are they are types with '*', but remove them when done.
*
* Asynchronous output while we're editing an input line should be
* inserted in the output view *before* the input line, so that the
* lines being edited (with the prompt) float at the end of the input.
*
* A "page mode" option to emulate more/less behavior: At each page of
* output, pause for a user command. This required parsing the output
* to keep track of line lengths. It also requires remembering the
* output, if we want an option to scroll back, which suggests that
* this should be integrated with a terminal emulator like xterm.
*/
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <netdb.h>
#include <stdlib.h>
#include <errno.h>
#include <grp.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <termios.h>
#include "config.h"
#include "extern.h"
#if defined (HAVE_SYS_WAIT_H)
# include <sys/wait.h>
#endif
#ifdef READLINE_LIBRARY
# include "readline.h"
# include "history.h"
#else
# include <readline/readline.h>
# include <readline/history.h>
#endif
#ifndef COMMAND
#define COMMAND "/bin/bash"
#endif
#ifndef COMMAND_ARGS
#define COMMAND_ARGS COMMAND
#endif
#ifndef ALT_COMMAND
#define ALT_COMMAND "/bin/sh"
#endif
#ifndef ALT_COMMAND_ARGS
#define ALT_COMMAND_ARGS ALT_COMMAND
#endif
#ifndef HAVE_MEMMOVE
# if __GNUC__ > 1
# define memmove(d, s, n) __builtin_memcpy(d, s, n)
# else
# define memmove(d, s, n) memcpy(d, s, n)
# endif
#else
# define memmove(d, s, n) memcpy(d, s, n)
#endif
#define APPLICATION_NAME "rlfe"
static int in_from_inferior_fd;
static int out_to_inferior_fd;
static void set_edit_mode ();
static void usage_exit ();
static char *hist_file = 0;
static int hist_size = 0;
/* Unfortunately, we cannot safely display echo from the inferior process.
The reason is that the echo bit in the pty is "owned" by the inferior,
and if we try to turn it off, we could confuse the inferior.
Thus, when echoing, we get echo twice: First readline echoes while
we're actually editing. Then we send the line to the inferior, and the
terminal driver send back an extra echo.
The work-around is to remember the input lines, and when we see that
line come back, we supress the output.
A better solution (supposedly available on SVR4) would be a smarter
terminal driver, with more flags ... */
#define ECHO_SUPPRESS_MAX 1024
char echo_suppress_buffer[ECHO_SUPPRESS_MAX];
int echo_suppress_start = 0;
int echo_suppress_limit = 0;
/*#define DEBUG*/
#ifdef DEBUG
FILE *logfile = NULL;
#define DPRINT0(FMT) (fprintf(logfile, FMT), fflush(logfile))
#define DPRINT1(FMT, V1) (fprintf(logfile, FMT, V1), fflush(logfile))
#define DPRINT2(FMT, V1, V2) (fprintf(logfile, FMT, V1, V2), fflush(logfile))
#else
#define DPRINT0(FMT) ((void) 0) /* Do nothing */
#define DPRINT1(FMT, V1) ((void) 0) /* Do nothing */
#define DPRINT2(FMT, V1, V2) ((void) 0) /* Do nothing */
#endif
struct termios orig_term;
/* Pid of child process. */
static pid_t child = -1;
static void
sig_child (int signo)
{
int status;
wait (&status);
if (hist_file != 0)
{
write_history (hist_file);
if (hist_size)
history_truncate_file (hist_file, hist_size);
}
DPRINT0 ("(Child process died.)\n");
tcsetattr(STDIN_FILENO, TCSANOW, &orig_term);
exit (0);
}
volatile int propagate_sigwinch = 0;
/* sigwinch_handler
* propagate window size changes from input file descriptor to
* master side of pty.
*/
void sigwinch_handler(int signal) {
propagate_sigwinch = 1;
}
/* get_slave_pty() returns an integer file descriptor.
* If it returns < 0, an error has occurred.
* Otherwise, it has returned the slave file descriptor.
*/
int get_slave_pty(char *name) {
struct group *gptr;
gid_t gid;
int slave = -1;
/* chown/chmod the corresponding pty, if possible.
* This will only work if the process has root permissions.
* Alternatively, write and exec a small setuid program that
* does just this.
*/
if ((gptr = getgrnam("tty")) != 0) {
gid = gptr->gr_gid;
} else {
/* if the tty group does not exist, don't change the
* group on the slave pty, only the owner
*/
gid = -1;
}
/* Note that we do not check for errors here. If this is code
* where these actions are critical, check for errors!
*/
chown(name, getuid(), gid);
/* This code only makes the slave read/writeable for the user.
* If this is for an interactive shell that will want to
* receive "write" and "wall" messages, OR S_IWGRP into the
* second argument below.
*/
chmod(name, S_IRUSR|S_IWUSR);
/* open the corresponding slave pty */
slave = open(name, O_RDWR);
return (slave);
}
/* Certain special characters, such as ctrl/C, we want to pass directly
to the inferior, rather than letting readline handle them. */
static char special_chars[20];
static int special_chars_count;
static void
add_special_char(int ch)
{
if (ch != 0)
special_chars[special_chars_count++] = ch;
}
static int eof_char;
static int
is_special_char(int ch)
{
int i;
#if 0
if (ch == eof_char && rl_point == rl_end)
return 1;
#endif
for (i = special_chars_count; --i >= 0; )
if (special_chars[i] == ch)
return 1;
return 0;
}
static char buf[1024];
/* buf[0 .. buf_count-1] is the what has been emitted on the current line.
It is used as the readline prompt. */
static int buf_count = 0;
int do_emphasize_input = 1;
int current_emphasize_input;
char *start_input_mode = "\033[1m";
char *end_input_mode = "\033[0m";
int num_keys = 0;
static void maybe_emphasize_input (int on)
{
if (on == current_emphasize_input
|| (on && ! do_emphasize_input))
return;
fprintf (rl_outstream, on ? start_input_mode : end_input_mode);
fflush (rl_outstream);
current_emphasize_input = on;
}
static void
null_prep_terminal (int meta)
{
}
static void
null_deprep_terminal ()
{
maybe_emphasize_input (0);
}
static int
pre_input_change_mode (void)
{
return 0;
}
char pending_special_char;
static void
line_handler (char *line)
{
if (line == NULL)
{
char buf[1];
DPRINT0("saw eof!\n");
buf[0] = '\004'; /* ctrl/d */
write (out_to_inferior_fd, buf, 1);
}
else
{
static char enter[] = "\r";
/* Send line to inferior: */
int length = strlen (line);
if (length > ECHO_SUPPRESS_MAX-2)
{
echo_suppress_start = 0;
echo_suppress_limit = 0;
}
else
{
if (echo_suppress_limit + length > ECHO_SUPPRESS_MAX - 2)
{
if (echo_suppress_limit - echo_suppress_start + length
<= ECHO_SUPPRESS_MAX - 2)
{
memmove (echo_suppress_buffer,
echo_suppress_buffer + echo_suppress_start,
echo_suppress_limit - echo_suppress_start);
echo_suppress_limit -= echo_suppress_start;
echo_suppress_start = 0;
}
else
{
echo_suppress_limit = 0;
}
echo_suppress_start = 0;
}
memcpy (echo_suppress_buffer + echo_suppress_limit,
line, length);
echo_suppress_limit += length;
echo_suppress_buffer[echo_suppress_limit++] = '\r';
echo_suppress_buffer[echo_suppress_limit++] = '\n';
}
write (out_to_inferior_fd, line, length);
if (pending_special_char == 0)
{
write (out_to_inferior_fd, enter, sizeof(enter)-1);
if (*line)
add_history (line);
}
free (line);
}
rl_callback_handler_remove ();
buf_count = 0;
num_keys = 0;
if (pending_special_char != 0)
{
write (out_to_inferior_fd, &pending_special_char, 1);
pending_special_char = 0;
}
}
/* Value of rl_getc_function.
Use this because readline should read from stdin, not rl_instream,
points to the pty (so readline has monitor its terminal modes). */
int
my_rl_getc (FILE *dummy)
{
int ch = rl_getc (stdin);
if (is_special_char (ch))
{
pending_special_char = ch;
return '\r';
}
return ch;
}
int
main(int argc, char** argv)
{
char *path;
int i;
int master;
char *name;
int in_from_tty_fd;
struct sigaction act;
struct winsize ws;
struct termios t;
int maxfd;
fd_set in_set;
static char empty_string[1] = "";
char *prompt = empty_string;
int ioctl_err = 0;
int arg_base = 1;
#ifdef DEBUG
logfile = fopen("/tmp/rlfe.log", "w");
#endif
while (arg_base<argc)
{
if (argv[arg_base][0] != '-')
break;
if (arg_base+1 >= argc )
usage_exit();
switch(argv[arg_base][1])
{
case 'h':
arg_base++;
hist_file = argv[arg_base];
break;
case 's':
arg_base++;
hist_size = atoi(argv[arg_base]);
if (hist_size<0)
usage_exit();
break;
default:
usage_exit();
}
arg_base++;
}
if (hist_file)
read_history (hist_file);
set_edit_mode ();
rl_readline_name = APPLICATION_NAME;
if ((master = OpenPTY (&name)) < 0)
{
perror("ptypair: could not open master pty");
exit(1);
}
DPRINT1("pty name: '%s'\n", name);
/* set up SIGWINCH handler */
act.sa_handler = sigwinch_handler;
sigemptyset(&(act.sa_mask));
act.sa_flags = 0;
if (sigaction(SIGWINCH, &act, NULL) < 0)
{
perror("ptypair: could not handle SIGWINCH ");
exit(1);
}
if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) < 0)
{
perror("ptypair: could not get window size");
exit(1);
}
if ((child = fork()) < 0)
{
perror("cannot fork");
exit(1);
}
if (child == 0)
{
int slave; /* file descriptor for slave pty */
/* We are in the child process */
close(master);
#ifdef TIOCSCTTY
if ((slave = get_slave_pty(name)) < 0)
{
perror("ptypair: could not open slave pty");
exit(1);
}
#endif
/* We need to make this process a session group leader, because
* it is on a new PTY, and things like job control simply will
* not work correctly unless there is a session group leader
* and process group leader (which a session group leader
* automatically is). This also disassociates us from our old
* controlling tty.
*/
if (setsid() < 0)
{
perror("could not set session leader");
}
/* Tie us to our new controlling tty. */
#ifdef TIOCSCTTY
if (ioctl(slave, TIOCSCTTY, NULL))
{
perror("could not set new controlling tty");
}
#else
if ((slave = get_slave_pty(name)) < 0)
{
perror("ptypair: could not open slave pty");
exit(1);
}
#endif
/* make slave pty be standard in, out, and error */
dup2(slave, STDIN_FILENO);
dup2(slave, STDOUT_FILENO);
dup2(slave, STDERR_FILENO);
/* at this point the slave pty should be standard input */
if (slave > 2)
{
close(slave);
}
/* Try to restore window size; failure isn't critical */
if (ioctl(STDOUT_FILENO, TIOCSWINSZ, &ws) < 0)
{
perror("could not restore window size");
}
/* now start the shell */
{
static char* command_args[] = { COMMAND_ARGS, NULL };
static char* alt_command_args[] = { ALT_COMMAND_ARGS, NULL };
if (argc <= 1)
{
execvp (COMMAND, command_args);
execvp (ALT_COMMAND, alt_command_args);
}
else
execvp (argv[arg_base], &argv[arg_base]);
}
/* should never be reached */
exit(1);
}
/* parent */
signal (SIGCHLD, sig_child);
/* Note that we only set termios settings for standard input;
* the master side of a pty is NOT a tty.
*/
tcgetattr(STDIN_FILENO, &orig_term);
t = orig_term;
eof_char = t.c_cc[VEOF];
/* add_special_char(t.c_cc[VEOF]);*/
add_special_char(t.c_cc[VINTR]);
add_special_char(t.c_cc[VQUIT]);
add_special_char(t.c_cc[VSUSP]);
#if defined (VDISCARD)
add_special_char(t.c_cc[VDISCARD]);
#endif
t.c_lflag &= ~(ICANON | ISIG | ECHO | ECHOCTL | ECHOE | \
ECHOK | ECHONL
#if defined (ECHOKE)
| ECHOKE
#endif
#if defined (ECHOPRT)
| ECHOPRT
#endif
);
t.c_iflag &= ~ICRNL;
t.c_iflag |= IGNBRK;
t.c_cc[VMIN] = 1;
t.c_cc[VTIME] = 0;
tcsetattr(STDIN_FILENO, TCSANOW, &t);
in_from_inferior_fd = master;
out_to_inferior_fd = master;
rl_instream = fdopen (master, "r");
rl_getc_function = my_rl_getc;
rl_prep_term_function = null_prep_terminal;
rl_deprep_term_function = null_deprep_terminal;
rl_pre_input_hook = pre_input_change_mode;
rl_callback_handler_install (prompt, line_handler);
in_from_tty_fd = STDIN_FILENO;
FD_ZERO (&in_set);
maxfd = in_from_inferior_fd > in_from_tty_fd ? in_from_inferior_fd
: in_from_tty_fd;
for (;;)
{
int num;
FD_SET (in_from_inferior_fd, &in_set);
FD_SET (in_from_tty_fd, &in_set);
num = select(maxfd+1, &in_set, NULL, NULL, NULL);
if (propagate_sigwinch)
{
struct winsize ws;
if (ioctl (STDIN_FILENO, TIOCGWINSZ, &ws) >= 0)
{
ioctl (master, TIOCSWINSZ, &ws);
}
propagate_sigwinch = 0;
continue;
}
if (num <= 0)
{
perror ("select");
exit (-1);
}
if (FD_ISSET (in_from_tty_fd, &in_set))
{
extern int _rl_echoing_p;
struct termios term_master;
int do_canon = 1;
int do_icrnl = 1;
int ioctl_ret;
DPRINT1("[tty avail num_keys:%d]\n", num_keys);
/* If we can't get tty modes for the master side of the pty, we
can't handle non-canonical-mode programs. Always assume the
master is in canonical echo mode if we can't tell. */
ioctl_ret = tcgetattr(master, &term_master);
if (ioctl_ret >= 0)
{
do_canon = (term_master.c_lflag & ICANON) != 0;
do_icrnl = (term_master.c_lflag & ICRNL) != 0;
_rl_echoing_p = (term_master.c_lflag & ECHO) != 0;
DPRINT1 ("echo,canon,crnl:%03d\n",
100 * _rl_echoing_p
+ 10 * do_canon
+ 1 * do_icrnl);
}
else
{
if (ioctl_err == 0)
DPRINT1("tcgetattr on master fd failed: errno = %d\n", errno);
ioctl_err = 1;
}
if (do_canon == 0 && num_keys == 0)
{
char ch[10];
int count = read (STDIN_FILENO, ch, sizeof(ch));
DPRINT1("[read %d chars from stdin: ", count);
DPRINT2(" \"%.*s\"]\n", count, ch);
if (do_icrnl)
{
int i = count;
while (--i >= 0)
{
if (ch[i] == '\r')
ch[i] = '\n';
}
}
maybe_emphasize_input (1);
write (out_to_inferior_fd, ch, count);
}
else
{
if (num_keys == 0)
{
int i;
/* Re-install callback handler for new prompt. */
if (prompt != empty_string)
free (prompt);
if (prompt == NULL)
{
DPRINT0("New empty prompt\n");
prompt = empty_string;
}
else
{
if (do_emphasize_input && buf_count > 0)
{
prompt = malloc (buf_count + strlen (end_input_mode)
+ strlen (start_input_mode) + 5);
sprintf (prompt, "\001%s\002%.*s\001%s\002",
end_input_mode,
buf_count, buf,
start_input_mode);
}
else
{
prompt = malloc (buf_count + 1);
memcpy (prompt, buf, buf_count);
prompt[buf_count] = '\0';
}
DPRINT1("New prompt '%s'\n", prompt);
#if 0 /* ifdef HAVE_RL_ALREADY_PROMPTED */
/* Doesn't quite work when do_emphasize_input is 1. */
rl_already_prompted = buf_count > 0;
#else
if (buf_count > 0)
write (1, "\r", 1);
#endif
}
rl_callback_handler_install (prompt, line_handler);
}
num_keys++;
maybe_emphasize_input (1);
rl_callback_read_char ();
}
}
else /* output from inferior. */
{
int i;
int count;
int old_count;
if (buf_count > (sizeof(buf) >> 2))
buf_count = 0;
count = read (in_from_inferior_fd, buf+buf_count,
sizeof(buf) - buf_count);
DPRINT2("read %d from inferior, buf_count=%d", count, buf_count);
DPRINT2(": \"%.*s\"", count, buf+buf_count);
maybe_emphasize_input (0);
if (count <= 0)
{
DPRINT0 ("(Connection closed by foreign host.)\n");
tcsetattr(STDIN_FILENO, TCSANOW, &orig_term);
exit (0);
}
old_count = buf_count;
/* Look for any pending echo that we need to suppress. */
while (echo_suppress_start < echo_suppress_limit
&& count > 0
&& buf[buf_count] == echo_suppress_buffer[echo_suppress_start])
{
count--;
buf_count++;
echo_suppress_start++;
}
DPRINT1("suppressed %d characters of echo.\n", buf_count-old_count);
/* Write to the terminal anything that was not suppressed. */
if (count > 0)
write (1, buf + buf_count, count);
/* Finally, look for a prompt candidate.
* When we get around to going input (from the keyboard),
* we will consider the prompt to be anything since the last
* line terminator. So we need to save that text in the
* initial part of buf. However, anything before the
* most recent end-of-line is not interesting. */
buf_count += count;
#if 1
for (i = buf_count; --i >= old_count; )
#else
for (i = buf_count - 1; i-- >= buf_count - count; )
#endif
{
if (buf[i] == '\n' || buf[i] == '\r')
{
i++;
memmove (buf, buf+i, buf_count - i);
buf_count -= i;
break;
}
}
DPRINT2("-> i: %d, buf_count: %d\n", i, buf_count);
}
}
}
static void set_edit_mode ()
{
int vi = 0;
char *shellopts;
shellopts = getenv ("SHELLOPTS");
while (shellopts != 0)
{
if (strncmp ("vi", shellopts, 2) == 0)
{
vi = 1;
break;
}
shellopts = strchr (shellopts + 1, ':');
}
if (!vi)
{
if (getenv ("EDITOR") != 0)
vi |= strcmp (getenv ("EDITOR"), "vi") == 0;
}
if (vi)
rl_variable_bind ("editing-mode", "vi");
else
rl_variable_bind ("editing-mode", "emacs");
}
static void usage_exit ()
{
fprintf (stderr, "Usage: rlfe [-h histfile] [-s size] cmd [arg1] [arg2] ...\n\n");
exit (1);
}

2
examples/rlfe/screen.h Normal file
View file

@ -0,0 +1,2 @@
/* Dummy header to avoid modifying pty.c */
#include "os.h"

61
examples/rlkeymaps.c Normal file
View file

@ -0,0 +1,61 @@
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#if defined (READLINE_LIBRARY)
# include "readline.h"
# include "history.h"
#else
# include <readline/readline.h>
# include <readline/history.h>
#endif
int
main (int c, char **v)
{
Keymap nmap, emacsmap, newemacs;
int r, errs;
errs = 0;
nmap = rl_make_keymap ();
r = rl_set_keymap_name ("emacs", nmap);
if (r >= 0)
{
fprintf (stderr, "rlkeymaps: error: able to rename `emacs' keymap\n");
errs++;
}
emacsmap = rl_get_keymap_by_name ("emacs");
r = rl_set_keymap_name ("newemacs", emacsmap);
if (r >= 0)
{
fprintf (stderr, "rlkeymaps: error: able to set new name for emacs keymap\n");
errs++;
}
r = rl_set_keymap_name ("newemacs", nmap);
if (r < 0)
{
fprintf (stderr, "rlkeymaps: error: newemacs: could not set keymap name\n");
errs++;
}
newemacs = rl_copy_keymap (emacsmap);
r = rl_set_keymap_name ("newemacs", newemacs);
if (r < 0)
{
fprintf (stderr, "rlkeymaps: error: newemacs: could not set `newemacs' keymap to new map\n");
errs++;
}
r = rl_set_keymap_name ("emacscopy", newemacs);
if (r < 0)
{
fprintf (stderr, "rlkeymaps: error: emacscopy: could not rename created keymap\n");
errs++;
}
exit (errs);
}

354
examples/rlptytest.c Normal file
View file

@ -0,0 +1,354 @@
/*
*
* Another test harness for the readline callback interface.
*
* Author: Bob Rossi <bob@brasko.net>
*/
#if defined (HAVE_CONFIG_H)
#include <config.h>
#endif
#include <stdio.h>
#include <sys/types.h>
#include <errno.h>
#include <curses.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#if 1 /* LINUX */
#include <pty.h>
#else
#include <util.h>
#endif
#ifdef HAVE_LOCALE_H
# include <locale.h>
#endif
#ifdef READLINE_LIBRARY
# include "readline.h"
#else
# include <readline/readline.h>
#endif
/**
* Master/Slave PTY used to keep readline off of stdin/stdout.
*/
static int masterfd = -1;
static int slavefd;
void
sigint (s)
int s;
{
tty_reset (STDIN_FILENO);
close (masterfd);
close (slavefd);
printf ("\n");
exit (0);
}
void
sigwinch (s)
int s;
{
rl_resize_terminal ();
}
static int
user_input()
{
int size;
const int MAX = 1024;
char *buf = (char *)malloc(MAX+1);
size = read (STDIN_FILENO, buf, MAX);
if (size == -1)
return -1;
size = write (masterfd, buf, size);
if (size == -1)
return -1;
return 0;
}
static int
readline_input()
{
const int MAX = 1024;
char *buf = (char *)malloc(MAX+1);
int size;
size = read (masterfd, buf, MAX);
if (size == -1)
{
free( buf );
buf = NULL;
return -1;
}
buf[size] = 0;
/* Display output from readline */
if ( size > 0 )
fprintf(stderr, "%s", buf);
free( buf );
buf = NULL;
return 0;
}
static void
rlctx_send_user_command(char *line)
{
/* This happens when rl_callback_read_char gets EOF */
if ( line == NULL )
return;
if (strcmp (line, "exit") == 0) {
tty_reset (STDIN_FILENO);
close (masterfd);
close (slavefd);
printf ("\n");
exit (0);
}
/* Don't add the enter command */
if ( line && *line != '\0' )
add_history(line);
}
static void
custom_deprep_term_function ()
{
}
static int
init_readline (int inputfd, int outputfd)
{
FILE *inputFILE, *outputFILE;
inputFILE = fdopen (inputfd, "r");
if (!inputFILE)
return -1;
outputFILE = fdopen (outputfd, "w");
if (!outputFILE)
return -1;
rl_instream = inputFILE;
rl_outstream = outputFILE;
/* Tell readline what the prompt is if it needs to put it back */
rl_callback_handler_install("(rltest): ", rlctx_send_user_command);
/* Set the terminal type to dumb so the output of readline can be
* understood by tgdb */
if ( rl_reset_terminal("dumb") == -1 )
return -1;
/* For some reason, readline can not deprep the terminal.
* However, it doesn't matter because no other application is working on
* the terminal besides readline */
rl_deprep_term_function = custom_deprep_term_function;
using_history();
read_history(".history");
return 0;
}
static int
main_loop(void)
{
fd_set rset;
int max;
max = (masterfd > STDIN_FILENO) ? masterfd : STDIN_FILENO;
max = (max > slavefd) ? max : slavefd;
for (;;)
{
/* Reset the fd_set, and watch for input from GDB or stdin */
FD_ZERO(&rset);
FD_SET(STDIN_FILENO, &rset);
FD_SET(slavefd, &rset);
FD_SET(masterfd, &rset);
/* Wait for input */
if (select(max + 1, &rset, NULL, NULL, NULL) == -1)
{
if (errno == EINTR)
continue;
else
return -1;
}
/* Input received through the pty: Handle it
* Wrote to masterfd, slave fd has that input, alert readline to read it.
*/
if (FD_ISSET(slavefd, &rset))
rl_callback_read_char();
/* Input received through the pty.
* Readline read from slavefd, and it wrote to the masterfd.
*/
if (FD_ISSET(masterfd, &rset))
if ( readline_input() == -1 )
return -1;
/* Input received: Handle it, write to masterfd (input to readline) */
if (FD_ISSET(STDIN_FILENO, &rset))
if ( user_input() == -1 )
return -1;
}
return 0;
}
/* The terminal attributes before calling tty_cbreak */
static struct termios save_termios;
static struct winsize size;
static enum { RESET, TCBREAK } ttystate = RESET;
/* tty_cbreak: Sets terminal to cbreak mode. Also known as noncanonical mode.
* 1. Signal handling is still turned on, so the user can still type those.
* 2. echo is off
* 3. Read in one char at a time.
*
* fd - The file descriptor of the terminal
*
* Returns: 0 on success, -1 on error
*/
int tty_cbreak(int fd){
struct termios buf;
int ttysavefd = -1;
if(tcgetattr(fd, &save_termios) < 0)
return -1;
buf = save_termios;
buf.c_lflag &= ~(ECHO | ICANON);
buf.c_iflag &= ~(ICRNL | INLCR);
buf.c_cc[VMIN] = 1;
buf.c_cc[VTIME] = 0;
#if defined (VLNEXT) && defined (_POSIX_VDISABLE)
buf.c_cc[VLNEXT] = _POSIX_VDISABLE;
#endif
#if defined (VDSUSP) && defined (_POSIX_VDISABLE)
buf.c_cc[VDSUSP] = _POSIX_VDISABLE;
#endif
/* enable flow control; only stty start char can restart output */
#if 0
buf.c_iflag |= (IXON|IXOFF);
#ifdef IXANY
buf.c_iflag &= ~IXANY;
#endif
#endif
/* disable flow control; let ^S and ^Q through to pty */
buf.c_iflag &= ~(IXON|IXOFF);
#ifdef IXANY
buf.c_iflag &= ~IXANY;
#endif
if(tcsetattr(fd, TCSAFLUSH, &buf) < 0)
return -1;
ttystate = TCBREAK;
ttysavefd = fd;
/* set size */
if(ioctl(fd, TIOCGWINSZ, (char *)&size) < 0)
return -1;
#ifdef DEBUG
err_msg("%d rows and %d cols\n", size.ws_row, size.ws_col);
#endif
return (0);
}
int
tty_off_xon_xoff (int fd)
{
struct termios buf;
int ttysavefd = -1;
if(tcgetattr(fd, &buf) < 0)
return -1;
buf.c_iflag &= ~(IXON|IXOFF);
if(tcsetattr(fd, TCSAFLUSH, &buf) < 0)
return -1;
return 0;
}
/* tty_reset: Sets the terminal attributes back to their previous state.
* PRE: tty_cbreak must have already been called.
*
* fd - The file descrioptor of the terminal to reset.
*
* Returns: 0 on success, -1 on error
*/
int tty_reset(int fd)
{
if(ttystate != TCBREAK)
return (0);
if(tcsetattr(fd, TCSAFLUSH, &save_termios) < 0)
return (-1);
ttystate = RESET;
return 0;
}
int
main()
{
int val;
#ifdef HAVE_SETLOCALE
setlocale (LC_ALL, "");
#endif
val = openpty (&masterfd, &slavefd, NULL, NULL, NULL);
if (val == -1)
return -1;
val = tty_off_xon_xoff (masterfd);
if (val == -1)
return -1;
signal (SIGWINCH, sigwinch);
signal (SIGINT, sigint);
val = init_readline (slavefd, slavefd);
if (val == -1)
return -1;
val = tty_cbreak (STDIN_FILENO);
if (val == -1)
return -1;
val = main_loop ();
tty_reset (STDIN_FILENO);
if (val == -1)
return -1;
return 0;
}

101
examples/rltest.c Normal file
View file

@ -0,0 +1,101 @@
/* **************************************************************** */
/* */
/* Testing Readline */
/* */
/* **************************************************************** */
/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library for
reading lines of text with interactive input and history editing.
Readline 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 3 of the License, or
(at your option) any later version.
Readline 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 Readline. If not, see <http://www.gnu.org/licenses/>.
*/
#if defined (HAVE_CONFIG_H)
#include <config.h>
#endif
#include <stdio.h>
#include <sys/types.h>
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#else
extern void exit();
#endif
#ifdef HAVE_LOCALE_H
# include <locale.h>
#endif
#ifdef READLINE_LIBRARY
# include "readline.h"
# include "history.h"
#else
# include <readline/readline.h>
# include <readline/history.h>
#endif
extern HIST_ENTRY **history_list ();
int
main ()
{
char *temp, *prompt;
int done;
#ifdef HAVE_SETLOCALE
setlocale (LC_ALL, "");
#endif
temp = (char *)NULL;
prompt = "readline$ ";
done = 0;
while (!done)
{
temp = readline (prompt);
/* Test for EOF. */
if (!temp)
exit (1);
/* If there is anything on the line, print it and remember it. */
if (*temp)
{
fprintf (stderr, "%s\r\n", temp);
add_history (temp);
}
/* Check for `command' that we handle. */
if (strcmp (temp, "quit") == 0)
done = 1;
if (strcmp (temp, "list") == 0)
{
HIST_ENTRY **list;
register int i;
list = history_list ();
if (list)
{
for (i = 0; list[i]; i++)
fprintf (stderr, "%d: %s\r\n", i, list[i]->line);
}
}
free (temp);
}
exit (0);
}

49
examples/rlversion.c Normal file
View file

@ -0,0 +1,49 @@
/*
* rlversion -- print out readline's version number
*/
/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library for
reading lines of text with interactive input and history editing.
Readline 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 3 of the License, or
(at your option) any later version.
Readline 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 Readline. If not, see <http://www.gnu.org/licenses/>.
*/
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <stdio.h>
#include <sys/types.h>
#include "posixstat.h"
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#else
extern void exit();
#endif
#ifdef READLINE_LIBRARY
# include "readline.h"
#else
# include <readline/readline.h>
#endif
int
main()
{
printf ("%s\n", rl_library_version ? rl_library_version : "unknown");
exit (0);
}

BIN
examples/rlwrap-0.30.tar.gz Normal file

Binary file not shown.

273
funmap.c Normal file
View file

@ -0,0 +1,273 @@
/* funmap.c -- attach names to functions. */
/* Copyright (C) 1987-2021 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
Readline 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 3 of the License, or
(at your option) any later version.
Readline 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 Readline. If not, see <http://www.gnu.org/licenses/>.
*/
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#if !defined (BUFSIZ)
#include <stdio.h>
#endif /* BUFSIZ */
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#include "rlconf.h"
#include "readline.h"
#include "xmalloc.h"
#ifdef __STDC__
typedef int QSFUNC (const void *, const void *);
#else
typedef int QSFUNC ();
#endif
extern int _rl_qsort_string_compare (char **, char **);
FUNMAP **funmap;
static int funmap_size;
static int funmap_entry;
/* After initializing the function map, this is the index of the first
program specific function. */
int funmap_program_specific_entry_start;
static const FUNMAP default_funmap[] = {
{ "abort", rl_abort },
{ "accept-line", rl_newline },
{ "arrow-key-prefix", rl_arrow_keys },
{ "backward-byte", rl_backward_byte },
{ "backward-char", rl_backward_char },
{ "backward-delete-char", rl_rubout },
{ "backward-kill-line", rl_backward_kill_line },
{ "backward-kill-word", rl_backward_kill_word },
{ "backward-word", rl_backward_word },
{ "beginning-of-history", rl_beginning_of_history },
{ "beginning-of-line", rl_beg_of_line },
{ "bracketed-paste-begin", rl_bracketed_paste_begin },
{ "call-last-kbd-macro", rl_call_last_kbd_macro },
{ "capitalize-word", rl_capitalize_word },
{ "character-search", rl_char_search },
{ "character-search-backward", rl_backward_char_search },
{ "clear-display", rl_clear_display },
{ "clear-screen", rl_clear_screen },
{ "complete", rl_complete },
{ "copy-backward-word", rl_copy_backward_word },
{ "copy-forward-word", rl_copy_forward_word },
{ "copy-region-as-kill", rl_copy_region_to_kill },
{ "delete-char", rl_delete },
{ "delete-char-or-list", rl_delete_or_show_completions },
{ "delete-horizontal-space", rl_delete_horizontal_space },
{ "digit-argument", rl_digit_argument },
{ "do-lowercase-version", rl_do_lowercase_version },
{ "downcase-word", rl_downcase_word },
{ "dump-functions", rl_dump_functions },
{ "dump-macros", rl_dump_macros },
{ "dump-variables", rl_dump_variables },
{ "emacs-editing-mode", rl_emacs_editing_mode },
{ "end-kbd-macro", rl_end_kbd_macro },
{ "end-of-history", rl_end_of_history },
{ "end-of-line", rl_end_of_line },
{ "exchange-point-and-mark", rl_exchange_point_and_mark },
{ "fetch-history", rl_fetch_history },
{ "forward-backward-delete-char", rl_rubout_or_delete },
{ "forward-byte", rl_forward_byte },
{ "forward-char", rl_forward_char },
{ "forward-search-history", rl_forward_search_history },
{ "forward-word", rl_forward_word },
{ "history-search-backward", rl_history_search_backward },
{ "history-search-forward", rl_history_search_forward },
{ "history-substring-search-backward", rl_history_substr_search_backward },
{ "history-substring-search-forward", rl_history_substr_search_forward },
{ "insert-comment", rl_insert_comment },
{ "insert-completions", rl_insert_completions },
{ "kill-whole-line", rl_kill_full_line },
{ "kill-line", rl_kill_line },
{ "kill-region", rl_kill_region },
{ "kill-word", rl_kill_word },
{ "menu-complete", rl_menu_complete },
{ "menu-complete-backward", rl_backward_menu_complete },
{ "next-history", rl_get_next_history },
{ "next-screen-line", rl_next_screen_line },
{ "non-incremental-forward-search-history", rl_noninc_forward_search },
{ "non-incremental-reverse-search-history", rl_noninc_reverse_search },
{ "non-incremental-forward-search-history-again", rl_noninc_forward_search_again },
{ "non-incremental-reverse-search-history-again", rl_noninc_reverse_search_again },
{ "old-menu-complete", rl_old_menu_complete },
{ "operate-and-get-next", rl_operate_and_get_next },
{ "overwrite-mode", rl_overwrite_mode },
#if defined (_WIN32)
{ "paste-from-clipboard", rl_paste_from_clipboard },
#endif
{ "possible-completions", rl_possible_completions },
{ "previous-history", rl_get_previous_history },
{ "previous-screen-line", rl_previous_screen_line },
{ "print-last-kbd-macro", rl_print_last_kbd_macro },
{ "quoted-insert", rl_quoted_insert },
{ "re-read-init-file", rl_re_read_init_file },
{ "redraw-current-line", rl_refresh_line},
{ "reverse-search-history", rl_reverse_search_history },
{ "revert-line", rl_revert_line },
{ "self-insert", rl_insert },
{ "set-mark", rl_set_mark },
{ "skip-csi-sequence", rl_skip_csi_sequence },
{ "start-kbd-macro", rl_start_kbd_macro },
{ "tab-insert", rl_tab_insert },
{ "tilde-expand", rl_tilde_expand },
{ "transpose-chars", rl_transpose_chars },
{ "transpose-words", rl_transpose_words },
{ "tty-status", rl_tty_status },
{ "undo", rl_undo_command },
{ "universal-argument", rl_universal_argument },
{ "unix-filename-rubout", rl_unix_filename_rubout },
{ "unix-line-discard", rl_unix_line_discard },
{ "unix-word-rubout", rl_unix_word_rubout },
{ "upcase-word", rl_upcase_word },
{ "yank", rl_yank },
{ "yank-last-arg", rl_yank_last_arg },
{ "yank-nth-arg", rl_yank_nth_arg },
{ "yank-pop", rl_yank_pop },
#if defined (VI_MODE)
{ "vi-append-eol", rl_vi_append_eol },
{ "vi-append-mode", rl_vi_append_mode },
{ "vi-arg-digit", rl_vi_arg_digit },
{ "vi-back-to-indent", rl_vi_back_to_indent },
{ "vi-backward-bigword", rl_vi_bWord },
{ "vi-backward-word", rl_vi_bword },
{ "vi-bWord", rl_vi_bWord },
{ "vi-bword", rl_vi_bword }, /* BEWARE: name matching is case insensitive */
{ "vi-change-case", rl_vi_change_case },
{ "vi-change-char", rl_vi_change_char },
{ "vi-change-to", rl_vi_change_to },
{ "vi-char-search", rl_vi_char_search },
{ "vi-column", rl_vi_column },
{ "vi-complete", rl_vi_complete },
{ "vi-delete", rl_vi_delete },
{ "vi-delete-to", rl_vi_delete_to },
{ "vi-eWord", rl_vi_eWord },
{ "vi-editing-mode", rl_vi_editing_mode },
{ "vi-end-bigword", rl_vi_eWord },
{ "vi-end-word", rl_vi_end_word },
{ "vi-eof-maybe", rl_vi_eof_maybe },
{ "vi-eword", rl_vi_eword }, /* BEWARE: name matching is case insensitive */
{ "vi-fWord", rl_vi_fWord },
{ "vi-fetch-history", rl_vi_fetch_history },
{ "vi-first-print", rl_vi_first_print },
{ "vi-forward-bigword", rl_vi_fWord },
{ "vi-forward-word", rl_vi_fword },
{ "vi-fword", rl_vi_fword }, /* BEWARE: name matching is case insensitive */
{ "vi-goto-mark", rl_vi_goto_mark },
{ "vi-insert-beg", rl_vi_insert_beg },
{ "vi-insertion-mode", rl_vi_insert_mode },
{ "vi-match", rl_vi_match },
{ "vi-movement-mode", rl_vi_movement_mode },
{ "vi-next-word", rl_vi_next_word },
{ "vi-overstrike", rl_vi_overstrike },
{ "vi-overstrike-delete", rl_vi_overstrike_delete },
{ "vi-prev-word", rl_vi_prev_word },
{ "vi-put", rl_vi_put },
{ "vi-redo", rl_vi_redo },
{ "vi-replace", rl_vi_replace },
{ "vi-rubout", rl_vi_rubout },
{ "vi-search", rl_vi_search },
{ "vi-search-again", rl_vi_search_again },
{ "vi-set-mark", rl_vi_set_mark },
{ "vi-subst", rl_vi_subst },
{ "vi-tilde-expand", rl_vi_tilde_expand },
{ "vi-undo", rl_vi_undo },
{ "vi-unix-word-rubout", rl_vi_unix_word_rubout },
{ "vi-yank-arg", rl_vi_yank_arg },
{ "vi-yank-pop", rl_vi_yank_pop },
{ "vi-yank-to", rl_vi_yank_to },
#endif /* VI_MODE */
{(char *)NULL, (rl_command_func_t *)NULL }
};
int
rl_add_funmap_entry (const char *name, rl_command_func_t *function)
{
if (funmap_entry + 2 >= funmap_size)
{
funmap_size += 64;
funmap = (FUNMAP **)xrealloc (funmap, funmap_size * sizeof (FUNMAP *));
}
funmap[funmap_entry] = (FUNMAP *)xmalloc (sizeof (FUNMAP));
funmap[funmap_entry]->name = name;
funmap[funmap_entry]->function = function;
funmap[++funmap_entry] = (FUNMAP *)NULL;
return funmap_entry;
}
static int funmap_initialized;
/* Make the funmap contain all of the default entries. */
void
rl_initialize_funmap (void)
{
register int i;
if (funmap_initialized)
return;
for (i = 0; default_funmap[i].name; i++)
rl_add_funmap_entry (default_funmap[i].name, default_funmap[i].function);
funmap_initialized = 1;
funmap_program_specific_entry_start = i;
}
/* Produce a NULL terminated array of known function names. The array
is sorted. The array itself is allocated, but not the strings inside.
You should free () the array when you done, but not the pointers. */
const char **
rl_funmap_names (void)
{
const char **result;
int result_size, result_index;
/* Make sure that the function map has been initialized. */
rl_initialize_funmap ();
for (result_index = result_size = 0, result = (const char **)NULL; funmap[result_index]; result_index++)
{
if (result_index + 2 > result_size)
{
result_size += 20;
result = (const char **)xrealloc (result, result_size * sizeof (char *));
}
result[result_index] = funmap[result_index]->name;
result[result_index + 1] = (char *)NULL;
}
qsort (result, result_index, sizeof (char *), (QSFUNC *)_rl_qsort_string_compare);
return (result);
}

1718
histexpand.c Normal file

File diff suppressed because it is too large Load diff

833
histfile.c Normal file
View file

@ -0,0 +1,833 @@
/* histfile.c - functions to manipulate the history file. */
/* Copyright (C) 1989-2019 Free Software Foundation, Inc.
This file contains the GNU History Library (History), a set of
routines for managing the text of previously typed lines.
History 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 3 of the License, or
(at your option) any later version.
History 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 History. If not, see <http://www.gnu.org/licenses/>.
*/
/* The goal is to make the implementation transparent, so that you
don't have to know what data types are used, just what functions
you can call. I think I have done that. */
#define READLINE_LIBRARY
#if defined (__TANDEM)
# define _XOPEN_SOURCE_EXTENDED 1
# include <unistd.h>
# include <floss.h>
#endif
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <stdio.h>
#if defined (HAVE_LIMITS_H)
# include <limits.h>
#endif
#include <sys/types.h>
#if ! defined (_MINIX) && defined (HAVE_SYS_FILE_H)
# include <sys/file.h>
#endif
#include "posixstat.h"
#include <fcntl.h>
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include <ctype.h>
#if defined (__EMX__)
# undef HAVE_MMAP
#endif
#ifdef HISTORY_USE_MMAP
# include <sys/mman.h>
# ifdef MAP_FILE
# define MAP_RFLAGS (MAP_FILE|MAP_PRIVATE)
# define MAP_WFLAGS (MAP_FILE|MAP_SHARED)
# else
# define MAP_RFLAGS MAP_PRIVATE
# define MAP_WFLAGS MAP_SHARED
# endif
# ifndef MAP_FAILED
# define MAP_FAILED ((void *)-1)
# endif
#endif /* HISTORY_USE_MMAP */
#if defined(_WIN32)
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
#endif
/* If we're compiling for __EMX__ (OS/2) or __CYGWIN__ (cygwin32 environment
on win 95/98/nt), we want to open files with O_BINARY mode so that there
is no \n -> \r\n conversion performed. On other systems, we don't want to
mess around with O_BINARY at all, so we ensure that it's defined to 0. */
#if defined (__EMX__) || defined (__CYGWIN__)
# ifndef O_BINARY
# define O_BINARY 0
# endif
#else /* !__EMX__ && !__CYGWIN__ */
# undef O_BINARY
# define O_BINARY 0
#endif /* !__EMX__ && !__CYGWIN__ */
#include <errno.h>
#if !defined (errno)
extern int errno;
#endif /* !errno */
#include "history.h"
#include "histlib.h"
#include "rlshell.h"
#include "xmalloc.h"
#if !defined (PATH_MAX)
# define PATH_MAX 1024 /* default */
#endif
/* history file version; currently unused */
int history_file_version = 1;
/* If non-zero, we write timestamps to the history file in history_do_write() */
int history_write_timestamps = 0;
/* If non-zero, we assume that a history file that starts with a timestamp
uses timestamp-delimited entries and can include multi-line history
entries. Used by read_history_range */
int history_multiline_entries = 0;
/* Immediately after a call to read_history() or read_history_range(), this
will return the number of lines just read from the history file in that
call. */
int history_lines_read_from_file = 0;
/* Immediately after a call to write_history() or history_do_write(), this
will return the number of lines just written to the history file in that
call. This also works with history_truncate_file. */
int history_lines_written_to_file = 0;
/* Does S look like the beginning of a history timestamp entry? Placeholder
for more extensive tests. */
#define HIST_TIMESTAMP_START(s) (*(s) == history_comment_char && isdigit ((unsigned char)(s)[1]) )
static char *history_backupfile (const char *);
static char *history_tempfile (const char *);
static int histfile_backup (const char *, const char *);
static int histfile_restore (const char *, const char *);
static int history_rename (const char *, const char *);
/* Return the string that should be used in the place of this
filename. This only matters when you don't specify the
filename to read_history (), or write_history (). */
static char *
history_filename (const char *filename)
{
char *return_val;
const char *home;
int home_len;
return_val = filename ? savestring (filename) : (char *)NULL;
if (return_val)
return (return_val);
home = sh_get_env_value ("HOME");
#if defined (_WIN32)
if (home == 0)
home = sh_get_env_value ("APPDATA");
#endif
if (home == 0)
return (NULL);
else
home_len = strlen (home);
return_val = (char *)xmalloc (2 + home_len + 8); /* strlen(".history") == 8 */
strcpy (return_val, home);
return_val[home_len] = '/';
#if defined (__MSDOS__)
strcpy (return_val + home_len + 1, "_history");
#else
strcpy (return_val + home_len + 1, ".history");
#endif
return (return_val);
}
static char *
history_backupfile (const char *filename)
{
const char *fn;
char *ret, linkbuf[PATH_MAX+1];
size_t len;
ssize_t n;
struct stat fs;
fn = filename;
#if defined (HAVE_READLINK)
/* Follow symlink to avoid backing up symlink itself; call will fail if
not a symlink */
if ((n = readlink (filename, linkbuf, sizeof (linkbuf) - 1)) > 0)
{
linkbuf[n] = '\0';
fn = linkbuf;
}
#endif
len = strlen (fn);
ret = xmalloc (len + 2);
strcpy (ret, fn);
ret[len] = '-';
ret[len+1] = '\0';
return ret;
}
static char *
history_tempfile (const char *filename)
{
const char *fn;
char *ret, linkbuf[PATH_MAX+1];
size_t len;
ssize_t n;
struct stat fs;
int pid;
fn = filename;
#if defined (HAVE_READLINK)
/* Follow symlink so tempfile created in the same directory as any symlinked
history file; call will fail if not a symlink */
if ((n = readlink (filename, linkbuf, sizeof (linkbuf) - 1)) > 0)
{
linkbuf[n] = '\0';
fn = linkbuf;
}
#endif
len = strlen (fn);
ret = xmalloc (len + 11);
strcpy (ret, fn);
pid = (int)getpid ();
/* filename-PID.tmp */
ret[len] = '-';
ret[len+1] = (pid / 10000 % 10) + '0';
ret[len+2] = (pid / 1000 % 10) + '0';
ret[len+3] = (pid / 100 % 10) + '0';
ret[len+4] = (pid / 10 % 10) + '0';
ret[len+5] = (pid % 10) + '0';
strcpy (ret + len + 6, ".tmp");
return ret;
}
/* Add the contents of FILENAME to the history list, a line at a time.
If FILENAME is NULL, then read from ~/.history. Returns 0 if
successful, or errno if not. */
int
read_history (const char *filename)
{
return (read_history_range (filename, 0, -1));
}
/* Read a range of lines from FILENAME, adding them to the history list.
Start reading at the FROM'th line and end at the TO'th. If FROM
is zero, start at the beginning. If TO is less than FROM, read
until the end of the file. If FILENAME is NULL, then read from
~/.history. Returns 0 if successful, or errno if not. */
int
read_history_range (const char *filename, int from, int to)
{
register char *line_start, *line_end, *p;
char *input, *buffer, *bufend, *last_ts;
int file, current_line, chars_read, has_timestamps, reset_comment_char;
struct stat finfo;
size_t file_size;
#if defined (EFBIG)
int overflow_errno = EFBIG;
#elif defined (EOVERFLOW)
int overflow_errno = EOVERFLOW;
#else
int overflow_errno = EIO;
#endif
history_lines_read_from_file = 0;
buffer = last_ts = (char *)NULL;
input = history_filename (filename);
file = input ? open (input, O_RDONLY|O_BINARY, 0666) : -1;
if ((file < 0) || (fstat (file, &finfo) == -1))
goto error_and_exit;
if (S_ISREG (finfo.st_mode) == 0)
{
#ifdef EFTYPE
errno = EFTYPE;
#else
errno = EINVAL;
#endif
goto error_and_exit;
}
file_size = (size_t)finfo.st_size;
/* check for overflow on very large files */
if (file_size != finfo.st_size || file_size + 1 < file_size)
{
errno = overflow_errno;
goto error_and_exit;
}
if (file_size == 0)
{
xfree (input);
close (file);
return 0; /* don't waste time if we don't have to */
}
#ifdef HISTORY_USE_MMAP
/* We map read/write and private so we can change newlines to NULs without
affecting the underlying object. */
buffer = (char *)mmap (0, file_size, PROT_READ|PROT_WRITE, MAP_RFLAGS, file, 0);
if ((void *)buffer == MAP_FAILED)
{
errno = overflow_errno;
goto error_and_exit;
}
chars_read = file_size;
#else
buffer = (char *)malloc (file_size + 1);
if (buffer == 0)
{
errno = overflow_errno;
goto error_and_exit;
}
chars_read = read (file, buffer, file_size);
#endif
if (chars_read < 0)
{
error_and_exit:
if (errno != 0)
chars_read = errno;
else
chars_read = EIO;
if (file >= 0)
close (file);
FREE (input);
#ifndef HISTORY_USE_MMAP
FREE (buffer);
#endif
return (chars_read);
}
close (file);
/* Set TO to larger than end of file if negative. */
if (to < 0)
to = chars_read;
/* Start at beginning of file, work to end. */
bufend = buffer + chars_read;
*bufend = '\0'; /* null-terminate buffer for timestamp checks */
current_line = 0;
/* Heuristic: the history comment character rarely changes, so assume we
have timestamps if the buffer starts with `#[:digit:]' and temporarily
set history_comment_char so timestamp parsing works right */
reset_comment_char = 0;
if (history_comment_char == '\0' && buffer[0] == '#' && isdigit ((unsigned char)buffer[1]))
{
history_comment_char = '#';
reset_comment_char = 1;
}
has_timestamps = HIST_TIMESTAMP_START (buffer);
history_multiline_entries += has_timestamps && history_write_timestamps;
/* Skip lines until we are at FROM. */
if (has_timestamps)
last_ts = buffer;
for (line_start = line_end = buffer; line_end < bufend && current_line < from; line_end++)
if (*line_end == '\n')
{
p = line_end + 1;
/* If we see something we think is a timestamp, continue with this
line. We should check more extensively here... */
if (HIST_TIMESTAMP_START(p) == 0)
current_line++;
else
last_ts = p;
line_start = p;
/* If we are at the last line (current_line == from) but we have
timestamps (has_timestamps), then line_start points to the
text of the last command, and we need to skip to its end. */
if (current_line >= from && has_timestamps)
{
for (line_end = p; line_end < bufend && *line_end != '\n'; line_end++)
;
line_start = (*line_end == '\n') ? line_end + 1 : line_end;
}
}
/* If there are lines left to gobble, then gobble them now. */
for (line_end = line_start; line_end < bufend; line_end++)
if (*line_end == '\n')
{
/* Change to allow Windows-like \r\n end of line delimiter. */
if (line_end > line_start && line_end[-1] == '\r')
line_end[-1] = '\0';
else
*line_end = '\0';
if (*line_start)
{
if (HIST_TIMESTAMP_START(line_start) == 0)
{
if (last_ts == NULL && history_length > 0 && history_multiline_entries)
_hs_append_history_line (history_length - 1, line_start);
else
add_history (line_start);
if (last_ts)
{
add_history_time (last_ts);
last_ts = NULL;
}
}
else
{
last_ts = line_start;
current_line--;
}
}
current_line++;
if (current_line >= to)
break;
line_start = line_end + 1;
}
history_lines_read_from_file = current_line;
if (reset_comment_char)
history_comment_char = '\0';
FREE (input);
#ifndef HISTORY_USE_MMAP
FREE (buffer);
#else
munmap (buffer, file_size);
#endif
return (0);
}
/* We need a special version for WIN32 because Windows rename() refuses to
overwrite an existing file. */
static int
history_rename (const char *old, const char *new)
{
#if defined (_WIN32)
return (MoveFileEx (old, new, MOVEFILE_REPLACE_EXISTING) == 0 ? -1 : 0);
#else
return (rename (old, new));
#endif
}
/* Save FILENAME to BACK, handling case where FILENAME is a symlink
(e.g., ~/.bash_history -> .histfiles/.bash_history.$HOSTNAME) */
static int
histfile_backup (const char *filename, const char *back)
{
#if defined (HAVE_READLINK)
char linkbuf[PATH_MAX+1];
ssize_t n;
/* Follow to target of symlink to avoid renaming symlink itself */
if ((n = readlink (filename, linkbuf, sizeof (linkbuf) - 1)) > 0)
{
linkbuf[n] = '\0';
return (history_rename (linkbuf, back));
}
#endif
return (history_rename (filename, back));
}
/* Restore ORIG from BACKUP handling case where ORIG is a symlink
(e.g., ~/.bash_history -> .histfiles/.bash_history.$HOSTNAME) */
static int
histfile_restore (const char *backup, const char *orig)
{
#if defined (HAVE_READLINK)
char linkbuf[PATH_MAX+1];
ssize_t n;
/* Follow to target of symlink to avoid renaming symlink itself */
if ((n = readlink (orig, linkbuf, sizeof (linkbuf) - 1)) > 0)
{
linkbuf[n] = '\0';
return (history_rename (backup, linkbuf));
}
#endif
return (history_rename (backup, orig));
}
/* Should we call chown, based on whether finfo and nfinfo describe different
files with different owners? */
#define SHOULD_CHOWN(finfo, nfinfo) \
(finfo.st_uid != nfinfo.st_uid || finfo.st_gid != nfinfo.st_gid)
/* Truncate the history file FNAME, leaving only LINES trailing lines.
If FNAME is NULL, then use ~/.history. Writes a new file and renames
it to the original name. Returns 0 on success, errno on failure. */
int
history_truncate_file (const char *fname, int lines)
{
char *buffer, *filename, *tempname, *bp, *bp1; /* bp1 == bp+1 */
int file, chars_read, rv, orig_lines, exists, r;
struct stat finfo, nfinfo;
size_t file_size;
history_lines_written_to_file = 0;
buffer = (char *)NULL;
filename = history_filename (fname);
tempname = 0;
file = filename ? open (filename, O_RDONLY|O_BINARY, 0666) : -1;
rv = exists = 0;
/* Don't try to truncate non-regular files. */
if (file == -1 || fstat (file, &finfo) == -1)
{
rv = errno;
if (file != -1)
close (file);
goto truncate_exit;
}
exists = 1;
nfinfo.st_uid = finfo.st_uid;
nfinfo.st_gid = finfo.st_gid;
if (S_ISREG (finfo.st_mode) == 0)
{
close (file);
#ifdef EFTYPE
rv = EFTYPE;
#else
rv = EINVAL;
#endif
goto truncate_exit;
}
file_size = (size_t)finfo.st_size;
/* check for overflow on very large files */
if (file_size != finfo.st_size || file_size + 1 < file_size)
{
close (file);
#if defined (EFBIG)
rv = errno = EFBIG;
#elif defined (EOVERFLOW)
rv = errno = EOVERFLOW;
#else
rv = errno = EINVAL;
#endif
goto truncate_exit;
}
buffer = (char *)malloc (file_size + 1);
if (buffer == 0)
{
rv = errno;
close (file);
goto truncate_exit;
}
chars_read = read (file, buffer, file_size);
close (file);
if (chars_read <= 0)
{
rv = (chars_read < 0) ? errno : 0;
goto truncate_exit;
}
orig_lines = lines;
/* Count backwards from the end of buffer until we have passed
LINES lines. bp1 is set funny initially. But since bp[1] can't
be a comment character (since it's off the end) and *bp can't be
both a newline and the history comment character, it should be OK. */
for (bp1 = bp = buffer + chars_read - 1; lines && bp > buffer; bp--)
{
if (*bp == '\n' && HIST_TIMESTAMP_START(bp1) == 0)
lines--;
bp1 = bp;
}
/* If this is the first line, then the file contains exactly the
number of lines we want to truncate to, so we don't need to do
anything. It's the first line if we don't find a newline between
the current value of i and 0. Otherwise, write from the start of
this line until the end of the buffer. */
for ( ; bp > buffer; bp--)
{
if (*bp == '\n' && HIST_TIMESTAMP_START(bp1) == 0)
{
bp++;
break;
}
bp1 = bp;
}
/* Write only if there are more lines in the file than we want to
truncate to. */
if (bp <= buffer)
{
rv = 0;
/* No-op if LINES == 0 at this point */
history_lines_written_to_file = orig_lines - lines;
goto truncate_exit;
}
tempname = history_tempfile (filename);
if ((file = open (tempname, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0600)) != -1)
{
if (write (file, bp, chars_read - (bp - buffer)) < 0)
rv = errno;
if (fstat (file, &nfinfo) < 0 && rv == 0)
rv = errno;
if (close (file) < 0 && rv == 0)
rv = errno;
}
else
rv = errno;
truncate_exit:
FREE (buffer);
history_lines_written_to_file = orig_lines - lines;
if (rv == 0 && filename && tempname)
rv = histfile_restore (tempname, filename);
if (rv != 0)
{
rv = errno;
if (tempname)
unlink (tempname);
history_lines_written_to_file = 0;
}
#if defined (HAVE_CHOWN)
/* Make sure the new filename is owned by the same user as the old. If one
user is running this, it's a no-op. If the shell is running after sudo
with a shared history file, we don't want to leave the history file
owned by root. */
if (rv == 0 && exists && SHOULD_CHOWN (finfo, nfinfo))
r = chown (filename, finfo.st_uid, finfo.st_gid);
#endif
xfree (filename);
FREE (tempname);
return rv;
}
/* Workhorse function for writing history. Writes the last NELEMENT entries
from the history list to FILENAME. OVERWRITE is non-zero if you
wish to replace FILENAME with the entries. */
static int
history_do_write (const char *filename, int nelements, int overwrite)
{
register int i;
char *output, *tempname, *histname;
int file, mode, rv, exists;
struct stat finfo, nfinfo;
#ifdef HISTORY_USE_MMAP
size_t cursize;
history_lines_written_to_file = 0;
mode = overwrite ? O_RDWR|O_CREAT|O_TRUNC|O_BINARY : O_RDWR|O_APPEND|O_BINARY;
#else
mode = overwrite ? O_WRONLY|O_CREAT|O_TRUNC|O_BINARY : O_WRONLY|O_APPEND|O_BINARY;
#endif
histname = history_filename (filename);
exists = histname ? (stat (histname, &finfo) == 0) : 0;
tempname = (overwrite && exists && S_ISREG (finfo.st_mode)) ? history_tempfile (histname) : 0;
output = tempname ? tempname : histname;
file = output ? open (output, mode, 0600) : -1;
rv = 0;
if (file == -1)
{
rv = errno;
FREE (histname);
FREE (tempname);
return (rv);
}
#ifdef HISTORY_USE_MMAP
cursize = overwrite ? 0 : lseek (file, 0, SEEK_END);
#endif
if (nelements > history_length)
nelements = history_length;
/* Build a buffer of all the lines to write, and write them in one syscall.
Suggested by Peter Ho (peter@robosts.oxford.ac.uk). */
{
HIST_ENTRY **the_history; /* local */
register int j;
int buffer_size;
char *buffer;
the_history = history_list ();
/* Calculate the total number of bytes to write. */
for (buffer_size = 0, i = history_length - nelements; i < history_length; i++)
{
if (history_write_timestamps && the_history[i]->timestamp && the_history[i]->timestamp[0])
buffer_size += strlen (the_history[i]->timestamp) + 1;
buffer_size += strlen (the_history[i]->line) + 1;
}
/* Allocate the buffer, and fill it. */
#ifdef HISTORY_USE_MMAP
if (ftruncate (file, buffer_size+cursize) == -1)
goto mmap_error;
buffer = (char *)mmap (0, buffer_size, PROT_READ|PROT_WRITE, MAP_WFLAGS, file, cursize);
if ((void *)buffer == MAP_FAILED)
{
mmap_error:
rv = errno;
close (file);
if (tempname)
unlink (tempname);
FREE (histname);
FREE (tempname);
return rv;
}
#else
buffer = (char *)malloc (buffer_size);
if (buffer == 0)
{
rv = errno;
close (file);
if (tempname)
unlink (tempname);
FREE (histname);
FREE (tempname);
return rv;
}
#endif
for (j = 0, i = history_length - nelements; i < history_length; i++)
{
if (history_write_timestamps && the_history[i]->timestamp && the_history[i]->timestamp[0])
{
strcpy (buffer + j, the_history[i]->timestamp);
j += strlen (the_history[i]->timestamp);
buffer[j++] = '\n';
}
strcpy (buffer + j, the_history[i]->line);
j += strlen (the_history[i]->line);
buffer[j++] = '\n';
}
#ifdef HISTORY_USE_MMAP
if (msync (buffer, buffer_size, MS_ASYNC) != 0 || munmap (buffer, buffer_size) != 0)
rv = errno;
#else
if (write (file, buffer, buffer_size) < 0)
rv = errno;
xfree (buffer);
#endif
}
history_lines_written_to_file = nelements;
if (close (file) < 0 && rv == 0)
rv = errno;
if (rv == 0 && histname && tempname)
rv = histfile_restore (tempname, histname);
if (rv != 0)
{
rv = errno;
if (tempname)
unlink (tempname);
history_lines_written_to_file = 0;
}
#if defined (HAVE_CHOWN)
/* Make sure the new filename is owned by the same user as the old. If one
user is running this, it's a no-op. If the shell is running after sudo
with a shared history file, we don't want to leave the history file
owned by root. */
if (rv == 0 && exists)
mode = chown (histname, finfo.st_uid, finfo.st_gid);
#endif
FREE (histname);
FREE (tempname);
return (rv);
}
/* Append NELEMENT entries to FILENAME. The entries appended are from
the end of the list minus NELEMENTs up to the end of the list. */
int
append_history (int nelements, const char *filename)
{
return (history_do_write (filename, nelements, HISTORY_APPEND));
}
/* Overwrite FILENAME with the current history. If FILENAME is NULL,
then write the history list to ~/.history. Values returned
are as in read_history ().*/
int
write_history (const char *filename)
{
return (history_do_write (filename, history_length, HISTORY_OVERWRITE));
}

92
histlib.h Normal file
View file

@ -0,0 +1,92 @@
/* histlib.h -- internal definitions for the history library. */
/* Copyright (C) 1989-2009,2021-2022 Free Software Foundation, Inc.
This file contains the GNU History Library (History), a set of
routines for managing the text of previously typed lines.
History 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 3 of the License, or
(at your option) any later version.
History 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 History. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined (_HISTLIB_H_)
#define _HISTLIB_H_
#if defined (HAVE_STRING_H)
# include <string.h>
#else
# include <strings.h>
#endif /* !HAVE_STRING_H */
#if !defined (STREQ)
#define STREQ(a, b) (((a)[0] == (b)[0]) && (strcmp ((a), (b)) == 0))
#define STREQN(a, b, n) (((n) == 0) ? (1) \
: ((a)[0] == (b)[0]) && (strncmp ((a), (b), (n)) == 0))
#endif
#ifndef savestring
#define savestring(x) strcpy (xmalloc (1 + strlen (x)), (x))
#endif
#ifndef whitespace
#define whitespace(c) (((c) == ' ') || ((c) == '\t'))
#endif
#ifndef _rl_digit_p
#define _rl_digit_p(c) ((c) >= '0' && (c) <= '9')
#endif
#ifndef _rl_digit_value
#define _rl_digit_value(c) ((c) - '0')
#endif
#ifndef member
# if !defined (strchr) && !defined (__STDC__)
extern char *strchr ();
# endif /* !strchr && !__STDC__ */
#define member(c, s) ((c) ? ((char *)strchr ((s), (c)) != (char *)NULL) : 0)
#endif
#ifndef FREE
# define FREE(x) if (x) free (x)
#endif
/* Possible history errors passed to hist_error. */
#define EVENT_NOT_FOUND 0
#define BAD_WORD_SPEC 1
#define SUBST_FAILED 2
#define BAD_MODIFIER 3
#define NO_PREV_SUBST 4
/* Possible definitions for history starting point specification. */
#define NON_ANCHORED_SEARCH 0
#define ANCHORED_SEARCH 0x01
#define PATTERN_SEARCH 0x02
/* Possible definitions for what style of writing the history file we want. */
#define HISTORY_APPEND 0
#define HISTORY_OVERWRITE 1
/* internal extern function declarations used by other parts of the library */
/* histsearch.c */
extern int _hs_history_patsearch (const char *, int, int);
/* history.c */
extern void _hs_replace_history_data (int, histdata_t *, histdata_t *);
extern int _hs_at_end_of_history (void);
/* histfile.c */
extern void _hs_append_history_line (int, const char *);
#endif /* !_HISTLIB_H_ */

614
history.c Normal file
View file

@ -0,0 +1,614 @@
/* history.c -- standalone history library */
/* Copyright (C) 1989-2021 Free Software Foundation, Inc.
This file contains the GNU History Library (History), a set of
routines for managing the text of previously typed lines.
History 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 3 of the License, or
(at your option) any later version.
History 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 History. If not, see <http://www.gnu.org/licenses/>.
*/
/* The goal is to make the implementation transparent, so that you
don't have to know what data types are used, just what functions
you can call. I think I have done that. */
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <stdio.h>
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#if defined (HAVE_UNISTD_H)
# ifdef _MINIX
# include <sys/types.h>
# endif
# include <unistd.h>
#endif
#include <errno.h>
#include "history.h"
#include "histlib.h"
#include "xmalloc.h"
#if !defined (errno)
extern int errno;
#endif
/* How big to make the_history when we first allocate it. */
#define DEFAULT_HISTORY_INITIAL_SIZE 502
#define MAX_HISTORY_INITIAL_SIZE 8192
/* The number of slots to increase the_history by. */
#define DEFAULT_HISTORY_GROW_SIZE 50
static char *hist_inittime (void);
/* **************************************************************** */
/* */
/* History Functions */
/* */
/* **************************************************************** */
/* An array of HIST_ENTRY. This is where we store the history. */
static HIST_ENTRY **the_history = (HIST_ENTRY **)NULL;
/* Non-zero means that we have enforced a limit on the amount of
history that we save. */
static int history_stifled;
/* The current number of slots allocated to the input_history. */
static int history_size;
/* If HISTORY_STIFLED is non-zero, then this is the maximum number of
entries to remember. */
int history_max_entries;
int max_input_history; /* backwards compatibility */
/* The current location of the interactive history pointer. Just makes
life easier for outside callers. */
int history_offset;
/* The number of strings currently stored in the history list. */
int history_length;
/* The logical `base' of the history array. It defaults to 1. */
int history_base = 1;
/* Return the current HISTORY_STATE of the history. */
HISTORY_STATE *
history_get_history_state (void)
{
HISTORY_STATE *state;
state = (HISTORY_STATE *)xmalloc (sizeof (HISTORY_STATE));
state->entries = the_history;
state->offset = history_offset;
state->length = history_length;
state->size = history_size;
state->flags = 0;
if (history_stifled)
state->flags |= HS_STIFLED;
return (state);
}
/* Set the state of the current history array to STATE. */
void
history_set_history_state (HISTORY_STATE *state)
{
the_history = state->entries;
history_offset = state->offset;
history_length = state->length;
history_size = state->size;
if (state->flags & HS_STIFLED)
history_stifled = 1;
}
/* Begin a session in which the history functions might be used. This
initializes interactive variables. */
void
using_history (void)
{
history_offset = history_length;
}
/* Return the number of bytes that the primary history entries are using.
This just adds up the lengths of the_history->lines and the associated
timestamps. */
int
history_total_bytes (void)
{
register int i, result;
for (i = result = 0; the_history && the_history[i]; i++)
result += HISTENT_BYTES (the_history[i]);
return (result);
}
/* Returns the magic number which says what history element we are
looking at now. In this implementation, it returns history_offset. */
int
where_history (void)
{
return (history_offset);
}
/* Make the current history item be the one at POS, an absolute index.
Returns zero if POS is out of range, else non-zero. */
int
history_set_pos (int pos)
{
if (pos > history_length || pos < 0 || !the_history)
return (0);
history_offset = pos;
return (1);
}
/* Are we currently at the end of the history list? */
int
_hs_at_end_of_history (void)
{
return (the_history == 0 || history_offset == history_length);
}
/* Return the current history array. The caller has to be careful, since this
is the actual array of data, and could be bashed or made corrupt easily.
The array is terminated with a NULL pointer. */
HIST_ENTRY **
history_list (void)
{
return (the_history);
}
/* Return the history entry at the current position, as determined by
history_offset. If there is no entry there, return a NULL pointer. */
HIST_ENTRY *
current_history (void)
{
return ((history_offset == history_length) || the_history == 0)
? (HIST_ENTRY *)NULL
: the_history[history_offset];
}
/* Back up history_offset to the previous history entry, and return
a pointer to that entry. If there is no previous entry then return
a NULL pointer. */
HIST_ENTRY *
previous_history (void)
{
return history_offset ? the_history[--history_offset] : (HIST_ENTRY *)NULL;
}
/* Move history_offset forward to the next history entry, and return
a pointer to that entry. If there is no next entry then return a
NULL pointer. */
HIST_ENTRY *
next_history (void)
{
return (history_offset == history_length) ? (HIST_ENTRY *)NULL : the_history[++history_offset];
}
/* Return the history entry which is logically at OFFSET in the history array.
OFFSET is relative to history_base. */
HIST_ENTRY *
history_get (int offset)
{
int local_index;
local_index = offset - history_base;
return (local_index >= history_length || local_index < 0 || the_history == 0)
? (HIST_ENTRY *)NULL
: the_history[local_index];
}
HIST_ENTRY *
alloc_history_entry (char *string, char *ts)
{
HIST_ENTRY *temp;
temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
temp->line = string ? savestring (string) : string;
temp->data = (char *)NULL;
temp->timestamp = ts;
return temp;
}
time_t
history_get_time (HIST_ENTRY *hist)
{
char *ts;
time_t t;
if (hist == 0 || hist->timestamp == 0)
return 0;
ts = hist->timestamp;
if (ts[0] != history_comment_char)
return 0;
errno = 0;
t = (time_t) strtol (ts + 1, (char **)NULL, 10); /* XXX - should use strtol() here */
if (errno == ERANGE)
return (time_t)0;
return t;
}
static char *
hist_inittime (void)
{
time_t t;
char ts[64], *ret;
t = (time_t) time ((time_t *)0);
#if defined (HAVE_VSNPRINTF) /* assume snprintf if vsnprintf exists */
snprintf (ts, sizeof (ts) - 1, "X%lu", (unsigned long) t);
#else
sprintf (ts, "X%lu", (unsigned long) t);
#endif
ret = savestring (ts);
ret[0] = history_comment_char;
return ret;
}
/* Place STRING at the end of the history list. The data field
is set to NULL. */
void
add_history (const char *string)
{
HIST_ENTRY *temp;
int new_length;
if (history_stifled && (history_length == history_max_entries))
{
register int i;
/* If the history is stifled, and history_length is zero,
and it equals history_max_entries, we don't save items. */
if (history_length == 0)
return;
/* If there is something in the slot, then remove it. */
if (the_history[0])
(void) free_history_entry (the_history[0]);
/* Copy the rest of the entries, moving down one slot. Copy includes
trailing NULL. */
memmove (the_history, the_history + 1, history_length * sizeof (HIST_ENTRY *));
new_length = history_length;
history_base++;
}
else
{
if (history_size == 0)
{
if (history_stifled && history_max_entries > 0)
history_size = (history_max_entries > MAX_HISTORY_INITIAL_SIZE)
? MAX_HISTORY_INITIAL_SIZE
: history_max_entries + 2;
else
history_size = DEFAULT_HISTORY_INITIAL_SIZE;
the_history = (HIST_ENTRY **)xmalloc (history_size * sizeof (HIST_ENTRY *));
new_length = 1;
}
else
{
if (history_length == (history_size - 1))
{
history_size += DEFAULT_HISTORY_GROW_SIZE;
the_history = (HIST_ENTRY **)
xrealloc (the_history, history_size * sizeof (HIST_ENTRY *));
}
new_length = history_length + 1;
}
}
temp = alloc_history_entry ((char *)string, hist_inittime ());
the_history[new_length] = (HIST_ENTRY *)NULL;
the_history[new_length - 1] = temp;
history_length = new_length;
}
/* Change the time stamp of the most recent history entry to STRING. */
void
add_history_time (const char *string)
{
HIST_ENTRY *hs;
if (string == 0 || history_length < 1)
return;
hs = the_history[history_length - 1];
FREE (hs->timestamp);
hs->timestamp = savestring (string);
}
/* Free HIST and return the data so the calling application can free it
if necessary and desired. */
histdata_t
free_history_entry (HIST_ENTRY *hist)
{
histdata_t x;
if (hist == 0)
return ((histdata_t) 0);
FREE (hist->line);
FREE (hist->timestamp);
x = hist->data;
xfree (hist);
return (x);
}
HIST_ENTRY *
copy_history_entry (HIST_ENTRY *hist)
{
HIST_ENTRY *ret;
char *ts;
if (hist == 0)
return hist;
ret = alloc_history_entry (hist->line, (char *)NULL);
ts = hist->timestamp ? savestring (hist->timestamp) : hist->timestamp;
ret->timestamp = ts;
ret->data = hist->data;
return ret;
}
/* Make the history entry at WHICH have LINE and DATA. This returns
the old entry so you can dispose of the data. In the case of an
invalid WHICH, a NULL pointer is returned. */
HIST_ENTRY *
replace_history_entry (int which, const char *line, histdata_t data)
{
HIST_ENTRY *temp, *old_value;
if (which < 0 || which >= history_length)
return ((HIST_ENTRY *)NULL);
temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
old_value = the_history[which];
temp->line = savestring (line);
temp->data = data;
temp->timestamp = old_value->timestamp ? savestring (old_value->timestamp) : 0;
the_history[which] = temp;
return (old_value);
}
/* Append LINE to the history line at offset WHICH, adding a newline to the
end of the current line first. This can be used to construct multi-line
history entries while reading lines from the history file. */
void
_hs_append_history_line (int which, const char *line)
{
HIST_ENTRY *hent;
size_t newlen, curlen, minlen;
char *newline;
hent = the_history[which];
curlen = strlen (hent->line);
minlen = curlen + strlen (line) + 2; /* min space needed */
if (curlen > 256) /* XXX - for now */
{
newlen = 512; /* now realloc in powers of 2 */
/* we recalcluate every time; the operations are cheap */
while (newlen < minlen)
newlen <<= 1;
}
else
newlen = minlen;
/* Assume that realloc returns the same pointer and doesn't try a new
alloc/copy if the new size is the same as the one last passed. */
newline = realloc (hent->line, newlen);
if (newline)
{
hent->line = newline;
hent->line[curlen++] = '\n';
strcpy (hent->line + curlen, line);
}
}
/* Replace the DATA in the specified history entries, replacing OLD with
NEW. WHICH says which one(s) to replace: WHICH == -1 means to replace
all of the history entries where entry->data == OLD; WHICH == -2 means
to replace the `newest' history entry where entry->data == OLD; and
WHICH >= 0 means to replace that particular history entry's data, as
long as it matches OLD. */
void
_hs_replace_history_data (int which, histdata_t *old, histdata_t *new)
{
HIST_ENTRY *entry;
register int i, last;
if (which < -2 || which >= history_length || history_length == 0 || the_history == 0)
return;
if (which >= 0)
{
entry = the_history[which];
if (entry && entry->data == old)
entry->data = new;
return;
}
last = -1;
for (i = 0; i < history_length; i++)
{
entry = the_history[i];
if (entry == 0)
continue;
if (entry->data == old)
{
last = i;
if (which == -1)
entry->data = new;
}
}
if (which == -2 && last >= 0)
{
entry = the_history[last];
entry->data = new; /* XXX - we don't check entry->old */
}
}
/* Remove history element WHICH from the history. The removed
element is returned to you so you can free the line, data,
and containing structure. */
HIST_ENTRY *
remove_history (int which)
{
HIST_ENTRY *return_value;
register int i;
#if 1
int nentries;
HIST_ENTRY **start, **end;
#endif
if (which < 0 || which >= history_length || history_length == 0 || the_history == 0)
return ((HIST_ENTRY *)NULL);
return_value = the_history[which];
#if 1
/* Copy the rest of the entries, moving down one slot. Copy includes
trailing NULL. */
nentries = history_length - which;
start = the_history + which;
end = start + 1;
memmove (start, end, nentries * sizeof (HIST_ENTRY *));
#else
for (i = which; i < history_length; i++)
the_history[i] = the_history[i + 1];
#endif
history_length--;
return (return_value);
}
HIST_ENTRY **
remove_history_range (int first, int last)
{
HIST_ENTRY **return_value;
register int i;
int nentries;
HIST_ENTRY **start, **end;
if (the_history == 0 || history_length == 0)
return ((HIST_ENTRY **)NULL);
if (first < 0 || first >= history_length || last < 0 || last >= history_length)
return ((HIST_ENTRY **)NULL);
if (first > last)
return (HIST_ENTRY **)NULL;
nentries = last - first + 1;
return_value = (HIST_ENTRY **)malloc ((nentries + 1) * sizeof (HIST_ENTRY *));
if (return_value == 0)
return return_value;
/* Return all the deleted entries in a list */
for (i = first ; i <= last; i++)
return_value[i - first] = the_history[i];
return_value[i - first] = (HIST_ENTRY *)NULL;
/* Copy the rest of the entries, moving down NENTRIES slots. Copy includes
trailing NULL. */
start = the_history + first;
end = the_history + last + 1;
memmove (start, end, (history_length - last) * sizeof (HIST_ENTRY *));
history_length -= nentries;
return (return_value);
}
/* Stifle the history list, remembering only MAX number of lines. */
void
stifle_history (int max)
{
register int i, j;
if (max < 0)
max = 0;
if (history_length > max)
{
/* This loses because we cannot free the data. */
for (i = 0, j = history_length - max; i < j; i++)
free_history_entry (the_history[i]);
history_base = i;
for (j = 0, i = history_length - max; j < max; i++, j++)
the_history[j] = the_history[i];
the_history[j] = (HIST_ENTRY *)NULL;
history_length = j;
}
history_stifled = 1;
max_input_history = history_max_entries = max;
}
/* Stop stifling the history. This returns the previous maximum
number of history entries. The value is positive if the history
was stifled, negative if it wasn't. */
int
unstifle_history (void)
{
if (history_stifled)
{
history_stifled = 0;
return (history_max_entries);
}
else
return (-history_max_entries);
}
int
history_is_stifled (void)
{
return (history_stifled);
}
void
clear_history (void)
{
register int i;
/* This loses because we cannot free the data. */
for (i = 0; i < history_length; i++)
{
free_history_entry (the_history[i]);
the_history[i] = (HIST_ENTRY *)NULL;
}
history_offset = history_length = 0;
history_base = 1; /* reset history base to default */
}

291
history.h Normal file
View file

@ -0,0 +1,291 @@
/* history.h -- the names of functions that you can call in history. */
/* Copyright (C) 1989-2022 Free Software Foundation, Inc.
This file contains the GNU History Library (History), a set of
routines for managing the text of previously typed lines.
History 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 3 of the License, or
(at your option) any later version.
History 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 History. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _HISTORY_H_
#define _HISTORY_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <time.h> /* XXX - for history timestamp code */
#if defined READLINE_LIBRARY
# include "rlstdc.h"
# include "rltypedefs.h"
#else
# include <readline/rlstdc.h>
# include <readline/rltypedefs.h>
#endif
#ifdef __STDC__
typedef void *histdata_t;
#else
typedef char *histdata_t;
#endif
/* Let's not step on anyone else's define for now, since we don't use this yet. */
#ifndef HS_HISTORY_VERSION
# define HS_HISTORY_VERSION 0x0802 /* History 8.2 */
#endif
/* The structure used to store a history entry. */
typedef struct _hist_entry {
char *line;
char *timestamp; /* char * rather than time_t for read/write */
histdata_t data;
} HIST_ENTRY;
/* Size of the history-library-managed space in history entry HS. */
#define HISTENT_BYTES(hs) (strlen ((hs)->line) + strlen ((hs)->timestamp))
/* A structure used to pass the current state of the history stuff around. */
typedef struct _hist_state {
HIST_ENTRY **entries; /* Pointer to the entries themselves. */
int offset; /* The location pointer within this array. */
int length; /* Number of elements within this array. */
int size; /* Number of slots allocated to this array. */
int flags;
} HISTORY_STATE;
/* Flag values for the `flags' member of HISTORY_STATE. */
#define HS_STIFLED 0x01
/* Initialization and state management. */
/* Begin a session in which the history functions might be used. This
just initializes the interactive variables. */
extern void using_history (void);
/* Return the current HISTORY_STATE of the history. */
extern HISTORY_STATE *history_get_history_state (void);
/* Set the state of the current history array to STATE. */
extern void history_set_history_state (HISTORY_STATE *);
/* Manage the history list. */
/* Place STRING at the end of the history list.
The associated data field (if any) is set to NULL. */
extern void add_history (const char *);
/* Change the timestamp associated with the most recent history entry to
STRING. */
extern void add_history_time (const char *);
/* Remove an entry from the history list. WHICH is the magic number that
tells us which element to delete. The elements are numbered from 0. */
extern HIST_ENTRY *remove_history (int);
/* Remove a set of entries from the history list: FIRST to LAST, inclusive */
extern HIST_ENTRY **remove_history_range (int, int);
/* Allocate a history entry consisting of STRING and TIMESTAMP and return
a pointer to it. */
extern HIST_ENTRY *alloc_history_entry (char *, char *);
/* Copy the history entry H, but not the (opaque) data pointer */
extern HIST_ENTRY *copy_history_entry (HIST_ENTRY *);
/* Free the history entry H and return any application-specific data
associated with it. */
extern histdata_t free_history_entry (HIST_ENTRY *);
/* Make the history entry at WHICH have LINE and DATA. This returns
the old entry so you can dispose of the data. In the case of an
invalid WHICH, a NULL pointer is returned. */
extern HIST_ENTRY *replace_history_entry (int, const char *, histdata_t);
/* Clear the history list and start over. */
extern void clear_history (void);
/* Stifle the history list, remembering only MAX number of entries. */
extern void stifle_history (int);
/* Stop stifling the history. This returns the previous amount the
history was stifled by. The value is positive if the history was
stifled, negative if it wasn't. */
extern int unstifle_history (void);
/* Return 1 if the history is stifled, 0 if it is not. */
extern int history_is_stifled (void);
/* Information about the history list. */
/* Return a NULL terminated array of HIST_ENTRY which is the current input
history. Element 0 of this list is the beginning of time. If there
is no history, return NULL. */
extern HIST_ENTRY **history_list (void);
/* Returns the number which says what history element we are now
looking at. */
extern int where_history (void);
/* Return the history entry at the current position, as determined by
history_offset. If there is no entry there, return a NULL pointer. */
extern HIST_ENTRY *current_history (void);
/* Return the history entry which is logically at OFFSET in the history
array. OFFSET is relative to history_base. */
extern HIST_ENTRY *history_get (int);
/* Return the timestamp associated with the HIST_ENTRY * passed as an
argument */
extern time_t history_get_time (HIST_ENTRY *);
/* Return the number of bytes that the primary history entries are using.
This just adds up the lengths of the_history->lines. */
extern int history_total_bytes (void);
/* Moving around the history list. */
/* Set the position in the history list to POS. */
extern int history_set_pos (int);
/* Back up history_offset to the previous history entry, and return
a pointer to that entry. If there is no previous entry, return
a NULL pointer. */
extern HIST_ENTRY *previous_history (void);
/* Move history_offset forward to the next item in the input_history,
and return the a pointer to that entry. If there is no next entry,
return a NULL pointer. */
extern HIST_ENTRY *next_history (void);
/* Searching the history list. */
/* Search the history for STRING, starting at history_offset.
If DIRECTION < 0, then the search is through previous entries,
else through subsequent. If the string is found, then
current_history () is the history entry, and the value of this function
is the offset in the line of that history entry that the string was
found in. Otherwise, nothing is changed, and a -1 is returned. */
extern int history_search (const char *, int);
/* Search the history for STRING, starting at history_offset.
The search is anchored: matching lines must begin with string.
DIRECTION is as in history_search(). */
extern int history_search_prefix (const char *, int);
/* Search for STRING in the history list, starting at POS, an
absolute index into the list. DIR, if negative, says to search
backwards from POS, else forwards.
Returns the absolute index of the history element where STRING
was found, or -1 otherwise. */
extern int history_search_pos (const char *, int, int);
/* Managing the history file. */
/* Add the contents of FILENAME to the history list, a line at a time.
If FILENAME is NULL, then read from ~/.history. Returns 0 if
successful, or errno if not. */
extern int read_history (const char *);
/* Read a range of lines from FILENAME, adding them to the history list.
Start reading at the FROM'th line and end at the TO'th. If FROM
is zero, start at the beginning. If TO is less than FROM, read
until the end of the file. If FILENAME is NULL, then read from
~/.history. Returns 0 if successful, or errno if not. */
extern int read_history_range (const char *, int, int);
/* Write the current history to FILENAME. If FILENAME is NULL,
then write the history list to ~/.history. Values returned
are as in read_history (). */
extern int write_history (const char *);
/* Append NELEMENT entries to FILENAME. The entries appended are from
the end of the list minus NELEMENTs up to the end of the list. */
extern int append_history (int, const char *);
/* Truncate the history file, leaving only the last NLINES lines. */
extern int history_truncate_file (const char *, int);
/* History expansion. */
/* Expand the string STRING, placing the result into OUTPUT, a pointer
to a string. Returns:
0) If no expansions took place (or, if the only change in
the text was the de-slashifying of the history expansion
character)
1) If expansions did take place
-1) If there was an error in expansion.
2) If the returned line should just be printed.
If an error occurred in expansion, then OUTPUT contains a descriptive
error message. */
extern int history_expand (char *, char **);
/* Extract a string segment consisting of the FIRST through LAST
arguments present in STRING. Arguments are broken up as in
the shell. */
extern char *history_arg_extract (int, int, const char *);
/* Return the text of the history event beginning at the current
offset into STRING. Pass STRING with *INDEX equal to the
history_expansion_char that begins this specification.
DELIMITING_QUOTE is a character that is allowed to end the string
specification for what to search for in addition to the normal
characters `:', ` ', `\t', `\n', and sometimes `?'. */
extern char *get_history_event (const char *, int *, int);
/* Return an array of tokens, much as the shell might. The tokens are
parsed out of STRING. */
extern char **history_tokenize (const char *);
/* Exported history variables. */
extern int history_base;
extern int history_length;
extern int history_max_entries;
extern int history_offset;
extern int history_lines_read_from_file;
extern int history_lines_written_to_file;
extern char history_expansion_char;
extern char history_subst_char;
extern char *history_word_delimiters;
extern char history_comment_char;
extern char *history_no_expand_chars;
extern char *history_search_delimiter_chars;
extern int history_quotes_inhibit_expansion;
extern int history_quoting_state;
extern int history_write_timestamps;
/* These two are undocumented; the second is reserved for future use */
extern int history_multiline_entries;
extern int history_file_version;
/* Backwards compatibility */
extern int max_input_history;
/* If set, this function is called to decide whether or not a particular
history expansion should be treated as a special case for the calling
application and not expanded. */
extern rl_linebuf_func_t *history_inhibit_expansion_function;
#ifdef __cplusplus
}
#endif
#endif /* !_HISTORY_H_ */

11
history.pc.in Normal file
View file

@ -0,0 +1,11 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: History
Description: Gnu History library for managing previously-entered lines
URL: http://tiswww.cwru.edu/php/chet/readline/rltop.html
Version: @LIBVERSION@
Libs: -L${libdir} -lhistory
Cflags: -I${includedir}

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