Adding upstream version 8.2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
This commit is contained in:
parent
d2b2af6dd3
commit
3a96b6e8dc
160 changed files with 152075 additions and 0 deletions
674
COPYING
Normal file
674
COPYING
Normal 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
310
INSTALL
Normal 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
171
MANIFEST
Normal 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
610
Makefile.in
Normal 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
485
NEWS
Normal 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
196
README
Normal 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
37
USAGE
Normal 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
2267
aclocal.m4
vendored
Normal file
File diff suppressed because it is too large
Load diff
54
ansi_stdlib.h
Normal file
54
ansi_stdlib.h
Normal 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 */
|
378
callback.c
Normal file
378
callback.c
Normal 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
165
chardefs.h
Normal 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
320
colors.c
Normal 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
126
colors.h
Normal 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
106
compat.c
Normal 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
2992
complete.c
Normal file
File diff suppressed because it is too large
Load diff
311
config.h.in
Normal file
311
config.h.in
Normal 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 */
|
345
configure.ac
Normal file
345
configure.ac
Normal 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
|
272
doc/Makefile.in
Normal file
272
doc/Makefile.in
Normal 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
506
doc/fdl.texi
Normal 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
505
doc/history.0
Normal file
|
@ -0,0 +1,505 @@
|
|||
HISTORY(3) Library Functions Manual HISTORY(3)
|
||||
|
||||
|
||||
|
||||
[1mNAME[0m
|
||||
history - GNU History Library
|
||||
|
||||
[1mCOPYRIGHT[0m
|
||||
The GNU History Library is Copyright (C) 1989-2020 by the Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
[1mDESCRIPTION[0m
|
||||
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.
|
||||
|
||||
[1mHISTORY EXPANSION[0m
|
||||
The history library supports a history expansion feature that is iden-
|
||||
tical to the history expansion in [1mbash. [22mThis 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 [4mevent[24m, and the portions
|
||||
of that line that are acted upon are [4mwords[24m. Various [4mmodifiers[24m are
|
||||
available to manipulate the selected words. The line is broken into
|
||||
words in the same fashion as [1mbash [22mdoes 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 [1mhistory_tokenize()[0m
|
||||
below). History expansions are introduced by the appearance of the
|
||||
history expansion character, which is [1m! [22mby default. Only backslash ([1m\[22m)
|
||||
and single quotes can quote the history expansion character.
|
||||
|
||||
[1mEvent Designators[0m
|
||||
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.
|
||||
|
||||
[1m! [22mStart a history substitution, except when followed by a [1mblank[22m,
|
||||
newline, = or (.
|
||||
[1m![4m[22mn[24m Refer to command line [4mn[24m.
|
||||
[1m!-[4m[22mn[24m Refer to the current command minus [4mn[24m.
|
||||
[1m!! [22mRefer to the previous command. This is a synonym for `!-1'.
|
||||
[1m![4m[22mstring[0m
|
||||
Refer to the most recent command preceding the current position
|
||||
in the history list starting with [4mstring[24m.
|
||||
[1m!?[4m[22mstring[24m[1m[?][0m
|
||||
Refer to the most recent command preceding the current position
|
||||
in the history list containing [4mstring[24m. The trailing [1m? [22mmay be
|
||||
omitted if [4mstring[24m is followed immediately by a newline. If
|
||||
[4mstring[24m is missing, the string from the most recent search is
|
||||
used; it is an error if there is no previous search string.
|
||||
[1m^[4m[22mstring1[24m[1m^[4m[22mstring2[24m[1m^[0m
|
||||
Quick substitution. Repeat the last command, replacing [4mstring1[0m
|
||||
with [4mstring2[24m. Equivalent to ``!!:s^[4mstring1[24m^[4mstring2[24m^'' (see [1mMod-[0m
|
||||
[1mifiers [22mbelow).
|
||||
[1m!# [22mThe entire command line typed so far.
|
||||
|
||||
[1mWord Designators[0m
|
||||
Word designators are used to select desired words from the event. A [1m:[0m
|
||||
separates the event specification from the word designator. It may be
|
||||
omitted if the word designator begins with a [1m^[22m, [1m$[22m, [1m*[22m, [1m-[22m, or [1m%[22m. 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.
|
||||
|
||||
[1m0 (zero)[0m
|
||||
The zeroth word. For the shell, this is the command word.
|
||||
[4mn[24m The [4mn[24mth word.
|
||||
[1m^ [22mThe first argument. That is, word 1.
|
||||
[1m$ [22mThe 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.
|
||||
[1m% [22mThe first word matched by the most recent `?[4mstring[24m?' search, if
|
||||
the search string begins with a character that is part of a
|
||||
word.
|
||||
[4mx[24m[1m-[4m[22my[24m A range of words; `-[4my[24m' abbreviates `0-[4my[24m'.
|
||||
[1m* [22mAll of the words but the zeroth. This is a synonym for `[4m1-$[24m'.
|
||||
It is not an error to use [1m* [22mif there is just one word in the
|
||||
event; the empty string is returned in that case.
|
||||
[1mx* [22mAbbreviates [4mx-$[24m.
|
||||
[1mx- [22mAbbreviates [4mx-$[24m like [1mx*[22m, but omits the last word. If [1mx [22mis miss-
|
||||
ing, it defaults to 0.
|
||||
|
||||
If a word designator is supplied without an event specification, the
|
||||
previous command is used as the event.
|
||||
|
||||
[1mModifiers[0m
|
||||
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.
|
||||
|
||||
[1mh [22mRemove a trailing file name component, leaving only the head.
|
||||
[1mt [22mRemove all leading file name components, leaving the tail.
|
||||
[1mr [22mRemove a trailing suffix of the form [4m.xxx[24m, leaving the basename.
|
||||
[1me [22mRemove all but the trailing suffix.
|
||||
[1mp [22mPrint the new command but do not execute it.
|
||||
[1mq [22mQuote the substituted words, escaping further substitutions.
|
||||
[1mx [22mQuote the substituted words as with [1mq[22m, but break into words at
|
||||
[1mblanks [22mand newlines. The [1mq [22mand [1mx [22mmodifiers are mutually exclu-
|
||||
sive; the last one supplied is used.
|
||||
[1ms/[4m[22mold[24m[1m/[4m[22mnew[24m[1m/[0m
|
||||
Substitute [4mnew[24m for the first occurrence of [4mold[24m 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 [4mold[24m and [4mnew[24m with
|
||||
a single backslash. If & appears in [4mnew[24m, it is replaced by [4mold[24m.
|
||||
A single backslash will quote the &. If [4mold[24m is null, it is set
|
||||
to the last [4mold[24m substituted, or, if no previous history substi-
|
||||
tutions took place, the last [4mstring[24m in a [1m!?[4m[22mstring[24m[1m[?] [22msearch.
|
||||
If [4mnew[24m is null, each matching [4mold[24m is deleted.
|
||||
[1m& [22mRepeat the previous substitution.
|
||||
[1mg [22mCause changes to be applied over the entire event line. This is
|
||||
used in conjunction with `[1m:s[22m' (e.g., `[1m:gs/[4m[22mold[24m[1m/[4m[22mnew[24m[1m/[22m') or `[1m:&[22m'.
|
||||
If used with `[1m:s[22m', 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 [1ma [22mmay be used as a synonym for [1mg[22m.
|
||||
[1mG [22mApply the following `[1ms[22m' or `[1m&[22m' modifier once to each word in the
|
||||
event line.
|
||||
|
||||
[1mPROGRAMMING WITH HISTORY FUNCTIONS[0m
|
||||
This section describes how to use the History library in other pro-
|
||||
grams.
|
||||
|
||||
[1mIntroduction to History[0m
|
||||
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 [4mexpansion[24m 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 [1mbash[22m.
|
||||
|
||||
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 [4m<readline/history.h>[24m 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.
|
||||
|
||||
[1mHistory Storage[0m
|
||||
The history list is an array of history entries. A history entry is
|
||||
declared as follows:
|
||||
|
||||
[4mtypedef[24m [4mvoid[24m [4m*[24m [1mhistdata_t;[0m
|
||||
|
||||
typedef struct _hist_entry {
|
||||
char *line;
|
||||
char *timestamp;
|
||||
histdata_t data;
|
||||
} HIST_ENTRY;
|
||||
|
||||
The history list itself might therefore be declared as
|
||||
|
||||
[4mHIST_ENTRY[24m [4m**[24m [1mthe_history_list;[0m
|
||||
|
||||
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 [1mHS_STIFLED[22m, the history has been stifled.
|
||||
|
||||
[1mHistory Functions[0m
|
||||
This section describes the calling sequence for the various functions
|
||||
exported by the GNU History library.
|
||||
|
||||
[1mInitializing History and State Management[0m
|
||||
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.
|
||||
|
||||
[4mvoid[24m [1musing_history [22m([4mvoid[24m)
|
||||
Begin a session in which the history functions might be used. This
|
||||
initializes the interactive variables.
|
||||
|
||||
[4mHISTORY_STATE[24m [4m*[24m [1mhistory_get_history_state [22m([4mvoid[24m)
|
||||
Return a structure describing the current state of the input history.
|
||||
|
||||
[4mvoid[24m [1mhistory_set_history_state [22m([4mHISTORY_STATE[24m [4m*state[24m)
|
||||
Set the state of the history list according to [4mstate[24m.
|
||||
|
||||
|
||||
[1mHistory List Management[0m
|
||||
These functions manage individual entries on the history list, or set
|
||||
parameters managing the list itself.
|
||||
|
||||
[4mvoid[24m [1madd_history [22m([4mconst[24m [4mchar[24m [4m*string[24m)
|
||||
Place [4mstring[24m at the end of the history list. The associated data field
|
||||
(if any) is set to [1mNULL[22m. If the maximum number of history entries has
|
||||
been set using [1mstifle_history()[22m, and the new number of history entries
|
||||
would exceed that maximum, the oldest history entry is removed.
|
||||
|
||||
[4mvoid[24m [1madd_history_time [22m([4mconst[24m [4mchar[24m [4m*string[24m)
|
||||
Change the time stamp associated with the most recent history entry to
|
||||
[4mstring[24m.
|
||||
|
||||
[4mHIST_ENTRY[24m [4m*[24m [1mremove_history [22m([4mint[24m [4mwhich[24m)
|
||||
Remove history entry at offset [4mwhich[24m from the history. The removed el-
|
||||
ement is returned so you can free the line, data, and containing struc-
|
||||
ture.
|
||||
|
||||
[4mhistdata_t[24m [1mfree_history_entry [22m([4mHIST_ENTRY[24m [4m*histent[24m)
|
||||
Free the history entry [4mhistent[24m and any history library private data as-
|
||||
sociated with it. Returns the application-specific data so the caller
|
||||
can dispose of it.
|
||||
|
||||
[4mHIST_ENTRY[24m [4m*[24m [1mreplace_history_entry [22m([4mint[24m [4mwhich,[24m [4mconst[24m [4mchar[24m [4m*line,[24m [4mhist-[0m
|
||||
[4mdata_t[24m [4mdata[24m)
|
||||
Make the history entry at offset [4mwhich[24m have [4mline[24m and [4mdata[24m. This re-
|
||||
turns the old entry so the caller can dispose of any application-spe-
|
||||
cific data. In the case of an invalid [4mwhich[24m, a [1mNULL [22mpointer is re-
|
||||
turned.
|
||||
|
||||
[4mvoid[24m [1mclear_history [22m([4mvoid[24m)
|
||||
Clear the history list by deleting all the entries.
|
||||
|
||||
[4mvoid[24m [1mstifle_history [22m([4mint[24m [4mmax[24m)
|
||||
Stifle the history list, remembering only the last [4mmax[24m entries. The
|
||||
history list will contain only [4mmax[24m entries at a time.
|
||||
|
||||
[4mint[24m [1munstifle_history [22m([4mvoid[24m)
|
||||
Stop stifling the history. This returns the previously-set maximum
|
||||
number of history entries (as set by [1mstifle_history()[22m). history was
|
||||
stifled. The value is positive if the history was stifled, negative if
|
||||
it wasn't.
|
||||
|
||||
[4mint[24m [1mhistory_is_stifled [22m([4mvoid[24m)
|
||||
Returns non-zero if the history is stifled, zero if it is not.
|
||||
|
||||
|
||||
[1mInformation About the History List[0m
|
||||
These functions return information about the entire history list or in-
|
||||
dividual list entries.
|
||||
|
||||
[4mHIST_ENTRY[24m [4m**[24m [1mhistory_list [22m([4mvoid[24m)
|
||||
Return a [1mNULL [22mterminated array of [4mHIST_ENTRY[24m [4m*[24m which is the current in-
|
||||
put history. Element 0 of this list is the beginning of time. If
|
||||
there is no history, return [1mNULL[22m.
|
||||
|
||||
[4mint[24m [1mwhere_history [22m([4mvoid[24m)
|
||||
Returns the offset of the current history element.
|
||||
|
||||
[4mHIST_ENTRY[24m [4m*[24m [1mcurrent_history [22m([4mvoid[24m)
|
||||
Return the history entry at the current position, as determined by
|
||||
[1mwhere_history()[22m. If there is no entry there, return a [1mNULL [22mpointer.
|
||||
|
||||
[4mHIST_ENTRY[24m [4m*[24m [1mhistory_get [22m([4mint[24m [4moffset[24m)
|
||||
Return the history entry at position [4moffset[24m. The range of valid values
|
||||
of [4moffset[24m starts at [1mhistory_base [22mand ends at [1mhistory_length [22m- 1. If
|
||||
there is no entry there, or if [4moffset[24m is outside the valid range, re-
|
||||
turn a [1mNULL [22mpointer.
|
||||
|
||||
[4mtime_t[24m [1mhistory_get_time [22m([4mHIST_ENTRY[24m [4m*[24m)
|
||||
Return the time stamp associated with the history entry passed as the
|
||||
argument.
|
||||
|
||||
[4mint[24m [1mhistory_total_bytes [22m([4mvoid[24m)
|
||||
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.
|
||||
|
||||
|
||||
[1mMoving Around the History List[0m
|
||||
These functions allow the current index into the history list to be set
|
||||
or changed.
|
||||
|
||||
[4mint[24m [1mhistory_set_pos [22m([4mint[24m [4mpos[24m)
|
||||
Set the current history offset to [4mpos[24m, an absolute index into the list.
|
||||
Returns 1 on success, 0 if [4mpos[24m is less than zero or greater than the
|
||||
number of history entries.
|
||||
|
||||
[4mHIST_ENTRY[24m [4m*[24m [1mprevious_history [22m([4mvoid[24m)
|
||||
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 [1mNULL [22mpointer.
|
||||
|
||||
[4mHIST_ENTRY[24m [4m*[24m [1mnext_history [22m([4mvoid[24m)
|
||||
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 [1mNULL [22mpointer.
|
||||
|
||||
|
||||
[1mSearching the History List[0m
|
||||
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 [4man-[0m
|
||||
[4mchored[24m, meaning that the string must match at the beginning of the his-
|
||||
tory entry.
|
||||
|
||||
[4mint[24m [1mhistory_search [22m([4mconst[24m [4mchar[24m [4m*string,[24m [4mint[24m [4mdirection[24m)
|
||||
Search the history for [4mstring[24m, starting at the current history offset.
|
||||
If [4mdirection[24m is less than 0, then the search is through previous en-
|
||||
tries, otherwise through subsequent entries. If [4mstring[24m 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 [4mstring[24m was found.
|
||||
Otherwise, nothing is changed, and a -1 is returned.
|
||||
|
||||
[4mint[24m [1mhistory_search_prefix [22m([4mconst[24m [4mchar[24m [4m*string,[24m [4mint[24m [4mdirection[24m)
|
||||
Search the history for [4mstring[24m, starting at the current history offset.
|
||||
The search is anchored: matching lines must begin with [4mstring[24m. If [4mdi-[0m
|
||||
[4mrection[24m is less than 0, then the search is through previous entries,
|
||||
otherwise through subsequent entries. If [4mstring[24m 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.
|
||||
|
||||
[4mint[24m [1mhistory_search_pos [22m([4mconst[24m [4mchar[24m [4m*string,[24m [4mint[24m [4mdirection,[24m [4mint[24m [4mpos[24m)
|
||||
Search for [4mstring[24m in the history list, starting at [4mpos[24m, an absolute in-
|
||||
dex into the list. If [4mdirection[24m is negative, the search proceeds back-
|
||||
ward from [4mpos[24m, otherwise forward. Returns the absolute index of the
|
||||
history element where [4mstring[24m was found, or -1 otherwise.
|
||||
|
||||
|
||||
[1mManaging the History File[0m
|
||||
The History library can read the history from and write it to a file.
|
||||
This section documents the functions for managing a history file.
|
||||
|
||||
[4mint[24m [1mread_history [22m([4mconst[24m [4mchar[24m [4m*filename[24m)
|
||||
Add the contents of [4mfilename[24m to the history list, a line at a time. If
|
||||
[4mfilename[24m is [1mNULL[22m, then read from [4m~/.history[24m. Returns 0 if successful,
|
||||
or [1merrno [22mif not.
|
||||
|
||||
[4mint[24m [1mread_history_range [22m([4mconst[24m [4mchar[24m [4m*filename,[24m [4mint[24m [4mfrom,[24m [4mint[24m [4mto[24m)
|
||||
Read a range of lines from [4mfilename[24m, adding them to the history list.
|
||||
Start reading at line [4mfrom[24m and end at [4mto[24m. If [4mfrom[24m is zero, start at
|
||||
the beginning. If [4mto[24m is less than [4mfrom[24m, then read until the end of the
|
||||
file. If [4mfilename[24m is [1mNULL[22m, then read from [4m~/.history[24m. Returns 0 if
|
||||
successful, or [1merrno [22mif not.
|
||||
|
||||
[4mint[24m [1mwrite_history [22m([4mconst[24m [4mchar[24m [4m*filename[24m)
|
||||
Write the current history to [4mfilename[24m, overwriting [4mfilename[24m if neces-
|
||||
sary. If [4mfilename[24m is [1mNULL[22m, then write the history list to [4m~/.history[24m.
|
||||
Returns 0 on success, or [1merrno [22mon a read or write error.
|
||||
|
||||
|
||||
[4mint[24m [1mappend_history [22m([4mint[24m [4mnelements,[24m [4mconst[24m [4mchar[24m [4m*filename[24m)
|
||||
Append the last [4mnelements[24m of the history list to [4mfilename[24m. If [4mfilename[0m
|
||||
is [1mNULL[22m, then append to [4m~/.history[24m. Returns 0 on success, or [1merrno [22mon
|
||||
a read or write error.
|
||||
|
||||
[4mint[24m [1mhistory_truncate_file [22m([4mconst[24m [4mchar[24m [4m*filename,[24m [4mint[24m [4mnlines[24m)
|
||||
Truncate the history file [4mfilename[24m, leaving only the last [4mnlines[24m lines.
|
||||
If [4mfilename[24m is [1mNULL[22m, then [4m~/.history[24m is truncated. Returns 0 on suc-
|
||||
cess, or [1merrno [22mon failure.
|
||||
|
||||
|
||||
[1mHistory Expansion[0m
|
||||
These functions implement history expansion.
|
||||
|
||||
[4mint[24m [1mhistory_expand [22m([4mchar[24m [4m*string,[24m [4mchar[24m [4m**output[24m)
|
||||
Expand [4mstring[24m, placing the result into [4moutput[24m, 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 [1m:p [22mmodifier.
|
||||
If an error occurred in expansion, then [4moutput[24m contains a descriptive
|
||||
error message.
|
||||
|
||||
[4mchar[24m [4m*[24m [1mget_history_event [22m([4mconst[24m [4mchar[24m [4m*string,[24m [4mint[24m [4m*cindex,[24m [4mint[24m [4mqchar[24m)
|
||||
Returns the text of the history event beginning at [4mstring[24m + [4m*cindex[24m.
|
||||
[4m*cindex[24m is modified to point to after the event specifier. At function
|
||||
entry, [4mcindex[24m points to the index into [4mstring[24m where the history event
|
||||
specification begins. [4mqchar[24m is a character that is allowed to end the
|
||||
event specification in addition to the ``normal'' terminating charac-
|
||||
ters.
|
||||
|
||||
[4mchar[24m [4m**[24m [1mhistory_tokenize [22m([4mconst[24m [4mchar[24m [4m*string[24m)
|
||||
Return an array of tokens parsed out of [4mstring[24m, much as the shell
|
||||
might. The tokens are split on the characters in the [1mhistory_word_de-[0m
|
||||
[1mlimiters [22mvariable, and shell quoting conventions are obeyed.
|
||||
|
||||
[4mchar[24m [4m*[24m [1mhistory_arg_extract [22m([4mint[24m [4mfirst,[24m [4mint[24m [4mlast,[24m [4mconst[24m [4mchar[24m [4m*string[24m)
|
||||
Extract a string segment consisting of the [4mfirst[24m through [4mlast[24m arguments
|
||||
present in [4mstring[24m. Arguments are split using [1mhistory_tokenize()[22m.
|
||||
|
||||
|
||||
[1mHistory Variables[0m
|
||||
This section describes the externally-visible variables exported by the
|
||||
GNU History Library.
|
||||
|
||||
[4mint[24m [1mhistory_base[0m
|
||||
The logical offset of the first entry in the history list.
|
||||
|
||||
[4mint[24m [1mhistory_length[0m
|
||||
The number of entries currently stored in the history list.
|
||||
|
||||
[4mint[24m [1mhistory_max_entries[0m
|
||||
The maximum number of history entries. This must be changed using [1msti-[0m
|
||||
[1mfle_history()[22m.
|
||||
|
||||
[4mint[24m [1mhistory_write_timestamps[0m
|
||||
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
|
||||
[4mhistory_comment_char[24m to delimit timestamp entries in the history file.
|
||||
If that variable does not have a value (the default), timestamps will
|
||||
not be written.
|
||||
|
||||
[4mchar[24m [1mhistory_expansion_char[0m
|
||||
The character that introduces a history event. The default is [1m![22m. Set-
|
||||
ting this to 0 inhibits history expansion.
|
||||
|
||||
[4mchar[24m [1mhistory_subst_char[0m
|
||||
The character that invokes word substitution if found at the start of a
|
||||
line. The default is [1m^[22m.
|
||||
|
||||
[4mchar[24m [1mhistory_comment_char[0m
|
||||
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.
|
||||
|
||||
[4mchar[24m [4m*[24m [1mhistory_word_delimiters[0m
|
||||
The characters that separate tokens for [1mhistory_tokenize()[22m. The de-
|
||||
fault value is [1m" \t\n()<>;&|"[22m.
|
||||
|
||||
[4mchar[24m [4m*[24m [1mhistory_no_expand_chars[0m
|
||||
The list of characters which inhibit history expansion if found immedi-
|
||||
ately following [1mhistory_expansion_char[22m. The default is space, tab,
|
||||
newline, [1m\r[22m, and [1m=[22m.
|
||||
|
||||
[4mchar[24m [4m*[24m [1mhistory_search_delimiter_chars[0m
|
||||
The list of additional characters which can delimit a history search
|
||||
string, in addition to space, tab, [4m:[24m and [4m?[24m in the case of a substring
|
||||
search. The default is empty.
|
||||
|
||||
[4mint[24m [1mhistory_quotes_inhibit_expansion[0m
|
||||
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.
|
||||
|
||||
[4mrl_linebuf_func_t[24m [4m*[24m [1mhistory_inhibit_expansion_function[0m
|
||||
This should be set to the address of a function that takes two argu-
|
||||
ments: a [1mchar * [22m([4mstring[24m) and an [1mint [22mindex into that string ([4mi[24m). It
|
||||
should return a non-zero value if the history expansion starting at
|
||||
[4mstring[i][24m should not be performed; zero if the expansion should be
|
||||
done. It is intended for use by applications like [1mbash [22mthat use the
|
||||
history expansion character for additional purposes. By default, this
|
||||
variable is set to [1mNULL[22m.
|
||||
|
||||
[1mFILES[0m
|
||||
[4m~/.history[0m
|
||||
Default filename for reading and writing saved history
|
||||
|
||||
[1mSEE ALSO[0m
|
||||
[4mThe[24m [4mGnu[24m [4mReadline[24m [4mLibrary[24m, Brian Fox and Chet Ramey
|
||||
[4mThe[24m [4mGnu[24m [4mHistory[24m [4mLibrary[24m, Brian Fox and Chet Ramey
|
||||
[4mbash[24m(1)
|
||||
[4mreadline[24m(3)
|
||||
|
||||
[1mAUTHORS[0m
|
||||
Brian Fox, Free Software Foundation
|
||||
bfox@gnu.org
|
||||
|
||||
Chet Ramey, Case Western Reserve University
|
||||
chet.ramey@case.edu
|
||||
|
||||
[1mBUG REPORTS[0m
|
||||
If you find a bug in the [1mhistory [22mlibrary, 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 [1mhistory [22mlibrary that you have.
|
||||
|
||||
Once you have determined that a bug actually exists, mail a bug report
|
||||
to [4mbug-readline[24m@[4mgnu.org[24m. If you have a fix, you are welcome to mail
|
||||
that as well! Suggestions and `philosophical' bug reports may be
|
||||
mailed to [4mbug-readline[24m@[4mgnu.org[24m or posted to the Usenet newsgroup
|
||||
[1mgnu.bash.bug[22m.
|
||||
|
||||
Comments and bug reports concerning this manual page should be directed
|
||||
to [4mchet.ramey@case.edu[24m.
|
||||
|
||||
|
||||
|
||||
GNU History 8.1 2020 July 17 HISTORY(3)
|
687
doc/history.3
Normal file
687
doc/history.3
Normal 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
BIN
doc/history.dvi
Normal file
Binary file not shown.
1751
doc/history.html
Normal file
1751
doc/history.html
Normal file
File diff suppressed because it is too large
Load diff
1426
doc/history.info
Normal file
1426
doc/history.info
Normal file
File diff suppressed because it is too large
Load diff
BIN
doc/history.pdf
Normal file
BIN
doc/history.pdf
Normal file
Binary file not shown.
6666
doc/history.ps
Normal file
6666
doc/history.ps
Normal file
File diff suppressed because it is too large
Load diff
85
doc/history.texi
Normal file
85
doc/history.texi
Normal 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
896
doc/history_3.ps
Normal 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
602
doc/hstech.texi
Normal 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
533
doc/hsuser.texi
Normal 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
1175
doc/readline.0
Normal file
File diff suppressed because it is too large
Load diff
1597
doc/readline.3
Normal file
1597
doc/readline.3
Normal file
File diff suppressed because it is too large
Load diff
BIN
doc/readline.dvi
Normal file
BIN
doc/readline.dvi
Normal file
Binary file not shown.
6286
doc/readline.html
Normal file
6286
doc/readline.html
Normal file
File diff suppressed because it is too large
Load diff
5320
doc/readline.info
Normal file
5320
doc/readline.info
Normal file
File diff suppressed because it is too large
Load diff
BIN
doc/readline.pdf
Normal file
BIN
doc/readline.pdf
Normal file
Binary file not shown.
12656
doc/readline.ps
Normal file
12656
doc/readline.ps
Normal file
File diff suppressed because it is too large
Load diff
1782
doc/readline_3.ps
Normal file
1782
doc/readline_3.ps
Normal file
File diff suppressed because it is too large
Load diff
84
doc/rlman.texi
Normal file
84
doc/rlman.texi
Normal 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
2815
doc/rltech.texi
Normal file
File diff suppressed because it is too large
Load diff
2488
doc/rluser.texi
Normal file
2488
doc/rluser.texi
Normal file
File diff suppressed because it is too large
Load diff
BIN
doc/rluserman.dvi
Normal file
BIN
doc/rluserman.dvi
Normal file
Binary file not shown.
2529
doc/rluserman.html
Normal file
2529
doc/rluserman.html
Normal file
File diff suppressed because it is too large
Load diff
2087
doc/rluserman.info
Normal file
2087
doc/rluserman.info
Normal file
File diff suppressed because it is too large
Load diff
BIN
doc/rluserman.pdf
Normal file
BIN
doc/rluserman.pdf
Normal file
Binary file not shown.
7574
doc/rluserman.ps
Normal file
7574
doc/rluserman.ps
Normal file
File diff suppressed because it is too large
Load diff
70
doc/rluserman.texi
Normal file
70
doc/rluserman.texi
Normal 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
1996
doc/texi2dvi
Normal file
File diff suppressed because it is too large
Load diff
5428
doc/texi2html
Normal file
5428
doc/texi2html
Normal file
File diff suppressed because it is too large
Load diff
11045
doc/texinfo.tex
Normal file
11045
doc/texinfo.tex
Normal file
File diff suppressed because it is too large
Load diff
11
doc/version.texi
Normal file
11
doc/version.texi
Normal 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
872
emacs_keymap.c
Normal 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
81
examples/Inputrc
Normal 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
193
examples/Makefile.in
Normal 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
|
41
examples/autoconf/BASH_CHECK_LIB_TERMCAP
Normal file
41
examples/autoconf/BASH_CHECK_LIB_TERMCAP
Normal 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
|
||||
])
|
119
examples/autoconf/RL_LIB_READLINE_VERSION
Normal file
119
examples/autoconf/RL_LIB_READLINE_VERSION
Normal 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
|
||||
])
|
76
examples/autoconf/wi_LIB_READLINE
Normal file
76
examples/autoconf/wi_LIB_READLINE
Normal 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
200
examples/excallback.c
Normal 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
506
examples/fileman.c
Normal 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
121
examples/hist_erasedups.c
Normal 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
151
examples/hist_purgecmd.c
Normal 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 (®ex, 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 (®ex, 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 (®ex);
|
||||
|
||||
return r;
|
||||
}
|
128
examples/histexamp.c
Normal file
128
examples/histexamp.c
Normal 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
111
examples/manexamp.c
Normal 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
139
examples/readlinebuf.h
Normal 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
115
examples/rl-callbacktest.c
Normal 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
374
examples/rl-fgets.c
Normal 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
6
examples/rl-test-timeout
Normal 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
245
examples/rl-timeout.c
Normal 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
166
examples/rl.c
Normal 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
37
examples/rlbasic.c
Normal 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
187
examples/rlcat.c
Normal 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
181
examples/rlevent.c
Normal 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
37
examples/rlfe/ChangeLog
Normal 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
184
examples/rlfe/Makefile.in
Normal 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
78
examples/rlfe/README
Normal 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
383
examples/rlfe/config.h.in
Normal 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
5637
examples/rlfe/configure
vendored
Executable file
File diff suppressed because it is too large
Load diff
442
examples/rlfe/configure.in
Normal file
442
examples/rlfe/configure.in
Normal 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
40
examples/rlfe/extern.h
Normal 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
531
examples/rlfe/os.h
Normal 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
388
examples/rlfe/pty.c
Normal 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
792
examples/rlfe/rlfe.c
Normal 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
2
examples/rlfe/screen.h
Normal file
|
@ -0,0 +1,2 @@
|
|||
/* Dummy header to avoid modifying pty.c */
|
||||
#include "os.h"
|
61
examples/rlkeymaps.c
Normal file
61
examples/rlkeymaps.c
Normal 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
354
examples/rlptytest.c
Normal 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
101
examples/rltest.c
Normal 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
49
examples/rlversion.c
Normal 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
BIN
examples/rlwrap-0.30.tar.gz
Normal file
Binary file not shown.
273
funmap.c
Normal file
273
funmap.c
Normal 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
1718
histexpand.c
Normal file
File diff suppressed because it is too large
Load diff
833
histfile.c
Normal file
833
histfile.c
Normal 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
92
histlib.h
Normal 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
614
history.c
Normal 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
291
history.h
Normal 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
11
history.pc.in
Normal 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
Loading…
Add table
Add a link
Reference in a new issue